diff --git a/src/assemble.c b/src/assemble.c index d0321a4..42302b3 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -4,7 +4,7 @@ #include "parser.h" #include "fileio.h" #include "parser.h" -#include "twopassassembly.c" +#include "encode.c" int main(int argc, char **argv) { // Check the arguments diff --git a/src/twopassassembly.c b/src/twopassassembly.c deleted file mode 100644 index 0a03c7e..0000000 --- a/src/twopassassembly.c +++ /dev/null @@ -1,232 +0,0 @@ -#include -#include "global.h" -#include "a64instruction/a64instruction.h" -#include "symboltable.c" -#include -#include - -#define HALT_BINARY 2315255808 - -// 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 wrd = 0; - - switch (instr->data.BranchData.BranchType) { - case a64inst_UNCONDITIONAL: - setBits(&wrd, 26, 30, 0x5); - setBits(&wrd, 25, 0, instr->data.BranchData.processOpData.unconditionalData.unconditionalOffset); - break; - - case a64inst_REGISTER: - setBits(&wrd, 16, 32, 0xD61F); - setBits(&wrd, 5, 10, instr->data.BranchData.processOpData.registerData.src); - break; - - case a64inst_CONDITIONAL: - 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 wrd; -} - -st* firstPass(a64inst_instruction instrs[], int numInstrs) { - // TODO: - // -iterate over instructions, adding to symbol table - // create symbol table and map labels to addresses/lines - st *table = (st*)malloc(sizeof(st)); - for (int i = 0; i < numInstrs; i++) { - // discuss defining a LABEL type - if (instrs[i].type == a64inst_LABEL) { - st_add(*table, &(instrs[i].data.LabelData.label), &i); - } - } - return table; -} - -word dpi(a64inst_instruction cI) { - word wrd = 0; - - a64inst_DPImmediateData data = cI.data.DPImmediateData; - - 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) { - 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 { - 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 - } - - return wrd; -} - -word dpr(a64inst_instruction cI) { - word wrd = 0; - - a64inst_DPRegisterData data = cI.data.DPRegisterData; - setBits(&wrd, 31, 32, data.regType); // sf - setBits(&wrd, 29, 31, data.processOp); // opc - setBits(&wrd, 28, 28, data.DPROpType); // M - setBits(&wrd, 25 ,28, 0x5); - setBits(&wrd, 16, 21, data.src2); // src2 - setBits(&wrd, 5, 10, data.src1); // src1 - setBits(&wrd, 0, 5, data.dest); // src2 - - if (data.DPROpType == a64inst_DPR_MULTIPLY) { - setBits(&wrd, 21, 31, 0xD8); - setBits(&wrd, 15, 16, data.processOpData.multiplydata.negProd); - setBits(&wrd, 10, 15, data.processOpData.multiplydata.summand); - - } else { - // Arithmetic Logic Instruction - setBits(&wrd, 22, 24, data.processOpData.arithmLogicData.shiftType); - setBits(&wrd, 10, 16, data.processOpData.arithmLogicData.shiftAmount); - - if (data.processOpData.arithmLogicData.type == a64inst_DPR_ARITHM) { - // Arithmetic - setBits(&wrd, 24, 25, 0x1); // bit 24 - } else { - setBits(&wrd, 21, 22, data.processOpData.arithmLogicData.negShiftedSrc2); - } - - } - - return wrd; - -} - -word sts(a64inst_instruction cI) { - word wrd = 0; - - a64inst_SingleTransferData data = cI.data.SingleTransferData; - a64inst_SingleDataTransferData data2 = data.processOpData.singleDataTransferData; - - 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: - 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: - setBits(&wrd, 10, 22, data2.a64inst_addressingModeData.unsignedOffset); - break; - // pre/post indexed - default: - 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; - } - - return wrd; -} - -word ldl(a64inst_instruction cI) { - word wrd = 0; - - a64inst_SingleTransferData data = cI.data.SingleTransferData; - 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) { - // TODO: - // iterate over instructions again, this time replacing labels - // with values from symbol table - // after a line has had all the values replaced, assemble it and append - word *arr = (word*)malloc(sizeof(word) * numInstrs); - int index = 0; - for (int i = 0; i < numInstrs; i++) { - a64inst_instruction cI = instrs[i]; - switch (cI.type) { - case a64inst_DPIMMEDIATE: - arr[index] = dpi(cI); - index++; - break; - case a64inst_DPREGISTER: - arr[index] = dpr(cI); - index++; - break; - case a64inst_SINGLETRANSFER: - arr[index] = sts(cI); - index++; - break; - case a64inst_LOADLITERAL: - arr[index] = ldl(cI); - index++; - break; - case a64inst_DIRECTIVE: - arr[index] = cI.data.DirectiveData.value; - index++; - break; - case a64inst_HALT: - arr[index] = HALT_BINARY; - index++; - break; - case a64inst_LABEL: - // Labels are handled in the first pass and used for addressing. - break; - case a64inst_BRANCH: - arr[index] = assembleBranch(&cI); - index++; - default: - break; - } - } - return arr; -}