Add execute for SDT instructions, w/ T
This commit is contained in:
parent
10d89ecf91
commit
14733b9660
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
#define __EXECUTE__
|
||||
#include "a64instruction.h"
|
||||
#include "emulator.h"
|
||||
#include "print.c"
|
||||
|
||||
void execute(Machine *state, a64inst_instruction *inst);
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user