Merge branch 'assembler-e' into 'assembler'
merge assembler-e into assembler See merge request lab2324_summer/armv8_43!4
This commit is contained in:
commit
adadbbb616
96
src/parser.c
96
src/parser.c
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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){
|
||||
|
||||
Loading…
Reference in New Issue
Block a user