diff --git a/lib/cretonne/meta/base/settings.py b/lib/cretonne/meta/base/settings.py index 2baf9927ce..434bd28a52 100644 --- a/lib/cretonne/meta/base/settings.py +++ b/lib/cretonne/meta/base/settings.py @@ -4,7 +4,7 @@ Cretonne shared settings. This module defines settings relevant for all code generators. """ from __future__ import absolute_import -from cdsl.settings import SettingGroup, BoolSetting, EnumSetting +from cdsl.settings import SettingGroup, BoolSetting, EnumSetting, NumSetting group = SettingGroup('shared') @@ -52,4 +52,22 @@ enable_atomics = BoolSetting( """Enable the use of atomic instructions""", default=True) +# +# Settings specific to the `spiderwasm` calling convention. +# +spiderwasm_prologue_words = NumSetting( + """ + Number of pointer-sized words pushed by the spiderwasm prologue. + + Functions with the `spiderwasm` calling convention don't generate their + own prologue and epilogue. They depend on externally generated code + that pushes a fixed number of words in the prologue and restores them + in the epilogue. + + This setting configures the number of pointer-sized words pushed on the + stack when the Cretonne-generated code is entered. This includes the + pushed return address on Intel ISAs. + """) + + group.close(globals()) diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index b68cd17041..1ccacce8b1 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -236,9 +236,19 @@ pub trait TargetIsa { fn prologue_epilogue(&self, func: &mut ir::Function) -> result::CtonResult { // This default implementation is unlikely to be good enough. use stack_layout::layout_stack; + use ir::stackslot::{StackSize, StackOffset}; - let align = if self.flags().is_64bit() { 8 } else { 4 }; - layout_stack(&mut func.stack_slots, align)?; + let word_size = if self.flags().is_64bit() { 8 } else { 4 }; + + // Account for the SpiderMonkey standard prologue pushes. + if func.signature.call_conv == ir::CallConv::SpiderWASM { + let bytes = self.flags().spiderwasm_prologue_words() as StackSize * word_size; + let mut ss = ir::StackSlotData::new(ir::StackSlotKind::IncomingArg, bytes); + ss.offset = -(bytes as StackOffset); + func.stack_slots.push(ss); + } + + layout_stack(&mut func.stack_slots, word_size)?; Ok(()) } diff --git a/lib/cretonne/src/settings.rs b/lib/cretonne/src/settings.rs index e45dba395c..43d1639028 100644 --- a/lib/cretonne/src/settings.rs +++ b/lib/cretonne/src/settings.rs @@ -323,10 +323,12 @@ mod tests { is_compressed = false\n\ enable_float = true\n\ enable_simd = true\n\ - enable_atomics = true\n" + enable_atomics = true\n\ + spiderwasm_prologue_words = 0\n" ); assert_eq!(f.opt_level(), super::OptLevel::Default); assert_eq!(f.enable_simd(), true); + assert_eq!(f.spiderwasm_prologue_words(), 0); } #[test]