summaryrefslogtreecommitdiff
path: root/compiler/codeGen/CgForeignCall.hs
diff options
context:
space:
mode:
authorSimon Marlow <simonmar@microsoft.com>2006-08-25 14:09:06 +0000
committerSimon Marlow <simonmar@microsoft.com>2006-08-25 14:09:06 +0000
commit123e4528172dc8fada65daa168cdb0175f56549f (patch)
treefd16bdc165dc5c7a8f365043f90358859020ca18 /compiler/codeGen/CgForeignCall.hs
parent30f7fffbe717563d0f68ea8e95f747aafff837ef (diff)
downloadhaskell-123e4528172dc8fada65daa168cdb0175f56549f.tar.gz
Load the target of a dynamic foreign call into a temporary
Fixes ffi011(opt) on x86_64. I don't know why this has only just appeared today, it's apparently been broken for some time.
Diffstat (limited to 'compiler/codeGen/CgForeignCall.hs')
-rw-r--r--compiler/codeGen/CgForeignCall.hs20
1 files changed, 15 insertions, 5 deletions
diff --git a/compiler/codeGen/CgForeignCall.hs b/compiler/codeGen/CgForeignCall.hs
index e66e1b8ead..822a04366c 100644
--- a/compiler/codeGen/CgForeignCall.hs
+++ b/compiler/codeGen/CgForeignCall.hs
@@ -110,13 +110,14 @@ emitForeignCall' safety results target args vols
| otherwise = do
id <- newTemp wordRep
temp_args <- load_args_into_temps args
+ temp_target <- load_target_into_temp target
emitSaveThreadState
stmtC (CmmCall (CmmForeignCall suspendThread CCallConv)
[(id,PtrHint)]
[ (CmmReg (CmmGlobal BaseReg), PtrHint) ]
vols
)
- stmtC (CmmCall target results temp_args vols)
+ stmtC (CmmCall temp_target results temp_args vols)
stmtC (CmmCall (CmmForeignCall resumeThread CCallConv)
[ (CmmGlobal BaseReg, PtrHint) ]
-- Assign the result to BaseReg: we
@@ -139,16 +140,25 @@ resumeThread = CmmLit (CmmLabel (mkRtsCodeLabel SLIT("resumeThread")))
--
-- This is a HACK; really it should be done in the back end, but
-- it's easier to generate the temporaries here.
-load_args_into_temps args = mapM maybe_assignTemp args
+load_args_into_temps = mapM arg_assign_temp
+ where arg_assign_temp (e,hint) = do
+ tmp <- maybe_assign_temp e
+ return (tmp,hint)
-maybe_assignTemp (e, hint)
- | hasNoGlobalRegs e = return (e, hint)
+load_target_into_temp (CmmForeignCall expr conv) = do
+ tmp <- maybe_assign_temp expr
+ return (CmmForeignCall tmp conv)
+load_target_info_temp other_target =
+ return other_target
+
+maybe_assign_temp e
+ | hasNoGlobalRegs e = return e
| otherwise = do
-- don't use assignTemp, it uses its own notion of "trivial"
-- expressions, which are wrong here
reg <- newTemp (cmmExprRep e)
stmtC (CmmAssign reg e)
- return (CmmReg reg, hint)
+ return (CmmReg reg)
-- -----------------------------------------------------------------------------
-- Save/restore the thread state in the TSO