From 14733b9660009241c7c32a1afdc0b81ae995ac5c Mon Sep 17 00:00:00 2001 From: sBubshait Date: Mon, 3 Jun 2024 14:47:50 +0100 Subject: [PATCH] Add execute for SDT instructions, w/ T --- src/execute.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--- src/execute.h | 1 + 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/execute.c b/src/execute.c index 3e8c57f..78e0efd 100644 --- a/src/execute.c +++ b/src/execute.c @@ -4,13 +4,16 @@ // if the shift flag is enabled. #define DPI_ARITHM_SHIFT 12 +// Prototypes +void execute_SDT(Machine *state, a64inst_instruction *inst); + // Truncate a given value to the size of a word or dword depending on the register type static dword truncateValue(dword value, a64inst_regType regType) { if (regType == a64inst_R) { - return value + return value; } else { //return value & ~(dword)((1 << WORD_BITS) - 1) - return value & (1 << WORD_BITS) - 1 + return value & (1 << WORD_BITS) - 1; } } @@ -18,7 +21,7 @@ static dword truncateValue(dword value, a64inst_regType regType) { // and accounting for the case where the zero register is accessed. Truncate // the 32 most significant bits stored in the R register when reading W register. static dword readRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType) { - assert(reg <= REGISTER_COUNT) + assert(reg <= REGISTER_COUNT); if (reg == ZERO_REGISTER) { return 0; } else { @@ -103,9 +106,59 @@ void execute(Machine *state, a64inst_instruction *inst) { case a64inst_DPREGISTER: break; + case a64inst_SINGLETRANSFER: + execute_SDT(state, inst); + break; + // Unknown instruction default: break; } +} + +void execute_SDT(Machine *state, a64inst_instruction *inst) { + word address; + bool isLoad; + if (inst->data.SingleTransferData.SingleTransferOpType == a64inst_SINGLE_TRANSFER_LOAD_LITERAL) { + // Load Literal + isLoad = true; + address = state->pc + inst->data.SingleTransferData.processOpData.loadLiteralData.offset * 4; + } else { + address = state->registers[inst->data.SingleTransferData.processOpData.singleDataTransferData.base]; + isLoad = inst->data.SingleTransferData.processOpData.singleDataTransferData.transferType == a64inst_LOAD; + switch (inst->data.SingleTransferData.processOpData.singleDataTransferData.addressingMode) { + case a64inst_UNSIGNED_OFFSET: + address += inst->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.unsignedOffset; + address *= inst->data.SingleTransferData.regType == a64inst_W ? 4 : 8; + break; + case a64inst_REGISTER_OFFSET: + address += state->registers[inst->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.offsetReg]; + break; + case a64inst_PRE_INDEXED: + address += inst->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.indexedOffset; + state->registers[inst->data.SingleTransferData.processOpData.singleDataTransferData.base] = address; + break; + case a64inst_POST_INDEXED: + state->registers[inst->data.SingleTransferData.processOpData.singleDataTransferData.base] = address + inst->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.indexedOffset; + break; + } + } + + if (isLoad) { + if (inst->data.SingleTransferData.regType == a64inst_W) { + // 32 bit access + state->registers[inst->data.SingleTransferData.target] = readWord(state->memory, address); + } else { + state->registers[inst->data.SingleTransferData.target] = readDoubleWord(state->memory, address); + } + }else { + if (inst->data.SingleTransferData.regType == a64inst_W) { + // 32 bit access + state->registers[inst->data.SingleTransferData.target] = readWord(state->memory, address); + } else { + state->registers[inst->data.SingleTransferData.target] = readDoubleWord(state->memory, address); + } + } + } \ No newline at end of file diff --git a/src/execute.h b/src/execute.h index fcf39ec..debc341 100644 --- a/src/execute.h +++ b/src/execute.h @@ -2,6 +2,7 @@ #define __EXECUTE__ #include "a64instruction.h" #include "emulator.h" +#include "print.c" void execute(Machine *state, a64inst_instruction *inst); #endif