asm output, random fixes
This commit is contained in:
+47
-18
@@ -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)?,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user