added returning & more asm instructions
This commit is contained in:
@@ -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:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)>,
|
||||
},
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user