Update encode to handle branches with sign extend

This commit is contained in:
sBubshait 2024-06-14 20:20:54 +01:00
parent 4139d7a083
commit 37a9cf0400

View File

@ -25,22 +25,41 @@ void setBits(word* wrd, uint8_t lsb, uint8_t msb, word value) {
*wrd |= (value << lsb) & mask;
}
/*
static int getLabelOffset(symbol_table* table, char* label, int currentIndex) {
address target = st_get(table, label);
return target - (currentIndex * 4);
}
*/
// Sign extend a given value to a 64-bit signed integer given the number of bits
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);
}
}
static int getLabelOffset(symbol_table* table, char* label, int currentIndex, int n_bits) {
address target = st_get(table, label);
return signExtend((unsigned int) (target - (currentIndex * 4)), n_bits);
}
// Generates assembled code based on the two-pass assembly method
word encodeBranch(a64inst_instruction *instr) {
word encodeBranch(a64inst_instruction *instr, int index, symbol_table *st) {
word wrd = 0;
switch (instr->data.BranchData.BranchType) {
case a64inst_UNCONDITIONAL:
setBits(&wrd, 26, 30, 0x5);
setBits(&wrd, 0, 25, instr->data.BranchData.processOpData.unconditionalData.unconditionalOffset);
setBits(&wrd, 26, 29, 0x5);
setBits(&wrd, 0, 25, getLabelOffset(st, instr->data.BranchData.processOpData.unconditionalData.label, index, 26));
break;
case a64inst_REGISTER:
@ -50,7 +69,7 @@ word encodeBranch(a64inst_instruction *instr) {
case a64inst_CONDITIONAL:
setBits(&wrd, 26, 32, 0x15);
setBits(&wrd, 5, 24, instr->data.BranchData.processOpData.conditionalData.offset);
setBits(&wrd, 5, 24, getLabelOffset(st, instr->data.BranchData.processOpData.conditionalData.label, index, 19));
setBits(&wrd, 0, 4, instr->data.BranchData.processOpData.conditionalData.cond);
break;
}
@ -168,7 +187,7 @@ word encodeLoadLiteral(a64inst_instruction cI) {
return wrd;
}
word *encode(a64inst_instruction insts[], int instCount, symbol_table* table) {
word *encode(a64inst_instruction insts[], int instCount, symbol_table* st) {
word *arr = (word*)malloc(sizeof(word) * instCount);
int index = 0;
for (int i = 0; i < instCount; i++) {
@ -202,7 +221,7 @@ word *encode(a64inst_instruction insts[], int instCount, symbol_table* table) {
// Labels are handled in the first pass and used for addressing.
break;
case a64inst_BRANCH:
arr[index] = encodeBranch(&inst);
arr[index] = encodeBranch(&inst, index, st);
index++;
default:
break;