diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/GHC/Builtin/Names.hs | 5 | ||||
-rw-r--r-- | compiler/GHC/Builtin/Types.hs | 8 | ||||
-rw-r--r-- | compiler/GHC/Builtin/primops.txt.pp | 36 | ||||
-rw-r--r-- | compiler/GHC/ByteCode/Asm.hs | 9 | ||||
-rw-r--r-- | compiler/GHC/Cmm.hs | 6 | ||||
-rw-r--r-- | compiler/GHC/Cmm/Expr.hs | 11 | ||||
-rw-r--r-- | compiler/GHC/CmmToAsm/Ppr.hs | 14 | ||||
-rw-r--r-- | compiler/GHC/CmmToC.hs | 193 | ||||
-rw-r--r-- | compiler/GHC/Core.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/Core/Opt/ConstantFold.hs | 59 | ||||
-rw-r--r-- | compiler/GHC/CoreToByteCode.hs | 57 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Foreign/Call.hs | 32 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Foreign/Decl.hs | 6 | ||||
-rw-r--r-- | compiler/GHC/HsToCore/Quote.hs | 5 | ||||
-rw-r--r-- | compiler/GHC/Runtime/Heap/Inspect.hs | 4 | ||||
-rw-r--r-- | compiler/GHC/StgToCmm/DataCon.hs | 17 | ||||
-rw-r--r-- | compiler/GHC/StgToCmm/Prim.hs | 26 | ||||
-rw-r--r-- | compiler/GHC/StgToCmm/Utils.hs | 6 | ||||
-rw-r--r-- | compiler/GHC/Types/Literal.hs | 211 | ||||
-rw-r--r-- | compiler/GHC/Utils/Outputable.hs | 30 |
20 files changed, 540 insertions, 199 deletions
diff --git a/compiler/GHC/Builtin/Names.hs b/compiler/GHC/Builtin/Names.hs index 881753f6f2..cf0f72c50f 100644 --- a/compiler/GHC/Builtin/Names.hs +++ b/compiler/GHC/Builtin/Names.hs @@ -336,7 +336,7 @@ basicKnownKeyNames -- FFI primitive types that are not wired-in. stablePtrTyConName, ptrTyConName, funPtrTyConName, int8TyConName, int16TyConName, int32TyConName, int64TyConName, - word16TyConName, word32TyConName, word64TyConName, + word8TyConName, word16TyConName, word32TyConName, word64TyConName, -- Others otherwiseIdName, inlineIdName, @@ -1463,7 +1463,8 @@ int32TyConName = tcQual gHC_INT (fsLit "Int32") int32TyConKey int64TyConName = tcQual gHC_INT (fsLit "Int64") int64TyConKey -- Word module -word16TyConName, word32TyConName, word64TyConName :: Name +word8TyConName, word16TyConName, word32TyConName, word64TyConName :: Name +word8TyConName = tcQual gHC_WORD (fsLit "Word8") word8TyConKey word16TyConName = tcQual gHC_WORD (fsLit "Word16") word16TyConKey word32TyConName = tcQual gHC_WORD (fsLit "Word32") word32TyConKey word64TyConName = tcQual gHC_WORD (fsLit "Word64") word64TyConKey diff --git a/compiler/GHC/Builtin/Types.hs b/compiler/GHC/Builtin/Types.hs index 52febf72d2..d06bc4a12b 100644 --- a/compiler/GHC/Builtin/Types.hs +++ b/compiler/GHC/Builtin/Types.hs @@ -55,7 +55,7 @@ module GHC.Builtin.Types ( wordTyCon, wordDataCon, wordTyConName, wordTy, -- * Word8 - word8TyCon, word8DataCon, word8TyConName, word8Ty, + word8TyCon, word8DataCon, word8Ty, -- * List listTyCon, listTyCon_RDR, listTyConName, listTyConKey, @@ -251,7 +251,6 @@ wiredInTyCons = [ -- Units are not treated like other tuples, because they , floatTyCon , intTyCon , wordTyCon - , word8TyCon , listTyCon , orderingTyCon , maybeTyCon @@ -354,10 +353,9 @@ nothingDataConName = mkWiredInDataConName UserSyntax gHC_MAYBE (fsLit "Nothing") justDataConName = mkWiredInDataConName UserSyntax gHC_MAYBE (fsLit "Just") justDataConKey justDataCon -wordTyConName, wordDataConName, word8TyConName, word8DataConName :: Name +wordTyConName, wordDataConName, word8DataConName :: Name wordTyConName = mkWiredInTyConName UserSyntax gHC_TYPES (fsLit "Word") wordTyConKey wordTyCon wordDataConName = mkWiredInDataConName UserSyntax gHC_TYPES (fsLit "W#") wordDataConKey wordDataCon -word8TyConName = mkWiredInTyConName UserSyntax gHC_WORD (fsLit "Word8") word8TyConKey word8TyCon word8DataConName = mkWiredInDataConName UserSyntax gHC_WORD (fsLit "W8#") word8DataConKey word8DataCon floatTyConName, floatDataConName, doubleTyConName, doubleDataConName :: Name @@ -1641,7 +1639,7 @@ word8TyCon = pcTyCon word8TyConName (NoSourceText, fsLit "HsWord8"))) [] [word8DataCon] word8DataCon :: DataCon -word8DataCon = pcDataCon word8DataConName [] [wordPrimTy] word8TyCon +word8DataCon = pcDataCon word8DataConName [] [word8PrimTy] word8TyCon floatTy :: Type floatTy = mkTyConTy floatTyCon diff --git a/compiler/GHC/Builtin/primops.txt.pp b/compiler/GHC/Builtin/primops.txt.pp index ecc71baa69..364f4f0300 100644 --- a/compiler/GHC/Builtin/primops.txt.pp +++ b/compiler/GHC/Builtin/primops.txt.pp @@ -291,8 +291,8 @@ section "Int8#" primtype Int8# -primop Int8Extend "extendInt8#" GenPrimOp Int8# -> Int# -primop Int8Narrow "narrowInt8#" GenPrimOp Int# -> Int8# +primop Int8ExtendOp "extendInt8#" GenPrimOp Int8# -> Int# +primop Int8NarrowOp "narrowInt8#" GenPrimOp Int# -> Int8# primop Int8NegOp "negateInt8#" GenPrimOp Int8# -> Int8# @@ -332,8 +332,8 @@ section "Word8#" primtype Word8# -primop Word8Extend "extendWord8#" GenPrimOp Word8# -> Word# -primop Word8Narrow "narrowWord8#" GenPrimOp Word# -> Word8# +primop Word8ExtendOp "extendWord8#" GenPrimOp Word8# -> Word# +primop Word8NarrowOp "narrowWord8#" GenPrimOp Word# -> Word8# primop Word8NotOp "notWord8#" GenPrimOp Word8# -> Word8# @@ -373,8 +373,8 @@ section "Int16#" primtype Int16# -primop Int16Extend "extendInt16#" GenPrimOp Int16# -> Int# -primop Int16Narrow "narrowInt16#" GenPrimOp Int# -> Int16# +primop Int16ExtendOp "extendInt16#" GenPrimOp Int16# -> Int# +primop Int16NarrowOp "narrowInt16#" GenPrimOp Int# -> Int16# primop Int16NegOp "negateInt16#" GenPrimOp Int16# -> Int16# @@ -414,8 +414,8 @@ section "Word16#" primtype Word16# -primop Word16Extend "extendWord16#" GenPrimOp Word16# -> Word# -primop Word16Narrow "narrowWord16#" GenPrimOp Word# -> Word16# +primop Word16ExtendOp "extendWord16#" GenPrimOp Word16# -> Word# +primop Word16NarrowOp "narrowWord16#" GenPrimOp Word# -> Word16# primop Word16NotOp "notWord16#" GenPrimOp Word16# -> Word16# @@ -448,6 +448,26 @@ primop Word16LeOp "leWord16#" Compare Word16# -> Word16# -> Int# primop Word16LtOp "ltWord16#" Compare Word16# -> Word16# -> Int# primop Word16NeOp "neWord16#" Compare Word16# -> Word16# -> Int# +------------------------------------------------------------------------ +section "Int32#" + {Operations on 32-bit integers.} +------------------------------------------------------------------------ + +primtype Int32# + +primop Int32ExtendOp "extendInt32#" GenPrimOp Int32# -> Int# +primop Int32NarrowOp "narrowInt32#" GenPrimOp Int# -> Int32# + +------------------------------------------------------------------------ +section "Word32#" + {Operations on 32-bit unsigned integers.} +------------------------------------------------------------------------ + +primtype Word32# + +primop Word32ExtendOp "extendWord32#" GenPrimOp Word32# -> Word# +primop Word32NarrowOp "narrowWord32#" GenPrimOp Word# -> Word32# + #if WORD_SIZE_IN_BITS < 64 ------------------------------------------------------------------------ section "Int64#" diff --git a/compiler/GHC/ByteCode/Asm.hs b/compiler/GHC/ByteCode/Asm.hs index 92255f9ea0..ff8bacd6cc 100644 --- a/compiler/GHC/ByteCode/Asm.hs +++ b/compiler/GHC/ByteCode/Asm.hs @@ -464,6 +464,12 @@ assembleI platform i = case i of literal (LitNumber nt i) = case nt of LitNumInt -> int (fromIntegral i) LitNumWord -> int (fromIntegral i) + LitNumInt8 -> int8 (fromIntegral i) + LitNumWord8 -> int8 (fromIntegral i) + LitNumInt16 -> int16 (fromIntegral i) + LitNumWord16 -> int16 (fromIntegral i) + LitNumInt32 -> int32 (fromIntegral i) + LitNumWord32 -> int32 (fromIntegral i) LitNumInt64 -> int64 (fromIntegral i) LitNumWord64 -> int64 (fromIntegral i) LitNumInteger -> panic "GHC.ByteCode.Asm.literal: LitNumInteger" @@ -478,6 +484,9 @@ assembleI platform i = case i of float = words . mkLitF double = words . mkLitD platform int = words . mkLitI + int8 = words . mkLitI64 platform + int16 = words . mkLitI64 platform + int32 = words . mkLitI64 platform int64 = words . mkLitI64 platform words ws = lit (map BCONPtrWord ws) word w = words [w] diff --git a/compiler/GHC/Cmm.hs b/compiler/GHC/Cmm.hs index 5c4c619b69..3a461fa03c 100644 --- a/compiler/GHC/Cmm.hs +++ b/compiler/GHC/Cmm.hs @@ -228,6 +228,12 @@ data CmmStatic | CmmFileEmbed FilePath -- ^ an embedded binary file +instance Outputable CmmStatic where + ppr (CmmStaticLit lit) = text "CmmStaticLit" <+> ppr lit + ppr (CmmUninitialised n) = text "CmmUninitialised" <+> ppr n + ppr (CmmString _) = text "CmmString" + ppr (CmmFileEmbed fp) = text "CmmFileEmbed" <+> text fp + -- Static data before SRT generation data GenCmmStatics (rawOnly :: Bool) where CmmStatics diff --git a/compiler/GHC/Cmm/Expr.hs b/compiler/GHC/Cmm/Expr.hs index 08ab27c410..e1251c6c27 100644 --- a/compiler/GHC/Cmm/Expr.hs +++ b/compiler/GHC/Cmm/Expr.hs @@ -39,6 +39,7 @@ import GHC.Cmm.CLabel import GHC.Cmm.MachOp import GHC.Cmm.Type import GHC.Utils.Panic (panic) +import GHC.Utils.Outputable import GHC.Types.Unique import Data.Set (Set) @@ -210,6 +211,16 @@ data CmmLit -- of bytes used deriving Eq +instance Outputable CmmLit where + ppr (CmmInt n w) = text "CmmInt" <+> ppr n <+> ppr w + ppr (CmmFloat n w) = text "CmmFloat" <+> text (show n) <+> ppr w + ppr (CmmVec xs) = text "CmmVec" <+> ppr xs + ppr (CmmLabel _) = text "CmmLabel" + ppr (CmmLabelOff _ _) = text "CmmLabelOff" + ppr (CmmLabelDiffOff _ _ _ _) = text "CmmLabelDiffOff" + ppr (CmmBlock blk) = text "CmmBlock" <+> ppr blk + ppr CmmHighStackMark = text "CmmHighStackMark" + cmmExprType :: Platform -> CmmExpr -> CmmType cmmExprType platform = \case (CmmLit lit) -> cmmLitType platform lit diff --git a/compiler/GHC/CmmToAsm/Ppr.hs b/compiler/GHC/CmmToAsm/Ppr.hs index da99a0db07..a3606219da 100644 --- a/compiler/GHC/CmmToAsm/Ppr.hs +++ b/compiler/GHC/CmmToAsm/Ppr.hs @@ -1,4 +1,4 @@ -{-# LANGUAGE MagicHash #-} +{-# LANGUAGE CPP, MagicHash #-} ----------------------------------------------------------------------------- -- @@ -38,9 +38,17 @@ import Data.Word import Data.Bits import Data.ByteString (ByteString) import qualified Data.ByteString as BS -import GHC.Exts +import GHC.Exts hiding (extendWord8#) import GHC.Word +#if MIN_VERSION_base(4,16,0) +import GHC.Base (extendWord8#) +#else +extendWord8# :: Word# -> Word# +extendWord8# w = w +{-# INLINE extendWord8# #-} +#endif + -- ----------------------------------------------------------------------------- -- Converting floating-point literals to integrals for printing @@ -103,7 +111,7 @@ pprASCII str -- we know that the Chars we create are in the ASCII range -- so we bypass the check in "chr" chr' :: Word8 -> Char - chr' (W8# w#) = C# (chr# (word2Int# w#)) + chr' (W8# w#) = C# (chr# (word2Int# (extendWord8# w#))) octal :: Word8 -> String octal w = [ chr' (ord0 + (w `unsafeShiftR` 6) .&. 0x07) diff --git a/compiler/GHC/CmmToC.hs b/compiler/GHC/CmmToC.hs index d1f722febd..0733369679 100644 --- a/compiler/GHC/CmmToC.hs +++ b/compiler/GHC/CmmToC.hs @@ -159,8 +159,14 @@ pprWordArray platform is_ro lbl ds -- See Note [StgWord alignment] , pprAlignment (wordWidth platform) , text "= {" ] - $$ nest 8 (commafy (pprStatics platform ds)) + $$ nest 8 (commafy (staticLitsToWords platform $ toLits ds)) $$ text "};" + where + toLits :: [CmmStatic] -> [CmmLit] + toLits = map f + where + f (CmmStaticLit lit) = lit + f static = pprPanic "pprWordArray: Unexpected literal" (pprStatic platform static) pprAlignment :: Width -> SDoc pprAlignment words = @@ -501,59 +507,69 @@ pprLit1 platform lit = case lit of -- --------------------------------------------------------------------------- -- Static data -pprStatics :: Platform -> [CmmStatic] -> [SDoc] -pprStatics platform = pprStatics' +-- | Produce a list of word sized literals encoding the given list of 'CmmLit's. +staticLitsToWords :: Platform -> [CmmLit] -> [SDoc] +staticLitsToWords platform = go . foldMap decomposeMultiWord where - pprStatics' = \case - [] -> [] - (CmmStaticLit (CmmFloat f W32) : rest) - -- odd numbers of floats are padded to a word by mkVirtHeapOffsetsWithPadding - | wordWidth platform == W64, CmmStaticLit (CmmInt 0 W32) : rest' <- rest - -> pprLit1 platform (floatToWord platform f) : pprStatics' rest' - -- adjacent floats aren't padded but combined into a single word - | wordWidth platform == W64, CmmStaticLit (CmmFloat g W32) : rest' <- rest - -> pprLit1 platform (floatPairToWord platform f g) : pprStatics' rest' - | wordWidth platform == W32 - -> pprLit1 platform (floatToWord platform f) : pprStatics' rest - | otherwise - -> pprPanic "pprStatics: float" (vcat (map ppr' rest)) - where ppr' (CmmStaticLit l) = ppr (cmmLitType platform l) - ppr' _other = text "bad static!" - - (CmmStaticLit (CmmFloat f W64) : rest) - -> map (pprLit1 platform) (doubleToWords platform f) ++ pprStatics' rest - - (CmmStaticLit (CmmInt i W64) : rest) - | wordWidth platform == W32 - -> case platformByteOrder platform of - BigEndian -> pprStatics' (CmmStaticLit (CmmInt q W32) : - CmmStaticLit (CmmInt r W32) : rest) - LittleEndian -> pprStatics' (CmmStaticLit (CmmInt r W32) : - CmmStaticLit (CmmInt q W32) : rest) - where r = i .&. 0xffffffff - q = i `shiftR` 32 - - (CmmStaticLit (CmmInt a W32) : CmmStaticLit (CmmInt b W32) : rest) - | wordWidth platform == W64 - -> case platformByteOrder platform of - BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 32) .|. b) W64) : rest) - LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 32) .|. a) W64) : rest) - - (CmmStaticLit (CmmInt a W16) : CmmStaticLit (CmmInt b W16) : rest) - | wordWidth platform == W32 - -> case platformByteOrder platform of - BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 16) .|. b) W32) : rest) - LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 16) .|. a) W32) : rest) - - (CmmStaticLit (CmmInt _ w) : _) - | w /= wordWidth platform - -> pprPanic "pprStatics: cannot emit a non-word-sized static literal" (ppr w) - - (CmmStaticLit lit : rest) - -> pprLit1 platform lit : pprStatics' rest - - (other : _) - -> pprPanic "pprStatics: other" (pprStatic platform other) + -- rem_bytes is how many bytes remain in the word we are currently filling. + -- accum is the word we are filling. + go :: [CmmLit] -> [SDoc] + go [] = [] + go lits@(lit : _) + | Just _ <- isSubWordLit lit + = goSubWord wordWidthBytes 0 lits + go (lit : rest) + = pprLit1 platform lit : go rest + + goSubWord :: Int -> Integer -> [CmmLit] -> [SDoc] + goSubWord rem_bytes accum (lit : rest) + | Just (bytes, w) <- isSubWordLit lit + , rem_bytes >= widthInBytes w + = let accum' = + case platformByteOrder platform of + BigEndian -> (accum `shiftL` widthInBits w) .|. bytes + LittleEndian -> (accum `shiftL` widthInBits w) .|. byteSwap w bytes + in goSubWord (rem_bytes - widthInBytes w) accum' rest + goSubWord rem_bytes accum rest + = pprWord (byteSwap (wordWidth platform) $ accum `shiftL` (8*rem_bytes)) : go rest + + -- Decompose multi-word or floating-point literals into multiple + -- single-word (or smaller) literals. + decomposeMultiWord :: CmmLit -> [CmmLit] + decomposeMultiWord (CmmFloat n W64) + -- This will produce a W64 integer, which will then be broken up further + -- on the next iteration on 32-bit platforms. + = [doubleToWord64 n] + decomposeMultiWord (CmmFloat n W32) + = [floatToWord32 n] + decomposeMultiWord (CmmInt n W64) + | W32 <- wordWidth platform + = [CmmInt hi W32, CmmInt lo W32] + where + hi = n `shiftR` 32 + lo = n .&. 0xffffffff + decomposeMultiWord lit = [lit] + + -- Decompose a sub-word-sized literal into the integer value and its + -- (sub-word-sized) width. + isSubWordLit :: CmmLit -> Maybe (Integer, Width) + isSubWordLit lit = + case lit of + CmmInt n w + | w < wordWidth platform -> Just (n, w) + _ -> Nothing + + wordWidthBytes = widthInBytes $ wordWidth platform + + pprWord :: Integer -> SDoc + pprWord n = pprHexVal platform n (wordWidth platform) + +byteSwap :: Width -> Integer -> Integer +byteSwap width n = foldl' f 0 bytes + where + f acc m = (acc `shiftL` 8) .|. m + bytes = [ byte i | i <- [0..widthInBytes width - 1] ] + byte i = (n `shiftR` (i*8)) .&. 0xff pprStatic :: Platform -> CmmStatic -> SDoc pprStatic platform s = case s of @@ -1252,69 +1268,30 @@ pprStringInCStyle s = doubleQuotes (text (concatMap charToC (BS.unpack s))) -- This is a hack to turn the floating point numbers into ints that we -- can safely initialise to static locations. -castFloatToWord32Array :: STUArray s Int Float -> ST s (STUArray s Int Word32) -castFloatToWord32Array = U.castSTUArray - -castDoubleToWord64Array :: STUArray s Int Double -> ST s (STUArray s Int Word64) -castDoubleToWord64Array = U.castSTUArray - -floatToWord :: Platform -> Rational -> CmmLit -floatToWord platform r - = runST (do +floatToWord32 :: Rational -> CmmLit +floatToWord32 r + = runST $ do arr <- newArray_ ((0::Int),0) writeArray arr 0 (fromRational r) arr' <- castFloatToWord32Array arr w32 <- readArray arr' 0 - return (CmmInt (toInteger w32 `shiftL` wo) (wordWidth platform)) - ) - where wo | wordWidth platform == W64 - , BigEndian <- platformByteOrder platform - = 32 - | otherwise - = 0 - -floatPairToWord :: Platform -> Rational -> Rational -> CmmLit -floatPairToWord platform r1 r2 - = runST (do - arr <- newArray_ ((0::Int),1) - writeArray arr 0 (fromRational r1) - writeArray arr 1 (fromRational r2) - arr' <- castFloatToWord32Array arr - w32_1 <- readArray arr' 0 - w32_2 <- readArray arr' 1 - return (pprWord32Pair w32_1 w32_2) - ) - where pprWord32Pair w32_1 w32_2 - | BigEndian <- platformByteOrder platform = - CmmInt ((shiftL i1 32) .|. i2) W64 - | otherwise = - CmmInt ((shiftL i2 32) .|. i1) W64 - where i1 = toInteger w32_1 - i2 = toInteger w32_2 - -doubleToWords :: Platform -> Rational -> [CmmLit] -doubleToWords platform r - = runST (do + return (CmmInt (toInteger w32) W32) + where + castFloatToWord32Array :: STUArray s Int Float -> ST s (STUArray s Int Word32) + castFloatToWord32Array = U.castSTUArray + +doubleToWord64 :: Rational -> CmmLit +doubleToWord64 r + = runST $ do arr <- newArray_ ((0::Int),1) writeArray arr 0 (fromRational r) arr' <- castDoubleToWord64Array arr w64 <- readArray arr' 0 - return (pprWord64 w64) - ) - where targetWidth = wordWidth platform - pprWord64 w64 - | targetWidth == W64 = - [ CmmInt (toInteger w64) targetWidth ] - | targetWidth == W32 = - [ CmmInt (toInteger targetW1) targetWidth - , CmmInt (toInteger targetW2) targetWidth - ] - | otherwise = panic "doubleToWords.pprWord64" - where (targetW1, targetW2) = case platformByteOrder platform of - BigEndian -> (wHi, wLo) - LittleEndian -> (wLo, wHi) - wHi = w64 `shiftR` 32 - wLo = w64 .&. 0xFFFFffff + return $ CmmInt (toInteger w64) W64 + where + castDoubleToWord64Array :: STUArray s Int Double -> ST s (STUArray s Int Word64) + castDoubleToWord64Array = U.castSTUArray + -- --------------------------------------------------------------------------- -- Utils diff --git a/compiler/GHC/Core.hs b/compiler/GHC/Core.hs index 57976e836a..523c8e3d79 100644 --- a/compiler/GHC/Core.hs +++ b/compiler/GHC/Core.hs @@ -29,6 +29,7 @@ module GHC.Core ( mkIntLit, mkIntLitWrap, mkWordLit, mkWordLitWrap, + mkWord8Lit, mkWord64LitWord64, mkInt64LitInt64, mkCharLit, mkStringLit, mkFloatLit, mkFloatLitFloat, @@ -1997,6 +1998,9 @@ mkWordLit platform w = Lit (mkLitWord platform w) mkWordLitWrap :: Platform -> Integer -> Expr b mkWordLitWrap platform w = Lit (mkLitWordWrap platform w) +mkWord8Lit :: Integer -> Expr b +mkWord8Lit w = Lit (mkLitWord8 w) + mkWord64LitWord64 :: Word64 -> Expr b mkWord64LitWord64 w = Lit (mkLitWord64 (toInteger w)) diff --git a/compiler/GHC/Core/Opt/ConstantFold.hs b/compiler/GHC/Core/Opt/ConstantFold.hs index e02a470d7e..8eb920cdc9 100644 --- a/compiler/GHC/Core/Opt/ConstantFold.hs +++ b/compiler/GHC/Core/Opt/ConstantFold.hs @@ -198,6 +198,46 @@ primOpRules nm = \case SrlOp -> mkPrimOpRule nm 2 [ shiftRule LitNumWord shiftRightLogical ] -- coercions + + Int8ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendIntLit ] + Int16ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendIntLit ] + Int32ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendIntLit ] + Int8NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowInt8Lit + , subsumedByPrimOp Int8NarrowOp + , narrowSubsumesAnd AndIOp Int8NarrowOp 8 ] + Int16NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowInt16Lit + , subsumedByPrimOp Int8NarrowOp + , subsumedByPrimOp Int16NarrowOp + , narrowSubsumesAnd AndIOp Int16NarrowOp 16 ] + Int32NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowInt32Lit + , subsumedByPrimOp Int8NarrowOp + , subsumedByPrimOp Int16NarrowOp + , subsumedByPrimOp Int32NarrowOp + , narrowSubsumesAnd AndIOp Int32NarrowOp 32 ] + + Word8ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendWordLit + , extendNarrowPassthrough Word8NarrowOp 0xFF + ] + Word16ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendWordLit + , extendNarrowPassthrough Word16NarrowOp 0xFFFF + ] + Word32ExtendOp -> mkPrimOpRule nm 1 [ liftLitPlatform extendWordLit + , extendNarrowPassthrough Word32NarrowOp 0xFFFFFFFF + ] + Word8NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowWord8Lit + , subsumedByPrimOp Word8NarrowOp + , narrowSubsumesAnd AndOp Word8NarrowOp 8 ] + Word16NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowWord16Lit + , subsumedByPrimOp Word8NarrowOp + , subsumedByPrimOp Word16NarrowOp + , narrowSubsumesAnd AndOp Word16NarrowOp 16 ] + Word32NarrowOp -> mkPrimOpRule nm 1 [ liftLit narrowWord32Lit + , subsumedByPrimOp Word8NarrowOp + , subsumedByPrimOp Word16NarrowOp + , subsumedByPrimOp Word32NarrowOp + , narrowSubsumesAnd AndOp Word32NarrowOp 32 ] + + WordToIntOp -> mkPrimOpRule nm 1 [ liftLitPlatform wordToIntLit , inversePrimOp IntToWordOp ] IntToWordOp -> mkPrimOpRule nm 1 [ liftLitPlatform intToWordLit @@ -625,8 +665,14 @@ isMinBound :: Platform -> Literal -> Bool isMinBound _ (LitChar c) = c == minBound isMinBound platform (LitNumber nt i) = case nt of LitNumInt -> i == platformMinInt platform + LitNumInt8 -> i == toInteger (minBound :: Int8) + LitNumInt16 -> i == toInteger (minBound :: Int16) + LitNumInt32 -> i == toInteger (minBound :: Int32) LitNumInt64 -> i == toInteger (minBound :: Int64) LitNumWord -> i == 0 + LitNumWord8 -> i == 0 + LitNumWord16 -> i == 0 + LitNumWord32 -> i == 0 LitNumWord64 -> i == 0 LitNumNatural -> i == 0 LitNumInteger -> False @@ -636,8 +682,14 @@ isMaxBound :: Platform -> Literal -> Bool isMaxBound _ (LitChar c) = c == maxBound isMaxBound platform (LitNumber nt i) = case nt of LitNumInt -> i == platformMaxInt platform + LitNumInt8 -> i == toInteger (maxBound :: Int8) + LitNumInt16 -> i == toInteger (maxBound :: Int16) + LitNumInt32 -> i == toInteger (maxBound :: Int32) LitNumInt64 -> i == toInteger (maxBound :: Int64) LitNumWord -> i == platformMaxWord platform + LitNumWord8 -> i == toInteger (maxBound :: Word8) + LitNumWord16 -> i == toInteger (maxBound :: Word16) + LitNumWord32 -> i == toInteger (maxBound :: Word32) LitNumWord64 -> i == toInteger (maxBound :: Word64) LitNumNatural -> False LitNumInteger -> False @@ -697,6 +749,13 @@ subsumedByPrimOp primop = do matchPrimOpId primop primop_id return e +-- | Transform `extendWordN (narrowWordN x)` into `x .&. 0xFF..FF` +extendNarrowPassthrough :: PrimOp -> Integer -> RuleM CoreExpr +extendNarrowPassthrough narrow_primop n = do + [Var primop_id `App` x] <- getArgs + matchPrimOpId narrow_primop primop_id + return (Var (mkPrimOpId AndOp) `App` x `App` Lit (LitNumber LitNumWord n)) + -- | narrow subsumes bitwise `and` with full mask (cf #16402): -- -- narrowN (x .&. m) diff --git a/compiler/GHC/CoreToByteCode.hs b/compiler/GHC/CoreToByteCode.hs index f8cb9737d9..96c7ea9dec 100644 --- a/compiler/GHC/CoreToByteCode.hs +++ b/compiler/GHC/CoreToByteCode.hs @@ -1387,6 +1387,12 @@ primRepToFFIType platform r VoidRep -> FFIVoid IntRep -> signed_word WordRep -> unsigned_word + Int8Rep -> FFISInt8 + Word8Rep -> FFIUInt8 + Int16Rep -> FFISInt16 + Word16Rep -> FFIUInt16 + Int32Rep -> FFISInt32 + Word32Rep -> FFIUInt32 Int64Rep -> FFISInt64 Word64Rep -> FFIUInt64 AddrRep -> FFIPointer @@ -1405,6 +1411,12 @@ mkDummyLiteral platform pr = case pr of IntRep -> mkLitInt platform 0 WordRep -> mkLitWord platform 0 + Int8Rep -> mkLitInt8 0 + Word8Rep -> mkLitWord8 0 + Int16Rep -> mkLitInt16 0 + Word16Rep -> mkLitWord16 0 + Int32Rep -> mkLitInt32 0 + Word32Rep -> mkLitWord32 0 Int64Rep -> mkLitInt64 0 Word64Rep -> mkLitWord64 0 AddrRep -> LitNullAddr @@ -1621,24 +1633,39 @@ pushAtom d p (AnnVar var) pushAtom _ _ (AnnLit lit) = do platform <- targetPlatform <$> getDynFlags - let code rep - = let size_words = WordOff (argRepSizeW platform rep) - in return (unitOL (PUSH_UBX lit (trunc16W size_words)), - wordsToBytes platform size_words) + let code :: PrimRep -> BcM (BCInstrList, ByteOff) + code rep = + return (unitOL instr, size_bytes) + where + size_bytes = ByteOff $ primRepSizeB platform rep + -- Here we handle the non-word-width cases specifically since we + -- must emit different bytecode for them. + instr = + case size_bytes of + 1 -> PUSH_UBX8 lit + 2 -> PUSH_UBX16 lit + 4 -> PUSH_UBX32 lit + _ -> PUSH_UBX lit (trunc16W $ bytesToWords platform size_bytes) case lit of - LitLabel _ _ _ -> code N - LitFloat _ -> code F - LitDouble _ -> code D - LitChar _ -> code N - LitNullAddr -> code N - LitString _ -> code N - LitRubbish -> code N + LitLabel _ _ _ -> code AddrRep + LitFloat _ -> code FloatRep + LitDouble _ -> code DoubleRep + LitChar _ -> code WordRep + LitNullAddr -> code AddrRep + LitString _ -> code AddrRep + LitRubbish -> code WordRep LitNumber nt _ -> case nt of - LitNumInt -> code N - LitNumWord -> code N - LitNumInt64 -> code L - LitNumWord64 -> code L + LitNumInt -> code IntRep + LitNumWord -> code WordRep + LitNumInt8 -> code Int8Rep + LitNumWord8 -> code Word8Rep + LitNumInt16 -> code Int16Rep + LitNumWord16 -> code Word16Rep + LitNumInt32 -> code Int32Rep + LitNumWord32 -> code Word32Rep + LitNumInt64 -> code Int64Rep + LitNumWord64 -> code Word64Rep -- No LitInteger's or LitNatural's should be left by the time this is -- called. CorePrep should have converted them all to a real core -- representation. diff --git a/compiler/GHC/HsToCore/Foreign/Call.hs b/compiler/GHC/HsToCore/Foreign/Call.hs index e580057b77..f28d476c05 100644 --- a/compiler/GHC/HsToCore/Foreign/Call.hs +++ b/compiler/GHC/HsToCore/Foreign/Call.hs @@ -21,9 +21,7 @@ where #include "HsVersions.h" - import GHC.Prelude -import GHC.Platform import GHC.Core @@ -41,7 +39,6 @@ import GHC.Core.Type import GHC.Core.Multiplicity import GHC.Types.Id ( Id ) import GHC.Core.Coercion -import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim import GHC.Core.TyCon import GHC.Builtin.Types @@ -355,36 +352,13 @@ resultWrapper result_ty | Just (tycon, tycon_arg_tys) <- maybe_tc_app , Just data_con <- isDataProductTyCon_maybe tycon -- One constructor, no existentials , [Scaled _ unwrapped_res_ty] <- dataConInstOrigArgTys data_con tycon_arg_tys -- One argument - = do { dflags <- getDynFlags - ; let platform = targetPlatform dflags - ; (maybe_ty, wrapper) <- resultWrapper unwrapped_res_ty - ; let narrow_wrapper = maybeNarrow platform tycon - marshal_con e = Var (dataConWrapId data_con) + = do { (maybe_ty, wrapper) <- resultWrapper unwrapped_res_ty + ; let marshal_con e = Var (dataConWrapId data_con) `mkTyApps` tycon_arg_tys - `App` wrapper (narrow_wrapper e) + `App` wrapper e ; return (maybe_ty, marshal_con) } | otherwise = pprPanic "resultWrapper" (ppr result_ty) where maybe_tc_app = splitTyConApp_maybe result_ty - --- When the result of a foreign call is smaller than the word size, we --- need to sign- or zero-extend the result up to the word size. The C --- standard appears to say that this is the responsibility of the --- caller, not the callee. - -maybeNarrow :: Platform -> TyCon -> (CoreExpr -> CoreExpr) -maybeNarrow platform tycon - | tycon `hasKey` int8TyConKey = \e -> App (Var (mkPrimOpId Narrow8IntOp)) e - | tycon `hasKey` int16TyConKey = \e -> App (Var (mkPrimOpId Narrow16IntOp)) e - | tycon `hasKey` int32TyConKey - , platformWordSizeInBytes platform > 4 - = \e -> App (Var (mkPrimOpId Narrow32IntOp)) e - - | tycon `hasKey` word8TyConKey = \e -> App (Var (mkPrimOpId Narrow8WordOp)) e - | tycon `hasKey` word16TyConKey = \e -> App (Var (mkPrimOpId Narrow16WordOp)) e - | tycon `hasKey` word32TyConKey - , platformWordSizeInBytes platform > 4 - = \e -> App (Var (mkPrimOpId Narrow32WordOp)) e - | otherwise = id diff --git a/compiler/GHC/HsToCore/Foreign/Decl.hs b/compiler/GHC/HsToCore/Foreign/Decl.hs index cae1d3f115..1dea63982f 100644 --- a/compiler/GHC/HsToCore/Foreign/Decl.hs +++ b/compiler/GHC/HsToCore/Foreign/Decl.hs @@ -849,6 +849,12 @@ primTyDescChar platform ty = case typePrimRep1 (getPrimTyOf ty) of IntRep -> signed_word WordRep -> unsigned_word + Int8Rep -> 'B' + Word8Rep -> 'b' + Int16Rep -> 'S' + Word16Rep -> 's' + Int32Rep -> 'W' + Word32Rep -> 'w' Int64Rep -> 'L' Word64Rep -> 'l' AddrRep -> 'p' diff --git a/compiler/GHC/HsToCore/Quote.hs b/compiler/GHC/HsToCore/Quote.hs index 16d17fd82e..7f2d0b5d85 100644 --- a/compiler/GHC/HsToCore/Quote.hs +++ b/compiler/GHC/HsToCore/Quote.hs @@ -2784,11 +2784,10 @@ repTyVarSig (MkC bndr) = rep2 tyVarSigName [bndr] repLiteral :: HsLit GhcRn -> MetaM (Core TH.Lit) repLiteral (HsStringPrim _ bs) - = do platform <- getPlatform - word8_ty <- lookupType word8TyConName + = do word8_ty <- lookupType word8TyConName let w8s = unpack bs w8s_expr = map (\w8 -> mkCoreConApps word8DataCon - [mkWordLit platform (toInteger w8)]) w8s + [mkWord8Lit (toInteger w8)]) w8s rep2_nw stringPrimLName [mkListExpr word8_ty w8s_expr] repLiteral lit = do lit' <- case lit of diff --git a/compiler/GHC/Runtime/Heap/Inspect.hs b/compiler/GHC/Runtime/Heap/Inspect.hs index 1b912339e5..d5758cdfbd 100644 --- a/compiler/GHC/Runtime/Heap/Inspect.hs +++ b/compiler/GHC/Runtime/Heap/Inspect.hs @@ -467,6 +467,10 @@ repPrim t = rep where | t == wordPrimTyCon = text $ show (build x :: Word) | t == floatPrimTyCon = text $ show (build x :: Float) | t == doublePrimTyCon = text $ show (build x :: Double) + | t == int8PrimTyCon = text $ show (build x :: Int8) + | t == word8PrimTyCon = text $ show (build x :: Word8) + | t == int16PrimTyCon = text $ show (build x :: Int16) + | t == word16PrimTyCon = text $ show (build x :: Word16) | t == int32PrimTyCon = text $ show (build x :: Int32) | t == word32PrimTyCon = text $ show (build x :: Word32) | t == int64PrimTyCon = text $ show (build x :: Int64) diff --git a/compiler/GHC/StgToCmm/DataCon.hs b/compiler/GHC/StgToCmm/DataCon.hs index 681f1461f1..18a8775cdd 100644 --- a/compiler/GHC/StgToCmm/DataCon.hs +++ b/compiler/GHC/StgToCmm/DataCon.hs @@ -102,6 +102,21 @@ cgTopRhsCon dflags id con args nv_args_w_offsets) = mkVirtHeapOffsetsWithPadding profile StdHeader (addArgReps args) + ; let + -- Decompose padding into units of length 8, 4, 2, or 1 bytes to + -- allow the implementation of mk_payload to use widthFromBytes, + -- which only handles these cases. + fix_padding (x@(Padding n off) : rest) + | n == 0 = fix_padding rest + | n `elem` [1,2,4,8] = x : fix_padding rest + | n > 8 = add_pad 8 + | n > 4 = add_pad 4 + | n > 2 = add_pad 2 + | otherwise = add_pad 1 + where add_pad m = Padding m off : fix_padding (Padding (n-m) (off+m) : rest) + fix_padding (x : rest) = x : fix_padding rest + fix_padding [] = [] + mk_payload (Padding len _) = return (CmmInt 0 (widthFromBytes len)) mk_payload (FieldOff arg _) = do amode <- getArgAmode arg @@ -117,7 +132,7 @@ cgTopRhsCon dflags id con args info_tbl = mkDataConInfoTable profile con True ptr_wds nonptr_wds - ; payload <- mapM mk_payload nv_args_w_offsets + ; payload <- mapM mk_payload (fix_padding nv_args_w_offsets) -- NB1: nv_args_w_offsets is sorted into ptrs then non-ptrs -- NB2: all the amodes should be Lits! -- TODO (osa): Why? diff --git a/compiler/GHC/StgToCmm/Prim.hs b/compiler/GHC/StgToCmm/Prim.hs index 625e76f085..4d13d3960c 100644 --- a/compiler/GHC/StgToCmm/Prim.hs +++ b/compiler/GHC/StgToCmm/Prim.hs @@ -1195,8 +1195,8 @@ emitPrimOp dflags primop = case primop of -- Int8# signed ops - Int8Extend -> \args -> opTranslate args (MO_SS_Conv W8 (wordWidth platform)) - Int8Narrow -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W8) + Int8ExtendOp -> \args -> opTranslate args (MO_SS_Conv W8 (wordWidth platform)) + Int8NarrowOp -> \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) @@ -1213,8 +1213,8 @@ emitPrimOp dflags primop = case primop of -- Word8# unsigned ops - Word8Extend -> \args -> opTranslate args (MO_UU_Conv W8 (wordWidth platform)) - Word8Narrow -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W8) + Word8ExtendOp -> \args -> opTranslate args (MO_UU_Conv W8 (wordWidth platform)) + Word8NarrowOp -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W8) Word8NotOp -> \args -> opTranslate args (MO_Not W8) Word8AddOp -> \args -> opTranslate args (MO_Add W8) Word8SubOp -> \args -> opTranslate args (MO_Sub W8) @@ -1231,8 +1231,8 @@ emitPrimOp dflags primop = case primop of -- Int16# signed ops - Int16Extend -> \args -> opTranslate args (MO_SS_Conv W16 (wordWidth platform)) - Int16Narrow -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W16) + Int16ExtendOp -> \args -> opTranslate args (MO_SS_Conv W16 (wordWidth platform)) + Int16NarrowOp -> \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) @@ -1249,8 +1249,8 @@ emitPrimOp dflags primop = case primop of -- Word16# unsigned ops - Word16Extend -> \args -> opTranslate args (MO_UU_Conv W16 (wordWidth platform)) - Word16Narrow -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W16) + Word16ExtendOp -> \args -> opTranslate args (MO_UU_Conv W16 (wordWidth platform)) + Word16NarrowOp -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W16) Word16NotOp -> \args -> opTranslate args (MO_Not W16) Word16AddOp -> \args -> opTranslate args (MO_Add W16) Word16SubOp -> \args -> opTranslate args (MO_Sub W16) @@ -1265,6 +1265,16 @@ emitPrimOp dflags primop = case primop of Word16LtOp -> \args -> opTranslate args (MO_U_Lt W16) Word16NeOp -> \args -> opTranslate args (MO_Ne W16) +-- Int32# signed ops + + Int32ExtendOp -> \args -> opTranslate args (MO_SS_Conv W32 (wordWidth platform)) + Int32NarrowOp -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W32) + +-- Word32# unsigned ops + + Word32ExtendOp -> \args -> opTranslate args (MO_UU_Conv W32 (wordWidth platform)) + Word32NarrowOp -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W32) + -- Char# ops CharEqOp -> \args -> opTranslate args (MO_Eq (wordWidth platform)) diff --git a/compiler/GHC/StgToCmm/Utils.hs b/compiler/GHC/StgToCmm/Utils.hs index dbb4481d72..8cca28cc5a 100644 --- a/compiler/GHC/StgToCmm/Utils.hs +++ b/compiler/GHC/StgToCmm/Utils.hs @@ -106,8 +106,14 @@ mkSimpleLit platform = \case (wordWidth platform) LitNullAddr -> zeroCLit platform (LitNumber LitNumInt i) -> CmmInt i (wordWidth platform) + (LitNumber LitNumInt8 i) -> CmmInt i W8 + (LitNumber LitNumInt16 i) -> CmmInt i W16 + (LitNumber LitNumInt32 i) -> CmmInt i W32 (LitNumber LitNumInt64 i) -> CmmInt i W64 (LitNumber LitNumWord i) -> CmmInt i (wordWidth platform) + (LitNumber LitNumWord8 i) -> CmmInt i W8 + (LitNumber LitNumWord16 i) -> CmmInt i W16 + (LitNumber LitNumWord32 i) -> CmmInt i W32 (LitNumber LitNumWord64 i) -> CmmInt i W64 (LitFloat r) -> CmmFloat r W32 (LitDouble r) -> CmmFloat r W64 diff --git a/compiler/GHC/Types/Literal.hs b/compiler/GHC/Types/Literal.hs index 461f4ac70a..a5c855a4fa 100644 --- a/compiler/GHC/Types/Literal.hs +++ b/compiler/GHC/Types/Literal.hs @@ -17,6 +17,12 @@ module GHC.Types.Literal -- ** Creating Literals , mkLitInt, mkLitIntWrap, mkLitIntWrapC, mkLitIntUnchecked , mkLitWord, mkLitWordWrap, mkLitWordWrapC + , mkLitInt8, mkLitInt8Wrap + , mkLitWord8, mkLitWord8Wrap + , mkLitInt16, mkLitInt16Wrap + , mkLitWord16, mkLitWord16Wrap + , mkLitInt32, mkLitInt32Wrap + , mkLitWord32, mkLitWord32Wrap , mkLitInt64, mkLitInt64Wrap , mkLitWord64, mkLitWord64Wrap , mkLitFloat, mkLitDouble @@ -40,9 +46,13 @@ module GHC.Types.Literal -- ** Coercions , wordToIntLit, intToWordLit - , narrowLit , narrow8IntLit, narrow16IntLit, narrow32IntLit , narrow8WordLit, narrow16WordLit, narrow32WordLit + , narrowInt8Lit, narrowInt16Lit, narrowInt32Lit + , narrowWord8Lit, narrowWord16Lit, narrowWord32Lit + , extendIntLit, extendWordLit + , int8Lit, int16Lit, int32Lit + , word8Lit, word16Lit, word32Lit , charToIntLit, intToCharLit , floatToIntLit, intToFloatLit, doubleToIntLit, intToDoubleLit , nullAddrLit, rubbishLit, floatToDoubleLit, doubleToFloatLit @@ -152,8 +162,14 @@ data LitNumType = LitNumInteger -- ^ @Integer@ (see Note [BigNum literals]) | LitNumNatural -- ^ @Natural@ (see Note [BigNum literals]) | LitNumInt -- ^ @Int#@ - according to target machine + | LitNumInt8 -- ^ @Int8#@ - exactly 8 bits + | LitNumInt16 -- ^ @Int16#@ - exactly 16 bits + | LitNumInt32 -- ^ @Int32#@ - exactly 32 bits | LitNumInt64 -- ^ @Int64#@ - exactly 64 bits | LitNumWord -- ^ @Word#@ - according to target machine + | LitNumWord8 -- ^ @Word8#@ - exactly 8 bits + | LitNumWord16 -- ^ @Word16#@ - exactly 16 bits + | LitNumWord32 -- ^ @Word32#@ - exactly 32 bits | LitNumWord64 -- ^ @Word64#@ - exactly 64 bits deriving (Data,Enum,Eq,Ord) @@ -163,8 +179,14 @@ litNumIsSigned nt = case nt of LitNumInteger -> True LitNumNatural -> False LitNumInt -> True + LitNumInt8 -> True + LitNumInt16 -> True + LitNumInt32 -> True LitNumInt64 -> True LitNumWord -> False + LitNumWord8 -> False + LitNumWord16 -> False + LitNumWord32 -> False LitNumWord64 -> False {- @@ -290,6 +312,12 @@ wrapLitNumber platform v@(LitNumber nt i) = case nt of LitNumWord -> case platformWordSize platform of PW4 -> LitNumber nt (toInteger (fromIntegral i :: Word32)) PW8 -> LitNumber nt (toInteger (fromIntegral i :: Word64)) + LitNumInt8 -> LitNumber nt (toInteger (fromIntegral i :: Int8)) + LitNumWord8 -> LitNumber nt (toInteger (fromIntegral i :: Word8)) + LitNumInt16 -> LitNumber nt (toInteger (fromIntegral i :: Int16)) + LitNumWord16 -> LitNumber nt (toInteger (fromIntegral i :: Word16)) + LitNumInt32 -> LitNumber nt (toInteger (fromIntegral i :: Int32)) + LitNumWord32 -> LitNumber nt (toInteger (fromIntegral i :: Word32)) LitNumInt64 -> LitNumber nt (toInteger (fromIntegral i :: Int64)) LitNumWord64 -> LitNumber nt (toInteger (fromIntegral i :: Word64)) LitNumInteger -> v @@ -305,7 +333,13 @@ litNumCheckRange :: Platform -> LitNumType -> Integer -> Bool litNumCheckRange platform nt i = case nt of LitNumInt -> platformInIntRange platform i LitNumWord -> platformInWordRange platform i + LitNumInt8 -> inInt8Range i + LitNumInt16 -> inInt16Range i + LitNumInt32 -> inInt32Range i LitNumInt64 -> inInt64Range i + LitNumWord8 -> inWord8Range i + LitNumWord16 -> inWord16Range i + LitNumWord32 -> inWord32Range i LitNumWord64 -> inWord64Range i LitNumNatural -> i >= 0 LitNumInteger -> True @@ -364,6 +398,84 @@ mkLitWordWrapC platform i = (n, i /= i') where n@(LitNumber _ i') = mkLitWordWrap platform i +-- | Creates a 'Literal' of type @Int8#@ +mkLitInt8 :: Integer -> Literal +mkLitInt8 x = ASSERT2( inInt8Range x, integer x ) (mkLitInt8Unchecked x) + +-- | Creates a 'Literal' of type @Int8#@. +-- If the argument is out of the range, it is wrapped. +mkLitInt8Wrap :: Platform -> Integer -> Literal +mkLitInt8Wrap platform i = wrapLitNumber platform $ mkLitInt8Unchecked i + +-- | Creates a 'Literal' of type @Int8#@ without checking its range. +mkLitInt8Unchecked :: Integer -> Literal +mkLitInt8Unchecked i = LitNumber LitNumInt8 i + +-- | Creates a 'Literal' of type @Word8#@ +mkLitWord8 :: Integer -> Literal +mkLitWord8 x = ASSERT2( inWord8Range x, integer x ) (mkLitWord8Unchecked x) + +-- | Creates a 'Literal' of type @Word8#@. +-- If the argument is out of the range, it is wrapped. +mkLitWord8Wrap :: Platform -> Integer -> Literal +mkLitWord8Wrap platform i = wrapLitNumber platform $ mkLitWord8Unchecked i + +-- | Creates a 'Literal' of type @Word8#@ without checking its range. +mkLitWord8Unchecked :: Integer -> Literal +mkLitWord8Unchecked i = LitNumber LitNumWord8 i + +-- | Creates a 'Literal' of type @Int16#@ +mkLitInt16 :: Integer -> Literal +mkLitInt16 x = ASSERT2( inInt16Range x, integer x ) (mkLitInt16Unchecked x) + +-- | Creates a 'Literal' of type @Int16#@. +-- If the argument is out of the range, it is wrapped. +mkLitInt16Wrap :: Platform -> Integer -> Literal +mkLitInt16Wrap platform i = wrapLitNumber platform $ mkLitInt16Unchecked i + +-- | Creates a 'Literal' of type @Int16#@ without checking its range. +mkLitInt16Unchecked :: Integer -> Literal +mkLitInt16Unchecked i = LitNumber LitNumInt16 i + +-- | Creates a 'Literal' of type @Word16#@ +mkLitWord16 :: Integer -> Literal +mkLitWord16 x = ASSERT2( inWord16Range x, integer x ) (mkLitWord16Unchecked x) + +-- | Creates a 'Literal' of type @Word16#@. +-- If the argument is out of the range, it is wrapped. +mkLitWord16Wrap :: Platform -> Integer -> Literal +mkLitWord16Wrap platform i = wrapLitNumber platform $ mkLitWord16Unchecked i + +-- | Creates a 'Literal' of type @Word16#@ without checking its range. +mkLitWord16Unchecked :: Integer -> Literal +mkLitWord16Unchecked i = LitNumber LitNumWord16 i + +-- | Creates a 'Literal' of type @Int32#@ +mkLitInt32 :: Integer -> Literal +mkLitInt32 x = ASSERT2( inInt32Range x, integer x ) (mkLitInt32Unchecked x) + +-- | Creates a 'Literal' of type @Int32#@. +-- If the argument is out of the range, it is wrapped. +mkLitInt32Wrap :: Platform -> Integer -> Literal +mkLitInt32Wrap platform i = wrapLitNumber platform $ mkLitInt32Unchecked i + +-- | Creates a 'Literal' of type @Int32#@ without checking its range. +mkLitInt32Unchecked :: Integer -> Literal +mkLitInt32Unchecked i = LitNumber LitNumInt32 i + +-- | Creates a 'Literal' of type @Word32#@ +mkLitWord32 :: Integer -> Literal +mkLitWord32 x = ASSERT2( inWord32Range x, integer x ) (mkLitWord32Unchecked x) + +-- | Creates a 'Literal' of type @Word32#@. +-- If the argument is out of the range, it is wrapped. +mkLitWord32Wrap :: Platform -> Integer -> Literal +mkLitWord32Wrap platform i = wrapLitNumber platform $ mkLitWord32Unchecked i + +-- | Creates a 'Literal' of type @Word32#@ without checking its range. +mkLitWord32Unchecked :: Integer -> Literal +mkLitWord32Unchecked i = LitNumber LitNumWord32 i + -- | Creates a 'Literal' of type @Int64#@ mkLitInt64 :: Integer -> Literal mkLitInt64 x = ASSERT2( inInt64Range x, integer x ) (mkLitInt64Unchecked x) @@ -418,7 +530,20 @@ mkLitNatural x = ASSERT2( inNaturalRange x, integer x ) inNaturalRange :: Integer -> Bool inNaturalRange x = x >= 0 -inInt64Range, inWord64Range :: Integer -> Bool +inInt8Range, inWord8Range, inInt16Range, inWord16Range :: Integer -> Bool +inInt32Range, inWord32Range, inInt64Range, inWord64Range :: Integer -> Bool +inInt8Range x = x >= toInteger (minBound :: Int8) && + x <= toInteger (maxBound :: Int8) +inWord8Range x = x >= toInteger (minBound :: Word8) && + x <= toInteger (maxBound :: Word8) +inInt16Range x = x >= toInteger (minBound :: Int16) && + x <= toInteger (maxBound :: Int16) +inWord16Range x = x >= toInteger (minBound :: Word16) && + x <= toInteger (maxBound :: Word16) +inInt32Range x = x >= toInteger (minBound :: Int32) && + x <= toInteger (maxBound :: Int32) +inWord32Range x = x >= toInteger (minBound :: Word32) && + x <= toInteger (maxBound :: Word32) inInt64Range x = x >= toInteger (minBound :: Int64) && x <= toInteger (maxBound :: Int64) inWord64Range x = x >= toInteger (minBound :: Word64) && @@ -466,6 +591,8 @@ mapLitValue _ _ l = pprPanic "mapLitValue" (ppr l) narrow8IntLit, narrow16IntLit, narrow32IntLit, narrow8WordLit, narrow16WordLit, narrow32WordLit, + int8Lit, int16Lit, int32Lit, + word8Lit, word16Lit, word32Lit, charToIntLit, intToCharLit, floatToIntLit, intToFloatLit, doubleToIntLit, intToDoubleLit, floatToDoubleLit, doubleToFloatLit @@ -489,16 +616,46 @@ intToWordLit platform (LitNumber LitNumInt i) intToWordLit _ l = pprPanic "intToWordLit" (ppr l) -- | Narrow a literal number (unchecked result range) -narrowLit :: forall a. Integral a => Proxy a -> Literal -> Literal -narrowLit _ (LitNumber nt i) = LitNumber nt (toInteger (fromInteger i :: a)) -narrowLit _ l = pprPanic "narrowLit" (ppr l) - -narrow8IntLit = narrowLit (Proxy :: Proxy Int8) -narrow16IntLit = narrowLit (Proxy :: Proxy Int16) -narrow32IntLit = narrowLit (Proxy :: Proxy Int32) -narrow8WordLit = narrowLit (Proxy :: Proxy Word8) -narrow16WordLit = narrowLit (Proxy :: Proxy Word16) -narrow32WordLit = narrowLit (Proxy :: Proxy Word32) +narrowLit' :: forall a. Integral a => Proxy a -> LitNumType -> Literal -> Literal +narrowLit' _ nt' (LitNumber _ i) = LitNumber nt' (toInteger (fromInteger i :: a)) +narrowLit' _ _ l = pprPanic "narrowLit" (ppr l) + +narrow8IntLit = narrowLit' (Proxy :: Proxy Int8) LitNumInt +narrow16IntLit = narrowLit' (Proxy :: Proxy Int16) LitNumInt +narrow32IntLit = narrowLit' (Proxy :: Proxy Int32) LitNumInt +narrow8WordLit = narrowLit' (Proxy :: Proxy Word8) LitNumWord +narrow16WordLit = narrowLit' (Proxy :: Proxy Word16) LitNumWord +narrow32WordLit = narrowLit' (Proxy :: Proxy Word32) LitNumWord + +narrowInt8Lit, narrowInt16Lit, narrowInt32Lit, + narrowWord8Lit, narrowWord16Lit, narrowWord32Lit :: Literal -> Literal +narrowInt8Lit = narrowLit' (Proxy :: Proxy Int8) LitNumInt8 +narrowInt16Lit = narrowLit' (Proxy :: Proxy Int16) LitNumInt16 +narrowInt32Lit = narrowLit' (Proxy :: Proxy Int32) LitNumInt32 +narrowWord8Lit = narrowLit' (Proxy :: Proxy Word8) LitNumWord8 +narrowWord16Lit = narrowLit' (Proxy :: Proxy Word16) LitNumWord16 +narrowWord32Lit = narrowLit' (Proxy :: Proxy Word32) LitNumWord32 + +-- | Extend a fixed-width literal (e.g. 'Int16#') to a word-sized literal (e.g. +-- 'Int#'). +extendWordLit, extendIntLit :: Platform -> Literal -> Literal +extendWordLit platform (LitNumber _nt i) = mkLitWord platform i +extendWordLit _platform l = pprPanic "extendWordLit" (ppr l) +extendIntLit platform (LitNumber _nt i) = mkLitInt platform i +extendIntLit _platform l = pprPanic "extendIntLit" (ppr l) + +int8Lit (LitNumber _ i) = mkLitInt8 i +int8Lit l = pprPanic "int8Lit" (ppr l) +int16Lit (LitNumber _ i) = mkLitInt16 i +int16Lit l = pprPanic "int16Lit" (ppr l) +int32Lit (LitNumber _ i) = mkLitInt32 i +int32Lit l = pprPanic "int32Lit" (ppr l) +word8Lit (LitNumber _ i) = mkLitWord8 i +word8Lit l = pprPanic "word8Lit" (ppr l) +word16Lit (LitNumber _ i) = mkLitWord16 i +word16Lit l = pprPanic "word16Lit" (ppr l) +word32Lit (LitNumber _ i) = mkLitWord32 i +word32Lit l = pprPanic "word32Lit" (ppr l) charToIntLit (LitChar c) = mkLitIntUnchecked (toInteger (ord c)) charToIntLit l = pprPanic "charToIntLit" (ppr l) @@ -572,8 +729,14 @@ litIsTrivial (LitNumber nt _) = case nt of LitNumInteger -> False LitNumNatural -> False LitNumInt -> True + LitNumInt8 -> True + LitNumInt16 -> True + LitNumInt32 -> True LitNumInt64 -> True LitNumWord -> True + LitNumWord8 -> True + LitNumWord16 -> True + LitNumWord32 -> True LitNumWord64 -> True litIsTrivial _ = True @@ -585,8 +748,14 @@ litIsDupable platform x = case x of LitNumInteger -> platformInIntRange platform i LitNumNatural -> platformInWordRange platform i LitNumInt -> True + LitNumInt8 -> True + LitNumInt16 -> True + LitNumInt32 -> True LitNumInt64 -> True LitNumWord -> True + LitNumWord8 -> True + LitNumWord16 -> True + LitNumWord32 -> True LitNumWord64 -> True (LitString _) -> False _ -> True @@ -601,8 +770,14 @@ litIsLifted (LitNumber nt _) = case nt of LitNumInteger -> True LitNumNatural -> True LitNumInt -> False + LitNumInt8 -> False + LitNumInt16 -> False + LitNumInt32 -> False LitNumInt64 -> False LitNumWord -> False + LitNumWord8 -> False + LitNumWord16 -> False + LitNumWord32 -> False LitNumWord64 -> False litIsLifted _ = False @@ -623,8 +798,14 @@ literalType (LitNumber lt _) = case lt of LitNumInteger -> integerTy LitNumNatural -> naturalTy LitNumInt -> intPrimTy + LitNumInt8 -> int8PrimTy + LitNumInt16 -> int16PrimTy + LitNumInt32 -> int32PrimTy LitNumInt64 -> int64PrimTy LitNumWord -> wordPrimTy + LitNumWord8 -> word8PrimTy + LitNumWord16 -> word16PrimTy + LitNumWord32 -> word32PrimTy LitNumWord64 -> word64PrimTy literalType (LitRubbish) = mkForAllTy a Inferred (mkTyVarTy a) where @@ -700,8 +881,14 @@ pprLiteral add_par (LitNumber nt i) LitNumInteger -> pprIntegerVal add_par i LitNumNatural -> pprIntegerVal add_par i LitNumInt -> pprPrimInt i + LitNumInt8 -> pprPrimInt8 i + LitNumInt16 -> pprPrimInt16 i + LitNumInt32 -> pprPrimInt32 i LitNumInt64 -> pprPrimInt64 i LitNumWord -> pprPrimWord i + LitNumWord8 -> pprPrimWord8 i + LitNumWord16 -> pprPrimWord16 i + LitNumWord32 -> pprPrimWord32 i LitNumWord64 -> pprPrimWord64 i pprLiteral add_par (LitLabel l mb fod) = add_par (text "__label" <+> b <+> ppr fod) diff --git a/compiler/GHC/Utils/Outputable.hs b/compiler/GHC/Utils/Outputable.hs index 3698c5a4b2..7cbd0c4ffd 100644 --- a/compiler/GHC/Utils/Outputable.hs +++ b/compiler/GHC/Utils/Outputable.hs @@ -62,7 +62,9 @@ module GHC.Utils.Outputable ( primFloatSuffix, primCharSuffix, primWordSuffix, primDoubleSuffix, primInt64Suffix, primWord64Suffix, primIntSuffix, - pprPrimChar, pprPrimInt, pprPrimWord, pprPrimInt64, pprPrimWord64, + pprPrimChar, pprPrimInt, pprPrimWord, + pprPrimInt8, pprPrimInt16, pprPrimInt32, pprPrimInt64, + pprPrimWord8, pprPrimWord16, pprPrimWord32, pprPrimWord64, pprFastFilePath, pprFilePathString, @@ -1149,22 +1151,40 @@ pprHsBytes bs = let escaped = concatMap escape $ BS.unpack bs -- Postfix modifiers for unboxed literals. -- See Note [Printing of literals in Core] in "GHC.Types.Literal". primCharSuffix, primFloatSuffix, primIntSuffix :: SDoc -primDoubleSuffix, primWordSuffix, primInt64Suffix, primWord64Suffix :: SDoc +primDoubleSuffix, primWordSuffix :: SDoc +primInt8Suffix, primWord8Suffix :: SDoc +primInt16Suffix, primWord16Suffix :: SDoc +primInt32Suffix, primWord32Suffix :: SDoc +primInt64Suffix, primWord64Suffix :: SDoc primCharSuffix = char '#' primFloatSuffix = char '#' primIntSuffix = char '#' primDoubleSuffix = text "##" primWordSuffix = text "##" -primInt64Suffix = text "L#" -primWord64Suffix = text "L##" +primInt8Suffix = text "#8" +primWord8Suffix = text "##8" +primInt16Suffix = text "#16" +primWord16Suffix = text "##16" +primInt32Suffix = text "#32" +primWord32Suffix = text "##32" +primInt64Suffix = text "#64" +primWord64Suffix = text "##64" -- | Special combinator for showing unboxed literals. pprPrimChar :: Char -> SDoc -pprPrimInt, pprPrimWord, pprPrimInt64, pprPrimWord64 :: Integer -> SDoc +pprPrimInt, pprPrimWord :: Integer -> SDoc +pprPrimInt8, pprPrimInt16, pprPrimInt32, pprPrimInt64 :: Integer -> SDoc +pprPrimWord8, pprPrimWord16, pprPrimWord32, pprPrimWord64 :: Integer -> SDoc pprPrimChar c = pprHsChar c <> primCharSuffix pprPrimInt i = integer i <> primIntSuffix pprPrimWord w = word w <> primWordSuffix +pprPrimInt8 i = integer i <> primInt8Suffix +pprPrimInt16 i = integer i <> primInt16Suffix +pprPrimInt32 i = integer i <> primInt32Suffix pprPrimInt64 i = integer i <> primInt64Suffix +pprPrimWord8 w = word w <> primWord8Suffix +pprPrimWord16 w = word w <> primWord16Suffix +pprPrimWord32 w = word w <> primWord32Suffix pprPrimWord64 w = word w <> primWord64Suffix --------------------- |