asm output, random fixes
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
compiler::program::{Addr, Instr, SymTable},
|
||||
ir::Symbol,
|
||||
util::LabeledFmt,
|
||||
util::{Bits32, LabeledFmt},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
@@ -70,7 +70,11 @@ pub enum LinkerInstruction<R = Reg, S = Symbol> {
|
||||
}
|
||||
|
||||
pub fn addi(dest: Reg, src: Reg, imm: BitsI32<11, 0>) -> RawInstruction {
|
||||
opi(op32i::ADD, dest, src, imm)
|
||||
opi(op32i::ADD, dest, src, imm.to_u())
|
||||
}
|
||||
|
||||
pub fn ori(dest: Reg, src: Reg, imm: Bits32<11, 0>) -> RawInstruction {
|
||||
opi(op32i::OR, dest, src, imm)
|
||||
}
|
||||
|
||||
impl Instr for LinkerInstruction {
|
||||
@@ -89,7 +93,7 @@ impl Instr for LinkerInstruction {
|
||||
src1,
|
||||
src2,
|
||||
} => opr(*op, *funct, *dest, *src1, *src2),
|
||||
Self::OpImm { op, dest, src, imm } => opi(*op, *dest, *src, BitsI32::new(*imm)),
|
||||
Self::OpImm { op, dest, src, imm } => opi(*op, *dest, *src, BitsI32::new(*imm).to_u()),
|
||||
Self::OpImmF7 {
|
||||
op,
|
||||
funct,
|
||||
@@ -113,8 +117,17 @@ impl Instr for LinkerInstruction {
|
||||
Self::La { dest, src } => {
|
||||
if let Some(addr) = sym_map.get(*src) {
|
||||
let offset = addr.val() as i32 - pos.val() as i32;
|
||||
data.extend(auipc(*dest, BitsI32::new(0)).to_le_bytes());
|
||||
addi(*dest, *dest, BitsI32::new(offset))
|
||||
let sign = offset.signum();
|
||||
let mut lower = offset % 0x1000;
|
||||
let mut upper = offset - lower;
|
||||
if (((lower >> 11) & 1) == 1) ^ (sign == -1) {
|
||||
let add = sign << 12;
|
||||
upper += add;
|
||||
lower = offset - upper;
|
||||
}
|
||||
assert!(upper + (lower << 20 >> 20) == offset);
|
||||
data.extend(auipc(*dest, BitsI32::new(upper)).to_le_bytes());
|
||||
addi(*dest, *dest, BitsI32::new(lower))
|
||||
} else {
|
||||
data.extend_from_slice(&[0; 2 * 4]);
|
||||
return Some(*src);
|
||||
|
||||
@@ -106,7 +106,10 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
|
||||
s,
|
||||
);
|
||||
}
|
||||
IRI::Ref { dest, src } => todo!(),
|
||||
IRI::Ref { dest, src } => {
|
||||
v.push(LI::addi(t0, sp, stack[src]));
|
||||
v.push(LI::sd(t0, stack[dest], sp));
|
||||
}
|
||||
IRI::LoadAddr { dest, offset, src } => {
|
||||
v.extend([
|
||||
LI::La {
|
||||
@@ -142,9 +145,13 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
|
||||
}
|
||||
v.push(LI::Call(*f));
|
||||
}
|
||||
IRI::AsmBlock { args, instructions } => {
|
||||
for (reg, var) in args {
|
||||
v.push(LI::addi(*reg, sp, stack[var]));
|
||||
IRI::AsmBlock {
|
||||
inputs,
|
||||
outputs,
|
||||
instructions,
|
||||
} => {
|
||||
for (reg, var) in inputs {
|
||||
v.push(LI::ld(*reg, stack[var], sp));
|
||||
}
|
||||
fn r(rr: RegRef) -> Reg {
|
||||
match rr {
|
||||
@@ -223,6 +230,9 @@ pub fn compile(program: &IRLProgram) -> UnlinkedProgram<LI> {
|
||||
AI::Branch { .. } => todo!(),
|
||||
}
|
||||
}
|
||||
for (reg, var) in outputs {
|
||||
v.push(LI::sd(*reg, stack[var], sp));
|
||||
}
|
||||
}
|
||||
IRI::Ret { src } => {
|
||||
let Some(rva) = stack_rva else {
|
||||
|
||||
@@ -80,8 +80,8 @@ pub const fn j_type(imm: Bits32<20, 1>, rd: Reg, opcode: u32) -> I {
|
||||
pub fn opr(op: Funct3, funct: Funct7, dest: Reg, src1: Reg, src2: Reg) -> I {
|
||||
r_type(funct, src2, src1, op, dest, OP)
|
||||
}
|
||||
pub fn opi(op: Funct3, dest: Reg, src: Reg, imm: BitsI32<11, 0>) -> RawInstruction {
|
||||
i_type(imm.to_u(), src, op, dest, IMM_OP)
|
||||
pub fn opi(op: Funct3, dest: Reg, src: Reg, imm: Bits32<11, 0>) -> RawInstruction {
|
||||
i_type(imm, src, op, dest, IMM_OP)
|
||||
}
|
||||
pub fn opif7(op: Funct3, funct: Funct7, dest: Reg, src: Reg, imm: BitsI32<4, 0>) -> I {
|
||||
i_type(
|
||||
|
||||
Reference in New Issue
Block a user