Merge branch 'assembler-e' into 'assembler'

merge assembler-e into assembler

See merge request lab2324_summer/armv8_43!4
This commit is contained in:
Dias Alberto, Ethan 2024-06-06 16:04:28 +00:00
commit adadbbb616
3 changed files with 98 additions and 16 deletions

View File

@ -10,10 +10,79 @@
//TODO: //TODO:
// - use string matching to get opcode, and operands (DONE) // - use string matching to get opcode, and operands (DONE)
// - check operand count (DONE) // - check operand count (DONE)
// - match opcode to a64 struct types (PARTIALLY DONE) // - match opcode to a64 struct types (DONE)
// - count operands and match type/values // - count operands and match type/values
// - generate final a64inst and return // - generate final a64inst and return
//calculate offsets from string
void calcluateAddressFormat(a64inst_instruction *instr, char *operandList[]){
if(strcmp(operandList[2][strlen(operandList[1])-1], "!")==0){
instr->data.processOpData.addressingMode = a64inst_PRE_INDEXED;
} else if(strcmp(operandList[1][strlen(operandList[0])-1], "]") == 0) {
//post-indexed
instr->data.processOpData.addressingMode = a64inst_POST_INDEXED;
} else if( (strcmp(operandList[2][strlen(operandList[1])-1], "x") == 0)
|| (strcmp(operandList[2][strlen(operandList[1])-1], "w") == 0)){
//register
instr->data.processOpData.addressingMode = a64inst_REGISTER_OFFSET;
} else {
instr->data.processOpData.addressingMode = a64inst_UNSIGNED_OFFSET;
}
}
void generateLoadStoreOperands(a64inst_instruction *instr, char *opcode, char *operandList[]){
switch(instr->data.type){
case a64inst_SINGLETRANSFER:
if(strcmp(operandList[0][0], "x")==0){
//x-register
instr->data.regType = 1;
} else {
instr->data.regType = 0;
}
char *endptr;
instr->data.target = strtol(operandList[0][0]+1, endptr, 2);
calcluateAddressFormat(instr, operandList);
break;
case a64inst_LOADLITERAL:
break;
}
}
void generateBranchOperands(a64inst_instruction *instr, char* opcode, char *operandList[]){
switch(instr->data.BranchType){
case a64inst_UNCONDITIONAL:
//define and sign extend immediate offset
//use symbol table
break;
case a64inst_REGISTER:
char *endptr;
instr->data.processOpData.src = strtol(operandList[0] + 1, endptr, 2)
break;
case a64inst_CONDITIONAL:
char* condition = strtok(strdup(opcode), "b.");
condition = strtok(NULL, "");
if(strcmp(condition, "eq")==0){
instr->data.processOpData.cond = EQ;
} else if (strcmp(condition, "ne")==0){
instr->data.processOpData.cond = NE;
} else if (strcmp(condition, "ge")==0){
instr->data.processOpData.cond = GE;
} else if (strcmp(condition, "lt")==0){
instr->data.processOpData.cond = LT;
} else if (strcmp(condition, "gt")==0){
instr->data.processOpData.cond = GT;
} else if (strcmp(condition, "le")==0){
instr->data.processOpData.cond = LE;
} else if (srtcmp(condition, "al")==0){
instr->data.processOpData.cond = AL;
}
break;
//calculate offset from symbol table.
}
}
void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[]){ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[]){
if((int isUnconditional = strcmp(opcode, "b")) == 0 || if((int isUnconditional = strcmp(opcode, "b")) == 0 ||
(int isRegister = strcmp(opcode, "br")) == 0 || (int isRegister = strcmp(opcode, "br")) == 0 ||
@ -27,16 +96,18 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[
instr->data.BranchData.BranchType = a64inst_CONDITIONAL; instr->data.BranchData.BranchType = a64inst_CONDITIONAL;
//instr->data.branchData.processOpData.cond = {remove first two chars of opcode} //instr->data.branchData.processOpData.cond = {remove first two chars of opcode}
} }
generateBranchOperands(instr, opcode, operandList);
} else if((int isLoad = strcmp(opcode, "ldr")) == 0 || (int isStore = strcmp(opcode, "str")) == 0){ } else if((int isLoad = strcmp(opcode, "ldr")) == 0 || (int isStore = strcmp(opcode, "str")) == 0){
//loading/storing instruction; classify operands //loading/storing instruction; classify operands
char *address = operandList[1]; char *address = operandList[1];
if( *address == '['){ if( *address == '['){
//type is register //type is register
instr->type = a64inst_SINGLETRANSFER; instr->type = a64inst_SINGLETRANSFER;
instr->data.SingleTransferOpType = a64inst_SINGLE_TRANSFER_SINGLE_DATA_TRANSFER;
if(isLoad == 0){ if(isLoad == 0){
instr->data.processOpData.singleDataTransferData.transferType = a64inst_LOAD; instr->data.processOpData.transferType = a64inst_LOAD;
} else { } else {
instr->data.processOpData.singleDataTransferData.transferType = a64inst_STORE; instr->data.processOpData.transferType = a64inst_STORE;
} }
} else { } else {
instr->type = a64inst_LOADLITERAL; instr->type = a64inst_LOADLITERAL;
@ -44,7 +115,12 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[
} }
} else { } else {
//data processing int numOperands = sizeof(operandList) / sizeof(operandList[0])
if(numOperands==3){
instr->type = a64inst_DPREGISTER;
} else {
instr->type = a64inst_DPIMMEDIATE;
}
} }
} }
@ -74,11 +150,6 @@ a64inst_instruction *parser(char asmLine[]){
return(instr); return(instr);
} }
if(strcmp(asmLine, HALT_ASM_CMD) == 0){
instr->type = a64inst_HALT;
return(instr);
}
//"opcode operand1, {operand2}, ..." //"opcode operand1, {operand2}, ..."
//duplicated as strtok modifies the input string //duplicated as strtok modifies the input string
char *stringptr = strdup(asmLine); char *stringptr = strdup(asmLine);
@ -88,10 +159,15 @@ a64inst_instruction *parser(char asmLine[]){
if(strcmp(opcode, ".int") == 0){ if(strcmp(opcode, ".int") == 0){
//type is directive //type is directive
instr->type = a64inst_DIRECTIVE;
} else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) { } else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) {
//type is label //type is label
//add to symbol table //add to symbol table
instr->type = a64inst_LABEL;
char *opcodeCpy = strdup(opcode);
char *labelData = strtok(opcodeCpy, ":");
instr->data.label = labelData;
} else { } else {
//type is instruction //type is instruction
int operandCount = 0; int operandCount = 0;
@ -100,7 +176,7 @@ a64inst_instruction *parser(char asmLine[]){
} }
return(a64inst_instruction); return(instr);
} }

View File

@ -1,2 +1,5 @@
#ifndef __PARSERCONSTS__
#define __PARSERCONSTS__
#define OPERAND_DELIMITER ", " #define OPERAND_DELIMITER ", "
#define HALT_ASM_CMD "and x0, x0, x0" #define HALT_ASM_CMD "and x0, x0, x0"
#endif

View File

@ -4,32 +4,35 @@
//generates assembled code based on two pass assembly method //generates assembled code based on two pass assembly method
word assembleBranch(a64inst_instruction *instr, int ){ word assembleBranch(a64inst_instruction *instr){
word binInstr = 0; word binInstr = 0;
binInstr += (5^28); //101 start of branch instr
switch (instr->data.BranchData.BranchType) switch (instr->data.BranchData.BranchType)
{ {
case a64inst_UNCONDITIONAL: case a64inst_UNCONDITIONAL:
//000101 //000101
//25-0: sign extended simm26 //25-0: sign extended simm26
binInstr += instr->data.processOpData.unconditionalOffset;
break; break;
case a64inst_REGISTER: case a64inst_REGISTER:
//1101011 //10000
//0000
//11111 //11111
//000000 //000000
//9-5: address from register //9-5: address from register
//0000 //0000
binInstr += ((instr->processOpData.src)^5);
break; break;
case a64inst_CONDITIONAL: case a64inst_CONDITIONAL:
// 01010100 // 01010100
// 25-5: sign extended offset // 25-5: sign extended offset
// 4-0: 0{condition} // 4-0: 0{condition}
binInstr += ((instr->processOpData.offset)^5);
binInstr += instr->processOpData.cond;
break; break;
default: default:
break; break;
} }
return binInstr;
} }
st* firstPass(a64inst_instruction instrs[], int numInstrs){ st* firstPass(a64inst_instruction instrs[], int numInstrs){