From 48efdf8284f3dce102e4baca2b907d1add2a0893 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 5 Jun 2024 20:53:56 +0100 Subject: [PATCH 01/12] classify directprocessing instruction type --- src/parser.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/parser.c b/src/parser.c index 53b8e0c..dd7a761 100644 --- a/src/parser.c +++ b/src/parser.c @@ -44,7 +44,12 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ } } else { - //data processing + int numOperands = sizeof(operandList) / sizeof(operandList[0]) + if(numOperands==3){ + instr->type = a64inst_DPREGISTER; + } else { + instr->type = a64inst_DPIMMEDIATE; + } } } @@ -97,10 +102,11 @@ a64inst_instruction *parser(char asmLine[]){ int operandCount = 0; const char *operandList[4]; tokeniseOperands(operands, &operandCount, operandList); + renameAliases(&opcode, &operandList); } - return(a64inst_instruction); + return(instr); } From f28d3b4047ae6a3f48131f6adfca28853057eab0 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 5 Jun 2024 21:01:39 +0100 Subject: [PATCH 02/12] removed alias function temporarily --- src/parser.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parser.c b/src/parser.c index dd7a761..8b59239 100644 --- a/src/parser.c +++ b/src/parser.c @@ -102,7 +102,6 @@ a64inst_instruction *parser(char asmLine[]){ int operandCount = 0; const char *operandList[4]; tokeniseOperands(operands, &operandCount, operandList); - renameAliases(&opcode, &operandList); } From 8931c151f8ab0c1a489952d2a12b749332c3ebac Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 5 Jun 2024 21:02:25 +0100 Subject: [PATCH 03/12] removed duped if statement --- src/parser.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/parser.c b/src/parser.c index 8b59239..538dd9d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -79,11 +79,6 @@ a64inst_instruction *parser(char asmLine[]){ return(instr); } - if(strcmp(asmLine, HALT_ASM_CMD) == 0){ - instr->type = a64inst_HALT; - return(instr); - } - //"opcode operand1, {operand2}, ..." //duplicated as strtok modifies the input string char *stringptr = strdup(asmLine); From bb0f93953910b759985f616c05b56962b78dd975 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 5 Jun 2024 21:07:28 +0100 Subject: [PATCH 04/12] construct instr IR from label --- src/parser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/parser.c b/src/parser.c index 538dd9d..be2f874 100644 --- a/src/parser.c +++ b/src/parser.c @@ -88,10 +88,15 @@ a64inst_instruction *parser(char asmLine[]){ if(strcmp(opcode, ".int") == 0){ //type is directive + instr->type = a64inst_DIRECTIVE; } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { //type is label //add to symbol table + instr->type = a64inst_LABEL; + char *opcodeCpy = strdup(opcode); + char *labelData = strtok(opcodeCpy, ":"); + instr->data.label = labelData; } else { //type is instruction int operandCount = 0; From 262fd6219de30007ac878c2c1b4bda431ce13342 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 5 Jun 2024 21:10:31 +0100 Subject: [PATCH 05/12] conditional definition of parser constants --- src/parser.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/parser.h b/src/parser.h index 8088efa..5c3a461 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,2 +1,5 @@ +#ifndef __PARSERCONSTS__ +#define __PARSERCONSTS__ #define OPERAND_DELIMITER ", " -#define HALT_ASM_CMD "and x0, x0, x0" \ No newline at end of file +#define HALT_ASM_CMD "and x0, x0, x0" +#endif \ No newline at end of file From 6177b2f7481a8b80d44d95bc60fb134fcc69556e Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 13:01:26 +0100 Subject: [PATCH 06/12] assemble branch instructions --- src/parser.c | 2 +- src/twopassassembly.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/parser.c b/src/parser.c index be2f874..004e5fb 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,7 +10,7 @@ //TODO: // - use string matching to get opcode, and operands (DONE) // - check operand count (DONE) -// - match opcode to a64 struct types (PARTIALLY DONE) +// - match opcode to a64 struct types (DONE) // - count operands and match type/values // - generate final a64inst and return diff --git a/src/twopassassembly.c b/src/twopassassembly.c index d6194a8..c701732 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -1,3 +1,5 @@ +#include "global.h" + //generates assembled code based on two pass assembly method void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){ @@ -13,26 +15,28 @@ void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){ word assembleBranch(a64inst_instruction *instr, int ){ word binInstr = 0; + binInstr += (5^28); //101 start of branch instr switch (instr->data.BranchData.BranchType) { case a64inst_UNCONDITIONAL: //000101 //25-0: sign extended simm26 - + binInstr += instr->data.processOpData.unconditionalOffset; break; case a64inst_REGISTER: - //1101011 - //0000 + //10000 //11111 //000000 //9-5: address from register //0000 - + binInstr += ((instr->processOpData.src)^5); break; case a64inst_CONDITIONAL: // 01010100 // 25-5: sign extended offset // 4-0: 0{condition} + binInstr += ((instr->processOpData.offset)^5); + binInstr += instr->processOpData.cond; break; default: break; From b93ab76b8257354baf6d3ab2987f739eb9c6411f Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 13:22:54 +0100 Subject: [PATCH 07/12] generate branch struct from operands (INCOMPLETE) --- src/parser.c | 34 ++++++++++++++++++++++++++++++++++ src/twopassassembly.c | 3 ++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/parser.c b/src/parser.c index 004e5fb..c3167f1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -14,6 +14,39 @@ // - count operands and match type/values // - generate final a64inst and return +void generateBranchOperands(a64inst_instruction *instr, char* opcode, char *operandList[]){ + switch(instr->data.BranchType){ + case a64inst_UNCONDITIONAL: + //define and sign extend immediate offset + //use symbol table + break; + case a64inst_REGISTER: + char *endptr; + instr->data.BranchData.processOpData.src = strtol(operandList[0] + 1, endptr, 2) + break; + case a64inst_CONDITIONAL: + char* condition = strtok(strdup(opcode), "b."); + condition = strtok(NULL, ""); + if(strcmp(condition, "eq")==0){ + instr->data.BranchData.processOpData.cond = EQ; + } else if (strcmp(condition, "ne")==0){ + instr->data.BranchData.processOpData.cond = NE; + } else if (strcmp(condition, "ge")==0){ + instr->data.BranchData.processOpData.cond = GE; + } else if (strcmp(condition, "lt")==0){ + instr->data.BranchData.processOpData.cond = LT; + } else if (strcmp(condition, "gt")==0){ + instr->data.BranchData.processOpData.cond = GT; + } else if (strcmp(condition, "le")==0){ + instr->data.BranchData.processOpData.cond = LE; + } else if (srtcmp(condition, "al")==0){ + instr->data.BranchData.processOpData.cond = AL; + } + break; + //calculate offset from symbol table. + } +} + void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[]){ if((int isUnconditional = strcmp(opcode, "b")) == 0 || (int isRegister = strcmp(opcode, "br")) == 0 || @@ -27,6 +60,7 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ instr->data.BranchData.BranchType = a64inst_CONDITIONAL; //instr->data.branchData.processOpData.cond = {remove first two chars of opcode} } + generateBranchOperands(instr, opcode, operandList); } else if((int isLoad = strcmp(opcode, "ldr")) == 0 || (int isStore = strcmp(opcode, "str")) == 0){ //loading/storing instruction; classify operands char *address = operandList[1]; diff --git a/src/twopassassembly.c b/src/twopassassembly.c index c701732..5729b61 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -13,7 +13,7 @@ void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){ } } -word assembleBranch(a64inst_instruction *instr, int ){ +word assembleBranch(a64inst_instruction *instr){ word binInstr = 0; binInstr += (5^28); //101 start of branch instr switch (instr->data.BranchData.BranchType) @@ -41,6 +41,7 @@ word assembleBranch(a64inst_instruction *instr, int ){ default: break; } + return binInstr; } void firstPass(a64inst_instruction instrs[], int numInstrs){ From 1011d7be714b10cd1cb3ec3bd6ab61887fd297df Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 14:14:10 +0100 Subject: [PATCH 08/12] classify load store addressing type --- src/parser.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/parser.c b/src/parser.c index c3167f1..ba00c26 100644 --- a/src/parser.c +++ b/src/parser.c @@ -14,6 +14,36 @@ // - count operands and match type/values // - generate final a64inst and return +void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){ + if(strcmp(operandList[0][strlen(operandList[0])-1], "{") == 0) { + //unsigned immediate offset + instr->data.processOpData.addressingMode = a64inst_UNSIGNED_OFFSET; + } else if(strcmp(operandList[0][strlen(operandList[0])-1], "]") == 0) { + //post-indexed + instr->data.processOpData.addressingMode = a64inst_POST_INDEXED; + } else { + //check second operand to distinguish between pre-indexed and register + if(strcmp(operandList[1][0], "#")==0){ + //pre-indexed + instr->data.processOpData.addressingMode = a64inst_PRE_INDEXED; + } else { + //register + instr->data.processOpData.addressingMode = a64inst_REGISTER_OFFSET; + } + } +} + +void generateLoadStoreOperands(a64inst_instruction *instr, char *opcode, char *operandList[]){ + switch(instr->data.type){ + case a64inst_SINGLETRANSFER: + calcluateAddressFormat(instr, operandList); + break; + case a64inst_LOADLITERAL: + break; + + } +} + void generateBranchOperands(a64inst_instruction *instr, char* opcode, char *operandList[]){ switch(instr->data.BranchType){ case a64inst_UNCONDITIONAL: From 872d4224f8ca1df526e017429d31e526762494a1 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 14:28:32 +0100 Subject: [PATCH 09/12] classify register type and base register for load/store --- src/parser.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/parser.c b/src/parser.c index ba00c26..cbbabd7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -14,6 +14,7 @@ // - count operands and match type/values // - generate final a64inst and return +//calculate offsets from string void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){ if(strcmp(operandList[0][strlen(operandList[0])-1], "{") == 0) { //unsigned immediate offset @@ -36,6 +37,14 @@ void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){ void generateLoadStoreOperands(a64inst_instruction *instr, char *opcode, char *operandList[]){ switch(instr->data.type){ case a64inst_SINGLETRANSFER: + if(strcmp(operandList[0][0], "x")==0){ + //x-register + instr->data.regType = 1; + } else { + instr->data.regType = 0; + } + char *endptr; + instr->processOpData.base = strtol(operandList[0][0]+1, endptr, 2); calcluateAddressFormat(instr, operandList); break; case a64inst_LOADLITERAL: @@ -97,10 +106,11 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ if( *address == '['){ //type is register instr->type = a64inst_SINGLETRANSFER; + instr->data.SingleTransferOpType = a64inst_SINGLE_TRANSFER_SINGLE_DATA_TRANSFER; if(isLoad == 0){ - instr->data.processOpData.singleDataTransferData.transferType = a64inst_LOAD; + instr->data.processOpData.transferType = a64inst_LOAD; } else { - instr->data.processOpData.singleDataTransferData.transferType = a64inst_STORE; + instr->data.processOpData.transferType = a64inst_STORE; } } else { instr->type = a64inst_LOADLITERAL; From 70e02768b65497afb594c4fcc28a15167a34be15 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 14:30:13 +0100 Subject: [PATCH 10/12] fix struct access --- src/parser.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/parser.c b/src/parser.c index cbbabd7..0f57bb7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -44,7 +44,7 @@ void generateLoadStoreOperands(a64inst_instruction *instr, char *opcode, char *o instr->data.regType = 0; } char *endptr; - instr->processOpData.base = strtol(operandList[0][0]+1, endptr, 2); + instr->data.target = strtol(operandList[0][0]+1, endptr, 2); calcluateAddressFormat(instr, operandList); break; case a64inst_LOADLITERAL: @@ -61,25 +61,25 @@ void generateBranchOperands(a64inst_instruction *instr, char* opcode, char *oper break; case a64inst_REGISTER: char *endptr; - instr->data.BranchData.processOpData.src = strtol(operandList[0] + 1, endptr, 2) + instr->data.processOpData.src = strtol(operandList[0] + 1, endptr, 2) break; case a64inst_CONDITIONAL: char* condition = strtok(strdup(opcode), "b."); condition = strtok(NULL, ""); if(strcmp(condition, "eq")==0){ - instr->data.BranchData.processOpData.cond = EQ; + instr->data.processOpData.cond = EQ; } else if (strcmp(condition, "ne")==0){ - instr->data.BranchData.processOpData.cond = NE; + instr->data.processOpData.cond = NE; } else if (strcmp(condition, "ge")==0){ - instr->data.BranchData.processOpData.cond = GE; + instr->data.processOpData.cond = GE; } else if (strcmp(condition, "lt")==0){ - instr->data.BranchData.processOpData.cond = LT; + instr->data.processOpData.cond = LT; } else if (strcmp(condition, "gt")==0){ - instr->data.BranchData.processOpData.cond = GT; + instr->data.processOpData.cond = GT; } else if (strcmp(condition, "le")==0){ - instr->data.BranchData.processOpData.cond = LE; + instr->data.processOpData.cond = LE; } else if (srtcmp(condition, "al")==0){ - instr->data.BranchData.processOpData.cond = AL; + instr->data.processOpData.cond = AL; } break; //calculate offset from symbol table. From f1ac860d6a99725d6030fd8ca26df9ca8e9028c3 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 14:46:16 +0100 Subject: [PATCH 11/12] rewrite address format calculation as { is not in the actual asm syntax --- src/parser.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/parser.c b/src/parser.c index 0f57bb7..037188f 100644 --- a/src/parser.c +++ b/src/parser.c @@ -16,22 +16,19 @@ //calculate offsets from string void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){ - if(strcmp(operandList[0][strlen(operandList[0])-1], "{") == 0) { - //unsigned immediate offset - instr->data.processOpData.addressingMode = a64inst_UNSIGNED_OFFSET; + + if(strcmp(operandList[1][strlen(operandList[1])-1], "!")==0){ + instr->data.processOpData.addressingMode = a64inst_PRE_INDEXED; } else if(strcmp(operandList[0][strlen(operandList[0])-1], "]") == 0) { //post-indexed instr->data.processOpData.addressingMode = a64inst_POST_INDEXED; + } else if( (strcmp(operandList[1][strlen(operandList[1])-1], "x") == 0) + || (strcmp(operandList[1][strlen(operandList[1])-1], "w") == 0)){ + //register + instr->data.processOpData.addressingMode = a64inst_REGISTER_OFFSET; } else { - //check second operand to distinguish between pre-indexed and register - if(strcmp(operandList[1][0], "#")==0){ - //pre-indexed - instr->data.processOpData.addressingMode = a64inst_PRE_INDEXED; - } else { - //register - instr->data.processOpData.addressingMode = a64inst_REGISTER_OFFSET; - } - } + instr->data.processOpData.addressingMode = a64inst_UNSIGNED_OFFSET; + } } void generateLoadStoreOperands(a64inst_instruction *instr, char *opcode, char *operandList[]){ From 5413d27026a9236a1a4e9b5e6a623f0c25a62a8c Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Thu, 6 Jun 2024 14:46:56 +0100 Subject: [PATCH 12/12] adjust operand counts for calculating address format --- src/parser.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/parser.c b/src/parser.c index 037188f..e9e05cf 100644 --- a/src/parser.c +++ b/src/parser.c @@ -16,14 +16,14 @@ //calculate offsets from string void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){ - - if(strcmp(operandList[1][strlen(operandList[1])-1], "!")==0){ + + if(strcmp(operandList[2][strlen(operandList[1])-1], "!")==0){ instr->data.processOpData.addressingMode = a64inst_PRE_INDEXED; - } else if(strcmp(operandList[0][strlen(operandList[0])-1], "]") == 0) { + } else if(strcmp(operandList[1][strlen(operandList[0])-1], "]") == 0) { //post-indexed instr->data.processOpData.addressingMode = a64inst_POST_INDEXED; - } else if( (strcmp(operandList[1][strlen(operandList[1])-1], "x") == 0) - || (strcmp(operandList[1][strlen(operandList[1])-1], "w") == 0)){ + } else if( (strcmp(operandList[2][strlen(operandList[1])-1], "x") == 0) + || (strcmp(operandList[2][strlen(operandList[1])-1], "w") == 0)){ //register instr->data.processOpData.addressingMode = a64inst_REGISTER_OFFSET; } else {