diff options
Diffstat (limited to 'compiler/codeGen/CgPrimOp.hs')
-rw-r--r-- | compiler/codeGen/CgPrimOp.hs | 209 |
1 files changed, 101 insertions, 108 deletions
diff --git a/compiler/codeGen/CgPrimOp.hs b/compiler/codeGen/CgPrimOp.hs index 3b11054efe..b0865d69d9 100644 --- a/compiler/codeGen/CgPrimOp.hs +++ b/compiler/codeGen/CgPrimOp.hs @@ -6,16 +6,9 @@ -- ----------------------------------------------------------------------------- -{-# OPTIONS -fno-warn-tabs #-} --- The above warning supression flag is a temporary kludge. --- While working on this module you are encouraged to remove it and --- detab the module (please do the detabbing in a separate patch). See --- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces --- for details - module CgPrimOp ( - cgPrimOp - ) where + cgPrimOp + ) where import BasicTypes import ForeignCall @@ -43,44 +36,44 @@ import StaticFlags -- --------------------------------------------------------------------------- -- Code generation for PrimOps -cgPrimOp :: [CmmFormal] -- where to put the results - -> PrimOp -- the op - -> [StgArg] -- arguments - -> StgLiveVars -- live vars, in case we need to save them - -> Code +cgPrimOp :: [CmmFormal] -- where to put the results + -> PrimOp -- the op + -> [StgArg] -- arguments + -> StgLiveVars -- live vars, in case we need to save them + -> Code cgPrimOp results op args live = do arg_exprs <- getArgAmodes args - let non_void_args = [ e | (r,e) <- arg_exprs, nonVoidArg r ] + let non_void_args = [ e | (r,e) <- arg_exprs, nonVoidArg r ] emitPrimOp results op non_void_args live -emitPrimOp :: [CmmFormal] -- where to put the results - -> PrimOp -- the op - -> [CmmExpr] -- arguments - -> StgLiveVars -- live vars, in case we need to save them - -> Code +emitPrimOp :: [CmmFormal] -- where to put the results + -> PrimOp -- the op + -> [CmmExpr] -- arguments + -> StgLiveVars -- live vars, in case we need to save them + -> Code -- First we handle various awkward cases specially. The remaining -- easy cases are then handled by translateOp, defined below. emitPrimOp [res_r,res_c] IntAddCOp [aa,bb] _ -{- +{- With some bit-twiddling, we can define int{Add,Sub}Czh portably in C, and without needing any comparisons. This may not be the fastest way to do it - if you have better code, please send it! --SDM - + Return : r = a + b, c = 0 if no overflow, 1 on overflow. - - We currently don't make use of the r value if c is != 0 (i.e. + + We currently don't make use of the r value if c is != 0 (i.e. overflow), we just convert to big integers and try again. This could be improved by making r and c the correct values for - plugging into a new J#. - - { r = ((I_)(a)) + ((I_)(b)); \ - c = ((StgWord)(~(((I_)(a))^((I_)(b))) & (((I_)(a))^r))) \ - >> (BITS_IN (I_) - 1); \ - } + plugging into a new J#. + + { r = ((I_)(a)) + ((I_)(b)); \ + c = ((StgWord)(~(((I_)(a))^((I_)(b))) & (((I_)(a))^r))) \ + >> (BITS_IN (I_) - 1); \ + } Wading through the mass of bracketry, it seems to reduce to: c = ( (~(a^b)) & (a^r) ) >>unsigned (BITS_IN(I_)-1) @@ -88,22 +81,22 @@ emitPrimOp [res_r,res_c] IntAddCOp [aa,bb] _ = stmtsC [ CmmAssign (CmmLocal res_r) (CmmMachOp mo_wordAdd [aa,bb]), CmmAssign (CmmLocal res_c) $ - CmmMachOp mo_wordUShr [ - CmmMachOp mo_wordAnd [ - CmmMachOp mo_wordNot [CmmMachOp mo_wordXor [aa,bb]], - CmmMachOp mo_wordXor [aa, CmmReg (CmmLocal res_r)] - ], - CmmLit (mkIntCLit (wORD_SIZE_IN_BITS - 1)) - ] + CmmMachOp mo_wordUShr [ + CmmMachOp mo_wordAnd [ + CmmMachOp mo_wordNot [CmmMachOp mo_wordXor [aa,bb]], + CmmMachOp mo_wordXor [aa, CmmReg (CmmLocal res_r)] + ], + CmmLit (mkIntCLit (wORD_SIZE_IN_BITS - 1)) + ] ] emitPrimOp [res_r,res_c] IntSubCOp [aa,bb] _ {- Similarly: - #define subIntCzh(r,c,a,b) \ - { r = ((I_)(a)) - ((I_)(b)); \ - c = ((StgWord)((((I_)(a))^((I_)(b))) & (((I_)(a))^r))) \ - >> (BITS_IN (I_) - 1); \ + #define subIntCzh(r,c,a,b) \ + { r = ((I_)(a)) - ((I_)(b)); \ + c = ((StgWord)((((I_)(a))^((I_)(b))) & (((I_)(a))^r))) \ + >> (BITS_IN (I_) - 1); \ } c = ((a^b) & (a^r)) >>unsigned (BITS_IN(I_)-1) @@ -111,27 +104,27 @@ emitPrimOp [res_r,res_c] IntSubCOp [aa,bb] _ = stmtsC [ CmmAssign (CmmLocal res_r) (CmmMachOp mo_wordSub [aa,bb]), CmmAssign (CmmLocal res_c) $ - CmmMachOp mo_wordUShr [ - CmmMachOp mo_wordAnd [ - CmmMachOp mo_wordXor [aa,bb], - CmmMachOp mo_wordXor [aa, CmmReg (CmmLocal res_r)] - ], - CmmLit (mkIntCLit (wORD_SIZE_IN_BITS - 1)) - ] + CmmMachOp mo_wordUShr [ + CmmMachOp mo_wordAnd [ + CmmMachOp mo_wordXor [aa,bb], + CmmMachOp mo_wordXor [aa, CmmReg (CmmLocal res_r)] + ], + CmmLit (mkIntCLit (wORD_SIZE_IN_BITS - 1)) + ] ] emitPrimOp [res] ParOp [arg] live = do - -- for now, just implement this in a C function - -- later, we might want to inline it. + -- for now, just implement this in a C function + -- later, we might want to inline it. vols <- getVolatileRegs live emitForeignCall' PlayRisky - [CmmHinted res NoHint] - (CmmCallee newspark CCallConv) - [ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint) - , (CmmHinted arg AddrHint) ] - (Just vols) + [CmmHinted res NoHint] + (CmmCallee newspark CCallConv) + [ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint) + , (CmmHinted arg AddrHint) ] + (Just vols) NoC_SRT -- No SRT b/c we do PlayRisky CmmMayReturn where @@ -148,15 +141,15 @@ emitPrimOp [res] SparkOp [arg] live = do res' <- newTemp bWord emitForeignCall' PlayRisky [CmmHinted res' NoHint] - (CmmCallee newspark CCallConv) - [ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint) - , (CmmHinted arg AddrHint) ] - (Just vols) + (CmmCallee newspark CCallConv) + [ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint) + , (CmmHinted arg AddrHint) ] + (Just vols) NoC_SRT -- No SRT b/c we do PlayRisky CmmMayReturn stmtC (CmmAssign (CmmLocal res) (CmmReg (CmmLocal tmp))) where - newspark = CmmLit (CmmLabel (mkCmmCodeLabel rtsPackageId (fsLit "newSpark"))) + newspark = CmmLit (CmmLabel (mkCmmCodeLabel rtsPackageId (fsLit "newSpark"))) emitPrimOp [res] GetCCSOfOp [arg] _live = stmtC (CmmAssign (CmmLocal res) val) @@ -172,15 +165,15 @@ emitPrimOp [res] ReadMutVarOp [mutv] _ emitPrimOp [] WriteMutVarOp [mutv,var] live = do - stmtC (CmmStore (cmmOffsetW mutv fixedHdrSize) var) - vols <- getVolatileRegs live - emitForeignCall' PlayRisky - [{-no results-}] - (CmmCallee (CmmLit (CmmLabel mkDirty_MUT_VAR_Label)) - CCallConv) - [ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint) + stmtC (CmmStore (cmmOffsetW mutv fixedHdrSize) var) + vols <- getVolatileRegs live + emitForeignCall' PlayRisky + [{-no results-}] + (CmmCallee (CmmLit (CmmLabel mkDirty_MUT_VAR_Label)) + CCallConv) + [ (CmmHinted (CmmReg (CmmGlobal BaseReg)) AddrHint) , (CmmHinted mutv AddrHint) ] - (Just vols) + (Just vols) NoC_SRT -- No SRT b/c we do PlayRisky CmmMayReturn @@ -188,7 +181,7 @@ emitPrimOp [] WriteMutVarOp [mutv,var] live -- r = ((StgArrWords *)(a))->bytes emitPrimOp [res] SizeofByteArrayOp [arg] _ = stmtC $ - CmmAssign (CmmLocal res) (cmmLoadIndexW arg fixedHdrSize bWord) + CmmAssign (CmmLocal res) (cmmLoadIndexW arg fixedHdrSize bWord) -- #define sizzeofMutableByteArrayzh(r,a) \ -- r = ((StgArrWords *)(a))->bytes @@ -208,13 +201,13 @@ emitPrimOp [res] ByteArrayContents_Char [arg] _ emitPrimOp [res] StableNameToIntOp [arg] _ = stmtC (CmmAssign (CmmLocal res) (cmmLoadIndexW arg fixedHdrSize bWord)) --- #define eqStableNamezh(r,sn1,sn2) \ +-- #define eqStableNamezh(r,sn1,sn2) \ -- (r = (((StgStableName *)sn1)->sn == ((StgStableName *)sn2)->sn)) emitPrimOp [res] EqStableNameOp [arg1,arg2] _ = stmtC (CmmAssign (CmmLocal res) (CmmMachOp mo_wordEq [ - cmmLoadIndexW arg1 fixedHdrSize bWord, - cmmLoadIndexW arg2 fixedHdrSize bWord - ])) + cmmLoadIndexW arg1 fixedHdrSize bWord, + cmmLoadIndexW arg2 fixedHdrSize bWord + ])) emitPrimOp [res] ReallyUnsafePtrEqualityOp [arg1,arg2] _ @@ -232,13 +225,13 @@ emitPrimOp [res] DataToTagOp [arg] _ {- Freezing arrays-of-ptrs requires changing an info table, for the benefit of the generational collector. It needs to scavenge mutable objects, even if they are in old space. When they become immutable, - they can be removed from this scavenge list. -} + they can be removed from this scavenge list. -} -- #define unsafeFreezzeArrayzh(r,a) --- { +-- { -- SET_INFO((StgClosure *)a,&stg_MUT_ARR_PTRS_FROZEN0_info); --- r = a; --- } +-- r = a; +-- } emitPrimOp [res] UnsafeFreezeArrayOp [arg] _ = stmtsC [ setInfo arg (CmmLit (CmmLabel mkMAP_FROZEN_infoLabel)), CmmAssign (CmmLocal res) arg ] @@ -246,7 +239,7 @@ emitPrimOp [res] UnsafeFreezeArrayArrayOp [arg] _ = stmtsC [ setInfo arg (CmmLit (CmmLabel mkMAP_FROZEN_infoLabel)), CmmAssign (CmmLocal res) arg ] --- #define unsafeFreezzeByteArrayzh(r,a) r=(a) +-- #define unsafeFreezzeByteArrayzh(r,a) r=(a) emitPrimOp [res] UnsafeFreezeByteArrayOp [arg] _ = stmtC (CmmAssign (CmmLocal res) arg) @@ -286,7 +279,7 @@ emitPrimOp [] WriteArrayArrayOp_ArrayArray [obj,ix,v] _ = doWritePtrArr emitPrimOp [] WriteArrayArrayOp_MutableArrayArray [obj,ix,v] _ = doWritePtrArrayOp obj ix v emitPrimOp [res] SizeofArrayOp [arg] _ - = stmtC $ + = stmtC $ CmmAssign (CmmLocal res) (cmmLoadIndexW arg (fixedHdrSize + oFFSET_StgMutArrPtrs_ptrs) bWord) emitPrimOp [res] SizeofMutableArrayOp [arg] live = emitPrimOp [res] SizeofArrayOp [arg] live @@ -430,16 +423,16 @@ emitPrimOp [res] op [arg] _ | Just (mop,rep) <- narrowOp op = stmtC (CmmAssign (CmmLocal res) $ - CmmMachOp (mop rep wordWidth) [CmmMachOp (mop wordWidth rep) [arg]]) + CmmMachOp (mop rep wordWidth) [CmmMachOp (mop wordWidth rep) [arg]]) emitPrimOp [res] op args live | Just prim <- callishOp op = do vols <- getVolatileRegs live - emitForeignCall' PlayRisky - [CmmHinted res NoHint] - (CmmPrim prim) - [CmmHinted a NoHint | a<-args] -- ToDo: hints? - (Just vols) + emitForeignCall' PlayRisky + [CmmHinted res NoHint] + (CmmPrim prim) + [CmmHinted a NoHint | a<-args] -- ToDo: hints? + (Just vols) NoC_SRT -- No SRT b/c we do PlayRisky CmmMayReturn @@ -458,9 +451,9 @@ nopOp Int2WordOp = True nopOp Word2IntOp = True nopOp Int2AddrOp = True nopOp Addr2IntOp = True -nopOp ChrOp = True -- Int# and Char# are rep'd the same -nopOp OrdOp = True -nopOp _ = False +nopOp ChrOp = True -- Int# and Char# are rep'd the same +nopOp OrdOp = True +nopOp _ = False -- These PrimOps turn into double casts @@ -471,7 +464,7 @@ narrowOp Narrow32IntOp = Just (MO_SS_Conv, W32) narrowOp Narrow8WordOp = Just (MO_UU_Conv, W8) narrowOp Narrow16WordOp = Just (MO_UU_Conv, W16) narrowOp Narrow32WordOp = Just (MO_UU_Conv, W32) -narrowOp _ = Nothing +narrowOp _ = Nothing -- Native word signless ops @@ -494,10 +487,10 @@ translateOp AndOp = Just mo_wordAnd translateOp OrOp = Just mo_wordOr translateOp XorOp = Just mo_wordXor translateOp NotOp = Just mo_wordNot -translateOp SllOp = Just mo_wordShl -translateOp SrlOp = Just mo_wordUShr +translateOp SllOp = Just mo_wordShl +translateOp SrlOp = Just mo_wordUShr -translateOp AddrRemOp = Just mo_wordURem +translateOp AddrRemOp = Just mo_wordURem -- Native word signed ops @@ -513,9 +506,9 @@ translateOp IntLeOp = Just mo_wordSLe translateOp IntGtOp = Just mo_wordSGt translateOp IntLtOp = Just mo_wordSLt -translateOp ISllOp = Just mo_wordShl -translateOp ISraOp = Just mo_wordSShr -translateOp ISrlOp = Just mo_wordUShr +translateOp ISllOp = Just mo_wordShl +translateOp ISraOp = Just mo_wordSShr +translateOp ISrlOp = Just mo_wordUShr -- Native word unsigned ops @@ -633,9 +626,9 @@ callishOp _ = Nothing -- Helpers for translating various minor variants of array indexing. -- Bytearrays outside the heap; hence non-pointers -doIndexOffAddrOp, doIndexByteArrayOp - :: Maybe MachOp -> CmmType - -> [LocalReg] -> [CmmExpr] -> Code +doIndexOffAddrOp, doIndexByteArrayOp + :: Maybe MachOp -> CmmType + -> [LocalReg] -> [CmmExpr] -> Code doIndexOffAddrOp maybe_post_read_cast rep [res] [addr,idx] = mkBasicIndexedRead 0 maybe_post_read_cast rep res addr idx doIndexOffAddrOp _ _ _ _ @@ -643,7 +636,7 @@ doIndexOffAddrOp _ _ _ _ doIndexByteArrayOp maybe_post_read_cast rep [res] [addr,idx] = mkBasicIndexedRead arrWordsHdrSize maybe_post_read_cast rep res addr idx -doIndexByteArrayOp _ _ _ _ +doIndexByteArrayOp _ _ _ _ = panic "CgPrimOp: doIndexByteArrayOp" doReadPtrArrayOp :: LocalReg -> CmmExpr -> CmmExpr -> Code @@ -651,9 +644,9 @@ doReadPtrArrayOp res addr idx = mkBasicIndexedRead arrPtrsHdrSize Nothing gcWord res addr idx -doWriteOffAddrOp, doWriteByteArrayOp - :: Maybe MachOp -> CmmType - -> [LocalReg] -> [CmmExpr] -> Code +doWriteOffAddrOp, doWriteByteArrayOp + :: Maybe MachOp -> CmmType + -> [LocalReg] -> [CmmExpr] -> Code doWriteOffAddrOp maybe_pre_write_cast rep [] [addr,idx,val] = mkBasicIndexedWrite 0 maybe_pre_write_cast rep addr idx val doWriteOffAddrOp _ _ _ _ @@ -661,7 +654,7 @@ doWriteOffAddrOp _ _ _ _ doWriteByteArrayOp maybe_pre_write_cast rep [] [addr,idx,val] = mkBasicIndexedWrite arrWordsHdrSize maybe_pre_write_cast rep addr idx val -doWriteByteArrayOp _ _ _ _ +doWriteByteArrayOp _ _ _ _ = panic "CgPrimOp: doWriteByteArrayOp" doWritePtrArrayOp :: CmmExpr -> CmmExpr -> CmmExpr -> Code @@ -682,16 +675,16 @@ loadArrPtrsSize :: CmmExpr -> CmmExpr loadArrPtrsSize addr = CmmLoad (cmmOffsetB addr off) bWord where off = fixedHdrSize*wORD_SIZE + oFFSET_StgMutArrPtrs_ptrs -mkBasicIndexedRead :: ByteOff -> Maybe MachOp -> CmmType - -> LocalReg -> CmmExpr -> CmmExpr -> Code +mkBasicIndexedRead :: ByteOff -> Maybe MachOp -> CmmType + -> LocalReg -> CmmExpr -> CmmExpr -> Code mkBasicIndexedRead off Nothing read_rep res base idx = stmtC (CmmAssign (CmmLocal res) (cmmLoadIndexOffExpr off read_rep base idx)) mkBasicIndexedRead off (Just cast) read_rep res base idx = stmtC (CmmAssign (CmmLocal res) (CmmMachOp cast [ - cmmLoadIndexOffExpr off read_rep base idx])) + cmmLoadIndexOffExpr off read_rep base idx])) -mkBasicIndexedWrite :: ByteOff -> Maybe MachOp -> CmmType - -> CmmExpr -> CmmExpr -> CmmExpr -> Code +mkBasicIndexedWrite :: ByteOff -> Maybe MachOp -> CmmType + -> CmmExpr -> CmmExpr -> CmmExpr -> Code mkBasicIndexedWrite off Nothing write_rep base idx val = stmtC (CmmStore (cmmIndexOffExpr off write_rep base idx) val) mkBasicIndexedWrite off (Just cast) write_rep base idx val |