diff --git a/src/CodeGen/calling_convention.rs b/src/CodeGen/calling_convention.rs index 029e96e5..f308b688 100644 --- a/src/CodeGen/calling_convention.rs +++ b/src/CodeGen/calling_convention.rs @@ -96,6 +96,7 @@ impl MachineCallingConvention { pub fn shadow(&self, _: Arch) -> i64 { match self.call_conv { CallConv::WindowsFastCall => 32, + CallConv::SystemV => 16, _ => 8, } } diff --git a/src/CodeGen/compilation/prolog.rs b/src/CodeGen/compilation/prolog.rs index b743a686..44cba6f3 100644 --- a/src/CodeGen/compilation/prolog.rs +++ b/src/CodeGen/compilation/prolog.rs @@ -5,7 +5,7 @@ use super::CompilationHelper; impl CompilationHelper { #[allow(missing_docs)] pub fn compile_prolog(&mut self, sink: &mut Vec) { - if self.alloc.stack_off > self.call.shadow(self.arch) { + if self.alloc.stack_off - self.call.align(self.arch) > self.call.shadow(self.arch) { let mut instr = MachineInstr::new( MachineMnemonic::Prolog ); instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) ); @@ -15,7 +15,7 @@ impl CompilationHelper { #[allow(missing_docs)] pub fn compile_epilog(&mut self, sink: &mut Vec) { - if self.alloc.stack_off > self.call.shadow(self.arch) { + if self.alloc.stack_off - self.call.align(self.arch) > self.call.shadow(self.arch) { let mut instr = MachineInstr::new( MachineMnemonic::Epilog ); instr.add_operand( MachineOperand::Imm(self.alloc.stack_off as f64) ); diff --git a/src/CodeGen/reg_alloc/mod.rs b/src/CodeGen/reg_alloc/mod.rs index 9a5dc7c7..93695734 100644 --- a/src/CodeGen/reg_alloc/mod.rs +++ b/src/CodeGen/reg_alloc/mod.rs @@ -325,7 +325,7 @@ impl RegAlloc { let ret = VarLocation::Mem(self.stack_off, ty); - self.stack_off += self.call.align(self.arch); + self.stack_off += ty.byteSize() as i64; ret } diff --git a/src/Target/wasm/asm/parser.rs b/src/Target/wasm/asm/parser.rs index 8be1f8ed..7edf510a 100644 --- a/src/Target/wasm/asm/parser.rs +++ b/src/Target/wasm/asm/parser.rs @@ -9,7 +9,7 @@ use super::{instr::*, lexer::Token}; pub(crate) struct wasmParser { pub(crate) tokens: VecDeque, /// The output instruction - pub out: Option, + pub(crate) out: Option, } impl wasmParser { diff --git a/src/Target/x64/compilation.rs b/src/Target/x64/compilation.rs index d61d1486..6b93c141 100644 --- a/src/Target/x64/compilation.rs +++ b/src/Target/x64/compilation.rs @@ -66,9 +66,12 @@ pub(crate) fn construct_compilation_helper(call_conv: CallConv) -> CompilationHe } fn x64_after_alloc(compiler: &CompilationHelper) { - if compiler.alloc.stack_off < 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 7071ce89..be706f36 100644 --- a/src/Target/x64/lower.rs +++ b/src/Target/x64/lower.rs @@ -25,13 +25,16 @@ 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; macro_rules! x64_stack { ($off:expr) => { - if unsafe {!USE_SP_FOR_STACK} { - Operand::Mem(X64Reg::Rbp - $off) - } else { - Operand::Mem(X64Reg::Rsp - $off) + unsafe { + if !USE_SP_FOR_STACK { + Operand::Mem(X64Reg::Rbp - $off as u32) + } else { + Operand::Mem(X64Reg::Rsp + ($off + SP_OFF) as u32) + } } }; } @@ -122,7 +125,7 @@ pub(crate) fn x64_lower(conv: CallConv, instrs: Vec) -> Vec for Operand { fn from(value: MachineOperand) -> Self { match value { - MachineOperand::Stack(stack, _) => x64_stack!(stack as u32), + MachineOperand::Stack(stack, _) => x64_stack!(stack as i32), MachineOperand::Imm(imm) => Operand::Imm(imm as i64), MachineOperand::Reg(reg) => match reg { crate::CodeGen::Reg::x64(x64_reg) => Operand::Reg(x64_reg), diff --git a/src/Target/x64/lower/ret.rs b/src/Target/x64/lower/ret.rs index 3a247809..75e311d9 100644 --- a/src/Target/x64/lower/ret.rs +++ b/src/Target/x64/lower/ret.rs @@ -1,6 +1,7 @@ use crate::CodeGen::{MachineInstr, MachineMnemonic, MachineOperand, Reg}; use crate::Target::x64::asm::instr::*; use crate::Target::x64::X64Reg; +use crate::IR::TypeMetadata; use super::fmove::x64_lower_fmove; @@ -14,7 +15,13 @@ pub(crate) fn x64_lower_return(sink: &mut Vec, instr: &MachineInstr) x64_lower_fmove(sink, &instr); } else { - sink.push( X64MCInstr::with2(Mnemonic::Mov, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), (*op).into())); + let mut mne = Mnemonic::Mov; + + if instr.meta == TypeMetadata::ptr { + mne = Mnemonic::Lea; + } + + sink.push( X64MCInstr::with2(mne, Operand::Reg(X64Reg::Rax.sub_ty(instr.meta)), (*op).into())); } sink.push( X64MCInstr::with0(Mnemonic::Ret).into() ); diff --git a/tests/tools/ygen-mc/errors/error0.yl b/tests/tools/ygen-mc/errors/error0.yl deleted file mode 100644 index d77ce837..00000000 --- a/tests/tools/ygen-mc/errors/error0.yl +++ /dev/null @@ -1,5 +0,0 @@ -# RUN: -cargo run -p ygen-mc -- -as=Hi -no-clr -no-out -no-asm -# STDOUT: -Error: unknown instruction: 'hi' -# EXIT_CODE=-1 \ No newline at end of file diff --git a/tests/x64/instr_combine-add-into-lea.yl b/tests/x64/instr_combine-add-into-lea.yl new file mode 100644 index 00000000..0490d8d7 --- /dev/null +++ b/tests/x64/instr_combine-add-into-lea.yl @@ -0,0 +1,12 @@ +# RUN: +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 ] + %ret = add i32 %a, %b +; CHECK: mov eax, ecx +; CHECK: ret + ret i32 %ret +} \ No newline at end of file diff --git a/tests/x64/ret.yl b/tests/x64/ret.yl index cdc73d6e..de4a6a38 100644 --- a/tests/x64/ret.yl +++ b/tests/x64/ret.yl @@ -1,5 +1,5 @@ # RUN: -cargo run -p ylc -- -in=%s -asm-clr | filecheck %s +cargo run -p ylc -- -in=%s -asm-clr --triple=x86_64-unknown-linux | filecheck %s # IN: define i32 @test() { diff --git a/tests/x64/rsp-adressing.yl b/tests/x64/rsp-adressing.yl new file mode 100644 index 00000000..c0bb689f --- /dev/null +++ b/tests/x64/rsp-adressing.yl @@ -0,0 +1,11 @@ +# RUN: +cargo run -p ylc -- -in=%s -asm-clr --triple=x86_64-unknown-linux | filecheck %s + +# IN: +define ptr @test() { + entry: + %1 = alloca i32 +; CHECK-NOT: pop rbp +; CHECK: lea rax, [ rsp + 8 ] + ret ptr %1 +} \ No newline at end of file