diff --git a/src/CodeGen/calling_convention.rs b/src/CodeGen/calling_convention.rs index 7bc05bfe..8335b8c8 100644 --- a/src/CodeGen/calling_convention.rs +++ b/src/CodeGen/calling_convention.rs @@ -59,8 +59,8 @@ impl MachineCallingConvention { match arch { Arch::X86_64 => { let args = vec![ - Reg::x64(X64Reg::Rcx), Reg::x64(X64Reg::Rdx), - Reg::x64(X64Reg::R8), Reg::x64(X64Reg::R9) + Reg::x64(X64Reg::Rcx.sub_ty(ty)), Reg::x64(X64Reg::Rdx.sub_ty(ty)), + Reg::x64(X64Reg::R8.sub_ty(ty)), Reg::x64(X64Reg::R9.sub_ty(ty)) ]; let arg = args.get(idx).cloned(); arg @@ -88,9 +88,9 @@ impl MachineCallingConvention { match arch { Arch::X86_64 => { let args = vec![ - Reg::x64(X64Reg::Rdi), Reg::x64(X64Reg::Rsi), - Reg::x64(X64Reg::Rcx), Reg::x64(X64Reg::Rdx), - Reg::x64(X64Reg::R8), Reg::x64(X64Reg::R9) + Reg::x64(X64Reg::Rdi.sub_ty(ty)), Reg::x64(X64Reg::Rsi.sub_ty(ty)), + Reg::x64(X64Reg::Rcx.sub_ty(ty)), Reg::x64(X64Reg::Rdx.sub_ty(ty)), + Reg::x64(X64Reg::R8.sub_ty(ty)), Reg::x64(X64Reg::R9.sub_ty(ty)) ]; let arg = args.get(idx).cloned(); arg diff --git a/src/CodeGen/compilation/mod.rs b/src/CodeGen/compilation/mod.rs index 935b7b4a..d70bd199 100644 --- a/src/CodeGen/compilation/mod.rs +++ b/src/CodeGen/compilation/mod.rs @@ -120,8 +120,8 @@ impl CompilationHelper { } pub(crate) fn alloc_stack(&mut self, ty: TypeMetadata) -> VarLocation { - if let Some(alloc) = self.alloc.alloc_rv { - alloc(&mut self.alloc, ty) + if let Some(alloc_stack) = self.alloc.alloc_stack { + alloc_stack(&mut self.alloc, ty) } else { panic!("no registered stack allocation function for {:?}", self.arch) } } diff --git a/src/CodeGen/instr.rs b/src/CodeGen/instr.rs index 46b68f37..90df96ca 100644 --- a/src/CodeGen/instr.rs +++ b/src/CodeGen/instr.rs @@ -74,6 +74,8 @@ impl MachineInstr { let mut out = Vec::new(); + let mut tmp_locs = Vec::new(); + for operand in &mut self.operands { if let MachineOperand::Imm(imm) = operand { let imm = *imm; @@ -117,12 +119,16 @@ impl MachineInstr { module.const_index += 1; helper.free(location); - helper.free(float); + tmp_locs.push(float); } } out.push(self.to_owned()); + for tmp in tmp_locs { + helper.free(tmp); + } + out } } diff --git a/src/IR/nodes/call.rs b/src/IR/nodes/call.rs index 6bf8c901..b302867d 100644 --- a/src/IR/nodes/call.rs +++ b/src/IR/nodes/call.rs @@ -95,7 +95,7 @@ impl Ir for Call, Var> { } fn output(&self) -> Option { - None // yes it has an output but it will get optimized away, so i just say "it has no output" + Some(self.inner3.to_owned()) } } diff --git a/src/IR/nodes/store.rs b/src/IR/nodes/store.rs index 3b08997f..0cb0b0a5 100644 --- a/src/IR/nodes/store.rs +++ b/src/IR/nodes/store.rs @@ -58,11 +58,11 @@ impl Ir for Store { } fn inputs(&self) -> Vec { - vec![self.inner2.to_owned()] + vec![self.inner1.to_owned(), self.inner2.to_owned()] } fn output(&self) -> Option { - Some(self.inner1.to_owned()) + None // technicly the ptr is the output } } @@ -112,11 +112,11 @@ impl Ir for Store { } fn inputs(&self) -> Vec { - vec![] + vec![self.inner1.to_owned()] } fn output(&self) -> Option { - Some(self.inner1.to_owned()) + None // techniclly the ptr is the output and not an argument } } diff --git a/src/Optimizations/Passes/DeadNodeElimination.rs b/src/Optimizations/Passes/DeadNodeElimination.rs index 2a625995..28f434c6 100644 --- a/src/Optimizations/Passes/DeadNodeElimination.rs +++ b/src/Optimizations/Passes/DeadNodeElimination.rs @@ -1,4 +1,4 @@ -use crate::Optimizations::Pass; +use crate::{prelude::Call, Optimizations::Pass, IR::{FuncId, Var}}; /// ## Pass DeadNodeElimination
/// deletes unused nodes @@ -38,7 +38,10 @@ impl Pass for DeadNodeElimination { if let Some(out) = out { if !used.contains(&out.name) { - to_remove.push(index - 1); + if let Some(_) = node.as_any().downcast_ref::, Var>>() {} else { + // node isn't call + to_remove.push(index - 1); + } } } diff --git a/src/Target/wasm/reg_alloc.rs b/src/Target/wasm/reg_alloc.rs index 9f9b7b94..0ba794f8 100644 --- a/src/Target/wasm/reg_alloc.rs +++ b/src/Target/wasm/reg_alloc.rs @@ -36,8 +36,18 @@ pub(crate) fn wasm_alloc(alloc: &mut Allocator, func: &Function) { } fn node_prep(alloc: &mut Allocator, node: &Box) { + let mut scopes = Vec::new(); + + for (name, location) in &alloc.vars { + scopes.push( (Var { + name: name.to_owned(), + ty: *alloc.var_types.get(name).unwrap(), + }, *location) ); + } + + alloc.scopes.insert(node.dump(), scopes); + let inputs = node.inputs(); - for _input in inputs { // potential freeing here } diff --git a/src/Target/x64/compilation.rs b/src/Target/x64/compilation.rs index 7c9e7d5e..d6670952 100644 --- a/src/Target/x64/compilation.rs +++ b/src/Target/x64/compilation.rs @@ -78,12 +78,12 @@ pub(crate) fn construct_compilation_helper(call_conv: CallConv) -> CompilationHe } fn x64_after_alloc(compiler: &CompilationHelper) { - if compiler.alloc.stack_off - 8 < compiler.call.shadow(compiler.arch) { + /*if compiler.alloc.stack_off - 8 < compiler.call.shadow(compiler.arch) { unsafe { super::lower::USE_SP_FOR_STACK = true; if compiler.call.call_conv == CallConv::WindowsFastCall { super::lower::SP_OFF = 32; } } - } + }*/ } \ No newline at end of file diff --git a/src/Target/x64/lower.rs b/src/Target/x64/lower.rs index be706f36..1b6f7226 100644 --- a/src/Target/x64/lower.rs +++ b/src/Target/x64/lower.rs @@ -24,18 +24,18 @@ mod fcast; use super::optimizer::X64AsmOpt; use super::{instr::{Mnemonic, Operand, X64MCInstr}, X64Reg}; -pub(crate) static mut USE_SP_FOR_STACK: bool = false; -pub(crate) static mut SP_OFF: i32 = -4; +//pub(crate) static mut USE_SP_FOR_STACK: bool = false; +//pub(crate) static mut SP_OFF: i32 = -4; macro_rules! x64_stack { ($off:expr) => { - unsafe { - if !USE_SP_FOR_STACK { + //unsafe { + //if !USE_SP_FOR_STACK { Operand::Mem(X64Reg::Rbp - $off as u32) - } else { + /*} else { Operand::Mem(X64Reg::Rsp + ($off + SP_OFF) as u32) - } - } + }*/ + //} }; } diff --git a/src/Target/x64/reg_alloc.rs b/src/Target/x64/reg_alloc.rs index c15a6b9d..17365a3d 100644 --- a/src/Target/x64/reg_alloc.rs +++ b/src/Target/x64/reg_alloc.rs @@ -5,6 +5,7 @@ use crate::IR::Var; fn arg_prep(alloc: &mut Allocator, func: &Function, call: MachineCallingConvention) { let mut index = 0; + for (name, ty) in &func.ty.args { if let Some(reg) = call.arg(Arch::X86_64, *ty, index) { // argument in an register @@ -57,6 +58,17 @@ fn node_prep(alloc: &mut Allocator, node: &Box) { // potential freeing here } + let mut scopes = Vec::new(); + + for (name, location) in &alloc.vars { + scopes.push( (Var { + name: name.to_owned(), + ty: *alloc.var_types.get(name).unwrap(), + }, *location) ); + } + + alloc.scopes.insert(node.dump(), scopes); + // handle specific nodes here (like alloca) if let Some(alloca) = node.as_any().downcast_ref::>() { let location = x64_alloc_stack(alloc, alloca.inner2); @@ -94,6 +106,8 @@ pub(crate) fn x64_alloc_rv(alloc: &mut Allocator, ty: TypeMetadata) -> VarLocati } pub(crate) fn x64_alloc_stack(alloc: &mut Allocator, ty: TypeMetadata) -> VarLocation { + alloc.epilog = true; + let ret = VarLocation::Mem(alloc.stack_off, ty); alloc.stack_off += ty.byteSize() as i64; diff --git a/tests/IR/ret/ret1.yl b/tests/IR/ret/ret1.yl index 431dfedb..6737dc31 100644 --- a/tests/IR/ret/ret1.yl +++ b/tests/IR/ret/ret1.yl @@ -3,7 +3,9 @@ cargo run -p ylc -- -in=%s -o=out.o gcc out.o -o a.exe ./a.exe # IN: -define u32 @main(u32 %0) { +define u32 @main(u32 %0) { +; %= = argc +; So when we call standalone ./a.exe we get 1 entry: ret u32 %0 } diff --git a/tests/x64/instr_combine-add-into-lea.yl b/tests/x64/instr_combine-add-into-lea.yl index 0490d8d7..2ea0bab2 100644 --- a/tests/x64/instr_combine-add-into-lea.yl +++ b/tests/x64/instr_combine-add-into-lea.yl @@ -4,9 +4,9 @@ cargo run -p ylc -- -in=%s -asm-clr --triple=x86_64-unknown-linux | filecheck %s # IN: define i32 @add(i32 %a, i32 %b) { entry: -; CHECK: lea ecx, [ esi + edi ] +; CHECK: lea [[ANY:.*]], [ esi + edi ] %ret = add i32 %a, %b -; CHECK: mov eax, ecx +; CHECK: mov eax, [[ANY:.*]] ; CHECK: ret ret i32 %ret } \ No newline at end of file diff --git a/tests/x64/rsp-adressing.yl b/tests/x64/rsp-adressing.yl index c0bb689f..57423ac4 100644 --- a/tests/x64/rsp-adressing.yl +++ b/tests/x64/rsp-adressing.yl @@ -5,7 +5,6 @@ cargo run -p ylc -- -in=%s -asm-clr --triple=x86_64-unknown-linux | filecheck %s define ptr @test() { entry: %1 = alloca i32 -; CHECK-NOT: pop rbp -; CHECK: lea rax, [ rsp + 8 ] +; CHECK: lea rax, [ rbp - 8 ] ret ptr %1 } \ No newline at end of file