diff --git a/src/assemble.c b/src/assemble.c index ae760c0..aa54b4e 100755 --- a/src/assemble.c +++ b/src/assemble.c @@ -1,5 +1,6 @@ #include #include +#include "parser.c" int main(int argc, char **argv) { diff --git a/src/emulate.c b/src/emulate.c old mode 100755 new mode 100644 index 82245e9..be41f56 --- a/src/emulate.c +++ b/src/emulate.c @@ -8,6 +8,11 @@ #include "decode.h" #include "execute.h" +int main(int arg, char **argv){ + return EXIT_SUCCESS; +} + +/* extern a64inst_instruction *decode(word w); int main(int argc, char **argv) { @@ -59,3 +64,4 @@ int main(int argc, char **argv) { return EXIT_SUCCESS; } +*/ diff --git a/src/parser.c b/src/parser.c index c0a3caa..fcef57b 100644 --- a/src/parser.c +++ b/src/parser.c @@ -12,43 +12,37 @@ // - use string matching to get opcode, and operands (DONE) // - check operand count (DONE) // - match opcode to a64 struct types (DONE) -// - count operands and match type/values -// - generate final a64inst and return +// - count operands and match type/values (DONE) +// - generate final a64inst and return (TODO: DP instrs) +// - ASK ABOUT OFFSET CALCULATION // - CREATE FUNC TO TIDY UP OPERANDS IN DP +int isOperandRegister(char *operand){ + return((strcmp(&(operand[0]), "x")==0) || (strcmp(&(operand[0]), "w")==0)); +} + //calculate offsets from string void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[], int numOperands){ - char *baseRegister = strdup(operandList[1]); - baseRegister++; - baseRegister++; char *endptr; - uint8_t base = strtol(baseRegister, endptr, 10); + uint8_t base = strtol(&(operandList[1][2]), &endptr, 10); instr->data.SingleTransferData.processOpData.singleDataTransferData.base = base; - if(strcmp(operandList[2][strlen(operandList[1])-1], "!")==0){ + if(strcmp(&(operandList[2][strlen(operandList[1])-1]), "!")==0){ instr->data.SingleTransferData.processOpData.singleDataTransferData.addressingMode = a64inst_PRE_INDEXED; - char *offsetParam = strdup(operandList[2]); - offsetParam++; - instr->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.indexedOffset = strtol(operandList[2], endptr, 10); - } else if(strcmp(operandList[1][strlen(operandList[0])-1], "]") == 0) { + instr->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.indexedOffset = strtol(&(operandList[2][1]), &endptr, 10); + } else if(strcmp(&(operandList[1][strlen(operandList[0])-1]), "]") == 0) { //post-indexed instr->data.SingleTransferData.processOpData.singleDataTransferData.addressingMode = a64inst_POST_INDEXED; - char *offsetParam = strdup(operandList[2]); - offsetParam++; - instr->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.indexedOffset = strtol(operandList[2], endptr, 10); - } else if( (isOperandRegister(operandList[2][0], "x") == 1) - || (isOperandRegister(operandList[2][0], "w") == 1)){ + instr->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.indexedOffset = strtol(&(operandList[2][1]), &endptr, 10); + } else if( (isOperandRegister(&(operandList[2][0])) == 1) + || (isOperandRegister(&(operandList[2][0])) == 1)){ //register instr->data.SingleTransferData.processOpData.singleDataTransferData.addressingMode = a64inst_REGISTER_OFFSET; - char *offsetRegister = strdup(operandList[2]); - offsetRegister++; - instr->data.SingleTransferData.processOpData.singleDataTransferData.addressingModeData.offsetReg = strtol(offsetRegister, endptr, 10); + instr->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.offsetReg = strtol(&(operandList[2][1]), &endptr, 10); } else { instr->data.SingleTransferData.processOpData.singleDataTransferData.addressingMode = a64inst_UNSIGNED_OFFSET; if(numOperands==3){ - char *offsetParam = strdup(operandList[2]); - offsetParam++; - int offset = strtol(operandList[2], endptr, 10); + int offset = strtol(&(operandList[2][1]), &endptr, 10); if(instr->data.SingleTransferData.regType == 1){ instr->data.SingleTransferData.processOpData.singleDataTransferData.a64inst_addressingModeData.unsignedOffset = offset/8; } else { @@ -61,59 +55,61 @@ void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[], in void generateLoadStoreOperands(a64inst_instruction *instr, char *opcode, char *operandList[], int numOperands){ switch(instr->type){ case a64inst_SINGLETRANSFER: - if(strcmp(operandList[0][0], "x")==0){ + if(strcmp(&(operandList[0][0]), "x")==0){ //x-register instr->data.SingleTransferData.regType = 1; } else { instr->data.SingleTransferData.regType = 0; } char *endptr; - instr->data.SingleTransferData.target = strtol(operandList[0][0]+1, endptr, 10); + instr->data.SingleTransferData.target = strtol(&(operandList[0][0])+1, &endptr, 10); calcluateAddressFormat(instr, operandList, numOperands); break; case a64inst_LOADLITERAL: break; + default: + break; } } void generateBranchOperands(a64inst_instruction *instr, char* opcode, char *operandList[]){ + char *endptr; switch(instr->data.BranchData.BranchType){ case a64inst_UNCONDITIONAL: //define and sign extend immediate offset //use symbol table + printf("unconditional"); break; case a64inst_REGISTER: - char *endptr; - instr->data.BranchData.processOpData.registerData.src = strtol(operandList[0] + 1, endptr, 10) + instr->data.BranchData.processOpData.registerData.src = strtol(operandList[0] + 1, &endptr, 10); break; case a64inst_CONDITIONAL: - char* condition = strtok(strdup(opcode), "b."); - condition = strtok(NULL, ""); - if(strcmp(condition, "eq")==0){ - instr->data.branchData.processOpData.conditionalData.cond = EQ; - } else if (strcmp(condition, "ne")==0){ - instr->data.branchData.processOpData.conditionalData.cond = NE; - } else if (strcmp(condition, "ge")==0){ - instr->data.branchData.processOpData.conditionalData.cond = GE; - } else if (strcmp(condition, "lt")==0){ - instr->data.branchData.processOpData.conditionalData.cond = LT; - } else if (strcmp(condition, "gt")==0){ - instr->data.branchData.processOpData.conditionalData.cond = GT; - } else if (strcmp(condition, "le")==0){ - instr->data.branchData.processOpData.conditionalData.cond = LE; - } else if (srtcmp(condition, "al")==0){ - instr->data.branchData.processOpData.conditionalData.cond = AL; + { + char *condition = NULL; + condition = strcpy(condition, opcode); + condition += 2; + if(strcmp(condition, "eq")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = EQ; + } else if (strcmp(condition, "ne")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = NE; + } else if (strcmp(condition, "ge")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = GE; + } else if (strcmp(condition, "lt")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = LT; + } else if (strcmp(condition, "gt")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = GT; + } else if (strcmp(condition, "le")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = LE; + } else if (strcmp(condition, "al")==0){ + instr->data.BranchData.processOpData.conditionalData.cond = AL; + } + break; + //calculate offset from symbol table. } - break; - //calculate offset from symbol table. } } -int isOperandRegister(char *operand){ - return((strcmp(operand[0], "x")==0) || (strcmp(operand[0], "w")==0)); -} - int classifyDPInst(char *operandList[]){ return(isOperandRegister(operandList[0]) && isOperandRegister(operandList[1]) && @@ -144,20 +140,21 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ if( *address == '['){ //type is register instr->type = a64inst_SINGLETRANSFER; - instr->data.singleTransferData.SingleTransferOpType = a64inst_SINGLE_TRANSFER_SINGLE_DATA_TRANSFER; + instr->data.SingleTransferData.SingleTransferOpType = a64inst_SINGLE_TRANSFER_SINGLE_DATA_TRANSFER; if(isLoad == 0){ - instr->data.SingleTransferData.transferType = a64inst_LOAD; + instr->data.SingleTransferData.processOpData.singleDataTransferData.transferType = a64inst_LOAD; } else { - instr->data.SingleTransferData.processOpData.transferType = a64inst_STORE; + instr->data.SingleTransferData.processOpData.singleDataTransferData.transferType = a64inst_STORE; } } else { instr->type = a64inst_LOADLITERAL; - if(strcmp(operandList[0][0], "#")==0){ + if(operandList[0][0] =='#'){ //offset is immediate - char *immOffset = strdup(operandList[0]) + char *immOffset = NULL; + immOffset = strcpy(immOffset, operandList[0]); immOffset++; - char *endptr; - int offset = strtol(immOffset, endptr, 10); + char *endptr = NULL; + int offset = strtol(immOffset, &endptr, 10); instr->data.SingleTransferData.processOpData.loadLiteralData.offset = offset; } else { //offset is literal, use symbol table and calculate difference @@ -174,17 +171,18 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[ } } -char *tokeniseOperands(char* str, int operandCount, char *operands[], int numOperands){ - char *operandsDupe = strdup(str); +void tokeniseOperands(char* str, int *operandCount, char *operands[], int *numOperands){ + char *operandsDupe = NULL; + operandsDupe = strcpy(operandsDupe, str); char *operand = strtok(operandsDupe, OPERAND_DELIMITER); operands[0] = operand; while (operand != NULL){ - operandCount++; + *operandCount = *(operandCount)+1; operand = strtok(NULL, OPERAND_DELIMITER); - operands[operandCount] = operand; + operands[*(operandCount)] = operand; } - numOperands = operandCount+1; + *(numOperands) = *(operandCount)+1; } //takes inputted assembly line and returns a @@ -203,7 +201,8 @@ a64inst_instruction *parser(char asmLine[]){ //"opcode operand1, {operand2}, ..." //duplicated as strtok modifies the input string - char *stringptr = strdup(asmLine); + char *stringptr = NULL; + stringptr = strcpy(stringptr, asmLine); char *opcode = strtok(stringptr, " "); char *operands = strtok(NULL, ""); @@ -212,17 +211,18 @@ a64inst_instruction *parser(char asmLine[]){ //type is directive instr->type = a64inst_DIRECTIVE; - } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { + } else if(opcode[strlen(opcode)-1]== ':') { //type is label //add to symbol table instr->type = a64inst_LABEL; - char *opcodeCpy = strdup(opcode); + char *opcodeCpy = NULL; + opcodeCpy = strcpy(opcodeCpy, opcode); char *labelData = strtok(opcodeCpy, ":"); - instr->data.labelData.label = labelData; + instr->data.LabelData.label = labelData; } else { //type is instruction int operandCount = 0; - const char *operandList[4]; + char *operandList[4]; //generate list of operands tokeniseOperands(operands, &operandCount, operandList, &numOperands); //categorise instruction type from opcode and operands diff --git a/src/parser.h b/src/parser.h index 5c3a461..e303b58 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,5 +1,2 @@ -#ifndef __PARSERCONSTS__ -#define __PARSERCONSTS__ #define OPERAND_DELIMITER ", " #define HALT_ASM_CMD "and x0, x0, x0" -#endif \ No newline at end of file