Update parse to use function pointers
This commit is contained in:
parent
e21ff75bad
commit
41fde09d75
@ -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]);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user