From 6e1e8a09b49cf7ceca35d990ad934cfc661e823f Mon Sep 17 00:00:00 2001 From: sewardj Date: Wed, 6 Feb 2002 15:48:56 +0000 Subject: [PATCH] [project @ 2002-02-06 15:48:56 by sewardj] x86 only: make %esp be 8-aligned before entering HC-world code. This avoids misalignment penalties for C doubles stored on the C stack. A quick test using nofib/imaginary/rfib shows that getting this wrong increases run time by about 10% on our 1 GHz PIII. --- ghc/rts/StgCRun.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/ghc/rts/StgCRun.c b/ghc/rts/StgCRun.c index 98e7085..3f9273a 100644 --- a/ghc/rts/StgCRun.c +++ b/ghc/rts/StgCRun.c @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: StgCRun.c,v 1.27 2002/01/07 22:35:55 ken Exp $ + * $Id: StgCRun.c,v 1.28 2002/02/06 15:48:56 sewardj Exp $ * * (c) The GHC Team, 1998-2000 * @@ -115,6 +115,8 @@ EXTFUN(StgReturn) StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) { + static volatile void* stg_esp_saved_before_stack_align; + unsigned char space[ RESERVED_C_STACK_BYTES + 4*sizeof(void *) ]; StgThreadReturnCode r; @@ -123,7 +125,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { * save callee-saves registers on behalf of the STG code. */ "movl %%esp, %%eax\n\t" - "addl %4, %%eax\n\t" + "addl %5, %%eax\n\t" "movl %%ebx,0(%%eax)\n\t" "movl %%esi,4(%%eax)\n\t" "movl %%edi,8(%%eax)\n\t" @@ -131,30 +133,53 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { /* * Set BaseReg */ - "movl %3,%%ebx\n\t" + "movl %4,%%ebx\n\t" /* - * grab the function argument from the stack, and jump to it. + * grab the function argument from the stack + */ + "movl %3,%%eax\n\t" + /* + * Get %%esp 8-aligned, first saving the current value. This + * moves it down another zero or four bytes, depending on + * whether it was already aligned or not. This is a bit + * subtle -- we must not have a swizzled %esp at any place + * where we might refer to one of the %digit parameters to + * this piece of assembly code, since gcc may generate + * %esp-relative stack offsets which will then be wrong. + */ + "movl %%esp, %6\n\t" + "subl $4, %%esp\n\t" + "andl $0xFFFFFFF8, %%esp\n\t" + /* + * And finally, jump to the function argument. */ - "movl %2,%%eax\n\t" "jmp *%%eax\n\t" ".global " STG_RETURN "\n" STG_RETURN ":\n\t" - - "movl %%esi, %%eax\n\t" /* Return value in R1 */ - + /* + * Restore %%esp to pre-alignment state. + */ + "movl %2, %%esp\n" + /* + * Move return value from R1 to %%eax + */ + "movl %%esi, %%eax\n\t" /* * restore callee-saves registers. (Don't stomp on %%eax!) */ "movl %%esp, %%edx\n\t" - "addl %4, %%edx\n\t" + "addl %5, %%edx\n\t" "movl 0(%%edx),%%ebx\n\t" /* restore the registers saved above */ "movl 4(%%edx),%%esi\n\t" "movl 8(%%edx),%%edi\n\t" "movl 12(%%edx),%%ebp\n\t" - : "=&a" (r), "=m" (space) - : "m" (f), "m" (basereg), "i" (RESERVED_C_STACK_BYTES) + : "=&a" (r), "=m" (space), + "=m" (stg_esp_saved_before_stack_align) + : "m" (f), "m" (basereg), "i" (RESERVED_C_STACK_BYTES), + "m" (stg_esp_saved_before_stack_align) + : "edx" /* stomps on %edx */ ); -- 1.7.10.4