From 422b0f3e62cc798c8a5bdc32ed6dcb7a67c50f83 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 4 Jun 2024 01:30:17 +0100 Subject: [PATCH 1/7] start classifying opcodes and writing skeleton for twopass assembly --- src/parser.c | 13 +++++++++++++ src/twopassassembly.c | 12 ++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/twopassassembly.c diff --git a/src/parser.c b/src/parser.c index 1c30fc3..4961480 100644 --- a/src/parser.c +++ b/src/parser.c @@ -14,6 +14,17 @@ // - count operands and match type/values // - generate final a64inst and return +void classifyOpcode(char* opcode, a64inst_instruction *instr){ + if(strcmp(opcode, "b") == 0 || strcmp(opcode, "br") == 0 || strncmp(opcode, "b.", strlen("b.")) == 2){ + instr->type = a64inst_BRANCH; + } else if(strcmp(opcode, "ldr") == 0 || strcmp(opcode, "str") == 0){ + //loading/storing instruction; classify operands + instr->type = a64inst_SINGLETRANSFER; + } else { + //data processing + } +} + char *tokeniseOperands(char* str, int operandCount, char *operands[]){ char *operandsDupe = strdup(str); int operandCount = 0; @@ -43,8 +54,10 @@ a64inst_instruction *parser(char asmLine[]){ if(opcode[0]=="."){ //type is directive + //define new type in a64instr struct } else if(opcode[strlen(opcode)-1]==":") { //type is label + //use symbol table to assemble } else { //type is instruction int operandCount = 0; diff --git a/src/twopassassembly.c b/src/twopassassembly.c new file mode 100644 index 0000000..24080f3 --- /dev/null +++ b/src/twopassassembly.c @@ -0,0 +1,12 @@ +//generates assembled code based on two pass assembly method + +void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){ + //TODO: + //generate symbol table based on inputted assembly code and labels + for(int i=0; itype==LABEL){ + // symbol table stuff here + } + } +} From bb3218b53588b11aedf6b978ff9679632b7f4389 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 4 Jun 2024 03:07:00 +0100 Subject: [PATCH 2/7] add detail to assembly skeleton --- src/parser.c | 7 ++++--- src/twopassassembly.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/parser.c b/src/parser.c index 4961480..e944ebc 100644 --- a/src/parser.c +++ b/src/parser.c @@ -22,6 +22,7 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr){ instr->type = a64inst_SINGLETRANSFER; } else { //data processing + } } @@ -52,12 +53,12 @@ a64inst_instruction *parser(char asmLine[]){ char *opcode = strtok(stringptr, " "); char *operands = strtok(NULL, ""); - if(opcode[0]=="."){ + if(strcmp(opcode, ".int") == 0){ //type is directive //define new type in a64instr struct - } else if(opcode[strlen(opcode)-1]==":") { + } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { //type is label - //use symbol table to assemble + //add to symbol table } else { //type is instruction int operandCount = 0; diff --git a/src/twopassassembly.c b/src/twopassassembly.c index 24080f3..d2536dd 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -10,3 +10,31 @@ void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){ } } } + +word assembleBranch(a64inst_instruction *instr){ + word binInstr = 0; + switch (instr->data.BranchData.BranchType) + { + case a64inst_UNCONDITIONAL: + //000101 + //25-0: sign extended simm26 + + break; + case a64inst_REGISTER: + //1101011 + //0000 + //11111 + //000000 + //9-5: address from register + //0000 + + break; + case a64inst_CONDITIONAL: + // 01010100 + // 25-5: sign extended offset + // 4-0: 0{condition} + break; + default: + break; + } +} From 13e2cc8c9d556cdb92d2f02de01980c36fbe8b8d Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 4 Jun 2024 03:35:06 +0100 Subject: [PATCH 3/7] classify branch type from opcode --- src/parser.c | 16 +++++++++++++--- src/twopassassembly.c | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/parser.c b/src/parser.c index e944ebc..0103a3d 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,13 +10,23 @@ //TODO: // - use string matching to get opcode, and operands (DONE) // - check operand count (DONE) -// - match opcode to a64 struct types +// - match opcode to a64 struct types (PARTIALLY DONE) // - count operands and match type/values // - generate final a64inst and return void classifyOpcode(char* opcode, a64inst_instruction *instr){ - if(strcmp(opcode, "b") == 0 || strcmp(opcode, "br") == 0 || strncmp(opcode, "b.", strlen("b.")) == 2){ - instr->type = a64inst_BRANCH; + if((int isUnconditional = strcmp(opcode, "b")) == 0 || + (int isRegister = strcmp(opcode, "br")) == 0 || + strncmp(opcode, "b.", 2) == 0){ + instr->type = a64inst_BRANCH; + if(isUnconditional){ + instr->data.BranchData.BranchType = a64inst_UNCONDITIONAL; + } else if (isRegister){ + instr->data.BranchData.BranchType = a64inst_REGISTER; + } else { + instr->data.BranchData.BranchType = a64inst_CONDITIONAL; + //instr->data.branchData.processOpData.cond = {remove first two chars of opcode} + } } else if(strcmp(opcode, "ldr") == 0 || strcmp(opcode, "str") == 0){ //loading/storing instruction; classify operands instr->type = a64inst_SINGLETRANSFER; diff --git a/src/twopassassembly.c b/src/twopassassembly.c index d2536dd..f7b75f8 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -11,7 +11,7 @@ void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){ } } -word assembleBranch(a64inst_instruction *instr){ +word assembleBranch(a64inst_instruction *instr, int ){ word binInstr = 0; switch (instr->data.BranchData.BranchType) { From ce0f825e1defb6efdb55240592d96f8920d93206 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 4 Jun 2024 04:24:56 +0100 Subject: [PATCH 4/7] add halt command handling --- src/parser.c | 10 ++++++++-- src/parser.h | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/parser.c b/src/parser.c index 0103a3d..98fa61a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -14,7 +14,7 @@ // - count operands and match type/values // - generate final a64inst and return -void classifyOpcode(char* opcode, a64inst_instruction *instr){ +void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[]){ if((int isUnconditional = strcmp(opcode, "b")) == 0 || (int isRegister = strcmp(opcode, "br")) == 0 || strncmp(opcode, "b.", 2) == 0){ @@ -29,7 +29,8 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr){ } } else if(strcmp(opcode, "ldr") == 0 || strcmp(opcode, "str") == 0){ //loading/storing instruction; classify operands - instr->type = a64inst_SINGLETRANSFER; + char *address = opcode[1]; + } else { //data processing @@ -57,6 +58,11 @@ a64inst_instruction *parser(char asmLine[]){ exit(EXIT_FAILURE); } + if(strcmp(asmLine, HALT_ASM_CMD) == 0){ + instr->type = a64inst_HALT; + return(instr); + } + //"opcode operand1, {operand2}, ..." char *stringptr = strdup(asmLine); diff --git a/src/parser.h b/src/parser.h index 5542aca..8088efa 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1 +1,2 @@ -#define OPERAND_DELIMITER ", " \ No newline at end of file +#define OPERAND_DELIMITER ", " +#define HALT_ASM_CMD "and x0, x0, x0" \ No newline at end of file From a8a1fd52a9fd651a6c8726f92a953e22e870ca5a Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 4 Jun 2024 04:31:46 +0100 Subject: [PATCH 5/7] add to twopassassembly skeleton --- src/twopassassembly.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/twopassassembly.c b/src/twopassassembly.c index f7b75f8..d6194a8 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -38,3 +38,16 @@ word assembleBranch(a64inst_instruction *instr, int ){ break; } } + +void firstPass(a64inst_instruction instrs[], int numInstrs){ + //TODO: + // -iterate over instructions, adding to symbol table + // create symbol table and map labels to addresses/lines +} + +void secondPass(a64inst_instruction instrs[], int numInstrs){ + //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 +} \ No newline at end of file From 129bdf3954d850b27e105e7f956003ddff2bb8fd Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Wed, 5 Jun 2024 19:52:50 +0100 Subject: [PATCH 6/7] classify opcode load/store --- src/parser.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/parser.c b/src/parser.c index 98fa61a..b736d29 100644 --- a/src/parser.c +++ b/src/parser.c @@ -27,9 +27,21 @@ 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} } - } else if(strcmp(opcode, "ldr") == 0 || strcmp(opcode, "str") == 0){ + } else if((int isLoad = strcmp(opcode, "ldr")) == 0 || (int isStore = strcmp(opcode, "str")) == 0){ //loading/storing instruction; classify operands - char *address = opcode[1]; + char *address = operandList[1]; + if( *address == '['){ + //type is register + instr->type = a64inst_SINGLETRANSFER; + if(isLoad == 0){ + instr->data.processOpData.singleDataTransferData.transferType = a64inst_LOAD; + } else { + instr->data.processOpData.singleDataTransferData.transferType = a64inst_STORE; + } + } else { + instr->type = a64inst_LOADLITERAL; + //instr->data.processOpData.offset = {} to be defined by symbol table + } } else { //data processing @@ -39,7 +51,6 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ char *tokeniseOperands(char* str, int operandCount, char *operands[]){ char *operandsDupe = strdup(str); - int operandCount = 0; char *operand = strtok(operandsDupe, OPERAND_DELIMITER); operands[0] = operand; @@ -71,7 +82,7 @@ a64inst_instruction *parser(char asmLine[]){ if(strcmp(opcode, ".int") == 0){ //type is directive - //define new type in a64instr struct + } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { //type is label //add to symbol table From 1d1089634fbdfbf1c7b0d0a65285c28b9004e017 Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Tue, 4 Jun 2024 04:24:56 +0100 Subject: [PATCH 7/7] add halt command handling --- src/parser.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/parser.c b/src/parser.c index b736d29..15f010a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -74,6 +74,11 @@ a64inst_instruction *parser(char asmLine[]){ return(instr); } + if(strcmp(asmLine, HALT_ASM_CMD) == 0){ + instr->type = a64inst_HALT; + return(instr); + } + //"opcode operand1, {operand2}, ..." char *stringptr = strdup(asmLine);