Skip to content

Commit

Permalink
fix(codegen): use correct destination for when generate expression & …
Browse files Browse the repository at this point in the history
…free registers
  • Loading branch information
MilkeeyCat committed Oct 6, 2024
1 parent 02bff0c commit e647b15
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
7 changes: 7 additions & 0 deletions src/archs/amd64/amd64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,13 @@ impl Architecture for Amd64 {
}

fn fn_postamble(&mut self, name: &str, stackframe: usize) {
assert_eq!(
self.registers.used().len(),
0,
"Function '{name}' didn't free all registers. {:?} are still allocated",
self.registers.used()
);

self.buf.push_str(&formatdoc!(
"
{name}_ret:
Expand Down
43 changes: 32 additions & 11 deletions src/codegen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,14 @@ impl CodeGen {
};

self.arch
.lea(&Destination::Register(r_op.clone()), &dst.into());
.lea(&Destination::Register(r_op.clone()), &dst.clone().into());
self.arch.mov(&Source::Register(r_op), dest, false)?;
self.arch.free(r)?;
} else {
self.arch.mov(&dst.into(), dest, false)?;
self.arch.mov(&dst.clone().into(), dest, false)?;
}

self.free(dst)?;
}
}
Expr::Cast(cast_expr) => {
Expand Down Expand Up @@ -448,22 +450,22 @@ impl CodeGen {

match &expr.op {
BinOp::Add => {
self.arch.add(&lhs, &rhs, dest, signed)?;
self.arch.add(&lhs, &rhs, &expr_dest, signed)?;
}
BinOp::Sub => {
self.arch.sub(&lhs, &rhs, dest, signed)?;
self.arch.sub(&lhs, &rhs, &expr_dest, signed)?;
}
BinOp::Mul => {
self.arch.mul(&lhs, &rhs, dest, signed)?;
self.arch.mul(&lhs, &rhs, &expr_dest, signed)?;
}
BinOp::Div => {
self.arch.div(&lhs, &rhs, dest, signed)?;
self.arch.div(&lhs, &rhs, &expr_dest, signed)?;
}
BinOp::BitwiseAnd | BinOp::BitwiseOr => {
self.arch.bitwise(
&lhs,
&rhs,
dest,
&expr_dest,
BitwiseOp::try_from(&expr.op).unwrap(),
signed,
)?;
Expand All @@ -472,7 +474,18 @@ impl CodeGen {
};

if dest.size() != expr_dest.size() {
self.arch.mov(&expr_dest.into(), dest, signed)?;
self.arch.mov(
&expr_dest.clone().into(),
&expr_dest.clone().with_size(dest.size()),
signed,
)?;
}
if let Destination::Memory(_) = dest {
self.arch.mov(
&expr_dest.clone().with_size(dest.size()).into(),
dest,
signed,
)?;
}
if let Some(r) = dest_r {
self.arch.free(r)?;
Expand Down Expand Up @@ -693,6 +706,8 @@ impl CodeGen {
dest,
unary_expr.expr.type_(&self.scope)?.signed(),
)?;

self.arch.free(r)?;
self.free(expr_dest)?;
}
UnOp::Deref => {
Expand Down Expand Up @@ -1067,7 +1082,9 @@ impl CodeGen {
if let Type::Array(_) = expr.type_(&self.scope)? {
let r = self.arch.alloc()?;

self.arch.lea(&r.dest(self.arch.word_size()), &dest.into());
self.arch
.lea(&r.dest(self.arch.word_size()), &dest.clone().into());
self.free(dest)?;

Ok(r.dest(self.arch.word_size()))
} else {
Expand All @@ -1085,12 +1102,13 @@ impl CodeGen {
Some(&index.dest(self.arch.word_size())),
None,
)?;
match base {
match &base {
Destination::Memory(memory) => {
self.arch.lea(&r_loc, &memory.effective_address);
}
Destination::Register(register) => {
self.arch.mov(&Source::Register(register), &r_loc, false)?;
self.arch
.mov(&Source::Register(register.to_owned()), &r_loc, false)?;
}
}
self.arch.array_offset(
Expand All @@ -1100,6 +1118,9 @@ impl CodeGen {
&r_loc,
)?;

self.free(base)?;
self.arch.free(index)?;

Ok(Destination::Memory(Memory {
effective_address: EffectiveAddress {
base: Base::Register(r),
Expand Down
6 changes: 5 additions & 1 deletion src/register/allocator/allocator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::AllocatorError;
use crate::register::Register;

#[derive(Clone)]
#[derive(Debug, Clone)]
pub struct RegisterAllocator {
registers: Vec<Register>,
used: Vec<usize>,
Expand Down Expand Up @@ -72,4 +72,8 @@ impl RegisterAllocator {
None => false,
}
}

pub fn used(&self) -> &[usize] {
&self.used
}
}

0 comments on commit e647b15

Please sign in to comment.