Add function for executing DPI arithm instructions w/ S

This commit is contained in:
Themis Demetriades 2024-06-03 17:38:04 +01:00
parent 679c84a075
commit 84586b4768
2 changed files with 44 additions and 13 deletions

View File

@ -1,4 +1,9 @@
#include <assert.h>
#include "execute.h" #include "execute.h"
#include "print.h"
// Defines the maximum value that can be held in a register
#define MAX_REG_VAL ((1 << DWORD_BITS) - 1)
// The number of bits to shift the immediate value in an immediate data processing instruction // The number of bits to shift the immediate value in an immediate data processing instruction
// if the shift flag is enabled. // if the shift flag is enabled.
@ -7,13 +12,18 @@
// Prototypes // Prototypes
void execute_SDT(Machine *state, a64inst_instruction *inst); void execute_SDT(Machine *state, a64inst_instruction *inst);
// Return maximum of two dwords
static dword max(dword a, dword b) {
return a > b ? a : b;
}
// 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 & (((dword)1 << WORD_BITS) - 1);
} }
} }
@ -31,20 +41,27 @@ static dword readRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regT
// Read from processor register, ensuring that a valid register specifier is given // Read from processor register, ensuring that a valid register specifier is given
// and truncating the value being written when it can't fit in the specified register. // and truncating the value being written when it can't fit in the specified register.
static dword writeRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType, dword value) { static void writeRegister(Machine *state, a64inst_regSpecifier reg, a64inst_regType regType, dword value) {
state->registers[reg] = truncateValue(value, regType); state->registers[reg] = truncateValue(value, regType);
} }
// Updates N and Z condition codes given the machine and a result value
static void updateCondNZ(Machine *state, dword result, a64inst_regType regType) {
state->conditionCodes.Negative = result & ((1 << (regType ? DWORD_BITS : WORD_BITS)) - 1);
state->conditionCodes.Zero = result == 0;
}
// Execute a data processing immediate instruction // Execute a data processing immediate instruction
static void executeDPImmediate(Machine *state, a64inst_instruction *inst) { static void executeDPImmediate(Machine *state, a64inst_instruction *inst) {
assert(inst->type == a64inst_DPIMMEDIATE); assert(inst->type == a64inst_DPIMMEDIATE);
a64inst_regType regType = inst->data.DPImmediateData.regType;
a64inst_regSpecifier dest = inst->data.DPImmediateData.dest;
switch(inst->data.DPImmediateData.DPIOpType) { switch(inst->data.DPImmediateData.DPIOpType) {
a64inst_regType regType = inst->data.DPImmediateData.regType;
word *dest = state->registers + inst->data.DPImmediateData.dest;
// Execute an arithmetic data processing instruction // Execute an arithmetic data processing instruction
case a64inst_DPI_ARITHM: case a64inst_DPI_ARITHM:;
// If shift flag is enabled, logical left shift by the number of bits specified by the architecture // If shift flag is enabled, logical left shift by the number of bits specified by the architecture
dword immediate = inst->data.DPImmediateData.processOpData.arithmData.immediate; dword immediate = inst->data.DPImmediateData.processOpData.arithmData.immediate;
@ -54,26 +71,39 @@ static void executeDPImmediate(Machine *state, a64inst_instruction *inst) {
} }
switch(inst->data.DPImmediateData.processOp) { switch(inst->data.DPImmediateData.processOp) {
dword result;
case(a64inst_ADDS): case(a64inst_ADDS):
// Fall through result = srcVal + immediate;
writeRegister(state, dest, regType, result);
updateCondNZ(state, result, regType);
state->conditionCodes.Overflow = max(srcVal, immediate) > result;
state->conditionCodes.Carry = state->conditionCodes.Overflow;
break;
case(a64inst_ADD): case(a64inst_ADD):
*dest = truncateValue(srcVal + immediate, regType); writeRegister(state, dest, regType, srcVal + immediate);
break; break;
case(a64inst_SUBS): case(a64inst_SUBS):
// Fall through result = srcVal - immediate;
writeRegister(state, dest, regType, result);
updateCondNZ(state, result, regType);
state->conditionCodes.Overflow = srcVal < result;
state->conditionCodes.Carry = state->conditionCodes.Overflow;
break;
case(a64inst_SUB): case(a64inst_SUB):
*dest = truncateValue(srcVal - immediate, regType); writeRegister(state, dest, regType, srcVal - immediate);
break; break;
// Unknown opcode detected! // Unknown opcode detected!
default: default:
fprintf(stderr, "Unknown opcode detected in a DPI arithmetic instruction!\n");
break; break;
} }
break; break;
// Execute a wide move data processing instruction // Execute a wide move data processing instruction
@ -96,6 +126,7 @@ void execute(Machine *state, a64inst_instruction *inst) {
// Execute a data processing immediate instruction // Execute a data processing immediate instruction
case a64inst_DPIMMEDIATE: case a64inst_DPIMMEDIATE:
executeDPImmediate(state, inst);
break; break;
// Execute a branch instruction // Execute a branch instruction
@ -104,6 +135,7 @@ void execute(Machine *state, a64inst_instruction *inst) {
// Execute a data processing register instruction // Execute a data processing register instruction
case a64inst_DPREGISTER: case a64inst_DPREGISTER:
readRegister(state, 0, 0); //FOR COMPILATION PURPOSES
break; break;
case a64inst_SINGLETRANSFER: case a64inst_SINGLETRANSFER:

View File

@ -2,7 +2,6 @@
#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