diff --git a/src/parser.c b/src/parser.c index 53b8e0c..e9e05cf 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,10 +10,79 @@ //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 +//calculate offsets from string +void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){ + + if(strcmp(operandList[2][strlen(operandList[1])-1], "!")==0){ + instr->data.processOpData.addressingMode = a64inst_PRE_INDEXED; + } else if(strcmp(operandList[1][strlen(operandList[0])-1], "]") == 0) { + //post-indexed + instr->data.processOpData.addressingMode = a64inst_POST_INDEXED; + } 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 { + instr->data.processOpData.addressingMode = a64inst_UNSIGNED_OFFSET; + } +} + +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->data.target = strtol(operandList[0][0]+1, endptr, 2); + calcluateAddressFormat(instr, operandList); + break; + case a64inst_LOADLITERAL: + break; + + } +} + +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.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.processOpData.cond = EQ; + } else if (strcmp(condition, "ne")==0){ + instr->data.processOpData.cond = NE; + } else if (strcmp(condition, "ge")==0){ + instr->data.processOpData.cond = GE; + } else if (strcmp(condition, "lt")==0){ + instr->data.processOpData.cond = LT; + } else if (strcmp(condition, "gt")==0){ + instr->data.processOpData.cond = GT; + } else if (strcmp(condition, "le")==0){ + instr->data.processOpData.cond = LE; + } else if (srtcmp(condition, "al")==0){ + instr->data.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,16 +96,18 @@ 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]; 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; @@ -44,7 +115,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; + } } } @@ -74,11 +150,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); @@ -88,10 +159,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; @@ -100,7 +176,7 @@ a64inst_instruction *parser(char asmLine[]){ } - return(a64inst_instruction); + return(instr); } 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 diff --git a/src/twopassassembly.c b/src/twopassassembly.c index 4710968..cda97ec 100644 --- a/src/twopassassembly.c +++ b/src/twopassassembly.c @@ -4,32 +4,35 @@ //generates assembled code based on two pass assembly method -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) { 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; } + return binInstr; } st* firstPass(a64inst_instruction instrs[], int numInstrs){