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.
|
// if the shift flag is enabled.
|
||||||
#define DPI_ARITHM_SHIFT 12
|
#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
|
// 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) {
|
static dword truncateValue(dword value, a64inst_regType regType) {
|
||||||
if (regType == a64inst_R) {
|
if (regType == a64inst_R) {
|
||||||
return value
|
return value;
|
||||||
} else {
|
} else {
|
||||||
//return value & ~(dword)((1 << WORD_BITS) - 1)
|
//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
|
// 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.
|
// 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) {
|
static dword readRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType) {
|
||||||
assert(reg <= REGISTER_COUNT)
|
assert(reg <= REGISTER_COUNT);
|
||||||
if (reg == ZERO_REGISTER) {
|
if (reg == ZERO_REGISTER) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
@ -103,9 +106,59 @@ void execute(Machine *state, a64inst_instruction *inst) {
|
|||||||
case a64inst_DPREGISTER:
|
case a64inst_DPREGISTER:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case a64inst_SINGLETRANSFER:
|
||||||
|
execute_SDT(state, inst);
|
||||||
|
break;
|
||||||
|
|
||||||
// Unknown instruction
|
// Unknown instruction
|
||||||
default:
|
default:
|
||||||
break;
|
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__
|
#define __EXECUTE__
|
||||||
#include "a64instruction.h"
|
#include "a64instruction.h"
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
|
#include "print.c"
|
||||||
|
|
||||||
void execute(Machine *state, a64inst_instruction *inst);
|
void execute(Machine *state, a64inst_instruction *inst);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user