added returning & more asm instructions

This commit is contained in:
2025-03-22 16:54:28 -04:00
parent 7f809d797c
commit 6c2f4e814f
11 changed files with 176 additions and 43 deletions

View File

@@ -1,7 +1,4 @@
use crate::{
compiler::arch::riscv64::*,
ir::{VarID, VarInst},
};
use crate::{compiler::arch::riscv64::*, ir::VarInst};
#[derive(Copy, Clone)]
pub enum RV64Instruction {
@@ -23,6 +20,16 @@ pub enum RV64Instruction {
offset: i64,
base: RegRef,
},
Sd {
src: RegRef,
offset: i64,
base: RegRef,
},
Add {
dest: RegRef,
src1: RegRef,
src2: RegRef,
},
}
#[derive(Copy, Clone)]
@@ -48,6 +55,8 @@ impl std::fmt::Debug for RV64Instruction {
Self::Mv { dest, src } => write!(f, "mv {dest:?}, {src:?}"),
Self::La { dest, src } => write!(f, "la {dest:?}, {src:?}"),
Self::Ld { dest, offset, base } => write!(f, "ld {dest:?}, {offset}({base:?})"),
Self::Sd { src, offset, base } => write!(f, "sd {src:?}, {offset}({base:?})"),
Self::Add { dest, src1, src2 } => write!(f, "add {dest:?}, {src1:?}, {src2:?}"),
}
}
}

View File

@@ -9,6 +9,7 @@ pub struct IRLFunction {
pub instructions: Vec<IRLInstruction>,
pub stack: HashMap<VarID, Size>,
pub args: Vec<(VarID, Size)>,
pub ret_size: Size,
pub makes_call: bool,
}
@@ -34,7 +35,7 @@ pub enum IRLInstruction {
len: Len,
},
Call {
dest: VarID,
dest: Option<(VarID, Size)>,
f: Symbol,
args: Vec<(VarID, Size)>,
},

View File

@@ -106,8 +106,14 @@ impl IRLProgram {
makes_call = true;
let fid = &p.fn_map[&f.id];
let sym = builder.func(fid);
let ret_size = p.size_of_var(dest.id).expect("unsized type");
let dest = if ret_size > 0 {
Some((dest.id, ret_size))
} else {
None
};
instrs.push(IRLInstruction::Call {
dest: dest.id,
dest,
f: sym,
args: args
.iter()
@@ -135,6 +141,7 @@ impl IRLProgram {
.iter()
.map(|a| (*a, p.size_of_var(*a).expect("unsized type")))
.collect(),
ret_size: p.size_of_type(&f.ret).expect("unsized type"),
stack,
},
);

View File

@@ -1,11 +1,12 @@
use std::fmt::Write;
use super::{arch::riscv64::RV64Instruction, inst::VarInst, DataID, FnID, IRUInstrInst, VarID};
use super::{arch::riscv64::RV64Instruction, inst::VarInst, DataID, FnID, IRUInstrInst, Type, VarID};
use crate::{common::FileSpan, compiler::arch::riscv64::Reg, util::Padder};
pub struct IRUFunction {
pub name: String,
pub args: Vec<VarID>,
pub ret: Type,
pub instructions: Vec<IRUInstrInst>,
}
@@ -49,9 +50,10 @@ pub struct IRInstructions {
}
impl IRUFunction {
pub fn new(name: String, args: Vec<VarID>, instructions: IRInstructions) -> Self {
pub fn new(name: String, args: Vec<VarID>, ret: Type, instructions: IRInstructions) -> Self {
Self {
name,
ret,
args,
instructions: instructions.vec,
}

View File

@@ -1,11 +1,11 @@
// TODO: move this into ir, not parser
use super::{IRUProgram, Type};
use crate::common::CompilerOutput;
use crate::common::{CompilerMsg, CompilerOutput};
impl IRUProgram {
pub fn validate(&self) -> CompilerOutput {
let mut output = CompilerOutput::new();
for f in self.fns.iter().flatten() {
for (f, fd) in self.fns.iter().flatten().zip(&self.fn_defs) {
for i in &f.instructions {
match &i.i {
super::IRUInstruction::Mv { dest, src } => {
@@ -35,6 +35,12 @@ impl IRUProgram {
todo!()
};
output.check_assign(self, ret, destty, dest.span);
if args.len() != argtys.len() {
output.err(CompilerMsg {
msg: "Wrong number of arguments to function".to_string(),
spans: vec![dest.span],
});
}
for (argv, argt) in args.iter().zip(argtys) {
let dest = self.get_var(argv.id);
output.check_assign(self, argt, &dest.ty, argv.span);
@@ -43,7 +49,10 @@ impl IRUProgram {
super::IRUInstruction::AsmBlock { instructions, args } => {
// TODO
}
super::IRUInstruction::Ret { src } => todo!(),
super::IRUInstruction::Ret { src } => {
let srcty = &self.get_var(src.id).ty;
output.check_assign(self, srcty, &fd.ret, src.span);
},
}
}
}