ARMv8/src/parser.c
2024-06-05 19:57:51 +01:00

101 lines
3.0 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;
}
return(operands);
}
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);
}
//"opcode operand1, {operand2}, ..."
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);
}