X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FStgCRun.c;h=4d5136f7789848a0649d7027043698991a053f55;hb=b43be28258a3d49bde40095b210047e99742f8a5;hp=dc29597f9acfe4101ff73b6dd6150ccff5891c03;hpb=6f985ae88171fb52ca68d75f667669e139b6b8c2;p=ghc-hetmet.git diff --git a/ghc/rts/StgCRun.c b/ghc/rts/StgCRun.c index dc29597..4d5136f 100644 --- a/ghc/rts/StgCRun.c +++ b/ghc/rts/StgCRun.c @@ -50,7 +50,7 @@ * in libc.a clobbers $s6. */ #include "ghcconfig.h" -#ifdef alpha_TARGET_ARCH +#ifdef alpha_HOST_ARCH #define alpha_EXTRA_CAREFUL register long fake_ra __asm__("$26"); register long fake_gp __asm__("$29"); @@ -112,7 +112,7 @@ StgFunPtr StgReturn(void) x86 architecture -------------------------------------------------------------------------- */ -#ifdef i386_TARGET_ARCH +#ifdef i386_HOST_ARCH StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) { @@ -175,7 +175,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { ------------------------------------------------------------------------- */ -#ifdef x86_64_TARGET_ARCH +#ifdef x86_64_HOST_ARCH extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg); @@ -225,7 +225,41 @@ static void StgRunIsImplementedInAssembler(void) "addq %0, %%rsp\n\t" "retq" - : : "i"(RESERVED_C_STACK_BYTES+48 /*stack frame size*/)); + : : "i"(RESERVED_C_STACK_BYTES+48+8 /*stack frame size*/)); + /* + HACK alert! + + The x86_64 ABI specifies that on a procedure call, %rsp is + aligned on a 16-byte boundary + 8. That is, the first + argument on the stack after the return address will be + 16-byte aligned. + + Which should be fine: RESERVED_C_STACK_BYTES+48 is a multiple + of 16 bytes. + + BUT... when we do a C-call from STG land, gcc likes to put the + stack alignment adjustment in the prolog. eg. if we're calling + a function with arguments in regs, gcc will insert 'subq $8,%rsp' + in the prolog, to keep %rsp aligned (the return address is 8 + bytes, remember). The mangler throws away the prolog, so we + lose the stack alignment. + + The hack is to add this extra 8 bytes to our %rsp adjustment + here, so that throughout STG code, %rsp is 16-byte aligned, + ready for a C-call. + + A quick way to see if this is wrong is to compile this code: + + main = System.Exit.exitWith ExitSuccess + + And run it with +RTS -sstderr. The stats code in the RTS, in + particular statsPrintf(), relies on the stack alignment because + it saves the %xmm regs on the stack, so it'll fall over if the + stack isn't aligned, and calling exitWith from Haskell invokes + shutdownHaskellAndExit using a C call. + + Future gcc releases will almost certainly break this hack... + */ } #endif /* x86-64 */ @@ -261,7 +295,7 @@ static void StgRunIsImplementedInAssembler(void) Updated info (GHC 4.08.2): not saving %i7 any more (see below). -------------------------------------------------------------------------- */ -#ifdef sparc_TARGET_ARCH +#ifdef sparc_HOST_ARCH StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) { @@ -329,7 +363,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) { tru64unix.compaq.com/docs/base_doc/DOCUMENTATION/V51_PDF/ARH9MBTE.PDF -------------------------------------------------------------------------- */ -#ifdef alpha_TARGET_ARCH +#ifdef alpha_HOST_ARCH StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) @@ -425,13 +459,13 @@ StgRun(StgFunPtr f, StgRegTable *basereg) return ret; } -#endif /* alpha_TARGET_ARCH */ +#endif /* alpha_HOST_ARCH */ /* ----------------------------------------------------------------------------- HP-PA architecture -------------------------------------------------------------------------- */ -#ifdef hppa1_1_TARGET_ARCH +#ifdef hppa1_1_HOST_ARCH StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg) @@ -518,7 +552,7 @@ StgRun(StgFunPtr f, StgRegTable *basereg) return ret; } -#endif /* hppa1_1_TARGET_ARCH */ +#endif /* hppa1_1_HOST_ARCH */ /* ----------------------------------------------------------------------------- PowerPC architecture @@ -527,11 +561,11 @@ StgRun(StgFunPtr f, StgRegTable *basereg) -------------------------------------------------------------------------- */ -#ifdef powerpc_TARGET_ARCH +#ifdef powerpc_HOST_ARCH extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg); -#ifdef darwin_TARGET_OS +#ifdef darwin_HOST_OS static void StgRunIsImplementedInAssembler(void) { #if HAVE_SUBSECTIONS_VIA_SYMBOLS @@ -644,9 +678,9 @@ static void StgRunIsImplementedInAssembler(void) -------------------------------------------------------------------------- */ -#ifdef powerpc64_TARGET_ARCH +#ifdef powerpc64_HOST_ARCH -#ifdef linux_TARGET_OS +#ifdef linux_HOST_OS extern StgThreadReturnCode StgRun(StgFunPtr f, StgRegTable *basereg); static void StgRunIsImplementedInAssembler(void) @@ -767,7 +801,7 @@ static void StgRunIsImplementedInAssembler(void) "\tblr\n" : : "i"(RESERVED_C_STACK_BYTES+304 /*stack frame size*/)); } -#else // linux_TARGET_OS +#else // linux_HOST_OS #error Only linux support for power64 right now. #endif @@ -786,7 +820,7 @@ static void StgRunIsImplementedInAssembler(void) loc31: saved gp (gcc 3.3 uses this slot) -------------------------------------------------------------------------- */ -#ifdef ia64_TARGET_ARCH +#ifdef ia64_HOST_ARCH /* the memory stack is rarely used, so 16K is excessive */ #undef RESERVED_C_STACK_BYTES