summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-03-23 13:36:39 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-03-23 13:36:39 +0000
commit7aede9b10573d1c652bf6f18e9fcaf65c2b6f656 (patch)
tree7d20819a12a21773225a2723deb7c06ce0fcaef7
parent851154f02d724ed74b0f5378d92603157b3ea69a (diff)
downloadhaskell-7aede9b10573d1c652bf6f18e9fcaf65c2b6f656.tar.gz
gcc is getting smarter, so we need to hit it with a bigger stick
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.
-rw-r--r--ghc/compiler/cmm/PprC.hs9
1 files changed, 9 insertions, 0 deletions
diff --git a/ghc/compiler/cmm/PprC.hs b/ghc/compiler/cmm/PprC.hs
index 6ce2df5bb2..51a3f07233 100644
--- a/ghc/compiler/cmm/PprC.hs
+++ b/ghc/compiler/cmm/PprC.hs
@@ -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