module GHC.StgToCmm.Prim (
cgOpApp,
shouldInlinePrimOp
) where
#include "HsVersions.h"
import GHC.Prelude hiding ((<*>))
import GHC.Platform
import GHC.Platform.Profile
import GHC.StgToCmm.Layout
import GHC.StgToCmm.Foreign
import GHC.StgToCmm.Env
import GHC.StgToCmm.Monad
import GHC.StgToCmm.Utils
import GHC.StgToCmm.Ticky
import GHC.StgToCmm.Heap
import GHC.StgToCmm.Prof ( costCentreFrom )
import GHC.Driver.Session
import GHC.Driver.Backend
import GHC.Types.Basic
import GHC.Cmm.BlockId
import GHC.Cmm.Graph
import GHC.Stg.Syntax
import GHC.Cmm
import GHC.Unit ( rtsUnit )
import GHC.Core.Type ( Type, tyConAppTyCon )
import GHC.Core.TyCon
import GHC.Cmm.CLabel
import GHC.Cmm.Utils
import GHC.Builtin.PrimOps
import GHC.Runtime.Heap.Layout
import GHC.Data.FastString
import GHC.Utils.Misc
import GHC.Utils.Panic
import Data.Maybe
import Data.Bits ((.&.), bit)
import Control.Monad (liftM, when, unless)
cgOpApp :: StgOp
-> [StgArg]
-> Type
-> FCode ReturnKind
cgOpApp (StgFCallOp fcall ty) stg_args res_ty
= cgForeignCall fcall ty stg_args res_ty
cgOpApp (StgPrimOp primop) args res_ty = do
dflags <- getDynFlags
cmm_args <- getNonVoidArgAmodes args
cmmPrimOpApp dflags primop cmm_args (Just res_ty)
cgOpApp (StgPrimCallOp primcall) args _res_ty
= do { cmm_args <- getNonVoidArgAmodes args
; let fun = CmmLit (CmmLabel (mkPrimCallLabel primcall))
; emitCall (NativeNodeCall, NativeReturn) fun cmm_args }
cmmPrimOpApp :: DynFlags -> PrimOp -> [CmmExpr] -> Maybe Type -> FCode ReturnKind
cmmPrimOpApp dflags primop cmm_args mres_ty =
case emitPrimOp dflags primop cmm_args of
PrimopCmmEmit_Internal f ->
let
res_ty = fromMaybe (primOpResultType primop) mres_ty
in emitReturn =<< f res_ty
PrimopCmmEmit_External -> do
let fun = CmmLit (CmmLabel (mkRtsPrimOpLabel primop))
emitCall (NativeNodeCall, NativeReturn) fun cmm_args
asUnsigned :: Width -> Integer -> Integer
asUnsigned w n = n .&. (bit (widthInBits w) 1)
shouldInlinePrimOp :: DynFlags -> PrimOp -> [CmmExpr] -> Bool
shouldInlinePrimOp dflags op args = case emitPrimOp dflags op args of
PrimopCmmEmit_External -> False
PrimopCmmEmit_Internal _ -> True
emitPrimOp
:: DynFlags
-> PrimOp
-> [CmmExpr]
-> PrimopCmmEmit
emitPrimOp dflags primop = case primop of
NewByteArrayOp_Char -> \case
[(CmmLit (CmmInt n w))]
| asUnsigned w n <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> doNewByteArrayOp res (fromInteger n)
_ -> PrimopCmmEmit_External
NewArrayOp -> \case
[(CmmLit (CmmInt n w)), init]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \[res] -> doNewArrayOp res (arrPtrsRep platform (fromInteger n)) mkMAP_DIRTY_infoLabel
[ (mkIntExpr platform (fromInteger n),
fixedHdrSize profile + pc_OFFSET_StgMutArrPtrs_ptrs (platformConstants platform))
, (mkIntExpr platform (nonHdrSizeW (arrPtrsRep platform (fromInteger n))),
fixedHdrSize profile + pc_OFFSET_StgMutArrPtrs_size (platformConstants platform))
]
(fromInteger n) init
_ -> PrimopCmmEmit_External
CopyArrayOp -> \case
[src, src_off, dst, dst_off, (CmmLit (CmmInt n _))] ->
opIntoRegs $ \ [] -> doCopyArrayOp src src_off dst dst_off (fromInteger n)
_ -> PrimopCmmEmit_External
CopyMutableArrayOp -> \case
[src, src_off, dst, dst_off, (CmmLit (CmmInt n _))] ->
opIntoRegs $ \ [] -> doCopyMutableArrayOp src src_off dst dst_off (fromInteger n)
_ -> PrimopCmmEmit_External
CopyArrayArrayOp -> \case
[src, src_off, dst, dst_off, (CmmLit (CmmInt n _))] ->
opIntoRegs $ \ [] -> doCopyArrayOp src src_off dst dst_off (fromInteger n)
_ -> PrimopCmmEmit_External
CopyMutableArrayArrayOp -> \case
[src, src_off, dst, dst_off, (CmmLit (CmmInt n _))] ->
opIntoRegs $ \ [] -> doCopyMutableArrayOp src src_off dst dst_off (fromInteger n)
_ -> PrimopCmmEmit_External
CloneArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneArray mkMAP_FROZEN_CLEAN_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
CloneMutableArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneArray mkMAP_DIRTY_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
FreezeArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneArray mkMAP_FROZEN_CLEAN_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
ThawArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneArray mkMAP_DIRTY_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
NewSmallArrayOp -> \case
[(CmmLit (CmmInt n w)), init]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] ->
doNewArrayOp res (smallArrPtrsRep (fromInteger n)) mkSMAP_DIRTY_infoLabel
[ (mkIntExpr platform (fromInteger n),
fixedHdrSize profile + pc_OFFSET_StgSmallMutArrPtrs_ptrs (platformConstants platform))
]
(fromInteger n) init
_ -> PrimopCmmEmit_External
CopySmallArrayOp -> \case
[src, src_off, dst, dst_off, (CmmLit (CmmInt n _))] ->
opIntoRegs $ \ [] -> doCopySmallArrayOp src src_off dst dst_off (fromInteger n)
_ -> PrimopCmmEmit_External
CopySmallMutableArrayOp -> \case
[src, src_off, dst, dst_off, (CmmLit (CmmInt n _))] ->
opIntoRegs $ \ [] -> doCopySmallMutableArrayOp src src_off dst dst_off (fromInteger n)
_ -> PrimopCmmEmit_External
CloneSmallArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneSmallArray mkSMAP_FROZEN_CLEAN_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
CloneSmallMutableArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneSmallArray mkSMAP_DIRTY_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
FreezeSmallArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneSmallArray mkSMAP_FROZEN_CLEAN_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
ThawSmallArrayOp -> \case
[src, src_off, (CmmLit (CmmInt n w))]
| wordsToBytes platform (asUnsigned w n) <= fromIntegral (maxInlineAllocSize dflags)
-> opIntoRegs $ \ [res] -> emitCloneSmallArray mkSMAP_DIRTY_infoLabel res src src_off (fromInteger n)
_ -> PrimopCmmEmit_External
ParOp -> \[arg] -> opIntoRegs $ \[res] ->
emitCCall
[(res,NoHint)]
(CmmLit (CmmLabel (mkForeignLabel (fsLit "newSpark") Nothing ForeignLabelInExternalPackage IsFunction)))
[(baseExpr, AddrHint), (arg,AddrHint)]
SparkOp -> \[arg] -> opIntoRegs $ \[res] -> do
tmp <- assignTemp arg
tmp2 <- newTemp (bWord platform)
emitCCall
[(tmp2,NoHint)]
(CmmLit (CmmLabel (mkForeignLabel (fsLit "newSpark") Nothing ForeignLabelInExternalPackage IsFunction)))
[(baseExpr, AddrHint), ((CmmReg (CmmLocal tmp)), AddrHint)]
emitAssign (CmmLocal res) (CmmReg (CmmLocal tmp))
GetCCSOfOp -> \[arg] -> opIntoRegs $ \[res] -> do
let
val
| profileIsProfiling profile = costCentreFrom platform (cmmUntag platform arg)
| otherwise = CmmLit (zeroCLit platform)
emitAssign (CmmLocal res) val
GetCurrentCCSOp -> \[_] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) cccsExpr
MyThreadIdOp -> \[] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) currentTSOExpr
ReadMutVarOp -> \[mutv] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) (cmmLoadIndexW platform mutv (fixedHdrSizeW profile) (gcWord platform))
WriteMutVarOp -> \[mutv, var] -> opIntoRegs $ \res@[] -> do
old_val <- CmmLocal <$> newTemp (cmmExprType platform var)
emitAssign old_val (cmmLoadIndexW platform mutv (fixedHdrSizeW profile) (gcWord platform))
emitPrimCall res MO_WriteBarrier []
emitStore (cmmOffsetW platform mutv (fixedHdrSizeW profile)) var
emitCCall
[]
(CmmLit (CmmLabel mkDirty_MUT_VAR_Label))
[(baseExpr, AddrHint), (mutv, AddrHint), (CmmReg old_val, AddrHint)]
SizeofByteArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emit $ mkAssign (CmmLocal res) (cmmLoadIndexW platform arg (fixedHdrSizeW profile) (bWord platform))
SizeofMutableByteArrayOp -> emitPrimOp dflags SizeofByteArrayOp
GetSizeofMutableByteArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) (cmmLoadIndexW platform arg (fixedHdrSizeW profile) (bWord platform))
TouchOp -> \args@[_] -> opIntoRegs $ \res@[] ->
emitPrimCall res MO_Touch args
ByteArrayContents_Char -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) (cmmOffsetB platform arg (arrWordsHdrSize profile))
MutableByteArrayContents_Char -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) (cmmOffsetB platform arg (arrWordsHdrSize profile))
StableNameToIntOp -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) (cmmLoadIndexW platform arg (fixedHdrSizeW profile) (bWord platform))
ReallyUnsafePtrEqualityOp -> \[arg1, arg2] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) (CmmMachOp (mo_wordEq platform) [arg1,arg2])
AddrToAnyOp -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) arg
AnyToAddrOp -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) arg
UnsafeFreezeArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emit $ catAGraphs
[ setInfo arg (CmmLit (CmmLabel mkMAP_FROZEN_DIRTY_infoLabel)),
mkAssign (CmmLocal res) arg ]
UnsafeFreezeArrayArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emit $ catAGraphs
[ setInfo arg (CmmLit (CmmLabel mkMAP_FROZEN_DIRTY_infoLabel)),
mkAssign (CmmLocal res) arg ]
UnsafeFreezeSmallArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emit $ catAGraphs
[ setInfo arg (CmmLit (CmmLabel mkSMAP_FROZEN_DIRTY_infoLabel)),
mkAssign (CmmLocal res) arg ]
UnsafeFreezeByteArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emitAssign (CmmLocal res) arg
ReadArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
IndexArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
WriteArrayOp -> \[obj, ix, v] -> opIntoRegs $ \[] ->
doWritePtrArrayOp obj ix v
IndexArrayArrayOp_ByteArray -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
IndexArrayArrayOp_ArrayArray -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
ReadArrayArrayOp_ByteArray -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
ReadArrayArrayOp_MutableByteArray -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
ReadArrayArrayOp_ArrayArray -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
ReadArrayArrayOp_MutableArrayArray -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadPtrArrayOp res obj ix
WriteArrayArrayOp_ByteArray -> \[obj,ix,v] -> opIntoRegs $ \[] ->
doWritePtrArrayOp obj ix v
WriteArrayArrayOp_MutableByteArray -> \[obj,ix,v] -> opIntoRegs $ \[] ->
doWritePtrArrayOp obj ix v
WriteArrayArrayOp_ArrayArray -> \[obj,ix,v] -> opIntoRegs $ \[] ->
doWritePtrArrayOp obj ix v
WriteArrayArrayOp_MutableArrayArray -> \[obj,ix,v] -> opIntoRegs $ \[] ->
doWritePtrArrayOp obj ix v
ReadSmallArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadSmallPtrArrayOp res obj ix
IndexSmallArrayOp -> \[obj, ix] -> opIntoRegs $ \[res] ->
doReadSmallPtrArrayOp res obj ix
WriteSmallArrayOp -> \[obj,ix,v] -> opIntoRegs $ \[] ->
doWriteSmallPtrArrayOp obj ix v
SizeofArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emit $ mkAssign (CmmLocal res) (cmmLoadIndexW platform arg
(fixedHdrSizeW profile + bytesToWordsRoundUp platform (pc_OFFSET_StgMutArrPtrs_ptrs (platformConstants platform)))
(bWord platform))
SizeofMutableArrayOp -> emitPrimOp dflags SizeofArrayOp
SizeofArrayArrayOp -> emitPrimOp dflags SizeofArrayOp
SizeofMutableArrayArrayOp -> emitPrimOp dflags SizeofArrayOp
SizeofSmallArrayOp -> \[arg] -> opIntoRegs $ \[res] ->
emit $ mkAssign (CmmLocal res)
(cmmLoadIndexW platform arg
(fixedHdrSizeW profile + bytesToWordsRoundUp platform (pc_OFFSET_StgSmallMutArrPtrs_ptrs (platformConstants platform)))
(bWord platform))
SizeofSmallMutableArrayOp -> emitPrimOp dflags SizeofSmallArrayOp
GetSizeofSmallMutableArrayOp -> emitPrimOp dflags SizeofSmallArrayOp
IndexOffAddrOp_Char -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp (Just (mo_u_8ToWord platform)) b8 res args
IndexOffAddrOp_WideChar -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp (Just (mo_u_32ToWord platform)) b32 res args
IndexOffAddrOp_Int -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
IndexOffAddrOp_Word -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
IndexOffAddrOp_Addr -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
IndexOffAddrOp_Float -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing f32 res args
IndexOffAddrOp_Double -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing f64 res args
IndexOffAddrOp_StablePtr -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
IndexOffAddrOp_Int8 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b8 res args
IndexOffAddrOp_Int16 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b16 res args
IndexOffAddrOp_Int32 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b32 res args
IndexOffAddrOp_Int64 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b64 res args
IndexOffAddrOp_Word8 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b8 res args
IndexOffAddrOp_Word16 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b16 res args
IndexOffAddrOp_Word32 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b32 res args
IndexOffAddrOp_Word64 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b64 res args
ReadOffAddrOp_Char -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp (Just (mo_u_8ToWord platform)) b8 res args
ReadOffAddrOp_WideChar -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp (Just (mo_u_32ToWord platform)) b32 res args
ReadOffAddrOp_Int -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
ReadOffAddrOp_Word -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
ReadOffAddrOp_Addr -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
ReadOffAddrOp_Float -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing f32 res args
ReadOffAddrOp_Double -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing f64 res args
ReadOffAddrOp_StablePtr -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing (bWord platform) res args
ReadOffAddrOp_Int8 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b8 res args
ReadOffAddrOp_Int16 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b16 res args
ReadOffAddrOp_Int32 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b32 res args
ReadOffAddrOp_Int64 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b64 res args
ReadOffAddrOp_Word8 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b8 res args
ReadOffAddrOp_Word16 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b16 res args
ReadOffAddrOp_Word32 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b32 res args
ReadOffAddrOp_Word64 -> \args -> opIntoRegs $ \res ->
doIndexOffAddrOp Nothing b64 res args
IndexByteArrayOp_Char -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp (Just (mo_u_8ToWord platform)) b8 res args
IndexByteArrayOp_WideChar -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp (Just (mo_u_32ToWord platform)) b32 res args
IndexByteArrayOp_Int -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
IndexByteArrayOp_Word -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
IndexByteArrayOp_Addr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
IndexByteArrayOp_Float -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing f32 res args
IndexByteArrayOp_Double -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing f64 res args
IndexByteArrayOp_StablePtr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
IndexByteArrayOp_Int8 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b8 res args
IndexByteArrayOp_Int16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b16 res args
IndexByteArrayOp_Int32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b32 res args
IndexByteArrayOp_Int64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b64 res args
IndexByteArrayOp_Word8 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b8 res args
IndexByteArrayOp_Word16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b16 res args
IndexByteArrayOp_Word32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b32 res args
IndexByteArrayOp_Word64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b64 res args
ReadByteArrayOp_Char -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp (Just (mo_u_8ToWord platform)) b8 res args
ReadByteArrayOp_WideChar -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp (Just (mo_u_32ToWord platform)) b32 res args
ReadByteArrayOp_Int -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
ReadByteArrayOp_Word -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
ReadByteArrayOp_Addr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
ReadByteArrayOp_Float -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing f32 res args
ReadByteArrayOp_Double -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing f64 res args
ReadByteArrayOp_StablePtr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing (bWord platform) res args
ReadByteArrayOp_Int8 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b8 res args
ReadByteArrayOp_Int16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b16 res args
ReadByteArrayOp_Int32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b32 res args
ReadByteArrayOp_Int64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b64 res args
ReadByteArrayOp_Word8 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b8 res args
ReadByteArrayOp_Word16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b16 res args
ReadByteArrayOp_Word32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b32 res args
ReadByteArrayOp_Word64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOp Nothing b64 res args
IndexByteArrayOp_Word8AsChar -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs (Just (mo_u_8ToWord platform)) b8 b8 res args
IndexByteArrayOp_Word8AsWideChar -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs (Just (mo_u_32ToWord platform)) b32 b8 res args
IndexByteArrayOp_Word8AsInt -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
IndexByteArrayOp_Word8AsWord -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
IndexByteArrayOp_Word8AsAddr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
IndexByteArrayOp_Word8AsFloat -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing f32 b8 res args
IndexByteArrayOp_Word8AsDouble -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing f64 b8 res args
IndexByteArrayOp_Word8AsStablePtr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
IndexByteArrayOp_Word8AsInt16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b16 b8 res args
IndexByteArrayOp_Word8AsInt32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b32 b8 res args
IndexByteArrayOp_Word8AsInt64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b64 b8 res args
IndexByteArrayOp_Word8AsWord16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b16 b8 res args
IndexByteArrayOp_Word8AsWord32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b32 b8 res args
IndexByteArrayOp_Word8AsWord64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b64 b8 res args
ReadByteArrayOp_Word8AsChar -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs (Just (mo_u_8ToWord platform)) b8 b8 res args
ReadByteArrayOp_Word8AsWideChar -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs (Just (mo_u_32ToWord platform)) b32 b8 res args
ReadByteArrayOp_Word8AsInt -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
ReadByteArrayOp_Word8AsWord -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
ReadByteArrayOp_Word8AsAddr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
ReadByteArrayOp_Word8AsFloat -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing f32 b8 res args
ReadByteArrayOp_Word8AsDouble -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing f64 b8 res args
ReadByteArrayOp_Word8AsStablePtr -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing (bWord platform) b8 res args
ReadByteArrayOp_Word8AsInt16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b16 b8 res args
ReadByteArrayOp_Word8AsInt32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b32 b8 res args
ReadByteArrayOp_Word8AsInt64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b64 b8 res args
ReadByteArrayOp_Word8AsWord16 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b16 b8 res args
ReadByteArrayOp_Word8AsWord32 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b32 b8 res args
ReadByteArrayOp_Word8AsWord64 -> \args -> opIntoRegs $ \res ->
doIndexByteArrayOpAs Nothing b64 b8 res args
WriteOffAddrOp_Char -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp (Just (mo_WordTo8 platform)) b8 res args
WriteOffAddrOp_WideChar -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp (Just (mo_WordTo32 platform)) b32 res args
WriteOffAddrOp_Int -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing (bWord platform) res args
WriteOffAddrOp_Word -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing (bWord platform) res args
WriteOffAddrOp_Addr -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing (bWord platform) res args
WriteOffAddrOp_Float -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing f32 res args
WriteOffAddrOp_Double -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing f64 res args
WriteOffAddrOp_StablePtr -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing (bWord platform) res args
WriteOffAddrOp_Int8 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b8 res args
WriteOffAddrOp_Int16 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b16 res args
WriteOffAddrOp_Int32 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b32 res args
WriteOffAddrOp_Int64 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b64 res args
WriteOffAddrOp_Word8 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b8 res args
WriteOffAddrOp_Word16 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b16 res args
WriteOffAddrOp_Word32 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b32 res args
WriteOffAddrOp_Word64 -> \args -> opIntoRegs $ \res ->
doWriteOffAddrOp Nothing b64 res args
WriteByteArrayOp_Char -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp (Just (mo_WordTo8 platform)) b8 res args
WriteByteArrayOp_WideChar -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp (Just (mo_WordTo32 platform)) b32 res args
WriteByteArrayOp_Int -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing (bWord platform) res args
WriteByteArrayOp_Word -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing (bWord platform) res args
WriteByteArrayOp_Addr -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing (bWord platform) res args
WriteByteArrayOp_Float -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing f32 res args
WriteByteArrayOp_Double -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing f64 res args
WriteByteArrayOp_StablePtr -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing (bWord platform) res args
WriteByteArrayOp_Int8 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Int16 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b16 res args
WriteByteArrayOp_Int32 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b32 res args
WriteByteArrayOp_Int64 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b64 res args
WriteByteArrayOp_Word8 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word16 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b16 res args
WriteByteArrayOp_Word32 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b32 res args
WriteByteArrayOp_Word64 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b64 res args
WriteByteArrayOp_Word8AsChar -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp (Just (mo_WordTo8 platform)) b8 res args
WriteByteArrayOp_Word8AsWideChar -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp (Just (mo_WordTo32 platform)) b8 res args
WriteByteArrayOp_Word8AsInt -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsWord -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsAddr -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsFloat -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsDouble -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsStablePtr -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsInt16 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsInt32 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsInt64 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsWord16 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsWord32 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
WriteByteArrayOp_Word8AsWord64 -> \args -> opIntoRegs $ \res ->
doWriteByteArrayOp Nothing b8 res args
CopyByteArrayOp -> \[src,src_off,dst,dst_off,n] -> opIntoRegs $ \[] ->
doCopyByteArrayOp src src_off dst dst_off n
CopyMutableByteArrayOp -> \[src,src_off,dst,dst_off,n] -> opIntoRegs $ \[] ->
doCopyMutableByteArrayOp src src_off dst dst_off n
CopyByteArrayToAddrOp -> \[src,src_off,dst,n] -> opIntoRegs $ \[] ->
doCopyByteArrayToAddrOp src src_off dst n
CopyMutableByteArrayToAddrOp -> \[src,src_off,dst,n] -> opIntoRegs $ \[] ->
doCopyMutableByteArrayToAddrOp src src_off dst n
CopyAddrToByteArrayOp -> \[src,dst,dst_off,n] -> opIntoRegs $ \[] ->
doCopyAddrToByteArrayOp src dst dst_off n
SetByteArrayOp -> \[ba,off,len,c] -> opIntoRegs $ \[] ->
doSetByteArrayOp ba off len c
CompareByteArraysOp -> \[ba1,ba1_off,ba2,ba2_off,n] -> opIntoRegs $ \[res] ->
doCompareByteArraysOp res ba1 ba1_off ba2 ba2_off n
BSwap16Op -> \[w] -> opIntoRegs $ \[res] ->
emitBSwapCall res w W16
BSwap32Op -> \[w] -> opIntoRegs $ \[res] ->
emitBSwapCall res w W32
BSwap64Op -> \[w] -> opIntoRegs $ \[res] ->
emitBSwapCall res w W64
BSwapOp -> \[w] -> opIntoRegs $ \[res] ->
emitBSwapCall res w (wordWidth platform)
BRev8Op -> \[w] -> opIntoRegs $ \[res] ->
emitBRevCall res w W8
BRev16Op -> \[w] -> opIntoRegs $ \[res] ->
emitBRevCall res w W16
BRev32Op -> \[w] -> opIntoRegs $ \[res] ->
emitBRevCall res w W32
BRev64Op -> \[w] -> opIntoRegs $ \[res] ->
emitBRevCall res w W64
BRevOp -> \[w] -> opIntoRegs $ \[res] ->
emitBRevCall res w (wordWidth platform)
PopCnt8Op -> \[w] -> opIntoRegs $ \[res] ->
emitPopCntCall res w W8
PopCnt16Op -> \[w] -> opIntoRegs $ \[res] ->
emitPopCntCall res w W16
PopCnt32Op -> \[w] -> opIntoRegs $ \[res] ->
emitPopCntCall res w W32
PopCnt64Op -> \[w] -> opIntoRegs $ \[res] ->
emitPopCntCall res w W64
PopCntOp -> \[w] -> opIntoRegs $ \[res] ->
emitPopCntCall res w (wordWidth platform)
Pdep8Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPdepCall res src mask W8
Pdep16Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPdepCall res src mask W16
Pdep32Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPdepCall res src mask W32
Pdep64Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPdepCall res src mask W64
PdepOp -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPdepCall res src mask (wordWidth platform)
Pext8Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPextCall res src mask W8
Pext16Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPextCall res src mask W16
Pext32Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPextCall res src mask W32
Pext64Op -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPextCall res src mask W64
PextOp -> \[src, mask] -> opIntoRegs $ \[res] ->
emitPextCall res src mask (wordWidth platform)
Clz8Op -> \[w] -> opIntoRegs $ \[res] ->
emitClzCall res w W8
Clz16Op -> \[w] -> opIntoRegs $ \[res] ->
emitClzCall res w W16
Clz32Op -> \[w] -> opIntoRegs $ \[res] ->
emitClzCall res w W32
Clz64Op -> \[w] -> opIntoRegs $ \[res] ->
emitClzCall res w W64
ClzOp -> \[w] -> opIntoRegs $ \[res] ->
emitClzCall res w (wordWidth platform)
Ctz8Op -> \[w] -> opIntoRegs $ \[res] ->
emitCtzCall res w W8
Ctz16Op -> \[w] -> opIntoRegs $ \[res] ->
emitCtzCall res w W16
Ctz32Op -> \[w] -> opIntoRegs $ \[res] ->
emitCtzCall res w W32
Ctz64Op -> \[w] -> opIntoRegs $ \[res] ->
emitCtzCall res w W64
CtzOp -> \[w] -> opIntoRegs $ \[res] ->
emitCtzCall res w (wordWidth platform)
WordToFloatOp -> \[w] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_UF_Conv W32) [w]
WordToDoubleOp -> \[w] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_UF_Conv W64) [w]
InterlockedExchange_Addr -> \[src, value] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value]
InterlockedExchange_Word -> \[src, value] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value]
FetchAddAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->
doAtomicAddrRMW res AMO_Add addr (bWord platform) n
FetchSubAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->
doAtomicAddrRMW res AMO_Sub addr (bWord platform) n
FetchAndAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->
doAtomicAddrRMW res AMO_And addr (bWord platform) n
FetchNandAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->
doAtomicAddrRMW res AMO_Nand addr (bWord platform) n
FetchOrAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->
doAtomicAddrRMW res AMO_Or addr (bWord platform) n
FetchXorAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->
doAtomicAddrRMW res AMO_Xor addr (bWord platform) n
AtomicReadAddrOp_Word -> \[addr] -> opIntoRegs $ \[res] ->
doAtomicReadAddr res addr (bWord platform)
AtomicWriteAddrOp_Word -> \[addr, val] -> opIntoRegs $ \[] ->
doAtomicWriteAddr addr (bWord platform) val
CasAddrOp_Addr -> \[dst, expected, new] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Cmpxchg (wordWidth platform)) [dst, expected, new]
CasAddrOp_Word -> \[dst, expected, new] -> opIntoRegs $ \[res] ->
emitPrimCall [res] (MO_Cmpxchg (wordWidth platform)) [dst, expected, new]
(VecBroadcastOp vcat n w) -> \[e] -> opIntoRegs $ \[res] -> do
checkVecCompatibility dflags vcat n w
doVecPackOp (vecElemInjectCast platform vcat w) ty zeros (replicate n e) res
where
zeros :: CmmExpr
zeros = CmmLit $ CmmVec (replicate n zero)
zero :: CmmLit
zero = case vcat of
IntVec -> CmmInt 0 w
WordVec -> CmmInt 0 w
FloatVec -> CmmFloat 0 w
ty :: CmmType
ty = vecVmmType vcat n w
(VecPackOp vcat n w) -> \es -> opIntoRegs $ \[res] -> do
checkVecCompatibility dflags vcat n w
when (es `lengthIsNot` n) $
panic "emitPrimOp: VecPackOp has wrong number of arguments"
doVecPackOp (vecElemInjectCast platform vcat w) ty zeros es res
where
zeros :: CmmExpr
zeros = CmmLit $ CmmVec (replicate n zero)
zero :: CmmLit
zero = case vcat of
IntVec -> CmmInt 0 w
WordVec -> CmmInt 0 w
FloatVec -> CmmFloat 0 w
ty :: CmmType
ty = vecVmmType vcat n w
(VecUnpackOp vcat n w) -> \[arg] -> opIntoRegs $ \res -> do
checkVecCompatibility dflags vcat n w
when (res `lengthIsNot` n) $
panic "emitPrimOp: VecUnpackOp has wrong number of results"
doVecUnpackOp (vecElemProjectCast platform vcat w) ty arg res
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecInsertOp vcat n w) -> \[v,e,i] -> opIntoRegs $ \[res] -> do
checkVecCompatibility dflags vcat n w
doVecInsertOp (vecElemInjectCast platform vcat w) ty v e i res
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecIndexByteArrayOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexByteArrayOp Nothing ty res0 args
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecReadByteArrayOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexByteArrayOp Nothing ty res0 args
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecWriteByteArrayOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doWriteByteArrayOp Nothing ty res0 args
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecIndexOffAddrOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexOffAddrOp Nothing ty res0 args
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecReadOffAddrOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexOffAddrOp Nothing ty res0 args
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecWriteOffAddrOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doWriteOffAddrOp Nothing ty res0 args
where
ty :: CmmType
ty = vecVmmType vcat n w
(VecIndexScalarByteArrayOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexByteArrayOpAs Nothing vecty ty res0 args
where
vecty :: CmmType
vecty = vecVmmType vcat n w
ty :: CmmType
ty = vecCmmCat vcat w
(VecReadScalarByteArrayOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexByteArrayOpAs Nothing vecty ty res0 args
where
vecty :: CmmType
vecty = vecVmmType vcat n w
ty :: CmmType
ty = vecCmmCat vcat w
(VecWriteScalarByteArrayOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doWriteByteArrayOp Nothing ty res0 args
where
ty :: CmmType
ty = vecCmmCat vcat w
(VecIndexScalarOffAddrOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexOffAddrOpAs Nothing vecty ty res0 args
where
vecty :: CmmType
vecty = vecVmmType vcat n w
ty :: CmmType
ty = vecCmmCat vcat w
(VecReadScalarOffAddrOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doIndexOffAddrOpAs Nothing vecty ty res0 args
where
vecty :: CmmType
vecty = vecVmmType vcat n w
ty :: CmmType
ty = vecCmmCat vcat w
(VecWriteScalarOffAddrOp vcat n w) -> \args -> opIntoRegs $ \res0 -> do
checkVecCompatibility dflags vcat n w
doWriteOffAddrOp Nothing ty res0 args
where
ty :: CmmType
ty = vecCmmCat vcat w
PrefetchByteArrayOp3 -> \args -> opIntoRegs $ \[] ->
doPrefetchByteArrayOp 3 args
PrefetchMutableByteArrayOp3 -> \args -> opIntoRegs $ \[] ->
doPrefetchMutableByteArrayOp 3 args
PrefetchAddrOp3 -> \args -> opIntoRegs $ \[] ->
doPrefetchAddrOp 3 args
PrefetchValueOp3 -> \args -> opIntoRegs $ \[] ->
doPrefetchValueOp 3 args
PrefetchByteArrayOp2 -> \args -> opIntoRegs $ \[] ->
doPrefetchByteArrayOp 2 args
PrefetchMutableByteArrayOp2 -> \args -> opIntoRegs $ \[] ->
doPrefetchMutableByteArrayOp 2 args
PrefetchAddrOp2 -> \args -> opIntoRegs $ \[] ->
doPrefetchAddrOp 2 args
PrefetchValueOp2 -> \args -> opIntoRegs $ \[] ->
doPrefetchValueOp 2 args
PrefetchByteArrayOp1 -> \args -> opIntoRegs $ \[] ->
doPrefetchByteArrayOp 1 args
PrefetchMutableByteArrayOp1 -> \args -> opIntoRegs $ \[] ->
doPrefetchMutableByteArrayOp 1 args
PrefetchAddrOp1 -> \args -> opIntoRegs $ \[] ->
doPrefetchAddrOp 1 args
PrefetchValueOp1 -> \args -> opIntoRegs $ \[] ->
doPrefetchValueOp 1 args
PrefetchByteArrayOp0 -> \args -> opIntoRegs $ \[] ->
doPrefetchByteArrayOp 0 args
PrefetchMutableByteArrayOp0 -> \args -> opIntoRegs $ \[] ->
doPrefetchMutableByteArrayOp 0 args
PrefetchAddrOp0 -> \args -> opIntoRegs $ \[] ->
doPrefetchAddrOp 0 args
PrefetchValueOp0 -> \args -> opIntoRegs $ \[] ->
doPrefetchValueOp 0 args
FetchAddByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->
doAtomicByteArrayRMW res AMO_Add mba ix (bWord platform) n
FetchSubByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->
doAtomicByteArrayRMW res AMO_Sub mba ix (bWord platform) n
FetchAndByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->
doAtomicByteArrayRMW res AMO_And mba ix (bWord platform) n
FetchNandByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->
doAtomicByteArrayRMW res AMO_Nand mba ix (bWord platform) n
FetchOrByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->
doAtomicByteArrayRMW res AMO_Or mba ix (bWord platform) n
FetchXorByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->
doAtomicByteArrayRMW res AMO_Xor mba ix (bWord platform) n
AtomicReadByteArrayOp_Int -> \[mba, ix] -> opIntoRegs $ \[res] ->
doAtomicReadByteArray res mba ix (bWord platform)
AtomicWriteByteArrayOp_Int -> \[mba, ix, val] -> opIntoRegs $ \[] ->
doAtomicWriteByteArray mba ix (bWord platform) val
CasByteArrayOp_Int -> \[mba, ix, old, new] -> opIntoRegs $ \[res] ->
doCasByteArray res mba ix (bWord platform) old new
Int8ToWord8Op -> \args -> opNop args
Word8ToInt8Op -> \args -> opNop args
Int16ToWord16Op -> \args -> opNop args
Word16ToInt16Op -> \args -> opNop args
Int32ToWord32Op -> \args -> opNop args
Word32ToInt32Op -> \args -> opNop args
IntToWordOp -> \args -> opNop args
WordToIntOp -> \args -> opNop args
IntToAddrOp -> \args -> opNop args
AddrToIntOp -> \args -> opNop args
ChrOp -> \args -> opNop args
OrdOp -> \args -> opNop args
Narrow8IntOp -> \args -> opNarrow args (MO_SS_Conv, W8)
Narrow16IntOp -> \args -> opNarrow args (MO_SS_Conv, W16)
Narrow32IntOp -> \args -> opNarrow args (MO_SS_Conv, W32)
Narrow8WordOp -> \args -> opNarrow args (MO_UU_Conv, W8)
Narrow16WordOp -> \args -> opNarrow args (MO_UU_Conv, W16)
Narrow32WordOp -> \args -> opNarrow args (MO_UU_Conv, W32)
DoublePowerOp -> \args -> opCallish args MO_F64_Pwr
DoubleSinOp -> \args -> opCallish args MO_F64_Sin
DoubleCosOp -> \args -> opCallish args MO_F64_Cos
DoubleTanOp -> \args -> opCallish args MO_F64_Tan
DoubleSinhOp -> \args -> opCallish args MO_F64_Sinh
DoubleCoshOp -> \args -> opCallish args MO_F64_Cosh
DoubleTanhOp -> \args -> opCallish args MO_F64_Tanh
DoubleAsinOp -> \args -> opCallish args MO_F64_Asin
DoubleAcosOp -> \args -> opCallish args MO_F64_Acos
DoubleAtanOp -> \args -> opCallish args MO_F64_Atan
DoubleAsinhOp -> \args -> opCallish args MO_F64_Asinh
DoubleAcoshOp -> \args -> opCallish args MO_F64_Acosh
DoubleAtanhOp -> \args -> opCallish args MO_F64_Atanh
DoubleLogOp -> \args -> opCallish args MO_F64_Log
DoubleLog1POp -> \args -> opCallish args MO_F64_Log1P
DoubleExpOp -> \args -> opCallish args MO_F64_Exp
DoubleExpM1Op -> \args -> opCallish args MO_F64_ExpM1
DoubleSqrtOp -> \args -> opCallish args MO_F64_Sqrt
FloatPowerOp -> \args -> opCallish args MO_F32_Pwr
FloatSinOp -> \args -> opCallish args MO_F32_Sin
FloatCosOp -> \args -> opCallish args MO_F32_Cos
FloatTanOp -> \args -> opCallish args MO_F32_Tan
FloatSinhOp -> \args -> opCallish args MO_F32_Sinh
FloatCoshOp -> \args -> opCallish args MO_F32_Cosh
FloatTanhOp -> \args -> opCallish args MO_F32_Tanh
FloatAsinOp -> \args -> opCallish args MO_F32_Asin
FloatAcosOp -> \args -> opCallish args MO_F32_Acos
FloatAtanOp -> \args -> opCallish args MO_F32_Atan
FloatAsinhOp -> \args -> opCallish args MO_F32_Asinh
FloatAcoshOp -> \args -> opCallish args MO_F32_Acosh
FloatAtanhOp -> \args -> opCallish args MO_F32_Atanh
FloatLogOp -> \args -> opCallish args MO_F32_Log
FloatLog1POp -> \args -> opCallish args MO_F32_Log1P
FloatExpOp -> \args -> opCallish args MO_F32_Exp
FloatExpM1Op -> \args -> opCallish args MO_F32_ExpM1
FloatSqrtOp -> \args -> opCallish args MO_F32_Sqrt
IntAddOp -> \args -> opTranslate args (mo_wordAdd platform)
IntSubOp -> \args -> opTranslate args (mo_wordSub platform)
WordAddOp -> \args -> opTranslate args (mo_wordAdd platform)
WordSubOp -> \args -> opTranslate args (mo_wordSub platform)
AddrAddOp -> \args -> opTranslate args (mo_wordAdd platform)
AddrSubOp -> \args -> opTranslate args (mo_wordSub platform)
IntEqOp -> \args -> opTranslate args (mo_wordEq platform)
IntNeOp -> \args -> opTranslate args (mo_wordNe platform)
WordEqOp -> \args -> opTranslate args (mo_wordEq platform)
WordNeOp -> \args -> opTranslate args (mo_wordNe platform)
AddrEqOp -> \args -> opTranslate args (mo_wordEq platform)
AddrNeOp -> \args -> opTranslate args (mo_wordNe platform)
WordAndOp -> \args -> opTranslate args (mo_wordAnd platform)
WordOrOp -> \args -> opTranslate args (mo_wordOr platform)
WordXorOp -> \args -> opTranslate args (mo_wordXor platform)
WordNotOp -> \args -> opTranslate args (mo_wordNot platform)
WordSllOp -> \args -> opTranslate args (mo_wordShl platform)
WordSrlOp -> \args -> opTranslate args (mo_wordUShr platform)
AddrRemOp -> \args -> opTranslate args (mo_wordURem platform)
IntMulOp -> \args -> opTranslate args (mo_wordMul platform)
IntMulMayOfloOp -> \args -> opTranslate args (MO_S_MulMayOflo (wordWidth platform))
IntQuotOp -> \args -> opTranslate args (mo_wordSQuot platform)
IntRemOp -> \args -> opTranslate args (mo_wordSRem platform)
IntNegOp -> \args -> opTranslate args (mo_wordSNeg platform)
IntGeOp -> \args -> opTranslate args (mo_wordSGe platform)
IntLeOp -> \args -> opTranslate args (mo_wordSLe platform)
IntGtOp -> \args -> opTranslate args (mo_wordSGt platform)
IntLtOp -> \args -> opTranslate args (mo_wordSLt platform)
IntAndOp -> \args -> opTranslate args (mo_wordAnd platform)
IntOrOp -> \args -> opTranslate args (mo_wordOr platform)
IntXorOp -> \args -> opTranslate args (mo_wordXor platform)
IntNotOp -> \args -> opTranslate args (mo_wordNot platform)
IntSllOp -> \args -> opTranslate args (mo_wordShl platform)
IntSraOp -> \args -> opTranslate args (mo_wordSShr platform)
IntSrlOp -> \args -> opTranslate args (mo_wordUShr platform)
WordGeOp -> \args -> opTranslate args (mo_wordUGe platform)
WordLeOp -> \args -> opTranslate args (mo_wordULe platform)
WordGtOp -> \args -> opTranslate args (mo_wordUGt platform)
WordLtOp -> \args -> opTranslate args (mo_wordULt platform)
WordMulOp -> \args -> opTranslate args (mo_wordMul platform)
WordQuotOp -> \args -> opTranslate args (mo_wordUQuot platform)
WordRemOp -> \args -> opTranslate args (mo_wordURem platform)
AddrGeOp -> \args -> opTranslate args (mo_wordUGe platform)
AddrLeOp -> \args -> opTranslate args (mo_wordULe platform)
AddrGtOp -> \args -> opTranslate args (mo_wordUGt platform)
AddrLtOp -> \args -> opTranslate args (mo_wordULt platform)
Int8ToIntOp -> \args -> opTranslate args (MO_SS_Conv W8 (wordWidth platform))
IntToInt8Op -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W8)
Int8NegOp -> \args -> opTranslate args (MO_S_Neg W8)
Int8AddOp -> \args -> opTranslate args (MO_Add W8)
Int8SubOp -> \args -> opTranslate args (MO_Sub W8)
Int8MulOp -> \args -> opTranslate args (MO_Mul W8)
Int8QuotOp -> \args -> opTranslate args (MO_S_Quot W8)
Int8RemOp -> \args -> opTranslate args (MO_S_Rem W8)
Int8SllOp -> \args -> opTranslate args (MO_Shl W8)
Int8SraOp -> \args -> opTranslate args (MO_S_Shr W8)
Int8SrlOp -> \args -> opTranslate args (MO_U_Shr W8)
Int8EqOp -> \args -> opTranslate args (MO_Eq W8)
Int8GeOp -> \args -> opTranslate args (MO_S_Ge W8)
Int8GtOp -> \args -> opTranslate args (MO_S_Gt W8)
Int8LeOp -> \args -> opTranslate args (MO_S_Le W8)
Int8LtOp -> \args -> opTranslate args (MO_S_Lt W8)
Int8NeOp -> \args -> opTranslate args (MO_Ne W8)
Word8ToWordOp -> \args -> opTranslate args (MO_UU_Conv W8 (wordWidth platform))
WordToWord8Op -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W8)
Word8AddOp -> \args -> opTranslate args (MO_Add W8)
Word8SubOp -> \args -> opTranslate args (MO_Sub W8)
Word8MulOp -> \args -> opTranslate args (MO_Mul W8)
Word8QuotOp -> \args -> opTranslate args (MO_U_Quot W8)
Word8RemOp -> \args -> opTranslate args (MO_U_Rem W8)
Word8AndOp -> \args -> opTranslate args (MO_And W8)
Word8OrOp -> \args -> opTranslate args (MO_Or W8)
Word8XorOp -> \args -> opTranslate args (MO_Xor W8)
Word8NotOp -> \args -> opTranslate args (MO_Not W8)
Word8SllOp -> \args -> opTranslate args (MO_Shl W8)
Word8SrlOp -> \args -> opTranslate args (MO_U_Shr W8)
Word8EqOp -> \args -> opTranslate args (MO_Eq W8)
Word8GeOp -> \args -> opTranslate args (MO_U_Ge W8)
Word8GtOp -> \args -> opTranslate args (MO_U_Gt W8)
Word8LeOp -> \args -> opTranslate args (MO_U_Le W8)
Word8LtOp -> \args -> opTranslate args (MO_U_Lt W8)
Word8NeOp -> \args -> opTranslate args (MO_Ne W8)
Int16ToIntOp -> \args -> opTranslate args (MO_SS_Conv W16 (wordWidth platform))
IntToInt16Op -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W16)
Int16NegOp -> \args -> opTranslate args (MO_S_Neg W16)
Int16AddOp -> \args -> opTranslate args (MO_Add W16)
Int16SubOp -> \args -> opTranslate args (MO_Sub W16)
Int16MulOp -> \args -> opTranslate args (MO_Mul W16)
Int16QuotOp -> \args -> opTranslate args (MO_S_Quot W16)
Int16RemOp -> \args -> opTranslate args (MO_S_Rem W16)
Int16SllOp -> \args -> opTranslate args (MO_Shl W16)
Int16SraOp -> \args -> opTranslate args (MO_S_Shr W16)
Int16SrlOp -> \args -> opTranslate args (MO_U_Shr W16)
Int16EqOp -> \args -> opTranslate args (MO_Eq W16)
Int16GeOp -> \args -> opTranslate args (MO_S_Ge W16)
Int16GtOp -> \args -> opTranslate args (MO_S_Gt W16)
Int16LeOp -> \args -> opTranslate args (MO_S_Le W16)
Int16LtOp -> \args -> opTranslate args (MO_S_Lt W16)
Int16NeOp -> \args -> opTranslate args (MO_Ne W16)
Word16ToWordOp -> \args -> opTranslate args (MO_UU_Conv W16 (wordWidth platform))
WordToWord16Op -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W16)
Word16AddOp -> \args -> opTranslate args (MO_Add W16)
Word16SubOp -> \args -> opTranslate args (MO_Sub W16)
Word16MulOp -> \args -> opTranslate args (MO_Mul W16)
Word16QuotOp -> \args -> opTranslate args (MO_U_Quot W16)
Word16RemOp -> \args -> opTranslate args (MO_U_Rem W16)
Word16AndOp -> \args -> opTranslate args (MO_And W16)
Word16OrOp -> \args -> opTranslate args (MO_Or W16)
Word16XorOp -> \args -> opTranslate args (MO_Xor W16)
Word16NotOp -> \args -> opTranslate args (MO_Not W16)
Word16SllOp -> \args -> opTranslate args (MO_Shl W16)
Word16SrlOp -> \args -> opTranslate args (MO_U_Shr W16)
Word16EqOp -> \args -> opTranslate args (MO_Eq W16)
Word16GeOp -> \args -> opTranslate args (MO_U_Ge W16)
Word16GtOp -> \args -> opTranslate args (MO_U_Gt W16)
Word16LeOp -> \args -> opTranslate args (MO_U_Le W16)
Word16LtOp -> \args -> opTranslate args (MO_U_Lt W16)
Word16NeOp -> \args -> opTranslate args (MO_Ne W16)
Int32ToIntOp -> \args -> opTranslate args (MO_SS_Conv W32 (wordWidth platform))
IntToInt32Op -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W32)
Int32NegOp -> \args -> opTranslate args (MO_S_Neg W32)
Int32AddOp -> \args -> opTranslate args (MO_Add W32)
Int32SubOp -> \args -> opTranslate args (MO_Sub W32)
Int32MulOp -> \args -> opTranslate args (MO_Mul W32)
Int32QuotOp -> \args -> opTranslate args (MO_S_Quot W32)
Int32RemOp -> \args -> opTranslate args (MO_S_Rem W32)
Int32SllOp -> \args -> opTranslate args (MO_Shl W32)
Int32SraOp -> \args -> opTranslate args (MO_S_Shr W32)
Int32SrlOp -> \args -> opTranslate args (MO_U_Shr W32)
Int32EqOp -> \args -> opTranslate args (MO_Eq W32)
Int32GeOp -> \args -> opTranslate args (MO_S_Ge W32)
Int32GtOp -> \args -> opTranslate args (MO_S_Gt W32)
Int32LeOp -> \args -> opTranslate args (MO_S_Le W32)
Int32LtOp -> \args -> opTranslate args (MO_S_Lt W32)
Int32NeOp -> \args -> opTranslate args (MO_Ne W32)
Word32ToWordOp -> \args -> opTranslate args (MO_UU_Conv W32 (wordWidth platform))
WordToWord32Op -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W32)
Word32AddOp -> \args -> opTranslate args (MO_Add W32)
Word32SubOp -> \args -> opTranslate args (MO_Sub W32)
Word32MulOp -> \args -> opTranslate args (MO_Mul W32)
Word32QuotOp -> \args -> opTranslate args (MO_U_Quot W32)
Word32RemOp -> \args -> opTranslate args (MO_U_Rem W32)
Word32AndOp -> \args -> opTranslate args (MO_And W32)
Word32OrOp -> \args -> opTranslate args (MO_Or W32)
Word32XorOp -> \args -> opTranslate args (MO_Xor W32)
Word32NotOp -> \args -> opTranslate args (MO_Not W32)
Word32SllOp -> \args -> opTranslate args (MO_Shl W32)
Word32SrlOp -> \args -> opTranslate args (MO_U_Shr W32)
Word32EqOp -> \args -> opTranslate args (MO_Eq W32)
Word32GeOp -> \args -> opTranslate args (MO_U_Ge W32)
Word32GtOp -> \args -> opTranslate args (MO_U_Gt W32)
Word32LeOp -> \args -> opTranslate args (MO_U_Le W32)
Word32LtOp -> \args -> opTranslate args (MO_U_Lt W32)
Word32NeOp -> \args -> opTranslate args (MO_Ne W32)
CharEqOp -> \args -> opTranslate args (MO_Eq (wordWidth platform))
CharNeOp -> \args -> opTranslate args (MO_Ne (wordWidth platform))
CharGeOp -> \args -> opTranslate args (MO_U_Ge (wordWidth platform))
CharLeOp -> \args -> opTranslate args (MO_U_Le (wordWidth platform))
CharGtOp -> \args -> opTranslate args (MO_U_Gt (wordWidth platform))
CharLtOp -> \args -> opTranslate args (MO_U_Lt (wordWidth platform))
DoubleEqOp -> \args -> opTranslate args (MO_F_Eq W64)
DoubleNeOp -> \args -> opTranslate args (MO_F_Ne W64)
DoubleGeOp -> \args -> opTranslate args (MO_F_Ge W64)
DoubleLeOp -> \args -> opTranslate args (MO_F_Le W64)
DoubleGtOp -> \args -> opTranslate args (MO_F_Gt W64)
DoubleLtOp -> \args -> opTranslate args (MO_F_Lt W64)
DoubleAddOp -> \args -> opTranslate args (MO_F_Add W64)
DoubleSubOp -> \args -> opTranslate args (MO_F_Sub W64)
DoubleMulOp -> \args -> opTranslate args (MO_F_Mul W64)
DoubleDivOp -> \args -> opTranslate args (MO_F_Quot W64)
DoubleNegOp -> \args -> opTranslate args (MO_F_Neg W64)
FloatEqOp -> \args -> opTranslate args (MO_F_Eq W32)
FloatNeOp -> \args -> opTranslate args (MO_F_Ne W32)
FloatGeOp -> \args -> opTranslate args (MO_F_Ge W32)
FloatLeOp -> \args -> opTranslate args (MO_F_Le W32)
FloatGtOp -> \args -> opTranslate args (MO_F_Gt W32)
FloatLtOp -> \args -> opTranslate args (MO_F_Lt W32)
FloatAddOp -> \args -> opTranslate args (MO_F_Add W32)
FloatSubOp -> \args -> opTranslate args (MO_F_Sub W32)
FloatMulOp -> \args -> opTranslate args (MO_F_Mul W32)
FloatDivOp -> \args -> opTranslate args (MO_F_Quot W32)
FloatNegOp -> \args -> opTranslate args (MO_F_Neg W32)
(VecAddOp FloatVec n w) -> \args -> opTranslate args (MO_VF_Add n w)
(VecSubOp FloatVec n w) -> \args -> opTranslate args (MO_VF_Sub n w)
(VecMulOp FloatVec n w) -> \args -> opTranslate args (MO_VF_Mul n w)
(VecDivOp FloatVec n w) -> \args -> opTranslate args (MO_VF_Quot n w)
(VecQuotOp FloatVec _ _) -> \_ -> panic "unsupported primop"
(VecRemOp FloatVec _ _) -> \_ -> panic "unsupported primop"
(VecNegOp FloatVec n w) -> \args -> opTranslate args (MO_VF_Neg n w)
(VecAddOp IntVec n w) -> \args -> opTranslate args (MO_V_Add n w)
(VecSubOp IntVec n w) -> \args -> opTranslate args (MO_V_Sub n w)
(VecMulOp IntVec n w) -> \args -> opTranslate args (MO_V_Mul n w)
(VecDivOp IntVec _ _) -> \_ -> panic "unsupported primop"
(VecQuotOp IntVec n w) -> \args -> opTranslate args (MO_VS_Quot n w)
(VecRemOp IntVec n w) -> \args -> opTranslate args (MO_VS_Rem n w)
(VecNegOp IntVec n w) -> \args -> opTranslate args (MO_VS_Neg n w)
(VecAddOp WordVec n w) -> \args -> opTranslate args (MO_V_Add n w)
(VecSubOp WordVec n w) -> \args -> opTranslate args (MO_V_Sub n w)
(VecMulOp WordVec n w) -> \args -> opTranslate args (MO_V_Mul n w)
(VecDivOp WordVec _ _) -> \_ -> panic "unsupported primop"
(VecQuotOp WordVec n w) -> \args -> opTranslate args (MO_VU_Quot n w)
(VecRemOp WordVec n w) -> \args -> opTranslate args (MO_VU_Rem n w)
(VecNegOp WordVec _ _) -> \_ -> panic "unsupported primop"
IntToDoubleOp -> \args -> opTranslate args (MO_SF_Conv (wordWidth platform) W64)
DoubleToIntOp -> \args -> opTranslate args (MO_FS_Conv W64 (wordWidth platform))
IntToFloatOp -> \args -> opTranslate args (MO_SF_Conv (wordWidth platform) W32)
FloatToIntOp -> \args -> opTranslate args (MO_FS_Conv W32 (wordWidth platform))
FloatToDoubleOp -> \args -> opTranslate args (MO_FF_Conv W32 W64)
DoubleToFloatOp -> \args -> opTranslate args (MO_FF_Conv W64 W32)
SameMutVarOp -> \args -> opTranslate args (mo_wordEq platform)
SameMVarOp -> \args -> opTranslate args (mo_wordEq platform)
SameIOPortOp -> \args -> opTranslate args (mo_wordEq platform)
SameMutableArrayOp -> \args -> opTranslate args (mo_wordEq platform)
SameMutableByteArrayOp -> \args -> opTranslate args (mo_wordEq platform)
SameMutableArrayArrayOp -> \args -> opTranslate args (mo_wordEq platform)
SameSmallMutableArrayOp -> \args -> opTranslate args (mo_wordEq platform)
SameTVarOp -> \args -> opTranslate args (mo_wordEq platform)
EqStablePtrOp -> \args -> opTranslate args (mo_wordEq platform)
EqStableNameOp -> \args -> opTranslate args (mo_wordEq platform)
IntQuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_S_QuotRem (wordWidth platform))
else Right (genericIntQuotRemOp (wordWidth platform))
Int8QuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_S_QuotRem W8)
else Right (genericIntQuotRemOp W8)
Int16QuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_S_QuotRem W16)
else Right (genericIntQuotRemOp W16)
Int32QuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_S_QuotRem W32)
else Right (genericIntQuotRemOp W32)
WordQuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_U_QuotRem (wordWidth platform))
else Right (genericWordQuotRemOp (wordWidth platform))
WordQuotRem2Op -> \args -> opCallishHandledLater args $
if (ncg && (x86ish || ppc)) || llvm
then Left (MO_U_QuotRem2 (wordWidth platform))
else Right (genericWordQuotRem2Op platform)
Word8QuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_U_QuotRem W8)
else Right (genericWordQuotRemOp W8)
Word16QuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_U_QuotRem W16)
else Right (genericWordQuotRemOp W16)
Word32QuotRemOp -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) && not (quotRemCanBeOptimized args)
then Left (MO_U_QuotRem W32)
else Right (genericWordQuotRemOp W32)
WordAdd2Op -> \args -> opCallishHandledLater args $
if (ncg && (x86ish || ppc)) || llvm
then Left (MO_Add2 (wordWidth platform))
else Right genericWordAdd2Op
WordAddCOp -> \args -> opCallishHandledLater args $
if (ncg && (x86ish || ppc)) || llvm
then Left (MO_AddWordC (wordWidth platform))
else Right genericWordAddCOp
WordSubCOp -> \args -> opCallishHandledLater args $
if (ncg && (x86ish || ppc)) || llvm
then Left (MO_SubWordC (wordWidth platform))
else Right genericWordSubCOp
IntAddCOp -> \args -> opCallishHandledLater args $
if (ncg && (x86ish || ppc)) || llvm
then Left (MO_AddIntC (wordWidth platform))
else Right genericIntAddCOp
IntSubCOp -> \args -> opCallishHandledLater args $
if (ncg && (x86ish || ppc)) || llvm
then Left (MO_SubIntC (wordWidth platform))
else Right genericIntSubCOp
WordMul2Op -> \args -> opCallishHandledLater args $
if ncg && (x86ish || ppc) || llvm
then Left (MO_U_Mul2 (wordWidth platform))
else Right genericWordMul2Op
IntMul2Op -> \args -> opCallishHandledLater args $
if ncg && x86ish || llvm
then Left (MO_S_Mul2 (wordWidth platform))
else Right genericIntMul2Op
FloatFabsOp -> \args -> opCallishHandledLater args $
if (ncg && x86ish || ppc) || llvm
then Left MO_F32_Fabs
else Right $ genericFabsOp W32
DoubleFabsOp -> \args -> opCallishHandledLater args $
if (ncg && x86ish || ppc) || llvm
then Left MO_F64_Fabs
else Right $ genericFabsOp W64
TagToEnumOp -> \[amode] -> PrimopCmmEmit_Internal $ \res_ty -> do
let tycon = tyConAppTyCon res_ty
MASSERT(isEnumerationTyCon tycon)
platform <- getPlatform
pure [tagToClosure platform tycon amode]
UnsafeThawArrayOp -> alwaysExternal
CasArrayOp -> alwaysExternal
UnsafeThawSmallArrayOp -> alwaysExternal
CasSmallArrayOp -> alwaysExternal
NewPinnedByteArrayOp_Char -> alwaysExternal
NewAlignedPinnedByteArrayOp_Char -> alwaysExternal
MutableByteArrayIsPinnedOp -> alwaysExternal
DoubleDecode_2IntOp -> alwaysExternal
DoubleDecode_Int64Op -> alwaysExternal
FloatDecode_IntOp -> alwaysExternal
ByteArrayIsPinnedOp -> alwaysExternal
ShrinkMutableByteArrayOp_Char -> alwaysExternal
ResizeMutableByteArrayOp_Char -> alwaysExternal
ShrinkSmallMutableArrayOp_Char -> alwaysExternal
NewArrayArrayOp -> alwaysExternal
NewMutVarOp -> alwaysExternal
AtomicModifyMutVar2Op -> alwaysExternal
AtomicModifyMutVar_Op -> alwaysExternal
CasMutVarOp -> alwaysExternal
CatchOp -> alwaysExternal
RaiseOp -> alwaysExternal
RaiseIOOp -> alwaysExternal
MaskAsyncExceptionsOp -> alwaysExternal
MaskUninterruptibleOp -> alwaysExternal
UnmaskAsyncExceptionsOp -> alwaysExternal
MaskStatus -> alwaysExternal
AtomicallyOp -> alwaysExternal
RetryOp -> alwaysExternal
CatchRetryOp -> alwaysExternal
CatchSTMOp -> alwaysExternal
NewTVarOp -> alwaysExternal
ReadTVarOp -> alwaysExternal
ReadTVarIOOp -> alwaysExternal
WriteTVarOp -> alwaysExternal
NewMVarOp -> alwaysExternal
TakeMVarOp -> alwaysExternal
TryTakeMVarOp -> alwaysExternal
PutMVarOp -> alwaysExternal
TryPutMVarOp -> alwaysExternal
ReadMVarOp -> alwaysExternal
TryReadMVarOp -> alwaysExternal
IsEmptyMVarOp -> alwaysExternal
NewIOPortrOp -> alwaysExternal
ReadIOPortOp -> alwaysExternal
WriteIOPortOp -> alwaysExternal
DelayOp -> alwaysExternal
WaitReadOp -> alwaysExternal
WaitWriteOp -> alwaysExternal
ForkOp -> alwaysExternal
ForkOnOp -> alwaysExternal
KillThreadOp -> alwaysExternal
YieldOp -> alwaysExternal
LabelThreadOp -> alwaysExternal
IsCurrentThreadBoundOp -> alwaysExternal
NoDuplicateOp -> alwaysExternal
ThreadStatusOp -> alwaysExternal
MkWeakOp -> alwaysExternal
MkWeakNoFinalizerOp -> alwaysExternal
AddCFinalizerToWeakOp -> alwaysExternal
DeRefWeakOp -> alwaysExternal
FinalizeWeakOp -> alwaysExternal
MakeStablePtrOp -> alwaysExternal
DeRefStablePtrOp -> alwaysExternal
MakeStableNameOp -> alwaysExternal
CompactNewOp -> alwaysExternal
CompactResizeOp -> alwaysExternal
CompactContainsOp -> alwaysExternal
CompactContainsAnyOp -> alwaysExternal
CompactGetFirstBlockOp -> alwaysExternal
CompactGetNextBlockOp -> alwaysExternal
CompactAllocateBlockOp -> alwaysExternal
CompactFixupPointersOp -> alwaysExternal
CompactAdd -> alwaysExternal
CompactAddWithSharing -> alwaysExternal
CompactSize -> alwaysExternal
SeqOp -> alwaysExternal
GetSparkOp -> alwaysExternal
NumSparks -> alwaysExternal
DataToTagOp -> alwaysExternal
MkApUpd0_Op -> alwaysExternal
NewBCOOp -> alwaysExternal
UnpackClosureOp -> alwaysExternal
ClosureSizeOp -> alwaysExternal
WhereFromOp -> alwaysExternal
GetApStackValOp -> alwaysExternal
ClearCCSOp -> alwaysExternal
TraceEventOp -> alwaysExternal
TraceEventBinaryOp -> alwaysExternal
TraceMarkerOp -> alwaysExternal
SetThreadAllocationCounter -> alwaysExternal
KeepAliveOp -> panic "keepAlive# should have been eliminated in CorePrep"
where
profile = targetProfile dflags
platform = profilePlatform profile
result_info = getPrimOpResultInfo primop
opNop :: [CmmExpr] -> PrimopCmmEmit
opNop args = opIntoRegs $ \[res] -> emitAssign (CmmLocal res) arg
where [arg] = args
opNarrow
:: [CmmExpr]
-> (Width -> Width -> MachOp, Width)
-> PrimopCmmEmit
opNarrow args (mop, rep) = opIntoRegs $ \[res] -> emitAssign (CmmLocal res) $
CmmMachOp (mop rep (wordWidth platform)) [CmmMachOp (mop (wordWidth platform) rep) [arg]]
where [arg] = args
opCallish :: [CmmExpr] -> CallishMachOp -> PrimopCmmEmit
opCallish args prim = opIntoRegs $ \[res] -> emitPrimCall [res] prim args
opTranslate :: [CmmExpr] -> MachOp -> PrimopCmmEmit
opTranslate args mop = opIntoRegs $ \[res] -> do
let stmt = mkAssign (CmmLocal res) (CmmMachOp mop args)
emit stmt
opCallishHandledLater
:: [CmmExpr]
-> Either CallishMachOp GenericOp
-> PrimopCmmEmit
opCallishHandledLater args callOrNot = opIntoRegs $ \res0 -> case callOrNot of
Left op -> emit $ mkUnsafeCall (PrimTarget op) res0 args
Right gen -> gen res0 args
opIntoRegs
:: ([LocalReg]
-> FCode ())
-> PrimopCmmEmit
opIntoRegs f = PrimopCmmEmit_Internal $ \res_ty -> do
regs <- case result_info of
ReturnsPrim VoidRep -> pure []
ReturnsPrim rep
-> do reg <- newTemp (primRepCmmType platform rep)
pure [reg]
ReturnsAlg tycon | isUnboxedTupleTyCon tycon
-> do (regs, _hints) <- newUnboxedTupleRegs res_ty
pure regs
_ -> panic "cgOpApp"
f regs
pure $ map (CmmReg . CmmLocal) regs
alwaysExternal = \_ -> PrimopCmmEmit_External
quotRemCanBeOptimized = \case
[_, CmmLit (CmmInt n _) ] -> isJust (exactLog2 n)
_ -> False
ncg = backend dflags == NCG
llvm = backend dflags == LLVM
x86ish = case platformArch platform of
ArchX86 -> True
ArchX86_64 -> True
_ -> False
ppc = case platformArch platform of
ArchPPC -> True
ArchPPC_64 _ -> True
_ -> False
data PrimopCmmEmit
= PrimopCmmEmit_External
| PrimopCmmEmit_Internal (Type
-> FCode [CmmExpr])
type GenericOp = [CmmFormal] -> [CmmActual] -> FCode ()
genericIntQuotRemOp :: Width -> GenericOp
genericIntQuotRemOp width [res_q, res_r] [arg_x, arg_y]
= emit $ mkAssign (CmmLocal res_q)
(CmmMachOp (MO_S_Quot width) [arg_x, arg_y]) <*>
mkAssign (CmmLocal res_r)
(CmmMachOp (MO_S_Rem width) [arg_x, arg_y])
genericIntQuotRemOp _ _ _ = panic "genericIntQuotRemOp"
genericWordQuotRemOp :: Width -> GenericOp
genericWordQuotRemOp width [res_q, res_r] [arg_x, arg_y]
= emit $ mkAssign (CmmLocal res_q)
(CmmMachOp (MO_U_Quot width) [arg_x, arg_y]) <*>
mkAssign (CmmLocal res_r)
(CmmMachOp (MO_U_Rem width) [arg_x, arg_y])
genericWordQuotRemOp _ _ _ = panic "genericWordQuotRemOp"
genericWordQuotRem2Op :: Platform -> GenericOp
genericWordQuotRem2Op platform [res_q, res_r] [arg_x_high, arg_x_low, arg_y]
= emit =<< f (widthInBits (wordWidth platform)) zero arg_x_high arg_x_low
where ty = cmmExprType platform arg_x_high
shl x i = CmmMachOp (MO_Shl (wordWidth platform)) [x, i]
shr x i = CmmMachOp (MO_U_Shr (wordWidth platform)) [x, i]
or x y = CmmMachOp (MO_Or (wordWidth platform)) [x, y]
ge x y = CmmMachOp (MO_U_Ge (wordWidth platform)) [x, y]
ne x y = CmmMachOp (MO_Ne (wordWidth platform)) [x, y]
minus x y = CmmMachOp (MO_Sub (wordWidth platform)) [x, y]
times x y = CmmMachOp (MO_Mul (wordWidth platform)) [x, y]
zero = lit 0
one = lit 1
negone = lit (fromIntegral (platformWordSizeInBits platform) 1)
lit i = CmmLit (CmmInt i (wordWidth platform))
f :: Int -> CmmExpr -> CmmExpr -> CmmExpr -> FCode CmmAGraph
f 0 acc high _ = return (mkAssign (CmmLocal res_q) acc <*>
mkAssign (CmmLocal res_r) high)
f i acc high low =
do roverflowedBit <- newTemp ty
rhigh' <- newTemp ty
rhigh'' <- newTemp ty
rlow' <- newTemp ty
risge <- newTemp ty
racc' <- newTemp ty
let high' = CmmReg (CmmLocal rhigh')
isge = CmmReg (CmmLocal risge)
overflowedBit = CmmReg (CmmLocal roverflowedBit)
let this = catAGraphs
[mkAssign (CmmLocal roverflowedBit)
(shr high negone),
mkAssign (CmmLocal rhigh')
(or (shl high one) (shr low negone)),
mkAssign (CmmLocal rlow')
(shl low one),
mkAssign (CmmLocal risge)
(or (overflowedBit `ne` zero)
(high' `ge` arg_y)),
mkAssign (CmmLocal rhigh'')
(high' `minus` (arg_y `times` isge)),
mkAssign (CmmLocal racc')
(or (shl acc one) isge)]
rest <- f (i 1) (CmmReg (CmmLocal racc'))
(CmmReg (CmmLocal rhigh''))
(CmmReg (CmmLocal rlow'))
return (this <*> rest)
genericWordQuotRem2Op _ _ _ = panic "genericWordQuotRem2Op"
genericWordAdd2Op :: GenericOp
genericWordAdd2Op [res_h, res_l] [arg_x, arg_y]
= do platform <- getPlatform
r1 <- newTemp (cmmExprType platform arg_x)
r2 <- newTemp (cmmExprType platform arg_x)
let topHalf x = CmmMachOp (MO_U_Shr (wordWidth platform)) [x, hww]
toTopHalf x = CmmMachOp (MO_Shl (wordWidth platform)) [x, hww]
bottomHalf x = CmmMachOp (MO_And (wordWidth platform)) [x, hwm]
add x y = CmmMachOp (MO_Add (wordWidth platform)) [x, y]
or x y = CmmMachOp (MO_Or (wordWidth platform)) [x, y]
hww = CmmLit (CmmInt (fromIntegral (widthInBits (halfWordWidth platform)))
(wordWidth platform))
hwm = CmmLit (CmmInt (halfWordMask platform) (wordWidth platform))
emit $ catAGraphs
[mkAssign (CmmLocal r1)
(add (bottomHalf arg_x) (bottomHalf arg_y)),
mkAssign (CmmLocal r2)
(add (topHalf (CmmReg (CmmLocal r1)))
(add (topHalf arg_x) (topHalf arg_y))),
mkAssign (CmmLocal res_h)
(topHalf (CmmReg (CmmLocal r2))),
mkAssign (CmmLocal res_l)
(or (toTopHalf (CmmReg (CmmLocal r2)))
(bottomHalf (CmmReg (CmmLocal r1))))]
genericWordAdd2Op _ _ = panic "genericWordAdd2Op"
genericWordAddCOp :: GenericOp
genericWordAddCOp [res_r, res_c] [aa, bb]
= do platform <- getPlatform
emit $ catAGraphs [
mkAssign (CmmLocal res_r) (CmmMachOp (mo_wordAdd platform) [aa,bb]),
mkAssign (CmmLocal res_c) $
CmmMachOp (mo_wordUShr platform) [
CmmMachOp (mo_wordOr platform) [
CmmMachOp (mo_wordAnd platform) [aa,bb],
CmmMachOp (mo_wordAnd platform) [
CmmMachOp (mo_wordOr platform) [aa,bb],
CmmMachOp (mo_wordNot platform) [CmmReg (CmmLocal res_r)]
]
],
mkIntExpr platform (platformWordSizeInBits platform 1)
]
]
genericWordAddCOp _ _ = panic "genericWordAddCOp"
genericWordSubCOp :: GenericOp
genericWordSubCOp [res_r, res_c] [aa, bb]
= do platform <- getPlatform
emit $ catAGraphs [
mkAssign (CmmLocal res_r) (CmmMachOp (mo_wordSub platform) [aa,bb]),
mkAssign (CmmLocal res_c) $
CmmMachOp (mo_wordUShr platform) [
CmmMachOp (mo_wordOr platform) [
CmmMachOp (mo_wordAnd platform) [
CmmMachOp (mo_wordNot platform) [aa],
bb
],
CmmMachOp (mo_wordAnd platform) [
CmmMachOp (mo_wordOr platform) [
CmmMachOp (mo_wordNot platform) [aa],
bb
],
CmmReg (CmmLocal res_r)
]
],
mkIntExpr platform (platformWordSizeInBits platform 1)
]
]
genericWordSubCOp _ _ = panic "genericWordSubCOp"
genericIntAddCOp :: GenericOp
genericIntAddCOp [res_r, res_c] [aa, bb]
= do platform <- getPlatform
emit $ catAGraphs [
mkAssign (CmmLocal res_r) (CmmMachOp (mo_wordAdd platform) [aa,bb]),
mkAssign (CmmLocal res_c) $
CmmMachOp (mo_wordUShr platform) [
CmmMachOp (mo_wordAnd platform) [
CmmMachOp (mo_wordNot platform) [CmmMachOp (mo_wordXor platform) [aa,bb]],
CmmMachOp (mo_wordXor platform) [aa, CmmReg (CmmLocal res_r)]
],
mkIntExpr platform (platformWordSizeInBits platform 1)
]
]
genericIntAddCOp _ _ = panic "genericIntAddCOp"
genericIntSubCOp :: GenericOp
genericIntSubCOp [res_r, res_c] [aa, bb]
= do platform <- getPlatform
emit $ catAGraphs [
mkAssign (CmmLocal res_r) (CmmMachOp (mo_wordSub platform) [aa,bb]),
mkAssign (CmmLocal res_c) $
CmmMachOp (mo_wordUShr platform) [
CmmMachOp (mo_wordAnd platform) [
CmmMachOp (mo_wordXor platform) [aa,bb],
CmmMachOp (mo_wordXor platform) [aa, CmmReg (CmmLocal res_r)]
],
mkIntExpr platform (platformWordSizeInBits platform 1)
]
]
genericIntSubCOp _ _ = panic "genericIntSubCOp"
genericWordMul2Op :: GenericOp
genericWordMul2Op [res_h, res_l] [arg_x, arg_y]
= do platform <- getPlatform
let t = cmmExprType platform arg_x
xlyl <- liftM CmmLocal $ newTemp t
xlyh <- liftM CmmLocal $ newTemp t
xhyl <- liftM CmmLocal $ newTemp t
r <- liftM CmmLocal $ newTemp t
let topHalf x = CmmMachOp (MO_U_Shr (wordWidth platform)) [x, hww]
toTopHalf x = CmmMachOp (MO_Shl (wordWidth platform)) [x, hww]
bottomHalf x = CmmMachOp (MO_And (wordWidth platform)) [x, hwm]
add x y = CmmMachOp (MO_Add (wordWidth platform)) [x, y]
sum = foldl1 add
mul x y = CmmMachOp (MO_Mul (wordWidth platform)) [x, y]
or x y = CmmMachOp (MO_Or (wordWidth platform)) [x, y]
hww = CmmLit (CmmInt (fromIntegral (widthInBits (halfWordWidth platform)))
(wordWidth platform))
hwm = CmmLit (CmmInt (halfWordMask platform) (wordWidth platform))
emit $ catAGraphs
[mkAssign xlyl
(mul (bottomHalf arg_x) (bottomHalf arg_y)),
mkAssign xlyh
(mul (bottomHalf arg_x) (topHalf arg_y)),
mkAssign xhyl
(mul (topHalf arg_x) (bottomHalf arg_y)),
mkAssign r
(sum [topHalf (CmmReg xlyl),
bottomHalf (CmmReg xhyl),
bottomHalf (CmmReg xlyh)]),
mkAssign (CmmLocal res_l)
(or (bottomHalf (CmmReg xlyl))
(toTopHalf (CmmReg r))),
mkAssign (CmmLocal res_h)
(sum [mul (topHalf arg_x) (topHalf arg_y),
topHalf (CmmReg xhyl),
topHalf (CmmReg xlyh),
topHalf (CmmReg r)])]
genericWordMul2Op _ _ = panic "genericWordMul2Op"
genericIntMul2Op :: GenericOp
genericIntMul2Op [res_c, res_h, res_l] both_args@[arg_x, arg_y]
= do dflags <- getDynFlags
platform <- getPlatform
let t = cmmExprType platform arg_x
p <- newTemp t
_ <- withSequel (AssignTo [p, res_l] False) $
cmmPrimOpApp dflags WordMul2Op both_args Nothing
let carryFill x = CmmMachOp (MO_S_Shr ww) [x, wwm1]
sub x y = CmmMachOp (MO_Sub ww) [x, y]
and x y = CmmMachOp (MO_And ww) [x, y]
neq x y = CmmMachOp (MO_Ne ww) [x, y]
f x y = (carryFill x) `and` y
wwm1 = CmmLit (CmmInt (fromIntegral (widthInBits ww 1)) ww)
rl x = CmmReg (CmmLocal x)
ww = wordWidth platform
emit $ catAGraphs
[ mkAssign (CmmLocal res_h) (rl p `sub` f arg_x arg_y `sub` f arg_y arg_x)
, mkAssign (CmmLocal res_c) (rl res_h `neq` carryFill (rl res_l))
]
genericIntMul2Op _ _ = panic "genericIntMul2Op"
genericFabsOp :: Width -> GenericOp
genericFabsOp w [res_r] [aa]
= do platform <- getPlatform
let zero = CmmLit (CmmFloat 0 w)
eq x y = CmmMachOp (MO_F_Eq w) [x, y]
gt x y = CmmMachOp (MO_F_Gt w) [x, y]
neg x = CmmMachOp (MO_F_Neg w) [x]
g1 = catAGraphs [mkAssign (CmmLocal res_r) zero]
g2 = catAGraphs [mkAssign (CmmLocal res_r) aa]
res_t <- CmmLocal <$> newTemp (cmmExprType platform aa)
let g3 = catAGraphs [mkAssign res_t aa,
mkAssign (CmmLocal res_r) (neg (CmmReg res_t))]
g4 <- mkCmmIfThenElse (gt aa zero) g2 g3
emit =<< mkCmmIfThenElse (eq aa zero) g1 g4
genericFabsOp _ _ _ = panic "genericFabsOp"
doIndexOffAddrOp :: Maybe MachOp
-> CmmType
-> [LocalReg]
-> [CmmExpr]
-> FCode ()
doIndexOffAddrOp maybe_post_read_cast rep [res] [addr,idx]
= mkBasicIndexedRead 0 maybe_post_read_cast rep res addr rep idx
doIndexOffAddrOp _ _ _ _
= panic "GHC.StgToCmm.Prim: doIndexOffAddrOp"
doIndexOffAddrOpAs :: Maybe MachOp
-> CmmType
-> CmmType
-> [LocalReg]
-> [CmmExpr]
-> FCode ()
doIndexOffAddrOpAs maybe_post_read_cast rep idx_rep [res] [addr,idx]
= mkBasicIndexedRead 0 maybe_post_read_cast rep res addr idx_rep idx
doIndexOffAddrOpAs _ _ _ _ _
= panic "GHC.StgToCmm.Prim: doIndexOffAddrOpAs"
doIndexByteArrayOp :: Maybe MachOp
-> CmmType
-> [LocalReg]
-> [CmmExpr]
-> FCode ()
doIndexByteArrayOp maybe_post_read_cast rep [res] [addr,idx]
= do profile <- getProfile
mkBasicIndexedRead (arrWordsHdrSize profile) maybe_post_read_cast rep res addr rep idx
doIndexByteArrayOp _ _ _ _
= panic "GHC.StgToCmm.Prim: doIndexByteArrayOp"
doIndexByteArrayOpAs :: Maybe MachOp
-> CmmType
-> CmmType
-> [LocalReg]
-> [CmmExpr]
-> FCode ()
doIndexByteArrayOpAs maybe_post_read_cast rep idx_rep [res] [addr,idx]
= do profile <- getProfile
mkBasicIndexedRead (arrWordsHdrSize profile) maybe_post_read_cast rep res addr idx_rep idx
doIndexByteArrayOpAs _ _ _ _ _
= panic "GHC.StgToCmm.Prim: doIndexByteArrayOpAs"
doReadPtrArrayOp :: LocalReg
-> CmmExpr
-> CmmExpr
-> FCode ()
doReadPtrArrayOp res addr idx
= do profile <- getProfile
platform <- getPlatform
mkBasicIndexedRead (arrPtrsHdrSize profile) Nothing (gcWord platform) res addr (gcWord platform) idx
doWriteOffAddrOp :: Maybe MachOp
-> CmmType
-> [LocalReg]
-> [CmmExpr]
-> FCode ()
doWriteOffAddrOp maybe_pre_write_cast idx_ty [] [addr,idx,val]
= mkBasicIndexedWrite 0 maybe_pre_write_cast addr idx_ty idx val
doWriteOffAddrOp _ _ _ _
= panic "GHC.StgToCmm.Prim: doWriteOffAddrOp"
doWriteByteArrayOp :: Maybe MachOp
-> CmmType
-> [LocalReg]
-> [CmmExpr]
-> FCode ()
doWriteByteArrayOp maybe_pre_write_cast idx_ty [] [addr,idx,val]
= do profile <- getProfile
mkBasicIndexedWrite (arrWordsHdrSize profile) maybe_pre_write_cast addr idx_ty idx val
doWriteByteArrayOp _ _ _ _
= panic "GHC.StgToCmm.Prim: doWriteByteArrayOp"
doWritePtrArrayOp :: CmmExpr
-> CmmExpr
-> CmmExpr
-> FCode ()
doWritePtrArrayOp addr idx val
= do profile <- getProfile
platform <- getPlatform
let ty = cmmExprType platform val
hdr_size = arrPtrsHdrSize profile
whenUpdRemSetEnabled
$ emitUpdRemSetPush (cmmLoadIndexOffExpr platform hdr_size ty addr ty idx)
emitPrimCall [] MO_WriteBarrier []
mkBasicIndexedWrite hdr_size Nothing addr ty idx val
emit (setInfo addr (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
emit $ mkStore (
cmmOffsetExpr platform
(cmmOffsetExprW platform (cmmOffsetB platform addr hdr_size)
(loadArrPtrsSize profile addr))
(CmmMachOp (mo_wordUShr platform) [idx,
mkIntExpr platform (pc_MUT_ARR_PTRS_CARD_BITS (platformConstants platform))])
) (CmmLit (CmmInt 1 W8))
loadArrPtrsSize :: Profile -> CmmExpr -> CmmExpr
loadArrPtrsSize profile addr = CmmLoad (cmmOffsetB platform addr off) (bWord platform)
where off = fixedHdrSize profile + pc_OFFSET_StgMutArrPtrs_ptrs (profileConstants profile)
platform = profilePlatform profile
mkBasicIndexedRead :: ByteOff
-> Maybe MachOp
-> CmmType
-> LocalReg
-> CmmExpr
-> CmmType
-> CmmExpr
-> FCode ()
mkBasicIndexedRead off Nothing ty res base idx_ty idx
= do platform <- getPlatform
emitAssign (CmmLocal res) (cmmLoadIndexOffExpr platform off ty base idx_ty idx)
mkBasicIndexedRead off (Just cast) ty res base idx_ty idx
= do platform <- getPlatform
emitAssign (CmmLocal res) (CmmMachOp cast [
cmmLoadIndexOffExpr platform off ty base idx_ty idx])
mkBasicIndexedWrite :: ByteOff
-> Maybe MachOp
-> CmmExpr
-> CmmType
-> CmmExpr
-> CmmExpr
-> FCode ()
mkBasicIndexedWrite off Nothing base idx_ty idx val
= do platform <- getPlatform
emitStore (cmmIndexOffExpr platform off (typeWidth idx_ty) base idx) val
mkBasicIndexedWrite off (Just cast) base idx_ty idx val
= mkBasicIndexedWrite off Nothing base idx_ty idx (CmmMachOp cast [val])
cmmIndexOffExpr :: Platform
-> ByteOff
-> Width
-> CmmExpr
-> CmmExpr
-> CmmExpr
cmmIndexOffExpr platform off width base idx
= cmmIndexExpr platform width (cmmOffsetB platform base off) idx
cmmLoadIndexOffExpr :: Platform
-> ByteOff
-> CmmType
-> CmmExpr
-> CmmType
-> CmmExpr
-> CmmExpr
cmmLoadIndexOffExpr platform off ty base idx_ty idx
= CmmLoad (cmmIndexOffExpr platform off (typeWidth idx_ty) base idx) ty
setInfo :: CmmExpr -> CmmExpr -> CmmAGraph
setInfo closure_ptr info_ptr = mkStore closure_ptr info_ptr
vecVmmType :: PrimOpVecCat -> Length -> Width -> CmmType
vecVmmType pocat n w = vec n (vecCmmCat pocat w)
vecCmmCat :: PrimOpVecCat -> Width -> CmmType
vecCmmCat IntVec = cmmBits
vecCmmCat WordVec = cmmBits
vecCmmCat FloatVec = cmmFloat
vecElemInjectCast :: Platform -> PrimOpVecCat -> Width -> Maybe MachOp
vecElemInjectCast _ FloatVec _ = Nothing
vecElemInjectCast platform IntVec W8 = Just (mo_WordTo8 platform)
vecElemInjectCast platform IntVec W16 = Just (mo_WordTo16 platform)
vecElemInjectCast platform IntVec W32 = Just (mo_WordTo32 platform)
vecElemInjectCast _ IntVec W64 = Nothing
vecElemInjectCast platform WordVec W8 = Just (mo_WordTo8 platform)
vecElemInjectCast platform WordVec W16 = Just (mo_WordTo16 platform)
vecElemInjectCast platform WordVec W32 = Just (mo_WordTo32 platform)
vecElemInjectCast _ WordVec W64 = Nothing
vecElemInjectCast _ _ _ = Nothing
vecElemProjectCast :: Platform -> PrimOpVecCat -> Width -> Maybe MachOp
vecElemProjectCast _ FloatVec _ = Nothing
vecElemProjectCast platform IntVec W8 = Just (mo_s_8ToWord platform)
vecElemProjectCast platform IntVec W16 = Just (mo_s_16ToWord platform)
vecElemProjectCast platform IntVec W32 = Just (mo_s_32ToWord platform)
vecElemProjectCast _ IntVec W64 = Nothing
vecElemProjectCast platform WordVec W8 = Just (mo_u_8ToWord platform)
vecElemProjectCast platform WordVec W16 = Just (mo_u_16ToWord platform)
vecElemProjectCast platform WordVec W32 = Just (mo_u_32ToWord platform)
vecElemProjectCast _ WordVec W64 = Nothing
vecElemProjectCast _ _ _ = Nothing
checkVecCompatibility :: DynFlags -> PrimOpVecCat -> Length -> Width -> FCode ()
checkVecCompatibility dflags vcat l w = do
when (backend dflags /= LLVM) $
sorry $ unlines ["SIMD vector instructions require the LLVM back-end."
,"Please use -fllvm."]
check vecWidth vcat l w
where
platform = targetPlatform dflags
check :: Width -> PrimOpVecCat -> Length -> Width -> FCode ()
check W128 FloatVec 4 W32 | not (isSseEnabled platform) =
sorry $ "128-bit wide single-precision floating point " ++
"SIMD vector instructions require at least -msse."
check W128 _ _ _ | not (isSse2Enabled platform) =
sorry $ "128-bit wide integer and double precision " ++
"SIMD vector instructions require at least -msse2."
check W256 FloatVec _ _ | not (isAvxEnabled dflags) =
sorry $ "256-bit wide floating point " ++
"SIMD vector instructions require at least -mavx."
check W256 _ _ _ | not (isAvx2Enabled dflags) =
sorry $ "256-bit wide integer " ++
"SIMD vector instructions require at least -mavx2."
check W512 _ _ _ | not (isAvx512fEnabled dflags) =
sorry $ "512-bit wide " ++
"SIMD vector instructions require -mavx512f."
check _ _ _ _ = return ()
vecWidth = typeWidth (vecVmmType vcat l w)
doVecPackOp :: Maybe MachOp
-> CmmType
-> CmmExpr
-> [CmmExpr]
-> CmmFormal
-> FCode ()
doVecPackOp maybe_pre_write_cast ty z es res = do
dst <- newTemp ty
emitAssign (CmmLocal dst) z
vecPack dst es 0
where
vecPack :: CmmFormal -> [CmmExpr] -> Int -> FCode ()
vecPack src [] _ =
emitAssign (CmmLocal res) (CmmReg (CmmLocal src))
vecPack src (e : es) i = do
dst <- newTemp ty
if isFloatType (vecElemType ty)
then emitAssign (CmmLocal dst) (CmmMachOp (MO_VF_Insert len wid)
[CmmReg (CmmLocal src), cast e, iLit])
else emitAssign (CmmLocal dst) (CmmMachOp (MO_V_Insert len wid)
[CmmReg (CmmLocal src), cast e, iLit])
vecPack dst es (i + 1)
where
iLit = CmmLit (CmmInt (toInteger i) W32)
cast :: CmmExpr -> CmmExpr
cast val = case maybe_pre_write_cast of
Nothing -> val
Just cast -> CmmMachOp cast [val]
len :: Length
len = vecLength ty
wid :: Width
wid = typeWidth (vecElemType ty)
doVecUnpackOp :: Maybe MachOp
-> CmmType
-> CmmExpr
-> [CmmFormal]
-> FCode ()
doVecUnpackOp maybe_post_read_cast ty e res =
vecUnpack res 0
where
vecUnpack :: [CmmFormal] -> Int -> FCode ()
vecUnpack [] _ =
return ()
vecUnpack (r : rs) i = do
if isFloatType (vecElemType ty)
then emitAssign (CmmLocal r) (cast (CmmMachOp (MO_VF_Extract len wid)
[e, iLit]))
else emitAssign (CmmLocal r) (cast (CmmMachOp (MO_V_Extract len wid)
[e, iLit]))
vecUnpack rs (i + 1)
where
iLit = CmmLit (CmmInt (toInteger i) W32)
cast :: CmmExpr -> CmmExpr
cast val = case maybe_post_read_cast of
Nothing -> val
Just cast -> CmmMachOp cast [val]
len :: Length
len = vecLength ty
wid :: Width
wid = typeWidth (vecElemType ty)
doVecInsertOp :: Maybe MachOp
-> CmmType
-> CmmExpr
-> CmmExpr
-> CmmExpr
-> CmmFormal
-> FCode ()
doVecInsertOp maybe_pre_write_cast ty src e idx res = do
platform <- getPlatform
let idx' :: CmmExpr
idx' = CmmMachOp (MO_SS_Conv (wordWidth platform) W32) [idx]
if isFloatType (vecElemType ty)
then emitAssign (CmmLocal res) (CmmMachOp (MO_VF_Insert len wid) [src, cast e, idx'])
else emitAssign (CmmLocal res) (CmmMachOp (MO_V_Insert len wid) [src, cast e, idx'])
where
cast :: CmmExpr -> CmmExpr
cast val = case maybe_pre_write_cast of
Nothing -> val
Just cast -> CmmMachOp cast [val]
len :: Length
len = vecLength ty
wid :: Width
wid = typeWidth (vecElemType ty)
doPrefetchByteArrayOp :: Int
-> [CmmExpr]
-> FCode ()
doPrefetchByteArrayOp locality [addr,idx]
= do profile <- getProfile
mkBasicPrefetch locality (arrWordsHdrSize profile) addr idx
doPrefetchByteArrayOp _ _
= panic "GHC.StgToCmm.Prim: doPrefetchByteArrayOp"
doPrefetchMutableByteArrayOp :: Int
-> [CmmExpr]
-> FCode ()
doPrefetchMutableByteArrayOp locality [addr,idx]
= do profile <- getProfile
mkBasicPrefetch locality (arrWordsHdrSize profile) addr idx
doPrefetchMutableByteArrayOp _ _
= panic "GHC.StgToCmm.Prim: doPrefetchByteArrayOp"
doPrefetchAddrOp ::Int
-> [CmmExpr]
-> FCode ()
doPrefetchAddrOp locality [addr,idx]
= mkBasicPrefetch locality 0 addr idx
doPrefetchAddrOp _ _
= panic "GHC.StgToCmm.Prim: doPrefetchAddrOp"
doPrefetchValueOp :: Int
-> [CmmExpr]
-> FCode ()
doPrefetchValueOp locality [addr]
= do platform <- getPlatform
mkBasicPrefetch locality 0 addr (CmmLit (CmmInt 0 (wordWidth platform)))
doPrefetchValueOp _ _
= panic "GHC.StgToCmm.Prim: doPrefetchValueOp"
mkBasicPrefetch :: Int
-> ByteOff
-> CmmExpr
-> CmmExpr
-> FCode ()
mkBasicPrefetch locality off base idx
= do platform <- getPlatform
emitPrimCall [] (MO_Prefetch_Data locality) [cmmIndexExpr platform W8 (cmmOffsetB platform base off) idx]
return ()
doNewByteArrayOp :: CmmFormal -> ByteOff -> FCode ()
doNewByteArrayOp res_r n = do
profile <- getProfile
platform <- getPlatform
let info_ptr = mkLblExpr mkArrWords_infoLabel
rep = arrWordsRep platform n
tickyAllocPrim (mkIntExpr platform (arrWordsHdrSize profile))
(mkIntExpr platform (nonHdrSize platform rep))
(zeroExpr platform)
let hdr_size = fixedHdrSize profile
base <- allocHeapClosure rep info_ptr cccsExpr
[ (mkIntExpr platform n,
hdr_size + pc_OFFSET_StgArrBytes_bytes (platformConstants platform))
]
emit $ mkAssign (CmmLocal res_r) base
doCompareByteArraysOp :: LocalReg -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> FCode ()
doCompareByteArraysOp res ba1 ba1_off ba2 ba2_off n = do
profile <- getProfile
platform <- getPlatform
ba1_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform ba1 (arrWordsHdrSize profile)) ba1_off
ba2_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform ba2 (arrWordsHdrSize profile)) ba2_off
l_ptr_eq <- newBlockId
l_ptr_ne <- newBlockId
emit (mkAssign (CmmLocal res) (zeroExpr platform))
emit (mkCbranch (cmmEqWord platform ba1_p ba2_p)
l_ptr_eq l_ptr_ne (Just False))
emitLabel l_ptr_ne
emitMemcmpCall res ba1_p ba2_p n 1
emitLabel l_ptr_eq
doCopyByteArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> FCode ()
doCopyByteArrayOp = emitCopyByteArray copy
where
copy _src _dst dst_p src_p bytes align =
emitMemcpyCall dst_p src_p bytes align
doCopyMutableByteArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> FCode ()
doCopyMutableByteArrayOp = emitCopyByteArray copy
where
copy src dst dst_p src_p bytes align = do
platform <- getPlatform
(moveCall, cpyCall) <- forkAltPair
(getCode $ emitMemmoveCall dst_p src_p bytes align)
(getCode $ emitMemcpyCall dst_p src_p bytes align)
emit =<< mkCmmIfThenElse (cmmEqWord platform src dst) moveCall cpyCall
emitCopyByteArray :: (CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> Alignment -> FCode ())
-> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> FCode ()
emitCopyByteArray copy src src_off dst dst_off n = do
profile <- getProfile
platform <- getPlatform
let byteArrayAlignment = wordAlignment platform
srcOffAlignment = cmmExprAlignment src_off
dstOffAlignment = cmmExprAlignment dst_off
align = minimum [byteArrayAlignment, srcOffAlignment, dstOffAlignment]
dst_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform dst (arrWordsHdrSize profile)) dst_off
src_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform src (arrWordsHdrSize profile)) src_off
copy src dst dst_p src_p n align
doCopyByteArrayToAddrOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode ()
doCopyByteArrayToAddrOp src src_off dst_p bytes = do
profile <- getProfile
platform <- getPlatform
src_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform src (arrWordsHdrSize profile)) src_off
emitMemcpyCall dst_p src_p bytes (mkAlignment 1)
doCopyMutableByteArrayToAddrOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> FCode ()
doCopyMutableByteArrayToAddrOp = doCopyByteArrayToAddrOp
doCopyAddrToByteArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> FCode ()
doCopyAddrToByteArrayOp src_p dst dst_off bytes = do
profile <- getProfile
platform <- getPlatform
dst_p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform dst (arrWordsHdrSize profile)) dst_off
emitMemcpyCall dst_p src_p bytes (mkAlignment 1)
doSetByteArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr
-> FCode ()
doSetByteArrayOp ba off len c = do
profile <- getProfile
platform <- getPlatform
let byteArrayAlignment = wordAlignment platform
offsetAlignment = cmmExprAlignment off
align = min byteArrayAlignment offsetAlignment
p <- assignTempE $ cmmOffsetExpr platform (cmmOffsetB platform ba (arrWordsHdrSize profile)) off
emitMemsetCall p c len align
doNewArrayOp :: CmmFormal
-> SMRep
-> CLabel
-> [(CmmExpr, ByteOff)]
-> WordOff
-> CmmExpr
-> FCode ()
doNewArrayOp res_r rep info payload n init = do
profile <- getProfile
platform <- getPlatform
let info_ptr = mkLblExpr info
tickyAllocPrim (mkIntExpr platform (hdrSize profile rep))
(mkIntExpr platform (nonHdrSize platform rep))
(zeroExpr platform)
base <- allocHeapClosure rep info_ptr cccsExpr payload
arr <- CmmLocal `fmap` newTemp (bWord platform)
emit $ mkAssign arr base
let mkOff off = cmmOffsetW platform (CmmReg arr) (hdrSizeW profile rep + off)
initialization = [ mkStore (mkOff off) init | off <- [0.. n 1] ]
emit (catAGraphs initialization)
emit $ mkAssign (CmmLocal res_r) (CmmReg arr)
assignTempE :: CmmExpr -> FCode CmmExpr
assignTempE e = do
t <- assignTemp e
return (CmmReg (CmmLocal t))
doCopyArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff
-> FCode ()
doCopyArrayOp = emitCopyArray copy
where
copy _src _dst dst_p src_p bytes =
do platform <- getPlatform
emitMemcpyCall dst_p src_p (mkIntExpr platform bytes)
(wordAlignment platform)
doCopyMutableArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff
-> FCode ()
doCopyMutableArrayOp = emitCopyArray copy
where
copy src dst dst_p src_p bytes = do
platform <- getPlatform
(moveCall, cpyCall) <- forkAltPair
(getCode $ emitMemmoveCall dst_p src_p (mkIntExpr platform bytes)
(wordAlignment platform))
(getCode $ emitMemcpyCall dst_p src_p (mkIntExpr platform bytes)
(wordAlignment platform))
emit =<< mkCmmIfThenElse (cmmEqWord platform src dst) moveCall cpyCall
emitCopyArray :: (CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> ByteOff
-> FCode ())
-> CmmExpr
-> CmmExpr
-> CmmExpr
-> CmmExpr
-> WordOff
-> FCode ()
emitCopyArray copy src0 src_off dst0 dst_off0 n =
when (n /= 0) $ do
profile <- getProfile
platform <- getPlatform
src <- assignTempE src0
dst <- assignTempE dst0
dst_off <- assignTempE dst_off0
emitCopyUpdRemSetPush platform (arrPtrsHdrSizeW profile) dst dst_off n
emit (setInfo dst (CmmLit (CmmLabel mkMAP_DIRTY_infoLabel)))
dst_elems_p <- assignTempE $ cmmOffsetB platform dst
(arrPtrsHdrSize profile)
dst_p <- assignTempE $ cmmOffsetExprW platform dst_elems_p dst_off
src_p <- assignTempE $ cmmOffsetExprW platform
(cmmOffsetB platform src (arrPtrsHdrSize profile)) src_off
let bytes = wordsToBytes platform n
copy src dst dst_p src_p bytes
dst_cards_p <- assignTempE $ cmmOffsetExprW platform dst_elems_p
(loadArrPtrsSize profile dst)
emitSetCards dst_off dst_cards_p n
doCopySmallArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff
-> FCode ()
doCopySmallArrayOp = emitCopySmallArray copy
where
copy _src _dst dst_p src_p bytes =
do platform <- getPlatform
emitMemcpyCall dst_p src_p (mkIntExpr platform bytes)
(wordAlignment platform)
doCopySmallMutableArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> WordOff
-> FCode ()
doCopySmallMutableArrayOp = emitCopySmallArray copy
where
copy src dst dst_p src_p bytes = do
platform <- getPlatform
(moveCall, cpyCall) <- forkAltPair
(getCode $ emitMemmoveCall dst_p src_p (mkIntExpr platform bytes)
(wordAlignment platform))
(getCode $ emitMemcpyCall dst_p src_p (mkIntExpr platform bytes)
(wordAlignment platform))
emit =<< mkCmmIfThenElse (cmmEqWord platform src dst) moveCall cpyCall
emitCopySmallArray :: (CmmExpr -> CmmExpr -> CmmExpr -> CmmExpr -> ByteOff
-> FCode ())
-> CmmExpr
-> CmmExpr
-> CmmExpr
-> CmmExpr
-> WordOff
-> FCode ()
emitCopySmallArray copy src0 src_off dst0 dst_off n =
when (n /= 0) $ do
profile <- getProfile
platform <- getPlatform
src <- assignTempE src0
dst <- assignTempE dst0
emitCopyUpdRemSetPush platform (smallArrPtrsHdrSizeW profile) dst dst_off n
emit (setInfo dst (CmmLit (CmmLabel mkSMAP_DIRTY_infoLabel)))
dst_p <- assignTempE $ cmmOffsetExprW platform
(cmmOffsetB platform dst (smallArrPtrsHdrSize profile)) dst_off
src_p <- assignTempE $ cmmOffsetExprW platform
(cmmOffsetB platform src (smallArrPtrsHdrSize profile)) src_off
let bytes = wordsToBytes platform n
copy src dst dst_p src_p bytes
emitCloneArray :: CLabel -> CmmFormal -> CmmExpr -> CmmExpr -> WordOff
-> FCode ()
emitCloneArray info_p res_r src src_off n = do
profile <- getProfile
platform <- getPlatform
let info_ptr = mkLblExpr info_p
rep = arrPtrsRep platform n
tickyAllocPrim (mkIntExpr platform (arrPtrsHdrSize profile))
(mkIntExpr platform (nonHdrSize platform rep))
(zeroExpr platform)
let hdr_size = fixedHdrSize profile
constants = platformConstants platform
base <- allocHeapClosure rep info_ptr cccsExpr
[ (mkIntExpr platform n,
hdr_size + pc_OFFSET_StgMutArrPtrs_ptrs constants)
, (mkIntExpr platform (nonHdrSizeW rep),
hdr_size + pc_OFFSET_StgMutArrPtrs_size constants)
]
arr <- CmmLocal `fmap` newTemp (bWord platform)
emit $ mkAssign arr base
dst_p <- assignTempE $ cmmOffsetB platform (CmmReg arr)
(arrPtrsHdrSize profile)
src_p <- assignTempE $ cmmOffsetExprW platform src
(cmmAddWord platform
(mkIntExpr platform (arrPtrsHdrSizeW profile)) src_off)
emitMemcpyCall dst_p src_p (mkIntExpr platform (wordsToBytes platform n))
(wordAlignment platform)
emit $ mkAssign (CmmLocal res_r) (CmmReg arr)
emitCloneSmallArray :: CLabel -> CmmFormal -> CmmExpr -> CmmExpr -> WordOff
-> FCode ()
emitCloneSmallArray info_p res_r src src_off n = do
profile <- getProfile
platform <- getPlatform
let info_ptr = mkLblExpr info_p
rep = smallArrPtrsRep n
tickyAllocPrim (mkIntExpr platform (smallArrPtrsHdrSize profile))
(mkIntExpr platform (nonHdrSize platform rep))
(zeroExpr platform)
let hdr_size = fixedHdrSize profile
base <- allocHeapClosure rep info_ptr cccsExpr
[ (mkIntExpr platform n,
hdr_size + pc_OFFSET_StgSmallMutArrPtrs_ptrs (platformConstants platform))
]
arr <- CmmLocal `fmap` newTemp (bWord platform)
emit $ mkAssign arr base
dst_p <- assignTempE $ cmmOffsetB platform (CmmReg arr)
(smallArrPtrsHdrSize profile)
src_p <- assignTempE $ cmmOffsetExprW platform src
(cmmAddWord platform
(mkIntExpr platform (smallArrPtrsHdrSizeW profile)) src_off)
emitMemcpyCall dst_p src_p (mkIntExpr platform (wordsToBytes platform n))
(wordAlignment platform)
emit $ mkAssign (CmmLocal res_r) (CmmReg arr)
emitSetCards :: CmmExpr -> CmmExpr -> WordOff -> FCode ()
emitSetCards dst_start dst_cards_start n = do
platform <- getPlatform
start_card <- assignTempE $ cardCmm platform dst_start
let end_card = cardCmm platform
(cmmSubWord platform
(cmmAddWord platform dst_start (mkIntExpr platform n))
(mkIntExpr platform 1))
emitMemsetCall (cmmAddWord platform dst_cards_start start_card)
(mkIntExpr platform 1)
(cmmAddWord platform (cmmSubWord platform end_card start_card) (mkIntExpr platform 1))
(mkAlignment 1)
cardCmm :: Platform -> CmmExpr -> CmmExpr
cardCmm platform i =
cmmUShrWord platform i (mkIntExpr platform (pc_MUT_ARR_PTRS_CARD_BITS (platformConstants platform)))
doReadSmallPtrArrayOp :: LocalReg
-> CmmExpr
-> CmmExpr
-> FCode ()
doReadSmallPtrArrayOp res addr idx = do
profile <- getProfile
platform <- getPlatform
mkBasicIndexedRead (smallArrPtrsHdrSize profile) Nothing (gcWord platform) res addr
(gcWord platform) idx
doWriteSmallPtrArrayOp :: CmmExpr
-> CmmExpr
-> CmmExpr
-> FCode ()
doWriteSmallPtrArrayOp addr idx val = do
profile <- getProfile
platform <- getPlatform
let ty = cmmExprType platform val
tmp <- newTemp ty
mkBasicIndexedRead (smallArrPtrsHdrSize profile) Nothing ty tmp addr ty idx
whenUpdRemSetEnabled $ emitUpdRemSetPush (CmmReg (CmmLocal tmp))
emitPrimCall [] MO_WriteBarrier []
mkBasicIndexedWrite (smallArrPtrsHdrSize profile) Nothing addr ty idx val
emit (setInfo addr (CmmLit (CmmLabel mkSMAP_DIRTY_infoLabel)))
doAtomicByteArrayRMW
:: LocalReg
-> AtomicMachOp
-> CmmExpr
-> CmmExpr
-> CmmType
-> CmmExpr
-> FCode ()
doAtomicByteArrayRMW res amop mba idx idx_ty n = do
profile <- getProfile
platform <- getPlatform
let width = typeWidth idx_ty
addr = cmmIndexOffExpr platform (arrWordsHdrSize profile)
width mba idx
doAtomicAddrRMW res amop addr idx_ty n
doAtomicAddrRMW
:: LocalReg
-> AtomicMachOp
-> CmmExpr
-> CmmType
-> CmmExpr
-> FCode ()
doAtomicAddrRMW res amop addr ty n =
emitPrimCall
[ res ]
(MO_AtomicRMW (typeWidth ty) amop)
[ addr, n ]
doAtomicReadByteArray
:: LocalReg
-> CmmExpr
-> CmmExpr
-> CmmType
-> FCode ()
doAtomicReadByteArray res mba idx idx_ty = do
profile <- getProfile
platform <- getPlatform
let width = typeWidth idx_ty
addr = cmmIndexOffExpr platform (arrWordsHdrSize profile)
width mba idx
doAtomicReadAddr res addr idx_ty
doAtomicReadAddr
:: LocalReg
-> CmmExpr
-> CmmType
-> FCode ()
doAtomicReadAddr res addr ty =
emitPrimCall
[ res ]
(MO_AtomicRead (typeWidth ty))
[ addr ]
doAtomicWriteByteArray
:: CmmExpr
-> CmmExpr
-> CmmType
-> CmmExpr
-> FCode ()
doAtomicWriteByteArray mba idx idx_ty val = do
profile <- getProfile
platform <- getPlatform
let width = typeWidth idx_ty
addr = cmmIndexOffExpr platform (arrWordsHdrSize profile)
width mba idx
doAtomicWriteAddr addr idx_ty val
doAtomicWriteAddr
:: CmmExpr
-> CmmType
-> CmmExpr
-> FCode ()
doAtomicWriteAddr addr ty val =
emitPrimCall
[ ]
(MO_AtomicWrite (typeWidth ty))
[ addr, val ]
doCasByteArray
:: LocalReg
-> CmmExpr
-> CmmExpr
-> CmmType
-> CmmExpr
-> CmmExpr
-> FCode ()
doCasByteArray res mba idx idx_ty old new = do
profile <- getProfile
platform <- getPlatform
let width = (typeWidth idx_ty)
addr = cmmIndexOffExpr platform (arrWordsHdrSize profile)
width mba idx
emitPrimCall
[ res ]
(MO_Cmpxchg width)
[ addr, old, new ]
emitMemcpyCall :: CmmExpr -> CmmExpr -> CmmExpr -> Alignment -> FCode ()
emitMemcpyCall dst src n align =
emitPrimCall
[ ]
(MO_Memcpy (alignmentBytes align))
[ dst, src, n ]
emitMemmoveCall :: CmmExpr -> CmmExpr -> CmmExpr -> Alignment -> FCode ()
emitMemmoveCall dst src n align =
emitPrimCall
[ ]
(MO_Memmove (alignmentBytes align))
[ dst, src, n ]
emitMemsetCall :: CmmExpr -> CmmExpr -> CmmExpr -> Alignment -> FCode ()
emitMemsetCall dst c n align =
emitPrimCall
[ ]
(MO_Memset (alignmentBytes align))
[ dst, c, n ]
emitMemcmpCall :: LocalReg -> CmmExpr -> CmmExpr -> CmmExpr -> Int -> FCode ()
emitMemcmpCall res ptr1 ptr2 n align = do
platform <- getPlatform
let is32Bit = typeWidth (localRegType res) == W32
cres <- if is32Bit
then return res
else newTemp b32
emitPrimCall
[ cres ]
(MO_Memcmp align)
[ ptr1, ptr2, n ]
unless is32Bit $
emit $ mkAssign (CmmLocal res)
(CmmMachOp
(mo_s_32ToWord platform)
[(CmmReg (CmmLocal cres))])
emitBSwapCall :: LocalReg -> CmmExpr -> Width -> FCode ()
emitBSwapCall res x width =
emitPrimCall
[ res ]
(MO_BSwap width)
[ x ]
emitBRevCall :: LocalReg -> CmmExpr -> Width -> FCode ()
emitBRevCall res x width =
emitPrimCall
[ res ]
(MO_BRev width)
[ x ]
emitPopCntCall :: LocalReg -> CmmExpr -> Width -> FCode ()
emitPopCntCall res x width =
emitPrimCall
[ res ]
(MO_PopCnt width)
[ x ]
emitPdepCall :: LocalReg -> CmmExpr -> CmmExpr -> Width -> FCode ()
emitPdepCall res x y width =
emitPrimCall
[ res ]
(MO_Pdep width)
[ x, y ]
emitPextCall :: LocalReg -> CmmExpr -> CmmExpr -> Width -> FCode ()
emitPextCall res x y width =
emitPrimCall
[ res ]
(MO_Pext width)
[ x, y ]
emitClzCall :: LocalReg -> CmmExpr -> Width -> FCode ()
emitClzCall res x width =
emitPrimCall
[ res ]
(MO_Clz width)
[ x ]
emitCtzCall :: LocalReg -> CmmExpr -> Width -> FCode ()
emitCtzCall res x width =
emitPrimCall
[ res ]
(MO_Ctz width)
[ x ]
emitCopyUpdRemSetPush :: Platform
-> WordOff
-> CmmExpr
-> CmmExpr
-> Int
-> FCode ()
emitCopyUpdRemSetPush _platform _hdr_size _dst _dst_off 0 = return ()
emitCopyUpdRemSetPush platform hdr_size dst dst_off n =
whenUpdRemSetEnabled $ do
updfr_off <- getUpdFrameOff
graph <- mkCall lbl (NativeNodeCall,NativeReturn) [] args updfr_off []
emit graph
where
lbl = mkLblExpr $ mkPrimCallLabel
$ PrimCall (fsLit "stg_copyArray_barrier") rtsUnit
args =
[ mkIntExpr platform hdr_size
, dst
, dst_off
, mkIntExpr platform n
]