From 41fde09d7538c30a725268d8746a527dec016590 Mon Sep 17 00:00:00 2001 From: sBubshait Date: Thu, 20 Jun 2024 04:48:05 +0100 Subject: [PATCH] Update parse to use function pointers --- src/assembler/parse.c | 99 +++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 59 deletions(-) diff --git a/src/assembler/parse.c b/src/assembler/parse.c index dc724ba..d80bfc6 100644 --- a/src/assembler/parse.c +++ b/src/assembler/parse.c @@ -3,7 +3,6 @@ * internal representation of instructions, a64inst_instruction. * * @author Ethan Dias Alberto - * @author George Niedringhaus * @author Saleh Bubshait */ @@ -20,7 +19,7 @@ #include "string_util.h" /************************************ - * STRUCTS + * STRUCTS AND FUNCTION POINTERS ************************************/ typedef struct { @@ -28,17 +27,19 @@ typedef struct { int immediate; } ShiftData; +typedef void (*InstructionParser)(a64inst_instruction *, char *, char **, int); + /************************************ * PROTOTYPES ************************************/ static void parse_instruction(char asmLine[], a64inst_instruction *instr); static void parseSingleTransfer(a64inst_instruction *instr, char *opcode, char *operandList[], int numOperands); -static void parseBranch(a64inst_instruction *instr, char* opcode, char *operandList[]); +static void parseBranch(a64inst_instruction *instr, char* opcode, char *operandList[], int numOperands); static void parseAddressingMode(a64inst_instruction *instr, char *operandList[], int numOperands); -static void parseDPImmediate(a64inst_instruction *inst, char *tokens[], int tokensCount); -static void parseDPRegister(a64inst_instruction *inst, char *tokens[], int tokensCount); -static void parseDirective(a64inst_instruction *inst, char *tokens[]); +static void parseDPImmediate(a64inst_instruction *inst, char *opcode, char *tokens[], int tokensCount); +static void parseDPRegister(a64inst_instruction *inst, char*opcode, char *tokens[], int tokensCount); +static void parseDirective(a64inst_instruction *inst, char*opcode, char *tokens[], int tokensCount); static ShiftData *parseShift(char *shift); static void classifyOpcode(char* opcode, a64inst_instruction *instr, char *tokens[], int *tokensCount); @@ -54,6 +55,16 @@ static const char *MULTIPLY_OPCODES[] = {"mul", "madd", "msub", "mneg"}; static const char *SHIFT_TYPE_OPCODES[] = {"lsl", "lsr", "asr", "ror"}; static const char *LOGIC_OPCODES[] = {"and", "ands", "bic", "bics", "eor", "eon", "orr", "orn"}; +static const InstructionParser instructionParsers[] = { + parseDPImmediate, // a64inst_DPIMMEDIATE + parseDPRegister, // a64inst_DPREGISTER + parseSingleTransfer, // a64inst_SINGLETRANSFER + parseSingleTransfer, // a64inst_LOADLITERAL (same as SINGLETRANSFER) + parseBranch, // a64inst_BRANCH + NULL, // a64inst_HALT (no specific parsing function needed) + NULL, // a64inst_LABEL (no specific parsing function needed) + parseDirective // a64inst_DIRECTIVE (handled within parse_instruction) +}; /************************************ * FUNCTIONS @@ -93,68 +104,37 @@ static void parse_instruction(char asmLine[], a64inst_instruction *instr) { return; } - - if(strcmp(opcode, ".int") == 0){ - // Directive - instr->type = a64inst_DIRECTIVE; - parseDirective(instr, tokens); - - - } else if(opcode[strlen(opcode)-1]== ':') { + if(opcode[strlen(opcode)-1]== ':') { // Label instr->type = a64inst_LABEL; opcode[strlen(opcode) - 1] = '\0'; // Remove the colon instr->data.LabelData.label = opcode; - + return; + } + + if(strcmp(opcode, ".int") == 0){ + // Directive + instr->type = a64inst_DIRECTIVE; } else { // Instruction - - // Classify the opcode into the correct instruction type. classifyOpcode(opcode, instr, tokens, &tokensCount); - - switch(instr->type){ - case a64inst_BRANCH: - parseBranch(instr, opcode, tokens); - break; - - case a64inst_SINGLETRANSFER: - parseSingleTransfer(instr, opcode, tokens, tokensCount); - parseAddressingMode(instr, tokens, tokensCount); - break; - - case a64inst_LOADLITERAL: - parseSingleTransfer(instr, opcode, tokens, tokensCount); - break; - - case a64inst_DPREGISTER: - //generate DP operands; - parseDPRegister(instr, tokens, tokensCount); - break; - - case a64inst_DPIMMEDIATE: - parseDPImmediate(instr, tokens, tokensCount); - break; - - default: - printf("Error: Invalid Instruction, '%s'\n", opcode); - break; - - } + } - } -} - -static void parseDirective(a64inst_instruction *instr, char *tokens[]) { - char *intValue = tokens[1]; - char *endptr; - if(strncmp(intValue, "0x", 2) == 0) { - intValue += 2; - instr->data.DirectiveData.value = strtol(intValue, &endptr, 16); + // Call the correct function to parse the instruction. + if (instructionParsers[instr->type] != NULL) { + instructionParsers[instr->type](instr, opcode, tokens, tokensCount); } else { - instr->data.DirectiveData.value = strtol(tokens[1], &endptr, 10); + printf("Error: Invalid Instruction, '%s'\n", opcode); + exit(EXIT_FAILURE); } } +static void parseDirective(a64inst_instruction *instr, char *opcode, char *tokens[], int tokensCount) { + char intValue[strlen(tokens[1]) + 1]; + *intValue = '#'; + strcpy(intValue + 1, tokens[1]); + instr->data.DirectiveData.value = getImmediate(intValue); +} static void parseSingleTransfer(a64inst_instruction *instr, char *opcode, char *tokens[], int tokensCount) { @@ -162,6 +142,7 @@ static void parseSingleTransfer(a64inst_instruction *instr, char *opcode, char * case a64inst_SINGLETRANSFER: instr->data.SingleTransferData.regType = getRegisterType(tokens[1]); instr->data.SingleTransferData.target = getRegister(tokens[1]); + parseAddressingMode(instr, tokens, tokensCount); break; case a64inst_LOADLITERAL: @@ -184,7 +165,7 @@ static void parseSingleTransfer(a64inst_instruction *instr, char *opcode, char * } } -void parseBranch(a64inst_instruction *instr, char* opcode, char *operandList[]) { +void parseBranch(a64inst_instruction *instr, char* opcode, char *operandList[], int numOperands) { switch(instr->data.BranchData.BranchType){ case a64inst_UNCONDITIONAL: //define and sign extend immediate offset @@ -221,7 +202,7 @@ void parseBranch(a64inst_instruction *instr, char* opcode, char *operandList[]) } } -void parseDPImmediate(a64inst_instruction *inst, char *tokens[], int tokensCount) { +void parseDPImmediate(a64inst_instruction *inst, char *opcode, char *tokens[], int tokensCount) { a64inst_DPImmediateData *data = &inst->data.DPImmediateData; data->dest = getRegister(tokens[1]); data->regType = getRegisterType(tokens[1]); @@ -251,7 +232,7 @@ void parseDPImmediate(a64inst_instruction *inst, char *tokens[], int tokensCount } } -void parseDPRegister(a64inst_instruction *inst, char *tokens[], int tokensCount) { +void parseDPRegister(a64inst_instruction *inst, char *opcode, char *tokens[], int tokensCount) { a64inst_DPRegisterData *data = &inst->data.DPRegisterData; data->dest = getRegister(tokens[1]); data->regType = getRegisterType(tokens[1]);