226 lines
6.2 KiB
C
226 lines
6.2 KiB
C
#include "global.h"
|
|
#include "a64instruction/a64instruction.h"
|
|
#include "symboltable.h"
|
|
//generates assembled code based on two pass assembly method
|
|
|
|
|
|
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:
|
|
//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){
|
|
//TODO:
|
|
// -iterate over instructions, adding to symbol table
|
|
// create symbol table and map labels to addresses/lines
|
|
struct st table;
|
|
for(int i=0; i<numInstrs; i++){
|
|
|
|
// discuss defining a LABEL type
|
|
if(instrs[i].type==a64inst_LABEL){
|
|
st_add(table, &(instrs[i].data.LabelData.label), &i);
|
|
}
|
|
}
|
|
return &table;
|
|
}
|
|
word assembleDPI(a64inst_instruction cI) {
|
|
word out = 0;
|
|
a64inst_DPImmediateData data = cI.data.DPImmediateData;
|
|
//sf
|
|
out += data.regType*(2^31);
|
|
out += data.processOp*(2^29);
|
|
out += 2^28;
|
|
// if arithmetic
|
|
if (data.DPIOpType == a64inst_DPI_ARITHM) {
|
|
out += 2^24;
|
|
// shift
|
|
if (data.processOpData.arithmData.shiftImmediate){
|
|
out += 2^22;
|
|
}
|
|
out += data.processOpData.arithmData.immediate*(2^10);
|
|
out += data.processOpData.arithmData.src*(2^5);
|
|
}
|
|
// if wide move
|
|
else {
|
|
out += 5*(2^23);
|
|
// hw
|
|
out += data.processOpData.wideMovData.shiftScalar*(2^21);
|
|
out += data.processOpData.wideMovData.immediate*(2^5);
|
|
}
|
|
// destination register
|
|
out += data.dest;
|
|
return out;
|
|
}
|
|
|
|
word assembleDPR(a64inst_instruction cI) {
|
|
word out = 0;
|
|
a64inst_DPRegisterData data = cI.data.DPRegisterData;
|
|
// sf
|
|
int sf = data.regType;
|
|
// bits 27-25
|
|
out += 5*(2^25);
|
|
int m = data.DPROpType;
|
|
int opc = 0;
|
|
int opr = 0;
|
|
int rm = 0;
|
|
int operand = 0;
|
|
int rn = 0;
|
|
int rd = 0;
|
|
// multiply
|
|
if (m == 1) {
|
|
//opc = 0;
|
|
opr = 8;
|
|
if (data.processOpData.multiplydata.negProd) {
|
|
operand += 32;
|
|
}
|
|
operand += data.processOpData.multiplydata.summand;
|
|
}
|
|
// arithmetic and logical
|
|
else {
|
|
// shift
|
|
opr += 2*data.processOpData.arithmLogicData.shiftType;
|
|
// arithmetic
|
|
if (data.processOpData.arithmLogicData.type == 1){
|
|
opr += 8;
|
|
}
|
|
// logical
|
|
else {
|
|
if (data.processOpData.arithmLogicData.negShiftedSrc2) {
|
|
opr += 1;
|
|
}
|
|
}
|
|
operand += data.processOpData.arithmLogicData.shiftAmount;
|
|
}
|
|
rm += data.src1;
|
|
rn += data.src2;
|
|
rd += data.dest;
|
|
out += sf*(2^31);
|
|
out += opc * (2^29);
|
|
out += m* (2^28);
|
|
out += opr * (2^21);
|
|
out += rm * (2^16);
|
|
out += operand * 1024;
|
|
out += rn * 32;
|
|
out += rd;
|
|
return out;
|
|
}
|
|
|
|
word assembleSTS(a64inst_instruction cI) {
|
|
a64inst_SingleTransferData data = cI.data.SingleTransferData;
|
|
word out = 0;
|
|
a64inst_SingleDataTransferData data2 = data.processOpData.singleDataTransferData;
|
|
// this deals with every bit in the 31-23 range apart from sf and U
|
|
out += (512+128+64+32)*(2^23);
|
|
int sf = data.regType;
|
|
int u = 0;
|
|
int l = data2.transferType;
|
|
int offset = 0;
|
|
int xn = data2.base;
|
|
int rt = data.target;
|
|
switch (data2.addressingMode) {
|
|
// register offset
|
|
case 2:
|
|
offset += 2074 + 64*data2.a64inst_addressingModeData.offsetReg;
|
|
break;
|
|
// unsigned offset
|
|
case 3:
|
|
offset += data2.a64inst_addressingModeData.unsignedOffset;
|
|
u = 1;
|
|
break;
|
|
// pre/post indexed
|
|
default:
|
|
offset = 1 + data2.addressingMode*2 + data2.a64inst_addressingModeData.indexedOffset*4;
|
|
break;
|
|
}
|
|
out += sf*(2^30);
|
|
out += u*(2^22);
|
|
out += offset*1024;
|
|
out += xn * 32;
|
|
out += rt;
|
|
return out;
|
|
}
|
|
|
|
word assembleLDL(a64inst_instruction cI) {
|
|
word out = 3*(2^27);
|
|
a64inst_SingleTransferData data = cI.data.SingleTransferData;
|
|
int sf = data.regType;
|
|
int simm19 = data.processOpData.loadLiteralData.offset;
|
|
int rt = data.target;
|
|
out += sf * (2^30);
|
|
out += simm19*32;
|
|
out += rt;
|
|
return out;
|
|
}
|
|
|
|
void secondPass(a64inst_instruction instrs[], int numInstrs, st* table, word arr[]){
|
|
//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
|
|
int index = 0;
|
|
int lbl = 0;
|
|
for (int i=0; i<numInstrs; i++) {
|
|
a64inst_instruction cI = instrs[i];
|
|
switch (cI.type) {
|
|
case a64inst_DPIMMEDIATE:
|
|
arr[index] = dpi(cI);
|
|
index++;
|
|
break;
|
|
case a64inst_DPREGISTER:
|
|
arr[index] = dpr(cI);
|
|
index++;
|
|
break;
|
|
case a64inst_SINGLETRANSFER:
|
|
arr[index] = sts(cI);
|
|
index++;
|
|
break;
|
|
case a64inst_LOADLITERAL:
|
|
arr[index] = ldl(cI);
|
|
index++;
|
|
break;
|
|
case a64inst_DIRECTIVE:
|
|
arr[index] = cI.data.DirectiveData.value;
|
|
index++;
|
|
break;
|
|
case a64inst_HALT:
|
|
arr[index] = 69*(2^25);
|
|
index++;
|
|
break;
|
|
case a64inst_LABEL:
|
|
lbl++;
|
|
break;
|
|
case a64inst_BRANCH:
|
|
arr[index] = assembleBranch(&cI, table, lbl);
|
|
index++;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return;
|
|
} |