mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 16:21:11 +00:00
Properly align the stack when used
This commit is contained in:
parent
c32cedc1bd
commit
6a95738b1c
2 changed files with 21 additions and 3 deletions
|
@ -21,6 +21,7 @@ pub trait CallConv<GPReg: GPRegTrait> {
|
||||||
const STACK_POINTER: GPReg;
|
const STACK_POINTER: GPReg;
|
||||||
const FRAME_POINTER: GPReg;
|
const FRAME_POINTER: GPReg;
|
||||||
|
|
||||||
|
const STACK_ALIGNMENT: u8;
|
||||||
const SHADOW_SPACE_SIZE: u8;
|
const SHADOW_SPACE_SIZE: u8;
|
||||||
// It may be worth ignoring the red zone and keeping things simpler.
|
// It may be worth ignoring the red zone and keeping things simpler.
|
||||||
const RED_ZONE_SIZE: u8;
|
const RED_ZONE_SIZE: u8;
|
||||||
|
@ -158,15 +159,31 @@ impl<'a, GPReg: GPRegTrait, ASM: Assembler<GPReg>, CC: CallConv<GPReg>> Backend<
|
||||||
ASM::push_register64bit(&mut out, *reg);
|
ASM::push_register64bit(&mut out, *reg);
|
||||||
pop_order.push(*reg);
|
pop_order.push(*reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Keep stack aligned while modifying stack.
|
||||||
|
let alignment = self.stack_size % CC::STACK_ALIGNMENT as i32;
|
||||||
|
let offset = if alignment == 0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
CC::STACK_ALIGNMENT as i32 - alignment
|
||||||
|
};
|
||||||
if self.stack_size > 0 {
|
if self.stack_size > 0 {
|
||||||
ASM::sub_register64bit_immediate32bit(&mut out, CC::STACK_POINTER, self.stack_size);
|
ASM::sub_register64bit_immediate32bit(
|
||||||
|
&mut out,
|
||||||
|
CC::STACK_POINTER,
|
||||||
|
self.stack_size + offset,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add function body.
|
// Add function body.
|
||||||
out.extend(&self.buf);
|
out.extend(&self.buf);
|
||||||
|
|
||||||
if self.stack_size > 0 {
|
if self.stack_size > 0 {
|
||||||
ASM::add_register64bit_immediate32bit(&mut out, CC::STACK_POINTER, self.stack_size);
|
ASM::add_register64bit_immediate32bit(
|
||||||
|
&mut out,
|
||||||
|
CC::STACK_POINTER,
|
||||||
|
self.stack_size + offset,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// Restore data in callee saved regs.
|
// Restore data in callee saved regs.
|
||||||
while let Some(reg) = pop_order.pop() {
|
while let Some(reg) = pop_order.pop() {
|
||||||
|
@ -299,7 +316,6 @@ impl<'a, GPReg: GPRegTrait, ASM: Assembler<GPReg>, CC: CallConv<GPReg>>
|
||||||
match val {
|
match val {
|
||||||
Some(SymbolStorage::GPRegeg(reg)) => {
|
Some(SymbolStorage::GPRegeg(reg)) => {
|
||||||
let offset = self.stack_size;
|
let offset = self.stack_size;
|
||||||
self.stack_size += 8;
|
|
||||||
if let Some(size) = self.stack_size.checked_add(8) {
|
if let Some(size) = self.stack_size.checked_add(8) {
|
||||||
self.stack_size = size;
|
self.stack_size = size;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -99,6 +99,7 @@ impl CallConv<X86_64GPReg> for X86_64SystemV {
|
||||||
}
|
}
|
||||||
const STACK_POINTER: X86_64GPReg = X86_64GPReg::RSP;
|
const STACK_POINTER: X86_64GPReg = X86_64GPReg::RSP;
|
||||||
const FRAME_POINTER: X86_64GPReg = X86_64GPReg::RBP;
|
const FRAME_POINTER: X86_64GPReg = X86_64GPReg::RBP;
|
||||||
|
const STACK_ALIGNMENT: u8 = 16;
|
||||||
const SHADOW_SPACE_SIZE: u8 = 0;
|
const SHADOW_SPACE_SIZE: u8 = 0;
|
||||||
const RED_ZONE_SIZE: u8 = 128;
|
const RED_ZONE_SIZE: u8 = 128;
|
||||||
}
|
}
|
||||||
|
@ -150,6 +151,7 @@ impl CallConv<X86_64GPReg> for X86_64WindowsFastcall {
|
||||||
}
|
}
|
||||||
const STACK_POINTER: X86_64GPReg = X86_64GPReg::RSP;
|
const STACK_POINTER: X86_64GPReg = X86_64GPReg::RSP;
|
||||||
const FRAME_POINTER: X86_64GPReg = X86_64GPReg::RBP;
|
const FRAME_POINTER: X86_64GPReg = X86_64GPReg::RBP;
|
||||||
|
const STACK_ALIGNMENT: u8 = 16;
|
||||||
const SHADOW_SPACE_SIZE: u8 = 32;
|
const SHADOW_SPACE_SIZE: u8 = 32;
|
||||||
const RED_ZONE_SIZE: u8 = 0;
|
const RED_ZONE_SIZE: u8 = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue