#include #include #include "parser.h" #include "a64instruction.h" //takes input string, read from asm file and returns //input as an a64 instruction //TODO: // - use string matching to get opcode, and operands (DONE) // - check operand count (DONE) // - 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, 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); char *operand = strtok(operandsDupe, OPERAND_DELIMITER); operands[0] = operand; while (operand != NULL){ operandCount++; operand = strtok(NULL, OPERAND_DELIMITER); operands[operandCount] = operand; } } //takes inputted assembly line and returns a //pointer to an abstract representation of the instruction a64inst_instruction *parser(char asmLine[]){ a64inst_instruction *instr = malloc(sizeof(a64inst_instruction)); if (instr == NULL){ 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); char *opcode = strtok(stringptr, " "); char *operands = strtok(NULL, ""); if(strcmp(opcode, ".int") == 0){ //type is directive } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { //type is label //add to symbol table } else { //type is instruction int operandCount = 0; const char *operandList[4]; tokeniseOperands(operands, &operandCount, operandList); } return(a64inst_instruction); }