gcc is getting smarter, so we need to hit it with a bigger stick
authorSimon Marlow <simonmar@microsoft.com>
Thu, 23 Mar 2006 13:36:39 +0000 (13:36 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Thu, 23 Mar 2006 13:36:39 +0000 (13:36 +0000)
On x86_64 we are using C argument registers for global registers in
the STG machine.  This is always going to be problematic when it comes
to making C calls from STG and compiling via C.  Prior to GCC 4.1.0
(approx) it was possible to just assign the argument expressions to
temporaries to avoid a clash.  Now, we need to add an extra dummy
function call as a barrier between the temporary assignments and the
actual call.  The dummy call is removed by the mangler.

ghc/compiler/cmm/PprC.hs

index 6ce2df5..51a3f07 100644 (file)
@@ -702,6 +702,15 @@ pprCall ppr_fn cconv results args vols
   | otherwise
   = save vols $$
     ptext SLIT("CALLER_SAVE_SYSTEM") $$
+#if x86_64_TARGET_ARCH
+       -- HACK around gcc optimisations.
+       -- x86_64 needs a __DISCARD__() here, to create a barrier between
+       -- putting the arguments into temporaries and passing the arguments
+       -- to the callee, because the argument expressions may refer to
+       -- machine registers that are also used for passing arguments in the
+       -- C calling convention.
+    ptext SLIT("__DISCARD__();") $$
+#endif
     ppr_assign results (ppr_fn <> parens (commafy (map pprArg args))) <> semi $$
     ptext SLIT("CALLER_RESTORE_SYSTEM") $$
     restore vols