ghc-prim 0.5.1.1 → 0.5.2.0
raw patch · 10 files changed
+405/−51 lines, 10 filessetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ GHC.Prim: compareByteArrays# :: ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#
+ GHC.Prim: pdep# :: Word# -> Word# -> Word#
+ GHC.Prim: pdep16# :: Word# -> Word# -> Word#
+ GHC.Prim: pdep32# :: Word# -> Word# -> Word#
+ GHC.Prim: pdep64# :: Word# -> Word# -> Word#
+ GHC.Prim: pdep8# :: Word# -> Word# -> Word#
+ GHC.Prim: pext# :: Word# -> Word# -> Word#
+ GHC.Prim: pext16# :: Word# -> Word# -> Word#
+ GHC.Prim: pext32# :: Word# -> Word# -> Word#
+ GHC.Prim: pext64# :: Word# -> Word# -> Word#
+ GHC.Prim: pext8# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: compareByteArrays# :: ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#
+ GHC.PrimopWrappers: pdep# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pdep16# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pdep32# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pdep64# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pdep8# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pext# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pext16# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pext32# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pext64# :: Word# -> Word# -> Word#
+ GHC.PrimopWrappers: pext8# :: Word# -> Word# -> Word#
- GHC.Types: data TYPE (a :: RuntimeRep) :: RuntimeRep -> *
+ GHC.Types: data TYPE (a :: RuntimeRep)
Files
- GHC/CString.hs +16/−12
- GHC/Prim.hs +105/−17
- GHC/PrimopWrappers.hs +33/−0
- GHC/Types.hs +2/−2
- Setup.hs +87/−1
- cbits/atomic.c +50/−8
- cbits/pdep.c +48/−0
- cbits/pext.c +44/−0
- changelog.md +10/−0
- ghc-prim.cabal +10/−11
GHC/CString.hs view
@@ -125,24 +125,28 @@ unpackCStringUtf8# addr = unpack 0# where+ -- We take care to strictly evaluate the character decoding as+ -- indexCharOffAddr# is marked with the can_fail flag and+ -- consequently GHC won't evaluate the expression unless it is absolutely+ -- needed. unpack nh | isTrue# (ch `eqChar#` '\0'# ) = [] | isTrue# (ch `leChar#` '\x7F'#) = C# ch : unpack (nh +# 1#) | isTrue# (ch `leChar#` '\xDF'#) =- C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +#- (ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#))) :- unpack (nh +# 2#)+ let !c = C# (chr# (((ord# ch -# 0xC0#) `uncheckedIShiftL#` 6#) +#+ (ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#)))+ in c : unpack (nh +# 2#) | isTrue# (ch `leChar#` '\xEF'#) =- C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +#- ((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 6#) +#- (ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#))) :- unpack (nh +# 3#)+ let !c = C# (chr# (((ord# ch -# 0xE0#) `uncheckedIShiftL#` 12#) +#+ ((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 6#) +#+ (ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#)))+ in c : unpack (nh +# 3#) | True =- C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +#- ((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 12#) +#- ((ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#) `uncheckedIShiftL#` 6#) +#- (ord# (indexCharOffAddr# addr (nh +# 3#)) -# 0x80#))) :- unpack (nh +# 4#)+ let !c = C# (chr# (((ord# ch -# 0xF0#) `uncheckedIShiftL#` 18#) +#+ ((ord# (indexCharOffAddr# addr (nh +# 1#)) -# 0x80#) `uncheckedIShiftL#` 12#) +#+ ((ord# (indexCharOffAddr# addr (nh +# 2#)) -# 0x80#) `uncheckedIShiftL#` 6#) +#+ (ord# (indexCharOffAddr# addr (nh +# 3#)) -# 0x80#)))+ in c : unpack (nh +# 4#) where !ch = indexCharOffAddr# addr nh
GHC/Prim.hs view
@@ -158,6 +158,16 @@ popCnt32#, popCnt64#, popCnt#,+ pdep8#,+ pdep16#,+ pdep32#,+ pdep64#,+ pdep#,+ pext8#,+ pext16#,+ pext32#,+ pext64#,+ pext#, clz8#, clz16#, clz32#,@@ -391,6 +401,7 @@ writeWord16Array#, writeWord32Array#, writeWord64Array#,+ compareByteArrays#, copyByteArray#, copyMutableByteArray#, copyByteArrayToAddr#,@@ -1489,7 +1500,7 @@ -- |Return non-zero if there is any possibility that the upper word of a -- signed integer multiply might contain useful information. Return -- zero only if you are completely sure that no overflow can occur.--- On a 32-bit platform, the recommmended implementation is to do a+-- On a 32-bit platform, the recommended implementation is to do a -- 32 x 32 -> 64 signed multiply, and subtract result[63:32] from -- (result[31] >>signed 31). If this is zero, meaning that the -- upper word is merely a sign extension of the lower one, no@@ -1728,6 +1739,56 @@ popCnt# :: Word# -> Word# popCnt# = popCnt# +-- |Deposit bits to lower 8 bits of a word at locations specified by a mask.++pdep8# :: Word# -> Word# -> Word#+pdep8# = pdep8#++-- |Deposit bits to lower 16 bits of a word at locations specified by a mask.++pdep16# :: Word# -> Word# -> Word#+pdep16# = pdep16#++-- |Deposit bits to lower 32 bits of a word at locations specified by a mask.++pdep32# :: Word# -> Word# -> Word#+pdep32# = pdep32#++-- |Deposit bits to a word at locations specified by a mask.++pdep64# :: Word# -> Word# -> Word#+pdep64# = pdep64#++-- |Deposit bits to a word at locations specified by a mask.++pdep# :: Word# -> Word# -> Word#+pdep# = pdep#++-- |Extract bits from lower 8 bits of a word at locations specified by a mask.++pext8# :: Word# -> Word# -> Word#+pext8# = pext8#++-- |Extract bits from lower 16 bits of a word at locations specified by a mask.++pext16# :: Word# -> Word# -> Word#+pext16# = pext16#++-- |Extract bits from lower 32 bits of a word at locations specified by a mask.++pext32# :: Word# -> Word# -> Word#+pext32# = pext32#++-- |Extract bits from a word at locations specified by a mask.++pext64# :: Word# -> Word# -> Word#+pext64# = pext64#++-- |Extract bits from a word at locations specified by a mask.++pext# :: Word# -> Word# -> Word#+pext# = pext#+ -- |Count leading zeros in the lower 8 bits of a word. clz8# :: Word# -> Word#@@ -2085,9 +2146,10 @@ -- |Given a source array, an offset into the source array, a -- destination array, an offset into the destination array, and a -- number of elements to copy, copy the elements from the source array--- to the destination array. The source and destination arrays can--- refer to the same array. Both arrays must fully contain the--- specified ranges, but this is not checked.+-- to the destination array. Both arrays must fully contain the+-- specified ranges, but this is not checked. In the case where+-- the source and destination are the same array the source and+-- destination regions may overlap. copyMutableArray# :: MutableArray# s a -> Int# -> MutableArray# s a -> Int# -> Int# -> State# s -> State# s copyMutableArray# = copyMutableArray#@@ -2196,6 +2258,8 @@ -- to the destination array. The source and destination arrays can -- refer to the same array. Both arrays must fully contain the -- specified ranges, but this is not checked.+-- The regions are allowed to overlap, although this is only possible when the same +-- array is provided as both the source and the destination. copySmallMutableArray# :: SmallMutableArray# s a -> Int# -> SmallMutableArray# s a -> Int# -> Int# -> State# s -> State# s copySmallMutableArray# = copySmallMutableArray#@@ -2398,7 +2462,7 @@ readWideCharArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s,Char# #) readWideCharArray# = readWideCharArray# --- |Read intger; offset in words.+-- |Read integer; offset in words. readIntArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s,Int# #) readIntArray# = readIntArray#@@ -2496,15 +2560,34 @@ writeWord64Array# :: MutableByteArray# s -> Int# -> Word# -> State# s -> State# s writeWord64Array# = writeWord64Array# --- |Copy a range of the ByteArray# to the specified region in the MutableByteArray#.--- Both arrays must fully contain the specified ranges, but this is not checked.--- The two arrays must not be the same array in different states, but this is not checked either.+-- |@compareByteArrays# src1 src1_ofs src2 src2_ofs n@ compares+-- @n@ bytes starting at offset @src1_ofs@ in the first+-- @ByteArray#@ @src1@ to the range of @n@ bytes+-- (i.e. same length) starting at offset @src2_ofs@ of the second+-- @ByteArray#@ @src2@. Both arrays must fully contain the+-- specified ranges, but this is not checked. Returns an @Int#@+-- less than, equal to, or greater than zero if the range is found,+-- respectively, to be byte-wise lexicographically less than, to+-- match, or be greater than the second range. +compareByteArrays# :: ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#+compareByteArrays# = compareByteArrays#++-- |@copyByteArray# src src_ofs dst dst_ofs n@ copies the range+-- starting at offset @src_ofs@ of length @n@ from the+-- @ByteArray#@ @src@ to the @MutableByteArray#@ @dst@+-- starting at offset @dst_ofs@. Both arrays must fully contain+-- the specified ranges, but this is not checked. The two arrays must+-- not be the same array in different states, but this is not checked+-- either.+ copyByteArray# :: ByteArray# -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s copyByteArray# = copyByteArray# -- |Copy a range of the first MutableByteArray# to the specified region in the second MutableByteArray#.--- Both arrays must fully contain the specified ranges, but this is not checked.+-- Both arrays must fully contain the specified ranges, but this is not checked. The regions are+-- allowed to overlap, although this is only possible when the same array is provided+-- as both the source and the destination. copyMutableByteArray# :: MutableByteArray# s -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s copyMutableByteArray# = copyMutableByteArray#@@ -2674,6 +2757,9 @@ -- |Copy a range of the first MutableArrayArray# to the specified region in the second -- MutableArrayArray#. -- Both arrays must fully contain the specified ranges, but this is not checked.+-- The regions are allowed to overlap, although this is only possible when the same +-- array is provided as both the source and the destination.+-- copyMutableArrayArray# :: MutableArrayArray# s -> Int# -> MutableArrayArray# s -> Int# -> Int# -> State# s -> State# s copyMutableArrayArray# = copyMutableArrayArray#@@ -3238,7 +3324,7 @@ compactSize# :: Compact# -> State# (RealWorld) -> (# State# (RealWorld),Word# #) compactSize# = compactSize# --- | Returns 1# if the given pointers are equal and 0# otherwise. +-- | Returns {\texttt 1\#} if the given pointers are equal and {\texttt 0\#} otherwise. reallyUnsafePtrEquality# :: a -> a -> Int# reallyUnsafePtrEquality# = reallyUnsafePtrEquality#@@ -3299,7 +3385,7 @@ addrToAny# :: Addr# -> (# a #) addrToAny# = addrToAny# --- | Retrive the address of any Haskell value. This is+-- | Retrieve the address of any Haskell value. This is -- essentially an {\texttt unsafeCoerce\#}, but if implemented as such -- the core lint pass complains and fails to compile. -- As a primop, it is opaque to core\/stg, and only appears@@ -3344,7 +3430,7 @@ -- | Returns the current @CostCentreStack@ (value is @NULL@ if -- not profiling). Takes a dummy argument which can be used to--- avoid the call to @getCCCS\#@ being floated out by the+-- avoid the call to @getCurrentCCS\#@ being floated out by the -- simplifier, which would result in an uninformative stack -- (\"CAF\"). @@ -3373,8 +3459,9 @@ proxy# = proxy# -- | The value of @seq a b@ is bottom if @a@ is bottom, and--- otherwise equal to @b@. @seq@ is usually introduced to--- improve performance by avoiding unneeded laziness.+-- otherwise equal to @b@. In other words, it evaluates the first +-- argument @a@ to weak head normal form (WHNF). @seq@ is usually +-- introduced to improve performance by avoiding unneeded laziness. -- -- A note on evaluation order: the expression @seq a b@ does -- /not/ guarantee that @a@ will be evaluated before @b@.@@ -3400,8 +3487,9 @@ -- -- * Casting @Any@ back to the real type -- --- * Casting an unboxed type to another unboxed type of the same size--- (but not coercions between floating-point and integral types)+-- * Casting an unboxed type to another unboxed type of the same size.+-- (Casting between floating-point and integral types does not work.+-- See the @GHC.Float@ module for functions to do work.) -- -- * Casting between two types that have the same runtime representation. One case is when -- the two types differ only in \"phantom\" type parameters, for example@@ -3413,7 +3501,7 @@ -- @unsafeCoerce\#@ to cast a T to an algebraic data type D, unless T is also -- an algebraic data type. For example, do not cast @Int->Int@ to @Bool@, even if -- you later cast that @Bool@ back to @Int->Int@ before applying it. The reasons--- have to do with GHC\'s internal representation details (for the congnoscenti, data values+-- have to do with GHC\'s internal representation details (for the cognoscenti, data values -- can be entered but function closures cannot). If you want a safe type to cast things -- to, use @Any@, which is not an algebraic data type. --
GHC/PrimopWrappers.hs view
@@ -195,6 +195,36 @@ {-# NOINLINE popCnt# #-} popCnt# :: Word# -> Word# popCnt# a1 = (GHC.Prim.popCnt#) a1+{-# NOINLINE pdep8# #-}+pdep8# :: Word# -> Word# -> Word#+pdep8# a1 a2 = (GHC.Prim.pdep8#) a1 a2+{-# NOINLINE pdep16# #-}+pdep16# :: Word# -> Word# -> Word#+pdep16# a1 a2 = (GHC.Prim.pdep16#) a1 a2+{-# NOINLINE pdep32# #-}+pdep32# :: Word# -> Word# -> Word#+pdep32# a1 a2 = (GHC.Prim.pdep32#) a1 a2+{-# NOINLINE pdep64# #-}+pdep64# :: Word# -> Word# -> Word#+pdep64# a1 a2 = (GHC.Prim.pdep64#) a1 a2+{-# NOINLINE pdep# #-}+pdep# :: Word# -> Word# -> Word#+pdep# a1 a2 = (GHC.Prim.pdep#) a1 a2+{-# NOINLINE pext8# #-}+pext8# :: Word# -> Word# -> Word#+pext8# a1 a2 = (GHC.Prim.pext8#) a1 a2+{-# NOINLINE pext16# #-}+pext16# :: Word# -> Word# -> Word#+pext16# a1 a2 = (GHC.Prim.pext16#) a1 a2+{-# NOINLINE pext32# #-}+pext32# :: Word# -> Word# -> Word#+pext32# a1 a2 = (GHC.Prim.pext32#) a1 a2+{-# NOINLINE pext64# #-}+pext64# :: Word# -> Word# -> Word#+pext64# a1 a2 = (GHC.Prim.pext64#) a1 a2+{-# NOINLINE pext# #-}+pext# :: Word# -> Word# -> Word#+pext# a1 a2 = (GHC.Prim.pext#) a1 a2 {-# NOINLINE clz8# #-} clz8# :: Word# -> Word# clz8# a1 = (GHC.Prim.clz8#) a1@@ -705,6 +735,9 @@ {-# NOINLINE writeWord64Array# #-} writeWord64Array# :: MutableByteArray# s -> Int# -> Word# -> State# s -> State# s writeWord64Array# a1 a2 a3 a4 = (GHC.Prim.writeWord64Array#) a1 a2 a3 a4+{-# NOINLINE compareByteArrays# #-}+compareByteArrays# :: ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#+compareByteArrays# a1 a2 a3 a4 a5 = (GHC.Prim.compareByteArrays#) a1 a2 a3 a4 a5 {-# NOINLINE copyByteArray# #-} copyByteArray# :: ByteArray# -> Int# -> MutableByteArray# s -> Int# -> Int# -> State# s -> State# s copyByteArray# a1 a2 a3 a4 a5 a6 = (GHC.Prim.copyByteArray#) a1 a2 a3 a4 a5 a6
GHC/Types.hs view
@@ -122,7 +122,7 @@ ********************************************************************* -} {- | The character type 'Char' is an enumeration whose values represent-Unicode (or equivalently ISO\/IEC 10646) characters (see+Unicode (or equivalently ISO\/IEC 10646) code points (i.e. characters, see <http://www.unicode.org/> for details). This set extends the ISO 8859-1 (Latin-1) character set (the first 256 characters), which is itself an extension of the ASCII character set (the first 128 characters). A character literal in@@ -450,7 +450,7 @@ #endif -- | The representation produced by GHC for conjuring up the kind of a--- 'TypeRep'.+-- 'TypeRep'. See Note [Representing TyCon kinds: KindRep] in TcTypeable. data KindRep = KindRepTyConApp TyCon [KindRep] | KindRepVar !KindBndr | KindRepApp KindRep KindRep
Setup.hs view
@@ -1,2 +1,88 @@++-- We need to do some ugly hacks here because of GHC magic++module Main (main) where++import Control.Monad+import Data.List+import Data.Maybe+import Distribution.PackageDescription import Distribution.Simple-main = defaultMain+import Distribution.Simple.LocalBuildInfo+import Distribution.Simple.Program+import Distribution.Simple.Utils+import Distribution.Text+import System.Cmd+import System.FilePath+import System.Exit+import System.Directory++main :: IO ()+main = do let hooks = simpleUserHooks {+ regHook = addPrimModule+ $ regHook simpleUserHooks,+ buildHook = build_primitive_sources+ $ buildHook simpleUserHooks,+ haddockHook = addPrimModuleForHaddock+ $ build_primitive_sources+ $ haddockHook simpleUserHooks }+ defaultMainWithHooks hooks++type Hook a = PackageDescription -> LocalBuildInfo -> UserHooks -> a -> IO ()++addPrimModule :: Hook a -> Hook a+addPrimModule f pd lbi uhs x =+ do let -- I'm not sure which one of these we actually need to change.+ -- It seems bad that there are two.+ pd' = addPrimModuleToPD pd+ lpd = addPrimModuleToPD (localPkgDescr lbi)+ lbi' = lbi { localPkgDescr = lpd }+ f pd' lbi' uhs x++addPrimModuleForHaddock :: Hook a -> Hook a+addPrimModuleForHaddock f pd lbi uhs x =+ do let pc = withPrograms lbi+ pc' = userSpecifyArgs "haddock" ["GHC/Prim.hs"] pc+ lbi' = lbi { withPrograms = pc' }+ f pd lbi' uhs x++addPrimModuleToPD :: PackageDescription -> PackageDescription+addPrimModuleToPD pd =+ case library pd of+ Just lib ->+ let ems = fromJust (simpleParse "GHC.Prim") : exposedModules lib+ lib' = lib { exposedModules = ems }+ in pd { library = Just lib' }+ Nothing ->+ error "Expected a library, but none found"++build_primitive_sources :: Hook a -> Hook a+build_primitive_sources f pd lbi uhs x+ = do when (compilerFlavor (compiler lbi) == GHC) $ do+ let genprimopcode = joinPath ["..", "..", "utils",+ "genprimopcode", "genprimopcode"]+ primops = joinPath ["..", "..", "compiler", "prelude",+ "primops.txt"]+ primhs = joinPath ["GHC", "Prim.hs"]+ primopwrappers = joinPath ["GHC", "PrimopWrappers.hs"]+ primhs_tmp = addExtension primhs "tmp"+ primopwrappers_tmp = addExtension primopwrappers "tmp"+ maybeExit $ system (genprimopcode ++ " --make-haskell-source < "+ ++ primops ++ " > " ++ primhs_tmp)+ maybeUpdateFile primhs_tmp primhs+ maybeExit $ system (genprimopcode ++ " --make-haskell-wrappers < "+ ++ primops ++ " > " ++ primopwrappers_tmp)+ maybeUpdateFile primopwrappers_tmp primopwrappers+ f pd lbi uhs x++-- Replace a file only if the new version is different from the old.+-- This prevents make from doing unnecessary work after we run 'setup makefile'+maybeUpdateFile :: FilePath -> FilePath -> IO ()+maybeUpdateFile source target = do+ r <- rawSystem "cmp" ["-s" {-quiet-}, source, target]+ case r of+ ExitSuccess -> removeFile source+ ExitFailure _ -> do exists <- doesFileExist target+ when exists $ removeFile target+ renameFile source target+
cbits/atomic.c view
@@ -260,61 +260,103 @@ #endif // AtomicReadByteArrayOp_Int+// Implies a full memory barrier (see compiler/prelude/primops.txt.pp)+// __ATOMIC_SEQ_CST: Full barrier in both directions (hoisting and sinking+// of code) and synchronizes with acquire loads and release stores in+// all threads.+//+// When we lack C11 atomics support we emulate these using the old GCC __sync+// primitives which the GCC documentation claims "usually" implies a full+// barrier. extern StgWord hs_atomicread8(StgWord x); StgWord hs_atomicread8(StgWord x) {- return *(volatile StgWord8 *) x;+#if HAVE_C11_ATOMICS+ return __atomic_load_n((StgWord8 *) x, __ATOMIC_SEQ_CST);+#else+ return __sync_add_and_fetch((StgWord8 *) x, 0);+#endif } extern StgWord hs_atomicread16(StgWord x); StgWord hs_atomicread16(StgWord x) {- return *(volatile StgWord16 *) x;+#if HAVE_C11_ATOMICS+ return __atomic_load_n((StgWord16 *) x, __ATOMIC_SEQ_CST);+#else+ return __sync_add_and_fetch((StgWord16 *) x, 0);+#endif } extern StgWord hs_atomicread32(StgWord x); StgWord hs_atomicread32(StgWord x) {- return *(volatile StgWord32 *) x;+#if HAVE_C11_ATOMICS+ return __atomic_load_n((StgWord32 *) x, __ATOMIC_SEQ_CST);+#else+ return __sync_add_and_fetch((StgWord32 *) x, 0);+#endif } extern StgWord64 hs_atomicread64(StgWord x); StgWord64 hs_atomicread64(StgWord x) {- return *(volatile StgWord64 *) x;+#if HAVE_C11_ATOMICS+ return __atomic_load_n((StgWord64 *) x, __ATOMIC_SEQ_CST);+#else+ return __sync_add_and_fetch((StgWord64 *) x, 0);+#endif } // AtomicWriteByteArrayOp_Int+// Implies a full memory barrier (see compiler/prelude/primops.txt.pp)+// __ATOMIC_SEQ_CST: Full barrier (see hs_atomicread8 above). extern void hs_atomicwrite8(StgWord x, StgWord val); void hs_atomicwrite8(StgWord x, StgWord val) {- *(volatile StgWord8 *) x = (StgWord8) val;+#if HAVE_C11_ATOMICS+ __atomic_store_n((StgWord8 *) x, (StgWord8) val, __ATOMIC_SEQ_CST);+#else+ while (!__sync_bool_compare_and_swap((StgWord8 *) x, *(StgWord8 *) x, (StgWord8) val));+#endif } extern void hs_atomicwrite16(StgWord x, StgWord val); void hs_atomicwrite16(StgWord x, StgWord val) {- *(volatile StgWord16 *) x = (StgWord16) val;+#if HAVE_C11_ATOMICS+ __atomic_store_n((StgWord16 *) x, (StgWord16) val, __ATOMIC_SEQ_CST);+#else+ while (!__sync_bool_compare_and_swap((StgWord16 *) x, *(StgWord16 *) x, (StgWord16) val));+#endif } extern void hs_atomicwrite32(StgWord x, StgWord val); void hs_atomicwrite32(StgWord x, StgWord val) {- *(volatile StgWord32 *) x = (StgWord32) val;+#if HAVE_C11_ATOMICS+ __atomic_store_n((StgWord32 *) x, (StgWord32) val, __ATOMIC_SEQ_CST);+#else+ while (!__sync_bool_compare_and_swap((StgWord32 *) x, *(StgWord32 *) x, (StgWord32) val));+#endif } extern void hs_atomicwrite64(StgWord x, StgWord64 val); void hs_atomicwrite64(StgWord x, StgWord64 val) {- *(volatile StgWord64 *) x = (StgWord64) val;+#if HAVE_C11_ATOMICS+ __atomic_store_n((StgWord64 *) x, (StgWord64) val, __ATOMIC_SEQ_CST);+#else+ while (!__sync_bool_compare_and_swap((StgWord64 *) x, *(StgWord64 *) x, (StgWord64) val));+#endif }
+ cbits/pdep.c view
@@ -0,0 +1,48 @@+#include "Rts.h"+#include "MachDeps.h"++extern StgWord64 hs_pdep64(StgWord64 src, StgWord64 mask);++StgWord64+hs_pdep64(StgWord64 src, StgWord64 mask)+{+ uint64_t result = 0;++ while (1) {+ // Mask out all but the lowest bit+ const uint64_t lowest = (-mask & mask);++ if (lowest == 0) {+ break;+ }++ const uint64_t lsb = (uint64_t)((int64_t)(src << 63) >> 63);++ result |= lsb & lowest;+ mask &= ~lowest;+ src >>= 1;+ }++ return result;+}++extern StgWord hs_pdep32(StgWord src, StgWord mask);+StgWord+hs_pdep32(StgWord src, StgWord mask)+{+ return hs_pdep64(src, mask);+}++extern StgWord hs_pdep16(StgWord src, StgWord mask);+StgWord+hs_pdep16(StgWord src, StgWord mask)+{+ return hs_pdep64(src, mask);+}++extern StgWord hs_pdep8(StgWord src, StgWord mask);+StgWord+hs_pdep8(StgWord src, StgWord mask)+{+ return hs_pdep64(src, mask);+}
+ cbits/pext.c view
@@ -0,0 +1,44 @@+#include "Rts.h"+#include "MachDeps.h"++extern StgWord64 hs_pext64(StgWord64 src, StgWord64 mask);++StgWord64+hs_pext64(StgWord64 src, StgWord64 mask)+{+ uint64_t result = 0;+ int offset = 0;++ for (int bit = 0; bit != sizeof(uint64_t) * 8; ++bit) {+ const uint64_t src_bit = (src >> bit) & 1;+ const uint64_t mask_bit = (mask >> bit) & 1;++ if (mask_bit) {+ result |= (uint64_t)(src_bit) << offset;+ ++offset;+ }+ }++ return result;+}++extern StgWord hs_pext32(StgWord src, StgWord mask);+StgWord+hs_pext32(StgWord src, StgWord mask)+{+ return hs_pext64(src, mask);+}++extern StgWord hs_pext16(StgWord src, StgWord mask);+StgWord+hs_pext16(StgWord src, StgWord mask)+{+ return hs_pext64(src, mask);+}++extern StgWord hs_pext8(StgWord src, StgWord mask);+StgWord+hs_pext8(StgWord src, StgWord mask)+{+ return hs_pext64(src, mask);+}
changelog.md view
@@ -1,3 +1,13 @@+## 0.5.2.0++- Shipped with GHC 8.4.1++- Added to `GHC.Prim`:++ compareByteArrays# :: ByteArray# -> Int# -> ByteArray# -> Int# -> Int# -> Int#++- Don't allocate a thunk for each unpacked UTF-8 character in `unpackCStringUtf8#`+ ## 0.5.1.1 *November 2017* - Shipped with GHC 8.2.2
ghc-prim.cabal view
@@ -1,13 +1,13 @@+cabal-version: 2.2 name: ghc-prim-version: 0.5.1.1--- NOTE: Don't forget to update ./changelog.md-license: BSD3+version: 0.5.2.0++license: BSD-3-Clause license-file: LICENSE category: GHC maintainer: libraries@haskell.org bug-reports: http://ghc.haskell.org/trac/ghc/newticket?component=libraries%20%28other%29&keywords=ghc-prim synopsis: GHC primitives-cabal-version: >=1.10 build-type: Simple description: This package contains the primitive types and operations supplied by GHC.@@ -19,10 +19,6 @@ location: http://git.haskell.org/ghc.git subdir: libraries/ghc-prim -flag include-ghc-prim- Description: Include GHC.Prim in exposed-modules- default: False- Library default-language: Haskell2010 other-extensions:@@ -49,7 +45,11 @@ GHC.PrimopWrappers GHC.Tuple GHC.Types+ GHC.Prim + virtual-modules:+ GHC.Prim+ -- OS Specific if os(windows) -- Windows requires some extra libraries for linking because the RTS@@ -64,9 +64,6 @@ -- on Windows. Required because of mingw32. extra-libraries: user32, mingw32, mingwex - if flag(include-ghc-prim)- exposed-modules: GHC.Prim- c-sources: cbits/atomic.c cbits/bswap.c@@ -74,6 +71,8 @@ cbits/ctz.c cbits/debug.c cbits/longlong.c+ cbits/pdep.c+ cbits/pext.c cbits/popcnt.c cbits/word2float.c