import SMRep
import ForeignCall
import Constants
-import CmdLineOpts ( opt_SccProfilingOn )
+import StaticFlags ( opt_SccProfilingOn, opt_SMP )
import Outputable
import Monad ( when )
vols <- getVolatileRegs live
id <- newTemp wordRep
emitSaveThreadState
- stmtC (CmmCall (CmmForeignCall suspendThread CCallConv) [(id,NoHint)]
- [ (CmmReg (CmmGlobal BaseReg), NoHint) ]
- Nothing{-save all; ToDo-}
+ stmtC (CmmCall (CmmForeignCall suspendThread CCallConv)
+ [(id,PtrHint)]
+ [ (CmmReg (CmmGlobal BaseReg), PtrHint) ]
+ (Just vols)
)
stmtC (the_call vols)
- stmtC (CmmCall (CmmForeignCall resumeThread CCallConv) []
- [ (CmmReg id, NoHint) ] (Just vols)
+ stmtC (CmmCall (CmmForeignCall resumeThread CCallConv)
+ (if opt_SMP then [(CmmGlobal BaseReg, PtrHint)] else [])
+ -- Assign the result to BaseReg: we might now have
+ -- a different Capability! Small optimisation:
+ -- only do this in SMP mode, where there are >1
+ -- Capabilities.
+ [ (CmmReg id, PtrHint) ]
+ (Just vols)
)
emitLoadThreadState
(call_args, cmm_target)
= case target of
StaticTarget lbl -> (args, CmmLit (CmmLabel
- (mkForeignLabel lbl Nothing False)))
- -- ToDo: what about the size here?
- -- it is currently tacked on by the NCG.
+ (mkForeignLabel lbl call_size False)))
DynamicTarget -> case args of (fn,_):rest -> (rest, fn)
the_call vols = CmmCall (CmmForeignCall cmm_target cconv)
results call_args (Just vols)
+ -- 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))
+ | otherwise = Nothing
+
+ -- ToDo: this might not be correct for 64-bit API
+ arg_size rep = max (machRepByteWidth rep) wORD_SIZE
+
emitForeignCall results (DNCall _) args live
= panic "emitForeignCall: DNCall"
-- -----------------------------------------------------------------------------
-- For certain types passed to foreign calls, we adjust the actual
--- value passed to the call. Two main cases: for ForeignObj# we pass
--- the pointer inside the ForeignObj# closure, and for ByteArray#/Array# we
--- pass the address of the actual array, not the address of the heap object.
+-- value passed to the call. For ByteArray#/Array# we pass the
+-- address of the actual array, not the address of the heap object.
shimForeignCallArg :: StgArg -> CmmExpr -> CmmExpr
shimForeignCallArg arg expr
- | tycon == foreignObjPrimTyCon
- = cmmLoadIndexW expr fixedHdrSize
-
| tycon == arrayPrimTyCon || tycon == mutableArrayPrimTyCon
= cmmOffsetB expr arrPtrsHdrSize