From 31fa1392e1bfdae281844f20632452a9b1a47799 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Thu, 13 Jun 2024 17:25:17 +0100 Subject: [PATCH] Restructring the assembling into binary, add helper funcs --- src/twopassassembly.c | 154 ++++++++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 66 deletions(-) diff --git a/src/twopassassembly.c b/src/twopassassembly.c index 34e379d..e9fcf2e 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -1,3 +1,4 @@ +#include #include "global.h" #include "a64instruction/a64instruction.h" #include "symboltable.c" @@ -6,36 +7,57 @@ #define HALT_BINARY 2315255808 -// Generates assembled code based on the two-pass assembly method +// Temp helper function to print binary representation of a word +// static void printBinary(word number) { +// for (int i = 31; i >= 0; i--) { +// putchar((number & (1 << i)) ? '1' : '0'); +// } +// putchar('\n'); +// } +// write the provided value to the bits in the range [lsb, msb) {inclusive, exclusive} to the word. +// Does not modify any other bits in the word. +void setBits(word* wrd, uint8_t lsb, uint8_t msb, word value) { + // Ensure LSB and MSB are within range of word size, and in the correct order + assert(lsb < msb && msb <= 32); + + // Create a mask with 1s in the range [lsb, msb) and 0s elsewhere + word mask = 0; + for (uint8_t i = lsb; i < msb; i++) { + mask |= 1 << i; + } + + // Clear the bits in the range [lsb, msb) in the word + *wrd &= ~mask; + + // Set the bits in the range [lsb, msb) to the value + *wrd |= (value << lsb) & mask; +} + + +// Generates assembled code based on the two-pass assembly method word assembleBranch(a64inst_instruction *instr) { - word binInstr = 0; - binInstr += (5 << 28); // 101 start of branch instr + word wrd = 0; + switch (instr->data.BranchData.BranchType) { case a64inst_UNCONDITIONAL: - // 000101 - // 25-0: sign extended simm26 - binInstr += instr->data.BranchData.processOpData.unconditionalData.unconditionalOffset; + setBits(&wrd, 26, 30, 0x5); + setBits(&wrd, 25, 0, instr->data.BranchData.processOpData.unconditionalData.unconditionalOffset); break; + case a64inst_REGISTER: - // 10000 - // 11111 - // 000000 - // 9-5: address from register - // 0000 - binInstr += ((instr->data.BranchData.processOpData.registerData.src) << 5); + setBits(&wrd, 16, 32, 0xD61F); + setBits(&wrd, 5, 10, instr->data.BranchData.processOpData.registerData.src); break; + case a64inst_CONDITIONAL: - // 01010100 - // 25-5: sign extended offset - // 4-0: 0{condition} - binInstr += ((instr->data.BranchData.processOpData.conditionalData.offset) << 5); - binInstr += instr->data.BranchData.processOpData.conditionalData.cond; - break; - default: + setBits(&wrd, 26, 32, 0x15); + setBits(&wrd, 5, 24, instr->data.BranchData.processOpData.conditionalData.offset); + setBits(&wrd, 0, 4, instr->data.BranchData.processOpData.conditionalData.cond); break; } - return binInstr; + + return wrd; } st* firstPass(a64inst_instruction instrs[], int numInstrs) { @@ -53,32 +75,30 @@ st* firstPass(a64inst_instruction instrs[], int numInstrs) { } word dpi(a64inst_instruction cI) { - word out = 0; + word wrd = 0; + a64inst_DPImmediateData data = cI.data.DPImmediateData; - // sf - out += data.regType * (1 << 31); - out += data.processOp * (1 << 29); - out += 1 << 28; - // if arithmetic + + setBits(&wrd, 31, 32, data.regType); // sf + setBits(&wrd, 29, 31, data.processOp); // opc + setBits(&wrd, 28, 29, 0x1); // constant value + setBits(&wrd, 0, 5, data.dest); // rd + if (data.DPIOpType == a64inst_DPI_ARITHM) { - out += 1 << 24; - // shift - if (data.processOpData.arithmData.shiftImmediate) { - out += 1 << 22; - } - out += data.processOpData.arithmData.immediate * (1 << 10); - out += data.processOpData.arithmData.src * (1 << 5); + setBits(&wrd, 23, 26, 0x2); //opi + setBits(&wrd, 5, 10, data.processOpData.arithmData.src); // rn + setBits(&wrd, 22, 23, data.processOpData.arithmData.shiftImmediate); // sh + setBits(&wrd, 10, 22, data.processOpData.arithmData.immediate); // imm12 } // if wide move else { - out += 5 * (1 << 23); - // hw - out += data.processOpData.wideMovData.shiftScalar * (1 << 21); - out += data.processOpData.wideMovData.immediate * (1 << 5); + setBits(&wrd, 23, 26, 0x5); //opi + // TODO: Check the following line, is it shiftScalar?: + setBits(&wrd, 21, 23, data.processOpData.wideMovData.shiftScalar); // hw + setBits(&wrd, 5, 21, data.processOpData.wideMovData.immediate); // imm16 } - // destination register - out += data.dest; - return out; + + return wrd; } word dpr(a64inst_instruction cI) { @@ -135,49 +155,51 @@ word dpr(a64inst_instruction cI) { } word sts(a64inst_instruction cI) { + word wrd = 0; + a64inst_SingleTransferData data = cI.data.SingleTransferData; - word out = 0; a64inst_SingleDataTransferData data2 = data.processOpData.singleDataTransferData; - // this deals with every bit in the 31-23 range apart from sf and U - out += (512 + 128 + 64 + 32U) * (1 << 23); - int sf = data.regType; - int u = 0; - int offset = 0; - int xn = data2.base; - int rt = data.target; + + setBits(&wrd, 22, 32, 0x2E0); + setBits(&wrd, 30, 31, data.regType); + setBits(&wrd, 24, 25, data2.addressingMode == a64inst_UNSIGNED_OFFSET); + setBits(&wrd, 22, 23, data2.transferType); + setBits(&wrd, 5, 10, data2.base); + setBits(&wrd, 0, 5, data.target); + switch (data2.addressingMode) { // register offset case a64inst_REGISTER_OFFSET: - offset += 2080 + 64 * data2.a64inst_addressingModeData.offsetReg; + setBits(&wrd, 21, 22, 1); + setBits(&wrd, 10, 16, 0x1A); + setBits(&wrd, 16, 21, data2.a64inst_addressingModeData.offsetReg); break; // unsigned offset case a64inst_UNSIGNED_OFFSET: - offset += data2.a64inst_addressingModeData.unsignedOffset; - u = 1; + setBits(&wrd, 10, 22, data2.a64inst_addressingModeData.unsignedOffset); break; // pre/post indexed default: - offset = 1 + data2.addressingMode * 2 + data2.a64inst_addressingModeData.indexedOffset * 4; + setBits(&wrd, 21, 22, 0); + setBits(&wrd, 11, 12, data2.addressingMode == a64inst_PRE_INDEXED); + setBits(&wrd, 10, 11, 1); + setBits(&wrd, 12, 21, data2.a64inst_addressingModeData.indexedOffset); break; } - out += sf * (1 << 30); - out += u * (1 << 22); - out += offset * 1024; - out += xn * 32; - out += rt; - return out; + + return wrd; } word ldl(a64inst_instruction cI) { - word out = 3 * (1 << 27); + word wrd = 0; + a64inst_SingleTransferData data = cI.data.SingleTransferData; - int sf = data.regType; - int simm19 = data.processOpData.loadLiteralData.offset; - int rt = data.target; - out += sf * (1 << 30); - out += simm19 * 32; - out += rt; - return out; + setBits(&wrd, 24, 32, 0x18); + setBits(&wrd, 30, 31, data.regType); + setBits(&wrd, 5, 24, data.processOpData.loadLiteralData.offset); + setBits(&wrd, 0, 5, data.target); + + return wrd; } word *secondPass(a64inst_instruction instrs[], int numInstrs, st* table) {