fixing struct regurns

This commit is contained in:
mlokr 2024-05-13 09:38:33 +02:00
parent 5c38115119
commit 0aec47e985
11 changed files with 88 additions and 30 deletions

View file

@ -9,7 +9,8 @@ Ty2 := struct {
} }
main := fn(): int { main := fn(): int {
inst := Ty2.{ ty: Ty.{ a: 4, b: 1 }, c: 3 }; finst := Ty2.{ ty: Ty.{ a: 4, b: 1 }, c: 3 };
inst := odher_pass(finst);
if inst.c == 3 { if inst.c == 3 {
return pass(&inst.ty); return pass(&inst.ty);
} }
@ -19,3 +20,7 @@ main := fn(): int {
pass := fn(t: *Ty): int { pass := fn(t: *Ty): int {
return t.a - t.b; return t.a - t.b;
} }
odher_pass := fn(t: Ty2): Ty2 {
return t;
}

View file

@ -388,7 +388,7 @@ impl<'a> Codegen<'a> {
let fn_label = self.labels[frame.label as usize].clone(); let fn_label = self.labels[frame.label as usize].clone();
log::dbg!("fn-args"); log::dbg!("fn-args");
let mut parama = 2..12; let mut parama = 3..12;
for (arg, &ty) in args.iter().zip(fn_label.args.iter()) { for (arg, &ty) in args.iter().zip(fn_label.args.iter()) {
let loc = self.load_arg(ty, &mut parama); let loc = self.load_arg(ty, &mut parama);
self.vars.push(Variable { self.vars.push(Variable {
@ -694,18 +694,50 @@ impl<'a> Codegen<'a> {
} => { } => {
let func = self.get_label(*id); let func = self.get_label(*id);
let fn_label = self.labels[func as usize].clone(); let fn_label = self.labels[func as usize].clone();
let mut parama = 2..12; let mut parama = 3..12;
for (earg, &ty) in args.iter().zip(fn_label.args.iter()) { for (earg, &ty) in args.iter().zip(fn_label.args.iter()) {
let arg = self.expr(earg, Some(ty))?; let arg = self.expr(earg, Some(ty))?;
self.assert_ty(earg.pos(), ty, arg.ty); self.assert_ty(earg.pos(), ty, arg.ty);
self.pass_arg(arg, &mut parama); self.pass_arg(arg, &mut parama);
} }
let size = self.size_of(fn_label.ret);
let loc = match size {
0 => Loc::Imm(0),
8 => Loc::RegRef(1),
16 => {
let stack = self.alloc_stack(16);
Loc::Stack(stack)
}
24..=u64::MAX => {
let stack = self.alloc_stack(size as u32);
let reg = self.gpa.allocate();
self.code
.encode(instrs::addi64(reg.0, STACK_PTR, stack as u64));
self.code.encode(instrs::cp(1, reg.0));
self.gpa.free(reg);
Loc::Stack(stack)
}
s => todo!("call return size: {}", s),
};
self.code.call(func); self.code.call(func);
let reg = self.gpa.allocate();
self.code.encode(instrs::cp(reg.0, 1)); match size {
0 => {}
8 => {}
16 => {
if let Loc::Stack(stack) = loc {
self.store_stack(1, stack, 16);
}
}
24..=u64::MAX => {}
s => todo!("call return size: {}", s),
}
Some(Value { Some(Value {
ty: self.ret, ty: fn_label.ret,
loc: Loc::Reg(reg), loc,
}) })
} }
E::Ident { name, id, .. } => { E::Ident { name, id, .. } => {
@ -721,13 +753,27 @@ impl<'a> Codegen<'a> {
if let Some(val) = val { if let Some(val) = val {
let val = self.expr(val, Some(self.ret))?; let val = self.expr(val, Some(self.ret))?;
self.assert_ty(pos, self.ret, val.ty); self.assert_ty(pos, self.ret, val.ty);
self.assign( let size = self.size_of(val.ty);
Value { match size {
ty: self.ret, 8 => {
loc: Loc::RegRef(1), let val = self.loc_to_reg(val.loc);
}, self.code.encode(instrs::cp(1, val.0));
val, self.gpa.free(val);
); }
16 => {
let (ptr, off) = self.loc_to_ptr(val.loc);
self.code.encode(instrs::ld(1, ptr.0, off, 16));
self.gpa.free(ptr);
}
24..=u64::MAX => {
let (ptr, off) = self.loc_to_ptr(val.loc);
self.code.encode(instrs::addi64(ptr.0, ptr.0, off));
self.code
.encode(instrs::bmc(ptr.0, 1, size.try_into().unwrap()));
self.gpa.free(ptr);
}
s => todo!("return size: {}", s),
};
} }
self.ret_relocs.push(RetReloc { self.ret_relocs.push(RetReloc {
offset: self.code.code.len() as u32, offset: self.code.code.len() as u32,
@ -847,13 +893,15 @@ impl<'a> Codegen<'a> {
None None
} }
E::BinOp { left, op, right } => { E::BinOp { left, op, right } => {
let left = self.expr(left, expeted)?;
let right = self.expr(right, Some(left.ty))?;
if op == T::Assign { if op == T::Assign {
let left = self.expr(left, expeted)?;
let right = self.expr(right, Some(left.ty))?;
return self.assign(left, right); return self.assign(left, right);
} }
let left = self.expr(left, expeted)?;
let lhs = self.loc_to_reg(left.loc); let lhs = self.loc_to_reg(left.loc);
let right = self.expr(right, Some(left.ty))?;
let rhs = self.loc_to_reg(right.loc); let rhs = self.loc_to_reg(right.loc);
let op = match op { let op = match op {
@ -1062,6 +1110,7 @@ impl<'a> Codegen<'a> {
todo!("expected stack location, got {:?}", value.loc); todo!("expected stack location, got {:?}", value.loc);
}; };
self.code.encode(instrs::addi64(p, STACK_PTR, stack)); self.code.encode(instrs::addi64(p, STACK_PTR, stack));
return;
} }
match value.loc { match value.loc {
@ -1254,8 +1303,8 @@ mod tests {
fn generate(input: &'static str, output: &mut String) { fn generate(input: &'static str, output: &mut String) {
let path = "test"; let path = "test";
let arena = crate::parser::Arena::default(); let arena = crate::parser::Arena::default();
let mut parser = super::parser::Parser::new(input, path, &arena); let mut parser = super::parser::Parser::new(&arena);
let exprs = parser.file(); let exprs = parser.file(input, path);
let mut codegen = super::Codegen::default(); let mut codegen = super::Codegen::default();
codegen.file(path, input.as_bytes(), &exprs); codegen.file(path, input.as_bytes(), &exprs);
let mut out = Vec::new(); let mut out = Vec::new();

View file

@ -14,12 +14,12 @@ fn main() -> io::Result<()> {
.skip(1) .skip(1)
.map(|path| std::fs::read_to_string(&path).map(|src| (path, src))) .map(|path| std::fs::read_to_string(&path).map(|src| (path, src)))
.collect::<io::Result<Vec<_>>>()?; .collect::<io::Result<Vec<_>>>()?;
let mut arena = parser::Arena::default(); let arena = parser::Arena::default();
let mut parser = parser::Parser::new(&arena);
let mut codegen = codegen::Codegen::default(); let mut codegen = codegen::Codegen::default();
for (path, content) in files.iter() { for (path, content) in files.iter() {
let file = parser::Parser::new(content, path, &arena).file(); let file = parser.file(&path, content.as_str());
codegen.file(path, content.as_bytes(), file); codegen.file(path, content.as_bytes(), file);
arena.clear();
} }
codegen.dump(&mut std::io::stdout()) codegen.dump(&mut std::io::stdout())
} }

View file

@ -23,19 +23,23 @@ pub struct Parser<'a, 'b> {
} }
impl<'a, 'b> Parser<'a, 'b> { impl<'a, 'b> Parser<'a, 'b> {
pub fn new(input: &'a str, path: &'a str, arena: &'b Arena<'a>) -> Self { pub fn new(arena: &'b Arena<'a>) -> Self {
let mut lexer = Lexer::new(input); let mut lexer = Lexer::new("");
let token = lexer.next(); let token = lexer.next();
Self { Self {
lexer, lexer,
token, token,
path, path: "",
arena, arena,
idents: Vec::new(), idents: Vec::new(),
} }
} }
pub fn file(&mut self) -> &'a [Expr<'a>] { pub fn file(&mut self, input: &'a str, path: &'a str) -> &'a [Expr<'a>] {
self.path = path;
self.lexer = Lexer::new(input);
self.token = self.lexer.next();
let f = self.collect(|s| (s.token.kind != TokenKind::Eof).then(|| s.expr())); let f = self.collect(|s| (s.token.kind != TokenKind::Eof).then(|| s.expr()));
self.pop_scope(0); self.pop_scope(0);
let has_undeclared = !self.idents.is_empty(); let has_undeclared = !self.idents.is_empty();
@ -717,8 +721,8 @@ mod tests {
fn parse(input: &'static str, output: &mut String) { fn parse(input: &'static str, output: &mut String) {
use std::fmt::Write; use std::fmt::Write;
let mut arena = super::Arena::default(); let mut arena = super::Arena::default();
let mut parser = super::Parser::new(input, "test", &arena); let mut parser = super::Parser::new(&arena);
for expr in parser.file() { for expr in parser.file(input, "test") {
writeln!(output, "{}", expr).unwrap(); writeln!(output, "{}", expr).unwrap();
} }
arena.clear(); arena.clear();

View file

@ -1,3 +1,3 @@
code size: 1120 code size: 1114
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,3 +1,3 @@
code size: 342 code size: 339
ret: 0 ret: 0
status: Ok(()) status: Ok(())

View file

@ -1,3 +1,3 @@
code size: 470 code size: 691
ret: 3 ret: 3
status: Ok(()) status: Ok(())

View file

View file

View file