X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fincludes%2FTailCalls.h;h=aa2d6f9c210aba61301ffee7a285d65cb64c82a6;hb=ceefdee5e6de7ae96b461b4104c32779bbb58e53;hp=13eea0e48043f31c678c78475ebcd97bd2bb6859;hpb=153b9cb9b11e05c4edb1b6bc0a7b972660e41f70;p=ghc-hetmet.git diff --git a/ghc/includes/TailCalls.h b/ghc/includes/TailCalls.h index 13eea0e..aa2d6f9 100644 --- a/ghc/includes/TailCalls.h +++ b/ghc/includes/TailCalls.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: TailCalls.h,v 1.18 2005/01/28 12:55:54 simonmar Exp $ + * $Id: TailCalls.h,v 1.20 2005/03/08 09:01:20 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -65,9 +65,31 @@ extern void __DISCARD__(void); #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; \ + __DISCARD__(); \ __target = (void *)(cont); \ goto *__target; \ }