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:
// - use string matching to get opcode, and operands (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
// - 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[]){
if((int isUnconditional = strcmp(opcode, "b")) == 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.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){
//loading/storing instruction; classify operands
char *address = operandList[1];
if( *address == '['){
//type is register
instr->type = a64inst_SINGLETRANSFER;
instr->data.SingleTransferOpType = a64inst_SINGLE_TRANSFER_SINGLE_DATA_TRANSFER;
if(isLoad == 0){
instr->data.processOpData.singleDataTransferData.transferType = a64inst_LOAD;
instr->data.processOpData.transferType = a64inst_LOAD;
} else {
instr->data.processOpData.singleDataTransferData.transferType = a64inst_STORE;
instr->data.processOpData.transferType = a64inst_STORE;
}
} else {
instr->type = a64inst_LOADLITERAL;
@ -44,7 +115,12 @@ void classifyOpcode(char* opcode, a64inst_instruction *instr, char *operandList[
}
} 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);
}
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);
@ -88,10 +159,15 @@ a64inst_instruction *parser(char asmLine[]){
if(strcmp(opcode, ".int") == 0){
//type is directive
instr->type = a64inst_DIRECTIVE;
} else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) {
//type is label
//add to symbol table
instr->type = a64inst_LABEL;
char *opcodeCpy = strdup(opcode);
char *labelData = strtok(opcodeCpy, ":");
instr->data.label = labelData;
} else {
//type is instruction
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 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
word assembleBranch(a64inst_instruction *instr, int ){
word assembleBranch(a64inst_instruction *instr){
word binInstr = 0;
binInstr += (5^28); //101 start of branch instr
switch (instr->data.BranchData.BranchType)
{
case a64inst_UNCONDITIONAL:
//000101
//25-0: sign extended simm26
binInstr += instr->data.processOpData.unconditionalOffset;
break;
case a64inst_REGISTER:
//1101011
//0000
//10000
//11111
//000000
//9-5: address from register
//0000
binInstr += ((instr->processOpData.src)^5);
break;
case a64inst_CONDITIONAL:
// 01010100
// 25-5: sign extended offset
// 4-0: 0{condition}
binInstr += ((instr->processOpData.offset)^5);
binInstr += instr->processOpData.cond;
break;
default:
break;
}
return binInstr;
}
st* firstPass(a64inst_instruction instrs[], int numInstrs){