Move the register-inplace special-case stuff into the ghc-prim package
[ghc-hetmet.git] / compiler / codeGen / CgForeignCall.hs
index 5d84da7..b3d779e 100644 (file)
@@ -1,3 +1,10 @@
+{-# OPTIONS -w #-}
+-- The above warning supression flag is a temporary kludge.
+-- While working on this module you are encouraged to remove it and fix
+-- any warnings in the module. See
+--     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
+-- for details
+
 -----------------------------------------------------------------------------
 --
 -- Code generation for foreign calls.
@@ -17,8 +24,6 @@ module CgForeignCall (
   emitOpenNursery,
  ) where
 
-#include "HsVersions.h"
-
 import StgSyn
 import CgProf
 import CgBindery
@@ -36,12 +41,7 @@ import ClosureInfo
 import Constants
 import StaticFlags
 import Outputable
-
-import MachRegs (callerSaveVolatileRegs)
-  -- HACK: this is part of the NCG so we shouldn't use this, but we need
-  -- it for now to eliminate the need for saved regs to be in CmmCall.
-  -- The long term solution is to factor callerSaveVolatileRegs
-  -- from nativeGen into codeGen
+import FastString
 
 import Control.Monad
 
@@ -49,7 +49,7 @@ import Control.Monad
 -- Code generation for Foreign Calls
 
 cgForeignCall
-       :: CmmHintFormals       -- where to put the results
+       :: CmmFormals   -- where to put the results
        -> ForeignCall          -- the op
        -> [StgArg]             -- arguments
        -> StgLiveVars  -- live vars, in case we need to save them
@@ -63,15 +63,16 @@ cgForeignCall results fcall stg_args live
                    | (stg_arg, (rep,expr)) <- stg_args `zip` reps_n_amodes, 
                       nonVoidArg rep]
 
-       arg_hints = zip arg_exprs (map (typeHint.stgArgType) stg_args)
+       arg_hints = zipWith CmmKinded
+                      arg_exprs (map (typeHint.stgArgType) stg_args)
   -- in
   emitForeignCall results fcall arg_hints live
 
 
 emitForeignCall
-       :: CmmHintFormals       -- where to put the results
+       :: CmmFormals   -- where to put the results
        -> ForeignCall          -- the op
-       -> [(CmmExpr,MachHint)] -- arguments
+       -> [CmmKinded CmmExpr] -- arguments
        -> StgLiveVars  -- live vars, in case we need to save them
        -> Code
 
@@ -79,20 +80,20 @@ emitForeignCall results (CCall (CCallSpec target cconv safety)) args live
   = do vols <- getVolatileRegs live
        srt <- getSRTInfo
        emitForeignCall' safety results
-               (CmmForeignCall cmm_target cconv) call_args (Just vols) srt
+         (CmmCallee cmm_target cconv) call_args (Just vols) srt CmmMayReturn
   where
       (call_args, cmm_target)
        = case target of
           StaticTarget lbl -> (args, CmmLit (CmmLabel 
                                        (mkForeignLabel lbl call_size False)))
-          DynamicTarget    ->  case args of (fn,_):rest -> (rest, fn)
+          DynamicTarget    ->  case args of (CmmKinded fn _):rest -> (rest, fn)
 
        -- in the stdcall calling convention, the symbol needs @size appended
        -- to it, where size is the total number of bytes of arguments.  We
        -- attach this info to the CLabel here, and the CLabel pretty printer
        -- will generate the suffix when the label is printed.
       call_size
-       | StdCallConv <- cconv = Just (sum (map (arg_size.cmmExprRep.fst) args))
+       | StdCallConv <- cconv = Just (sum (map (arg_size.cmmExprRep.kindlessCmm) args))
        | otherwise            = Nothing
 
        -- ToDo: this might not be correct for 64-bit API
@@ -105,22 +106,23 @@ emitForeignCall _ (DNCall _) _ _
 -- alternative entry point, used by CmmParse
 emitForeignCall'
        :: Safety
-       -> CmmHintFormals       -- where to put the results
+       -> CmmFormals   -- where to put the results
        -> CmmCallTarget        -- the op
-       -> [(CmmExpr,MachHint)] -- arguments
+       -> [CmmKinded CmmExpr] -- arguments
        -> Maybe [GlobalReg]    -- live vars, in case we need to save them
         -> C_SRT                -- the SRT of the calls continuation
+        -> CmmReturnInfo
        -> Code
-emitForeignCall' safety results target args vols srt
+emitForeignCall' safety results target args vols srt ret
   | not (playSafe safety) = do
     temp_args <- load_args_into_temps args
     let (caller_save, caller_load) = callerSaveVolatileRegs vols
     stmtsC caller_save
-    stmtC (CmmCall target results temp_args CmmUnsafe)
+    stmtC (CmmCall target results temp_args CmmUnsafe ret)
     stmtsC caller_load
 
   | otherwise = do
-    -- Both 'id' and 'new_base' are KindNonPtr because they're
+    -- Both 'id' and 'new_base' are GCKindNonPtr because they're
     -- RTS only objects and are not subject to garbage collection
     id <- newNonPtrTemp wordRep
     new_base <- newNonPtrTemp (cmmRegRep (CmmGlobal BaseReg))
@@ -134,23 +136,23 @@ emitForeignCall' safety results target args vols srt
     -- Once that happens, this function will just emit a (CmmSafe srt) call,
     -- and the CPS will will be the one to convert that
     -- to this sequence of three CmmUnsafe calls.
-    stmtC (CmmCall (CmmForeignCall suspendThread CCallConv) 
-                       [ (id,PtrHint) ]
-                       [ (CmmReg (CmmGlobal BaseReg), PtrHint) ] 
-                       CmmUnsafe)
-    stmtC (CmmCall temp_target results temp_args CmmUnsafe)
-    stmtC (CmmCall (CmmForeignCall resumeThread CCallConv) 
-                       [ (new_base, PtrHint) ]
-                       [ (CmmReg (CmmLocal id), PtrHint) ]
-                       CmmUnsafe)
+    stmtC (CmmCall (CmmCallee suspendThread CCallConv) 
+                       [ CmmKinded id PtrHint ]
+                       [ CmmKinded (CmmReg (CmmGlobal BaseReg)) PtrHint ] 
+                       CmmUnsafe ret)
+    stmtC (CmmCall temp_target results temp_args CmmUnsafe ret)
+    stmtC (CmmCall (CmmCallee resumeThread CCallConv) 
+                       [ CmmKinded new_base PtrHint ]
+                       [ CmmKinded (CmmReg (CmmLocal id)) PtrHint ]
+                       CmmUnsafe ret)
     -- Assign the result to BaseReg: we
     -- might now have a different Capability!
     stmtC (CmmAssign (CmmGlobal BaseReg) (CmmReg (CmmLocal new_base)))
     stmtsC caller_load
     emitLoadThreadState
 
-suspendThread = CmmLit (CmmLabel (mkRtsCodeLabel SLIT("suspendThread")))
-resumeThread  = CmmLit (CmmLabel (mkRtsCodeLabel SLIT("resumeThread")))
+suspendThread = CmmLit (CmmLabel (mkRtsCodeLabel (sLit "suspendThread")))
+resumeThread  = CmmLit (CmmLabel (mkRtsCodeLabel (sLit "resumeThread")))
 
 
 -- we might need to load arguments into temporaries before
@@ -161,13 +163,13 @@ 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 = mapM arg_assign_temp
-  where arg_assign_temp (e,hint) = do
+  where arg_assign_temp (CmmKinded e hint) = do
           tmp <- maybe_assign_temp e
-          return (tmp,hint)
+          return (CmmKinded tmp hint)
        
-load_target_into_temp (CmmForeignCall expr conv) = do 
+load_target_into_temp (CmmCallee expr conv) = do 
   tmp <- maybe_assign_temp expr
-  return (CmmForeignCall tmp conv)
+  return (CmmCallee tmp conv)
 load_target_into_temp other_target =
   return other_target