Update parse to use function pointers

This commit is contained in:
sBubshait 2024-06-20 04:48:05 +01:00
parent e21ff75bad
commit 41fde09d75

View File

@ -3,7 +3,6 @@
* internal representation of instructions, a64inst_instruction. * internal representation of instructions, a64inst_instruction.
* *
* @author Ethan Dias Alberto * @author Ethan Dias Alberto
* @author George Niedringhaus
* @author Saleh Bubshait * @author Saleh Bubshait
*/ */
@ -20,7 +19,7 @@
#include "string_util.h" #include "string_util.h"
/************************************ /************************************
* STRUCTS * STRUCTS AND FUNCTION POINTERS
************************************/ ************************************/
typedef struct { typedef struct {
@ -28,17 +27,19 @@ typedef struct {
int immediate; int immediate;
} ShiftData; } ShiftData;
typedef void (*InstructionParser)(a64inst_instruction *, char *, char **, int);
/************************************ /************************************
* PROTOTYPES * PROTOTYPES
************************************/ ************************************/
static void parse_instruction(char asmLine[], a64inst_instruction *instr); static void parse_instruction(char asmLine[], a64inst_instruction *instr);
static void parseSingleTransfer(a64inst_instruction *instr, char *opcode, char *operandList[], int numOperands); 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 parseAddressingMode(a64inst_instruction *instr, char *operandList[], int numOperands);
static void parseDPImmediate(a64inst_instruction *inst, char *tokens[], int tokensCount); static void parseDPImmediate(a64inst_instruction *inst, char *opcode, char *tokens[], int tokensCount);
static void parseDPRegister(a64inst_instruction *inst, char *tokens[], int tokensCount); static void parseDPRegister(a64inst_instruction *inst, char*opcode, char *tokens[], int tokensCount);
static void parseDirective(a64inst_instruction *inst, char *tokens[]); static void parseDirective(a64inst_instruction *inst, char*opcode, char *tokens[], int tokensCount);
static ShiftData *parseShift(char *shift); static ShiftData *parseShift(char *shift);
static void classifyOpcode(char* opcode, a64inst_instruction *instr, char *tokens[], int *tokensCount); 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 *SHIFT_TYPE_OPCODES[] = {"lsl", "lsr", "asr", "ror"};
static const char *LOGIC_OPCODES[] = {"and", "ands", "bic", "bics", "eor", "eon", "orr", "orn"}; 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 * FUNCTIONS
@ -93,68 +104,37 @@ static void parse_instruction(char asmLine[], a64inst_instruction *instr) {
return; return;
} }
if(opcode[strlen(opcode)-1]== ':') {
if(strcmp(opcode, ".int") == 0){
// Directive
instr->type = a64inst_DIRECTIVE;
parseDirective(instr, tokens);
} else if(opcode[strlen(opcode)-1]== ':') {
// Label // Label
instr->type = a64inst_LABEL; instr->type = a64inst_LABEL;
opcode[strlen(opcode) - 1] = '\0'; // Remove the colon opcode[strlen(opcode) - 1] = '\0'; // Remove the colon
instr->data.LabelData.label = opcode; instr->data.LabelData.label = opcode;
return;
}
if(strcmp(opcode, ".int") == 0){
// Directive
instr->type = a64inst_DIRECTIVE;
} else { } else {
// Instruction // Instruction
// Classify the opcode into the correct instruction type.
classifyOpcode(opcode, instr, tokens, &tokensCount); 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;
} }
} // Call the correct function to parse the instruction.
} if (instructionParsers[instr->type] != NULL) {
instructionParsers[instr->type](instr, opcode, tokens, tokensCount);
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);
} else { } 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) { 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: case a64inst_SINGLETRANSFER:
instr->data.SingleTransferData.regType = getRegisterType(tokens[1]); instr->data.SingleTransferData.regType = getRegisterType(tokens[1]);
instr->data.SingleTransferData.target = getRegister(tokens[1]); instr->data.SingleTransferData.target = getRegister(tokens[1]);
parseAddressingMode(instr, tokens, tokensCount);
break; break;
case a64inst_LOADLITERAL: 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){ switch(instr->data.BranchData.BranchType){
case a64inst_UNCONDITIONAL: case a64inst_UNCONDITIONAL:
//define and sign extend immediate offset //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; a64inst_DPImmediateData *data = &inst->data.DPImmediateData;
data->dest = getRegister(tokens[1]); data->dest = getRegister(tokens[1]);
data->regType = getRegisterType(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; a64inst_DPRegisterData *data = &inst->data.DPRegisterData;
data->dest = getRegister(tokens[1]); data->dest = getRegister(tokens[1]);
data->regType = getRegisterType(tokens[1]); data->regType = getRegisterType(tokens[1]);