From 4279f83dc0258a7c1904237be913544d1be808a5 Mon Sep 17 00:00:00 2001 From: simonmar Date: Tue, 8 Mar 2005 08:59:58 +0000 Subject: [PATCH] [project @ 2005-03-08 08:59:58 by simonmar] x86_64: Add __DISCARD__() function call to the tailcall sequence to work around bugs in gcc (see comment for details). --- ghc/includes/TailCalls.h | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/ghc/includes/TailCalls.h b/ghc/includes/TailCalls.h index 13eea0e..2ab36e9 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.19 2005/03/08 08:59:58 simonmar Exp $ * * (c) The GHC Team, 1998-1999 * @@ -65,9 +65,32 @@ 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 # + +*/ + #define JMP_(cont) \ { \ void *__target; \ + __DISCARD__(); \ __target = (void *)(cont); \ goto *__target; \ } -- 1.7.10.4