diff --git a/src/backend/arm_instr.rs b/src/backend/arm_instr.rs index be3a8c2..ccf7fb3 100644 --- a/src/backend/arm_instr.rs +++ b/src/backend/arm_instr.rs @@ -32,7 +32,7 @@ impl Display for ARMInstr { ARMInstr::Push(instr) => write!(f, "{}", instr), ARMInstr::Pop(instr) => write!(f, "{}", instr), ARMInstr::Bl(instr) => write!(f, "{}", instr), - ARMInstr::FunctionHead(name, align_size) => write!(f, ".align{}\n.global {}\n.type {}, %function\n{}:", align_size, name, name, name), + ARMInstr::FunctionHead(name, align_size) => write!(f, ".align {}\n.global {}\n.type {}, %function\n{}:", align_size, name, name, name), } } } diff --git a/src/backend/generator.rs b/src/backend/generator.rs index 5c1772a..247bd29 100644 --- a/src/backend/generator.rs +++ b/src/backend/generator.rs @@ -30,10 +30,7 @@ impl Generator { } pub fn to_text(&self) -> String { let mut text = String::new(); - text.push_str(".arch armv7ve - .arm - .fpu vfpv4 - .text"); + text.push_str(".arch armv7ve\n.arm\n.fpu vfpv4\n"); for var in &self.var_uninited { text.push_str(&format!(".comm {}, {}\n", var.name, var.size)); } @@ -41,6 +38,7 @@ impl Generator { text.push_str(&format!(".data\n.align 4\n.global {}\n.type {}, @object\n:{}\n", var.name, var.name, var.name)); text.push_str(&format!(".word 0\n")); } + text.push_str(".text\n"); for instr in &self.instrs { text.push_str(&format!("{}\n", instr)); } @@ -70,6 +68,17 @@ impl Generator { match ir_instr { IRInstr::Binary(dest, left, op, right) => self.emit_binary(dest, left, op, right, &var_index_to_stack_offset), IRInstr::Exit(v) => { + if let Some(v) = v { + let ret_alloc = self.register_allocator.alloc_reg(REG_R0).expect("Ran out of registers"); + let ret_reg = ret_alloc.reg; + let v_alloc = self.register_allocator.alloc(v).expect("Ran out of registers"); + let v_reg = v_alloc.reg; + if !v_alloc.is_reused { + let v_stack_offset = var_index_to_stack_offset.get(&v.index).expect("Variable not declared"); + self.instrs.push(LoadInstr::new_stack(v_reg, *v_stack_offset as i32)); + } + self.instrs.push(MoveInstr::new_uncond(ret_reg, RegisterOrImm::Reg(v_reg))); + } self.instrs.push(MoveInstr::new_fp_to_sp()); self.instrs.push(PopInstr::new_pop_fp_pc()); }, diff --git a/src/backend/register_allocator.rs b/src/backend/register_allocator.rs index b39bd8b..347e87e 100644 --- a/src/backend/register_allocator.rs +++ b/src/backend/register_allocator.rs @@ -43,7 +43,7 @@ pub const REGISTERS: &[Register] = &[ ]; pub const REGISTERS_CAN_ALLOC: &[Register] = &[ - REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_R8, REG_R9, REG_R10, REG_R11, REG_R12 + REG_R0, REG_R1, REG_R2, REG_R3, REG_R4, REG_R5, REG_R6, REG_R7, REG_R8, REG_R9, REG_R10, REG_R12 ]; pub struct RegisterAlloc { allocator: Weak>,