107 lines
3.3 KiB
C
107 lines
3.3 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#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);
|
|
|
|
}
|
|
|