diff --git a/cranelift/filetests/isa/intel/binary64.cton b/cranelift/filetests/isa/intel/binary64.cton index 8ac8deb58e..0b546961d8 100644 --- a/cranelift/filetests/isa/intel/binary64.cton +++ b/cranelift/filetests/isa/intel/binary64.cton @@ -634,6 +634,23 @@ ebb1: return } +; Test for the encoding of outgoing_arg stack slots. +function %outargs() { + ss0 = incoming_arg 16, offset -16 + ss1 = outgoing_arg 8, offset 8 + ss2 = outgoing_arg 8, offset 0 + +ebb0: + [-,%rcx] v1 = iconst.i64 1 + + ; asm: movq %rcx, 8(%rsp) + [-,ss1] v10 = spill v1 ; bin: 48 89 8c 24 00000008 + ; asm: movq %rcx, (%rsp) + [-,ss2] v11 = spill v1 ; bin: 48 89 8c 24 00000000 + + return +} + ; Tests for i32 instructions in 64-bit mode. ; ; Note that many i32 instructions can be encoded both with and without a REX diff --git a/lib/cretonne/src/isa/stack.rs b/lib/cretonne/src/isa/stack.rs index 907afe0208..730db28e18 100644 --- a/lib/cretonne/src/isa/stack.rs +++ b/lib/cretonne/src/isa/stack.rs @@ -4,7 +4,7 @@ //! defined in this module expresses the low-level details of accessing a stack slot from an //! encoded instruction. -use ir::stackslot::{StackSlots, StackOffset}; +use ir::stackslot::{StackSlots, StackOffset, StackSlotKind}; use ir::StackSlot; /// A method for referencing a stack slot in the current stack frame. @@ -38,12 +38,19 @@ impl StackRef { let size = frame.frame_size.expect( "Stack layout must be computed before referencing stack slots", ); - - // Offset where SP is pointing. (All ISAs have stacks growing downwards.) - let sp_offset = -(size as StackOffset); + let slot = &frame[ss]; + let offset = if slot.kind == StackSlotKind::OutgoingArg { + // Outgoing argument slots have offsets relative to our stack pointer. + slot.offset + } else { + // All other slots have offsets relative to our caller's stack frame. + // Offset where SP is pointing. (All ISAs have stacks growing downwards.) + let sp_offset = -(size as StackOffset); + slot.offset - sp_offset + }; StackRef { base: StackBase::SP, - offset: frame[ss].offset - sp_offset, + offset, } } }