diff --git a/.gitignore b/.gitignore index cc3fa4ca..07e54c13 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ *.o *.c *.exe -*.out \ No newline at end of file +*.out +.idx/* +.vscode/* \ No newline at end of file diff --git a/src/IR/nodes/call.rs b/src/IR/nodes/call.rs index 07be57f2..1b29b363 100644 --- a/src/IR/nodes/call.rs +++ b/src/IR/nodes/call.rs @@ -67,13 +67,8 @@ impl Ir for Call, Var> { fn uses(&self, var: &Var) -> bool { let mut uses = false; - if self.inner3 == *var { - uses = true; - } - - for arg in &self.inner2 { - if *arg == *var { + if arg.name == var.name { uses = true; } } diff --git a/src/Target/target_descr.rs b/src/Target/target_descr.rs index 6de1d8b9..3aaa8128 100644 --- a/src/Target/target_descr.rs +++ b/src/Target/target_descr.rs @@ -45,12 +45,15 @@ impl BackendInfos { } } - /// Delets the variable of the varsStorage (giving out it's resources) + /// Delets the variable of the varsStorage (freeing it's resources) pub(crate) fn drop(&mut self, var: &Var) { if let Some(loc) = &self.varsStorage.get(var) { if let VarStorage::Register(reg) = &loc { self.dropReg(reg.clone()); } // don't decrease the stack offset because if it isn't at the bottom other variables will may be overriden + self.varsStorage.remove(var); + } else { + panic!("wanted to drop reg but it has no location"); } } diff --git a/src/Target/x64/asm/optimizer.rs b/src/Target/x64/asm/optimizer.rs index 57608b40..7b7693f7 100644 --- a/src/Target/x64/asm/optimizer.rs +++ b/src/Target/x64/asm/optimizer.rs @@ -19,12 +19,10 @@ impl Optimize for Vec { if instr.mnemonic == Mnemonic::StartOptimization { optimize = true; - } - - if instr.mnemonic == Mnemonic::EndOptimization { + } else if instr.mnemonic == Mnemonic::EndOptimization { optimize = false; - } - + } + if !optimize { out.push(instr.to_owned()); continue; diff --git a/src/Target/x64/compilation/call.rs b/src/Target/x64/compilation/call.rs index ef42d7bc..022d5664 100644 --- a/src/Target/x64/compilation/call.rs +++ b/src/Target/x64/compilation/call.rs @@ -21,9 +21,13 @@ pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut T let var = registry.backend.getVarByReg(reg.clone()); if let Some(var) = var { // get the var - asm.push( Instr::with2(Mnemonic::Mov, Operand::Mem(x64Reg::Rbp - (offset as u32)), Operand::Reg(reg.clone())) ); - saved_var_memory_locations.insert(var.clone(), offset); - offset += 8; + if block.isVarUsedAfterNode(&boxed, &var) || call.inner2.contains(var) && registry.call.args64().contains(reg.as_any().downcast_ref::().unwrap()) { + asm.push( Instr::with2(Mnemonic::Mov, Operand::Mem(x64Reg::Rbp - (offset as u32)), Operand::Reg(reg.clone())) ); + saved_var_memory_locations.insert(var.clone(), offset); + offset += 8; + } /*else { + eprintln!("don't save {} which has location {:?}", var, reg); + }*/ } } } @@ -51,9 +55,15 @@ pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut T TypeMetadata::Void => vec![], }; + // don't change else some stuff will brake in some random linux vm idk why but it is so + //if args[reg_args] == x64Reg::Rsi { /*eprintln!("abc");*/ } + if args.contains(reg.as_any().downcast_ref::().unwrap()) { if let Some(offset) = saved_var_memory_locations.get(arg) { asm.push( Instr::with2(Mnemonic::Mov, Operand::Reg(args[reg_args].boxed()), Operand::Mem(x64Reg::Rbp - (*offset as u32)))); + } else { + eprintln!("arg {:?} wasn't saved but it needs to be put into {:?}", reg, args[reg_args]); + asm.push(Instr::with2(Mnemonic::Mov, Operand::Reg(args[reg_args].boxed()), Operand::Reg(reg.clone()))); } } else { asm.push(Instr::with2(Mnemonic::Mov, Operand::Reg(args[reg_args].boxed()), Operand::Reg(reg.clone()))); @@ -81,6 +91,10 @@ pub(crate) fn CompileCall(call: &Call, Var>, registry: &mut T } } + if registry.call.reset_eax() { + asm.push( Instr::with2(Mnemonic::Xor, Operand::Reg(x64Reg::Eax.boxed()), Operand::Reg(x64Reg::Eax.boxed()))); + } + asm.push( Instr::with1(Mnemonic::Call, Operand::Imm(0)) ); asm.push( Instr::with1(Mnemonic::Link, Operand::LinkDestination(call.inner1.name.to_string(), -4)) ); diff --git a/src/Target/x64/compilation/mod.rs b/src/Target/x64/compilation/mod.rs index 6a0556f7..734954a3 100644 --- a/src/Target/x64/compilation/mod.rs +++ b/src/Target/x64/compilation/mod.rs @@ -27,6 +27,7 @@ use super::{x64Reg, instr::*}; pub(crate) fn buildAsmX86<'a>(block: &'a Block, func: &Function, call: &CallConv, registry: &mut TargetBackendDescr<'a>) -> Vec { registry.block = Some(&block); + registry.backend.stackSafe = true; let info = &mut registry.backend; diff --git a/src/Target/x64/compilation/prolog.rs b/src/Target/x64/compilation/prolog.rs index fe470793..a373a3fa 100644 --- a/src/Target/x64/compilation/prolog.rs +++ b/src/Target/x64/compilation/prolog.rs @@ -4,7 +4,7 @@ pub(crate) fn x64BuildProlog(_: &Block, registry: &mut TargetBackendDescr) -> Ve let mut res = vec![]; if registry.backend.currStackOffsetForLocalVars != 0 || registry.backend.stackSafe { - res.push( Instr::with0(Mnemonic::Endbr64) ); + //res.push( Instr::with0(Mnemonic::Endbr64) ); res.push( Instr::with1(Mnemonic::Push, Operand::Reg(x64Reg::Rbp.boxed())) ); res.push( Instr::with2(Mnemonic::Mov, Operand::Reg(x64Reg::Rbp.boxed()), Operand::Reg(x64Reg::Rsp.boxed())) ); res.push( Instr::with2(Mnemonic::Sub, Operand::Reg(x64Reg::Rsp.boxed()), Operand::Imm(registry.backend.shadow + 8)) );