diff --git a/src/parser.c b/src/parser.c index 9f5f526..53b8e0c 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,16 +10,47 @@ //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 -//takes string of operands, and reference to operandcounter -//takes input of result array -//outputs array of operands -void tokeniseOperands(char* str, int operandCount, char *operands[]){ +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){ + 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((int isLoad = strcmp(opcode, "ldr")) == 0 || (int isStore = strcmp(opcode, "str")) == 0){ + //loading/storing instruction; classify operands + 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 + + } +} + +char *tokeniseOperands(char* str, int operandCount, char *operands[]){ char *operandsDupe = strdup(str); - int operandCount = 0; char *operand = strtok(operandsDupe, OPERAND_DELIMITER); operands[0] = operand; @@ -38,6 +69,16 @@ a64inst_instruction *parser(char asmLine[]){ exit(EXIT_FAILURE); } + if(strcmp(asmLine, HALT_ASM_CMD) == 0){ + instr->type = a64inst_HALT; + 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); @@ -45,10 +86,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 - } else if(opcode[strlen(opcode)-1]==":") { + + } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { //type is label + //add to symbol table } else { //type is instruction int operandCount = 0; 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 diff --git a/src/twopassassembly.c b/src/twopassassembly.c new file mode 100644 index 0000000..d6194a8 --- /dev/null +++ b/src/twopassassembly.c @@ -0,0 +1,53 @@ +//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 + } + } +} + +word assembleBranch(a64inst_instruction *instr, int ){ + 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; + } +} + +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