X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FTailCalls.h;h=670da9546f75de9df447311bef7f9edbfd293f0e;hb=a0f46309637779ccc141ec531e9b128596a5bba0;hp=05dc8528fa7ab710b0c09ac34de7b1f98e62ed49;hpb=6a9485d7f7d2c2d9f762215450c89e878ada13a4;p=ghc-hetmet.git diff --git a/ghc/includes/TailCalls.h b/ghc/includes/TailCalls.h index 05dc852..670da95 100644 --- a/ghc/includes/TailCalls.h +++ b/ghc/includes/TailCalls.h @@ -1,5 +1,4 @@ /* ----------------------------------------------------------------------------- - * $Id: TailCalls.h,v 1.14 2003/09/21 13:22:02 igloo Exp $ * * (c) The GHC Team, 1998-1999 * @@ -16,7 +15,7 @@ #ifdef USE_MINIINTERPRETER -#define JMP_(cont) return(stgCast(StgFunPtr,cont)) +#define JMP_(cont) return((StgFunPtr)(cont)) #define FB_ #define FE_ @@ -28,7 +27,7 @@ extern void __DISCARD__(void); Tail calling on x86 -------------------------------------------------------------------------- */ -#if i386_TARGET_ARCH +#if i386_HOST_ARCH /* Note about discard: possibly there to fool GCC into clearing up before we do the jump eg. if there are some arguments left on the C @@ -57,28 +56,48 @@ extern void __DISCARD__(void); goto *__target; \ } -#endif /* i386_TARGET_ARCH */ +#endif /* i386_HOST_ARCH */ /* ----------------------------------------------------------------------------- Tail calling on x86_64 -------------------------------------------------------------------------- */ -#if x86_64_TARGET_ARCH +#if x86_64_HOST_ARCH + +/* + NOTE about __DISCARD__(): + + On x86_64 this is necessary to work around bugs in the register + variable support in gcc. Without the __DISCARD__() call, gcc will + silently throw away assignements to global register variables that + happen before the jump. + + Here's the example: + + extern void g(void); + static void f(void) { + R1 = g; + __DISCARD__() + goto *R1; + } + + without the dummy function call, gcc throws away the assignment to R1 + (gcc 3.4.3) gcc bug #20359. +*/ #define JMP_(cont) \ { \ - void *__target; \ - __target = (void *)(cont); \ - goto *__target; \ + __DISCARD__(); \ + goto *(void *)(cont); \ } -#endif /* x86_64_TARGET_ARCH */ +#endif /* x86_64_HOST_ARCH */ /* ----------------------------------------------------------------------------- Tail calling on Sparc -------------------------------------------------------------------------- */ -#ifdef sparc_TARGET_ARCH +#ifdef sparc_HOST_ARCH #define JMP_(cont) ((F_) (cont))() /* Oh so happily, the above turns into a "call" instruction, @@ -90,15 +109,15 @@ extern void __DISCARD__(void); #define FB_ #define FE_ -#endif /* sparc_TARGET_ARCH */ +#endif /* sparc_HOST_ARCH */ /* ----------------------------------------------------------------------------- Tail calling on Alpha -------------------------------------------------------------------------- */ -#ifdef alpha_TARGET_ARCH +#ifdef alpha_HOST_ARCH -#ifdef IN_STG_CODE +#if IN_STG_CODE register void *_procedure __asm__("$27"); #endif @@ -112,7 +131,7 @@ register void *_procedure __asm__("$27"); #define FB_ #define FE_ -#endif /* alpha_TARGET_ARCH */ +#endif /* alpha_HOST_ARCH */ /* ----------------------------------------------------------------------------- Tail calling on HP @@ -173,7 +192,7 @@ but uses $$dyncall if necessary to cope, just in case you aren't. Tail calling on PowerPC -------------------------------------------------------------------------- */ -#ifdef powerpc_TARGET_ARCH +#ifdef powerpc_HOST_ARCH #define JMP_(cont) \ { \ @@ -201,13 +220,17 @@ but uses $$dyncall if necessary to cope, just in case you aren't. #define JMP_(cont) ((F_) (cont))() */ -#endif /* powerpc_TARGET_ARCH */ +#endif /* powerpc_HOST_ARCH */ + +#ifdef powerpc64_HOST_ARCH +#define JMP_(cont) ((F_) (cont))() +#endif /* ----------------------------------------------------------------------------- Tail calling on IA64 -------------------------------------------------------------------------- */ -#ifdef ia64_TARGET_ARCH +#ifdef ia64_HOST_ARCH /* The compiler can more intelligently decide how to do this. We therefore * implement it as a call and optimise to a jump at mangle time. */