Add execute branch instruction, w/ T
This commit is contained in:
parent
84586b4768
commit
9c299b3be0
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
void execute_SDT(Machine *state, a64inst_instruction *inst);
|
void execute_SDT(Machine *state, a64inst_instruction *inst);
|
||||||
|
void execute_Branch(Machine *state, a64inst_instruction *inst);
|
||||||
|
|
||||||
// Return maximum of two dwords
|
// Return maximum of two dwords
|
||||||
static dword max(dword a, dword b) {
|
static dword max(dword a, dword b) {
|
||||||
@ -27,6 +28,28 @@ static dword truncateValue(dword value, a64inst_regType regType) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sign extend a given value to a 64-bit signed integer given the number of bits
|
||||||
|
static int64_t signExtend(dword value, unsigned int n) {
|
||||||
|
if (n == 0 || n >= 64) {
|
||||||
|
// If n_bits is 0 or greater than or equal to 64, return the value as is
|
||||||
|
return (int64_t)value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t sign_bit_mask = (uint64_t)1 << (n - 1);
|
||||||
|
|
||||||
|
// Mask to isolate the n-bit value
|
||||||
|
uint64_t n_bit_mask = (sign_bit_mask << 1) - 1;
|
||||||
|
|
||||||
|
// Check if the sign bit is set
|
||||||
|
if (value & sign_bit_mask) {
|
||||||
|
// Sign bit is set, extend the sign
|
||||||
|
return (int64_t)(value | ~n_bit_mask);
|
||||||
|
} else {
|
||||||
|
// Sign bit is not set, return the value as is
|
||||||
|
return (int64_t)(value & n_bit_mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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 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.
|
||||||
@ -131,6 +154,7 @@ void execute(Machine *state, a64inst_instruction *inst) {
|
|||||||
|
|
||||||
// Execute a branch instruction
|
// Execute a branch instruction
|
||||||
case a64inst_BRANCH:
|
case a64inst_BRANCH:
|
||||||
|
execute_Branch(state, inst);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Execute a data processing register instruction
|
// Execute a data processing register instruction
|
||||||
@ -193,4 +217,41 @@ void execute_SDT(Machine *state, a64inst_instruction *inst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isConditionMet(Machine* state, a64inst_ConditionType cond) {
|
||||||
|
switch(cond) {
|
||||||
|
case EQ:
|
||||||
|
return state->conditionCodes.Zero;
|
||||||
|
case NE:
|
||||||
|
return !state->conditionCodes.Zero;
|
||||||
|
case GE:
|
||||||
|
return state->conditionCodes.Negative == state->conditionCodes.Overflow;
|
||||||
|
case LT:
|
||||||
|
return state->conditionCodes.Negative != state->conditionCodes.Overflow;
|
||||||
|
case GT:
|
||||||
|
return !state->conditionCodes.Zero && (state->conditionCodes.Negative == state->conditionCodes.Overflow);
|
||||||
|
case LE:
|
||||||
|
return state->conditionCodes.Zero || (state->conditionCodes.Negative != state->conditionCodes.Overflow);
|
||||||
|
case AL:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute_Branch(Machine *state, a64inst_instruction *inst) {
|
||||||
|
switch (inst->data.BranchData.BranchType) {
|
||||||
|
case a64inst_UNCONDITIONAL:
|
||||||
|
state->pc += signExtend(inst->data.BranchData.processOpData.unconditionalData.unconditionalOffset * 4, 26);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case a64inst_REGISTER:
|
||||||
|
state->pc = state->registers[inst->data.BranchData.processOpData.registerData.src];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case a64inst_CONDITIONAL:
|
||||||
|
if (isConditionMet(state, inst->data.BranchData.processOpData.conditionalData.cond)) {
|
||||||
|
state->pc += signExtend(inst->data.BranchData.processOpData.conditionalData.offset * 4, 19);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user