/* -----------------------------------------------------------------------------
- * $Id: TailCalls.h,v 1.18 2005/01/28 12:55:54 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
#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_HOST_ARCH */
function and these markers is shredded by the mangler.
-------------------------------------------------------------------------- */
+#ifndef FB_
+#if __GNUC__ < 3
/* The following __DISCARD__() has become necessary with gcc 2.96 on x86.
* It prevents gcc from moving stack manipulation code from the function
* body (aka the Real Code) into the function prologue, ie, from moving it
* it just doesn't choose to do it at the moment.
* -= chak
*/
-
-#ifndef FB_
#define FB_ __asm__ volatile ("--- BEGIN ---"); __DISCARD__ ();
+#else
+/* The __DISCARD__() doesn't appear to be necessary with gcc >= 3.2 at
+ * least, and it does cause some difficulty, preventing gcc from
+ * optimising around the beginning of the function. In particular,
+ * gcc leaves some stack assignments in the prologue when the call is
+ * present. --SDM
+
+ */
+#define FB_ __asm__ volatile ("--- BEGIN ---");
+#endif
#endif
#ifndef FE_