asm output, random fixes

This commit is contained in:
2025-04-07 19:42:40 -04:00
parent f57af3b2b5
commit cb9a366f43
18 changed files with 266 additions and 117 deletions
+18 -5
View File
@@ -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);
+14 -4
View File
@@ -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 {
+2 -2
View File
@@ -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(