Add execute for SDT instructions, w/ T

This commit is contained in:
sBubshait 2024-06-03 14:47:50 +01:00
parent 10d89ecf91
commit 14733b9660
2 changed files with 57 additions and 3 deletions

View File

@ -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);
}
}
}

View File

@ -2,6 +2,7 @@
#define __EXECUTE__
#include "a64instruction.h"
#include "emulator.h"
#include "print.c"
void execute(Machine *state, a64inst_instruction *inst);
#endif