From 8d388b2218bdeb78f429705993b1201d60989294 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 21 Feb 2018 10:34:41 -0800 Subject: [PATCH] Fix stack pointer offsets for outgoing arguments. StackSlotKind::OutgoingArg stack slots have an offset that is relative to our own stack pointer, while all other stack slot kinds have offsets that are relative to the caller's stack pointer. Make sure we generate the right sp-relative offsets for outgoing arguments too. --- cranelift/filetests/isa/intel/binary64.cton | 17 +++++++++++++++++ lib/cretonne/src/isa/stack.rs | 17 ++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) 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, } } }