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

View File

@@ -39,11 +39,7 @@ pub struct DataDef {
pub label: String,
}
#[derive(Debug, Clone, Copy)]
pub enum Origin {
Builtin,
File(FileSpan),
}
pub type Origin = FileSpan;
impl FnDef {
pub fn ty(&self) -> Type {

View File

@@ -45,7 +45,7 @@ pub enum IRUInstruction {
},
AsmBlock {
instructions: Vec<RV64Instruction>,
args: Vec<(Reg, VarInst)>,
args: Vec<AsmBlockArg>,
},
Ret {
src: VarInst,
@@ -64,6 +64,19 @@ pub enum IRUInstruction {
Break,
}
#[derive(Debug)]
pub struct AsmBlockArg {
pub var: VarInst,
pub reg: Reg,
pub ty: AsmBlockArgType,
}
#[derive(Debug)]
pub enum AsmBlockArgType {
In,
Out,
}
impl std::fmt::Debug for IRUInstruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
@@ -77,7 +90,9 @@ impl std::fmt::Debug for IRUInstruction {
f: func,
args,
} => write!(f, "{dest:?} <- {func:?}({args:?})")?,
Self::AsmBlock { args, instructions } => write!(f, "asm {args:?} {instructions:#?}")?,
Self::AsmBlock { args, instructions } => {
write!(f, "asm {args:?} {instructions:#?}")?
}
Self::Ret { src } => f.debug_struct("Ret").field("src", src).finish()?,
Self::Construct { dest, fields } => write!(f, "{dest:?} <- {fields:?}")?,
Self::Access { dest, src, field } => write!(f, "{dest:?} <- {src:?}.{field}")?,

View File

@@ -1,7 +1,4 @@
use std::{
collections::HashMap,
fmt::Debug,
};
use std::{collections::HashMap, fmt::Debug};
use crate::common::FileSpan;
@@ -98,10 +95,10 @@ impl IRUProgram {
pub fn size_of_var(&self, var: VarID) -> Option<Size> {
self.size_of_type(&self.var_defs[var.0].ty)
}
pub fn temp_var(&mut self, origin: FileSpan, ty: Type) -> VarInst {
pub fn temp_var(&mut self, origin: Origin, ty: Type) -> VarInst {
let v = self.def_var(VarDef {
name: format!("temp{}", self.temp),
origin: super::Origin::File(origin),
origin,
ty,
});
self.temp += 1;

View File

@@ -1,12 +1,19 @@
// TODO: move this into ir, not parser
use super::{IRUInstrInst, IRUInstruction, IRUProgram, Type};
use crate::common::{CompilerMsg, CompilerOutput};
use crate::common::{CompilerMsg, CompilerOutput, FileSpan};
impl IRUProgram {
pub fn validate(&self) -> CompilerOutput {
let mut output = CompilerOutput::new();
for (f, fd) in self.fns.iter().flatten().zip(&self.fn_defs) {
self.validate_fn(&f.instructions, &fd.ret, &mut output, false);
self.validate_fn(
&f.instructions,
fd.origin,
&fd.ret,
&mut output,
true,
false,
);
}
output
}
@@ -14,10 +21,13 @@ impl IRUProgram {
pub fn validate_fn(
&self,
instructions: &[IRUInstrInst],
origin: FileSpan,
ret: &Type,
output: &mut CompilerOutput,
needs_ret: bool,
breakable: bool,
) {
let mut no_ret = true;
for i in instructions {
match &i.i {
IRUInstruction::Mv { dest, src } => {
@@ -25,7 +35,9 @@ impl IRUProgram {
let src = self.get_var(src.id);
output.check_assign(self, &src.ty, &dest.ty, i.span);
}
IRUInstruction::Ref { dest, src } => todo!(),
IRUInstruction::Ref { dest, src } => {
// TODO
}
IRUInstruction::LoadData { dest, src } => {
let dest = self.get_var(dest.id);
let src = self.get_data(*src);
@@ -64,6 +76,7 @@ impl IRUProgram {
IRUInstruction::Ret { src } => {
let srcty = &self.get_var(src.id).ty;
output.check_assign(self, srcty, ret, src.span);
no_ret = false;
}
IRUInstruction::Construct { dest, fields } => {
let dest_def = self.get_var(dest.id);
@@ -120,10 +133,10 @@ impl IRUProgram {
IRUInstruction::If { cond, body } => {
let cond = self.get_var(cond.id);
output.check_assign(self, &cond.ty, &Type::Bits(64), i.span);
self.validate_fn(body, ret, output, breakable);
self.validate_fn(body, origin, ret, output, false, breakable);
}
IRUInstruction::Loop { body } => {
self.validate_fn(body, ret, output, true);
self.validate_fn(body, origin, ret, output, false, true);
}
IRUInstruction::Break => {
if !breakable {
@@ -136,5 +149,14 @@ impl IRUProgram {
}
}
}
if needs_ret && no_ret && *ret != Type::Unit {
output.err(CompilerMsg {
msg: format!(
"Function implicitly returns () at the end, must return {}",
self.type_name(ret)
),
spans: vec![origin],
});
}
}
}