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
+47 -18
View File
@@ -1,9 +1,14 @@
use crate::{
compiler::arch::riscv::Reg,
ir::{arch::riscv64::RV64Instruction, IRUInstruction, VarInst},
ir::{
arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, IRUInstruction, Type, VarInst,
},
parser::PAsmBlockArg,
};
use super::{FnLowerCtx, FnLowerable, PAsmBlock, PAsmBlockArg, PInstruction};
use super::{FnLowerCtx, FnLowerable, PAsmBlock, PInstruction, PUAsmBlockArg};
type PLAsmBlockArg = PAsmBlockArg<Reg, VarInst>;
impl FnLowerable for PInstruction {
type Output = RV64Instruction;
@@ -14,9 +19,35 @@ impl FnLowerable for PInstruction {
}
impl FnLowerable for PAsmBlock {
type Output = ();
type Output = VarInst;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
let mut args = Vec::new();
let mut output = None;
for a in &self.args {
if let Some(a) = a.lower(ctx) {
match a {
PAsmBlockArg::In { reg, var } => args.push(AsmBlockArg {
reg,
var,
ty: AsmBlockArgType::In,
}),
PAsmBlockArg::Out { reg } => {
if output.is_some() {
ctx.err("cannot evaluate to more than one register".to_string());
continue;
}
let var = ctx.temp(Type::Bits(64));
args.push(AsmBlockArg {
var,
reg,
ty: AsmBlockArgType::Out,
});
output = Some(var)
}
}
}
}
let block = IRUInstruction::AsmBlock {
instructions: {
let mut v = Vec::new();
@@ -27,27 +58,25 @@ impl FnLowerable for PAsmBlock {
}
v
},
args: {
let mut v = Vec::new();
for a in &self.args {
if let Some(a) = a.lower(ctx) {
v.push(a);
}
}
v
},
args,
};
ctx.push(block);
Some(())
output
}
}
impl FnLowerable for PAsmBlockArg {
type Output = (Reg, VarInst);
impl FnLowerable for PUAsmBlockArg {
type Output = PLAsmBlockArg;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
let var = ctx.get_var(&self.var)?;
let reg = Reg::from_ident(&self.reg, ctx)?;
Some((reg, var))
Some(match self {
PAsmBlockArg::In { reg, var } => PLAsmBlockArg::In {
reg: Reg::from_ident(reg, ctx)?,
var: var.as_ref()?.lower(ctx)?,
},
PAsmBlockArg::Out { reg } => PLAsmBlockArg::Out {
reg: Reg::from_ident(reg, ctx)?,
},
})
}
}