diff options
author | Simon Marlow <simonmar@microsoft.com> | 2006-08-25 14:09:06 +0000 |
---|---|---|
committer | Simon Marlow <simonmar@microsoft.com> | 2006-08-25 14:09:06 +0000 |
commit | 123e4528172dc8fada65daa168cdb0175f56549f (patch) | |
tree | fd16bdc165dc5c7a8f365043f90358859020ca18 /compiler/codeGen/CgForeignCall.hs | |
parent | 30f7fffbe717563d0f68ea8e95f747aafff837ef (diff) | |
download | haskell-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.hs | 20 |
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 |