Restructring the assembling into binary, add helper funcs
This commit is contained in:
parent
995c6d02fa
commit
31fa1392e1
@ -1,3 +1,4 @@
|
|||||||
|
#include <assert.h>
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "a64instruction/a64instruction.h"
|
#include "a64instruction/a64instruction.h"
|
||||||
#include "symboltable.c"
|
#include "symboltable.c"
|
||||||
@ -6,36 +7,57 @@
|
|||||||
|
|
||||||
#define HALT_BINARY 2315255808
|
#define HALT_BINARY 2315255808
|
||||||
|
|
||||||
// Generates assembled code based on the two-pass assembly method
|
// Temp helper function to print binary representation of a word
|
||||||
|
// static void printBinary(word number) {
|
||||||
|
// for (int i = 31; i >= 0; i--) {
|
||||||
|
// putchar((number & (1 << i)) ? '1' : '0');
|
||||||
|
// }
|
||||||
|
// putchar('\n');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// write the provided value to the bits in the range [lsb, msb) {inclusive, exclusive} to the word.
|
||||||
|
// Does not modify any other bits in the word.
|
||||||
|
void setBits(word* wrd, uint8_t lsb, uint8_t msb, word value) {
|
||||||
|
// Ensure LSB and MSB are within range of word size, and in the correct order
|
||||||
|
assert(lsb < msb && msb <= 32);
|
||||||
|
|
||||||
|
// Create a mask with 1s in the range [lsb, msb) and 0s elsewhere
|
||||||
|
word mask = 0;
|
||||||
|
for (uint8_t i = lsb; i < msb; i++) {
|
||||||
|
mask |= 1 << i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the bits in the range [lsb, msb) in the word
|
||||||
|
*wrd &= ~mask;
|
||||||
|
|
||||||
|
// Set the bits in the range [lsb, msb) to the value
|
||||||
|
*wrd |= (value << lsb) & mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generates assembled code based on the two-pass assembly method
|
||||||
word assembleBranch(a64inst_instruction *instr) {
|
word assembleBranch(a64inst_instruction *instr) {
|
||||||
word binInstr = 0;
|
word wrd = 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
|
setBits(&wrd, 26, 30, 0x5);
|
||||||
// 25-0: sign extended simm26
|
setBits(&wrd, 25, 0, instr->data.BranchData.processOpData.unconditionalData.unconditionalOffset);
|
||||||
binInstr += instr->data.BranchData.processOpData.unconditionalData.unconditionalOffset;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case a64inst_REGISTER:
|
case a64inst_REGISTER:
|
||||||
// 10000
|
setBits(&wrd, 16, 32, 0xD61F);
|
||||||
// 11111
|
setBits(&wrd, 5, 10, instr->data.BranchData.processOpData.registerData.src);
|
||||||
// 000000
|
|
||||||
// 9-5: address from register
|
|
||||||
// 0000
|
|
||||||
binInstr += ((instr->data.BranchData.processOpData.registerData.src) << 5);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case a64inst_CONDITIONAL:
|
case a64inst_CONDITIONAL:
|
||||||
// 01010100
|
setBits(&wrd, 26, 32, 0x15);
|
||||||
// 25-5: sign extended offset
|
setBits(&wrd, 5, 24, instr->data.BranchData.processOpData.conditionalData.offset);
|
||||||
// 4-0: 0{condition}
|
setBits(&wrd, 0, 4, instr->data.BranchData.processOpData.conditionalData.cond);
|
||||||
binInstr += ((instr->data.BranchData.processOpData.conditionalData.offset) << 5);
|
|
||||||
binInstr += instr->data.BranchData.processOpData.conditionalData.cond;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return binInstr;
|
|
||||||
|
return wrd;
|
||||||
}
|
}
|
||||||
|
|
||||||
st* firstPass(a64inst_instruction instrs[], int numInstrs) {
|
st* firstPass(a64inst_instruction instrs[], int numInstrs) {
|
||||||
@ -53,32 +75,30 @@ st* firstPass(a64inst_instruction instrs[], int numInstrs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
word dpi(a64inst_instruction cI) {
|
word dpi(a64inst_instruction cI) {
|
||||||
word out = 0;
|
word wrd = 0;
|
||||||
|
|
||||||
a64inst_DPImmediateData data = cI.data.DPImmediateData;
|
a64inst_DPImmediateData data = cI.data.DPImmediateData;
|
||||||
// sf
|
|
||||||
out += data.regType * (1 << 31);
|
setBits(&wrd, 31, 32, data.regType); // sf
|
||||||
out += data.processOp * (1 << 29);
|
setBits(&wrd, 29, 31, data.processOp); // opc
|
||||||
out += 1 << 28;
|
setBits(&wrd, 28, 29, 0x1); // constant value
|
||||||
// if arithmetic
|
setBits(&wrd, 0, 5, data.dest); // rd
|
||||||
|
|
||||||
if (data.DPIOpType == a64inst_DPI_ARITHM) {
|
if (data.DPIOpType == a64inst_DPI_ARITHM) {
|
||||||
out += 1 << 24;
|
setBits(&wrd, 23, 26, 0x2); //opi
|
||||||
// shift
|
setBits(&wrd, 5, 10, data.processOpData.arithmData.src); // rn
|
||||||
if (data.processOpData.arithmData.shiftImmediate) {
|
setBits(&wrd, 22, 23, data.processOpData.arithmData.shiftImmediate); // sh
|
||||||
out += 1 << 22;
|
setBits(&wrd, 10, 22, data.processOpData.arithmData.immediate); // imm12
|
||||||
}
|
|
||||||
out += data.processOpData.arithmData.immediate * (1 << 10);
|
|
||||||
out += data.processOpData.arithmData.src * (1 << 5);
|
|
||||||
}
|
}
|
||||||
// if wide move
|
// if wide move
|
||||||
else {
|
else {
|
||||||
out += 5 * (1 << 23);
|
setBits(&wrd, 23, 26, 0x5); //opi
|
||||||
// hw
|
// TODO: Check the following line, is it shiftScalar?:
|
||||||
out += data.processOpData.wideMovData.shiftScalar * (1 << 21);
|
setBits(&wrd, 21, 23, data.processOpData.wideMovData.shiftScalar); // hw
|
||||||
out += data.processOpData.wideMovData.immediate * (1 << 5);
|
setBits(&wrd, 5, 21, data.processOpData.wideMovData.immediate); // imm16
|
||||||
}
|
}
|
||||||
// destination register
|
|
||||||
out += data.dest;
|
return wrd;
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word dpr(a64inst_instruction cI) {
|
word dpr(a64inst_instruction cI) {
|
||||||
@ -135,49 +155,51 @@ word dpr(a64inst_instruction cI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
word sts(a64inst_instruction cI) {
|
word sts(a64inst_instruction cI) {
|
||||||
|
word wrd = 0;
|
||||||
|
|
||||||
a64inst_SingleTransferData data = cI.data.SingleTransferData;
|
a64inst_SingleTransferData data = cI.data.SingleTransferData;
|
||||||
word out = 0;
|
|
||||||
a64inst_SingleDataTransferData data2 = data.processOpData.singleDataTransferData;
|
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 + 32U) * (1 << 23);
|
setBits(&wrd, 22, 32, 0x2E0);
|
||||||
int sf = data.regType;
|
setBits(&wrd, 30, 31, data.regType);
|
||||||
int u = 0;
|
setBits(&wrd, 24, 25, data2.addressingMode == a64inst_UNSIGNED_OFFSET);
|
||||||
int offset = 0;
|
setBits(&wrd, 22, 23, data2.transferType);
|
||||||
int xn = data2.base;
|
setBits(&wrd, 5, 10, data2.base);
|
||||||
int rt = data.target;
|
setBits(&wrd, 0, 5, data.target);
|
||||||
|
|
||||||
switch (data2.addressingMode) {
|
switch (data2.addressingMode) {
|
||||||
// register offset
|
// register offset
|
||||||
case a64inst_REGISTER_OFFSET:
|
case a64inst_REGISTER_OFFSET:
|
||||||
offset += 2080 + 64 * data2.a64inst_addressingModeData.offsetReg;
|
setBits(&wrd, 21, 22, 1);
|
||||||
|
setBits(&wrd, 10, 16, 0x1A);
|
||||||
|
setBits(&wrd, 16, 21, data2.a64inst_addressingModeData.offsetReg);
|
||||||
break;
|
break;
|
||||||
// unsigned offset
|
// unsigned offset
|
||||||
case a64inst_UNSIGNED_OFFSET:
|
case a64inst_UNSIGNED_OFFSET:
|
||||||
offset += data2.a64inst_addressingModeData.unsignedOffset;
|
setBits(&wrd, 10, 22, data2.a64inst_addressingModeData.unsignedOffset);
|
||||||
u = 1;
|
|
||||||
break;
|
break;
|
||||||
// pre/post indexed
|
// pre/post indexed
|
||||||
default:
|
default:
|
||||||
offset = 1 + data2.addressingMode * 2 + data2.a64inst_addressingModeData.indexedOffset * 4;
|
setBits(&wrd, 21, 22, 0);
|
||||||
|
setBits(&wrd, 11, 12, data2.addressingMode == a64inst_PRE_INDEXED);
|
||||||
|
setBits(&wrd, 10, 11, 1);
|
||||||
|
setBits(&wrd, 12, 21, data2.a64inst_addressingModeData.indexedOffset);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
out += sf * (1 << 30);
|
|
||||||
out += u * (1 << 22);
|
return wrd;
|
||||||
out += offset * 1024;
|
|
||||||
out += xn * 32;
|
|
||||||
out += rt;
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word ldl(a64inst_instruction cI) {
|
word ldl(a64inst_instruction cI) {
|
||||||
word out = 3 * (1 << 27);
|
word wrd = 0;
|
||||||
|
|
||||||
a64inst_SingleTransferData data = cI.data.SingleTransferData;
|
a64inst_SingleTransferData data = cI.data.SingleTransferData;
|
||||||
int sf = data.regType;
|
setBits(&wrd, 24, 32, 0x18);
|
||||||
int simm19 = data.processOpData.loadLiteralData.offset;
|
setBits(&wrd, 30, 31, data.regType);
|
||||||
int rt = data.target;
|
setBits(&wrd, 5, 24, data.processOpData.loadLiteralData.offset);
|
||||||
out += sf * (1 << 30);
|
setBits(&wrd, 0, 5, data.target);
|
||||||
out += simm19 * 32;
|
|
||||||
out += rt;
|
return wrd;
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
word *secondPass(a64inst_instruction instrs[], int numInstrs, st* table) {
|
word *secondPass(a64inst_instruction instrs[], int numInstrs, st* table) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user