Merge branch 'assembler-e' into 'assembler'
Merge twopassassembly skeleton into main assembler branch See merge request lab2324_summer/armv8_43!2
This commit is contained in:
commit
3439f2ed98
59
src/parser.c
59
src/parser.c
@ -10,16 +10,47 @@
|
||||
//TODO:
|
||||
// - use string matching to get opcode, and operands (DONE)
|
||||
// - check operand count (DONE)
|
||||
// - match opcode to a64 struct types
|
||||
// - match opcode to a64 struct types (PARTIALLY DONE)
|
||||
// - count operands and match type/values
|
||||
// - generate final a64inst and return
|
||||
|
||||
//takes string of operands, and reference to operandcounter
|
||||
//takes input of result array
|
||||
//outputs array of operands
|
||||
void tokeniseOperands(char* str, int operandCount, char *operands[]){
|
||||
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);
|
||||
int operandCount = 0;
|
||||
char *operand = strtok(operandsDupe, OPERAND_DELIMITER);
|
||||
operands[0] = operand;
|
||||
|
||||
@ -38,6 +69,16 @@ a64inst_instruction *parser(char asmLine[]){
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(strcmp(asmLine, HALT_ASM_CMD) == 0){
|
||||
instr->type = a64inst_HALT;
|
||||
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);
|
||||
@ -45,10 +86,12 @@ a64inst_instruction *parser(char asmLine[]){
|
||||
char *opcode = strtok(stringptr, " ");
|
||||
char *operands = strtok(NULL, "");
|
||||
|
||||
if(opcode[0]=="."){
|
||||
if(strcmp(opcode, ".int") == 0){
|
||||
//type is directive
|
||||
} else if(opcode[strlen(opcode)-1]==":") {
|
||||
|
||||
} else if(strcmp(opcode[strlen(opcode)-1], ":") == 0) {
|
||||
//type is label
|
||||
//add to symbol table
|
||||
} else {
|
||||
//type is instruction
|
||||
int operandCount = 0;
|
||||
|
||||
@ -1 +1,2 @@
|
||||
#define OPERAND_DELIMITER ", "
|
||||
#define OPERAND_DELIMITER ", "
|
||||
#define HALT_ASM_CMD "and x0, x0, x0"
|
||||
53
src/twopassassembly.c
Normal file
53
src/twopassassembly.c
Normal file
@ -0,0 +1,53 @@
|
||||
//generates assembled code based on two pass assembly method
|
||||
|
||||
void generateSymbolTable(a64inst_instruction instrs[], int numInstrs){
|
||||
//TODO:
|
||||
//generate symbol table based on inputted assembly code and labels
|
||||
for(int i=0; i<numInstrs; i++){
|
||||
// discuss defining a LABEL type
|
||||
if(instrs[i]->type==LABEL){
|
||||
// symbol table stuff here
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
word assembleBranch(a64inst_instruction *instr, int ){
|
||||
word binInstr = 0;
|
||||
switch (instr->data.BranchData.BranchType)
|
||||
{
|
||||
case a64inst_UNCONDITIONAL:
|
||||
//000101
|
||||
//25-0: sign extended simm26
|
||||
|
||||
break;
|
||||
case a64inst_REGISTER:
|
||||
//1101011
|
||||
//0000
|
||||
//11111
|
||||
//000000
|
||||
//9-5: address from register
|
||||
//0000
|
||||
|
||||
break;
|
||||
case a64inst_CONDITIONAL:
|
||||
// 01010100
|
||||
// 25-5: sign extended offset
|
||||
// 4-0: 0{condition}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void firstPass(a64inst_instruction instrs[], int numInstrs){
|
||||
//TODO:
|
||||
// -iterate over instructions, adding to symbol table
|
||||
// create symbol table and map labels to addresses/lines
|
||||
}
|
||||
|
||||
void secondPass(a64inst_instruction instrs[], int numInstrs){
|
||||
//TODO:
|
||||
// iterate over instructions again, this time replacing labels
|
||||
// with values from symbol table
|
||||
// after a line has had all the values replaced, assemble it and append
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user