From 65f13758004e9838e1920b6d5e1d64b1d5af515e Mon Sep 17 00:00:00 2001 From: Taylor R Campbell Date: Sat, 31 Oct 2009 01:32:48 -0400 Subject: [PATCH] Align stack to 16 byte boundary in x86-64's C_to_interface. Otherwise, parts of the microcode fail spectacularly when compiled with `gcc -O3'. --- src/microcode/cmpauxmd/x86-64.m4 | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/microcode/cmpauxmd/x86-64.m4 b/src/microcode/cmpauxmd/x86-64.m4 index fbf7417e3..5560acfc8 100644 --- a/src/microcode/cmpauxmd/x86-64.m4 +++ b/src/microcode/cmpauxmd/x86-64.m4 @@ -532,6 +532,13 @@ x86_64_initialize_no_fp: leave ret +# Note: The AMD64 ABI mandates that on entry to a function, RSP - 8 +# must be a multiple of 0x10; that is, the stack must be 128-bit +# aligned. We push six quadwords onto the stack, but there is already +# a return address on the stack, for a total of seven quadwords, which +# is misaligned. Hence we push an extra dummy zero onto the stack, +# which we must pop off in interface_to_C. + define_c_label(C_to_interface) OP(push,q) REG(rbp) # Link according OP(mov,q) TW(REG(rsp),REG(rbp)) # to C's conventions @@ -540,6 +547,7 @@ define_c_label(C_to_interface) OP(push,q) REG(r13) OP(push,q) REG(r14) OP(push,q) REG(r15) + OP(push,q) IMM(0) # Align stack OP(mov,q) TW(REG(rdi),REG(rdx)) # Entry point # Preserve frame ptr OP(mov,q) TW(REG(rbp),ABS(EVR(C_Frame_Pointer))) @@ -670,6 +678,10 @@ IF387(` interface_to_C_proceed:') OP(mov,q) TW(REG(rdx),REG(rax)) # Set up result + # We need a dummy register for the POP (which is three bytes + # shorter than ADD $8,RSP); since we're about to pop into r15 + # anyway, we may as well use that. + OP(pop,q) REG(r15) # Undo stack alignment OP(pop,q) REG(r15) # Restore callee-saves OP(pop,q) REG(r14) # registers OP(pop,q) REG(r13) -- 2.25.1