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.
|
* 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]);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user