bits-extra 0.0.0.1 → 0.0.0.2
raw patch · 6 files changed
+150/−46 lines, 6 filesdep ~ghc-prim
Dependency ranges changed: ghc-prim
Files
- README.md +12/−0
- bits-extra.cabal +5/−3
- src/Data/Bits/Pdep.hs +9/−21
- src/Data/Bits/Pdep/Prim.hs +57/−0
- src/Data/Bits/Pext.hs +10/−22
- src/Data/Bits/Pext/Prim.hs +57/−0
README.md view
@@ -17,6 +17,8 @@ instruction set, a very slow emulated version of these operations is provided instead. +Note `ghc-8.4.1` is required to target the BMI2 CPU instructions.+ ## Compilation It is sufficient to build, test and benchmark the library as follows@@ -255,3 +257,13 @@ ## Reference * [Bit Manipulation Instruction Sets (Wikipedia)](https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets)+* [GHC differential D4236](https://phabricator.haskell.org/D4236)++## Acknowledgement++A lot of people helped in the writing of this library and the underlying GHC patch:++* Ben Gamari+* Moritz Angermann+* Alex Mason+* Moritz Kiefer
bits-extra.cabal view
@@ -2,10 +2,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 2b16093c79f84feabd7fb8a6c4c36ce7e5cfdcf7aa6a2c48d7d3d84d3166701b+-- hash: 547b5605d3febfb841362a7a119ad0091b5184712d7fdb7698dc5ae94e7f4249 name: bits-extra-version: 0.0.0.1+version: 0.0.0.2 description: Please see the README on Github at <https://github.com/haskell-works/bits-extra#readme> homepage: https://github.com/haskell-works/bits-extra#readme bug-reports: https://github.com/haskell-works/bits-extra/issues@@ -35,7 +35,7 @@ src ghc-options: -Wall -O2 build-depends:- base >=4.11 && <5+ base >=4.7 && <5 , ghc-prim if (flag(bmi2)) && (impl(ghc >=8.4.1)) ghc-options: -mbmi2 -msse4.2@@ -46,6 +46,8 @@ Data.Bits.Pext Data.Bits.Pext.Slow other-modules:+ Data.Bits.Pdep.Prim+ Data.Bits.Pext.Prim Paths_bits_extra default-language: Haskell2010
src/Data/Bits/Pdep.hs view
@@ -6,49 +6,37 @@ , fastPdepEnabled ) where -import GHC.Prim import GHC.Word +import qualified Data.Bits.Pdep.Prim as P+ -- | Bitwise parallel deposit. Deposits bits from the source at the locations -- described by the mask. class Pdep a where pdep :: a -> a -> a instance Pdep Word where- pdep (W# src#) (W# mask#) = W# (pdep# src# mask#)+ pdep = P.primPdep {-# INLINE pdep #-} instance Pdep Word8 where- pdep src mask = fromIntegral (pdep (fromIntegral src) (fromIntegral mask) :: Word32)+ pdep = P.primPdep8 {-# INLINE pdep #-} instance Pdep Word16 where- pdep src mask = fromIntegral (pdep (fromIntegral src) (fromIntegral mask) :: Word32)+ pdep = P.primPdep16 {-# INLINE pdep #-} -#if MIN_VERSION_base(4,11,0) instance Pdep Word32 where- pdep (W32# src#) (W32# mask#) = W32# (pdep32# src# mask#)+ pdep = P.primPdep32 {-# INLINE pdep #-} instance Pdep Word64 where- pdep (W64# src#) (W64# mask#) = W64# (pdep64# src# mask#)- {-# INLINE pdep #-}-#else-instance Pdep Word32 where- pdep = slowPdep+ pdep = P.primPdep64 {-# INLINE pdep #-} -instance Pdep Word64 where- pdep = slowPdep- {-# INLINE pdep #-}-#endif- -- | Runtime flag indicating whether the 'pdep' function is using the high-performance. -- BMI2 instruction set. A value of `False` indicates that `pdep` is emulated. fastPdepEnabled :: Bool-#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)-fastPdepEnabled = True-#else-fastPdepEnabled = False-#endif+fastPdepEnabled = P.fastPdepEnabled+{-# INLINE fastPdepEnabled #-}
+ src/Data/Bits/Pdep/Prim.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}++module Data.Bits.Pdep.Prim+ ( primPdep+ , primPdep8+ , primPdep16+ , primPdep32+ , primPdep64+ , fastPdepEnabled+ ) where++import GHC.Word++#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+import GHC.Prim+#else+import Data.Bits.Pdep.Slow+#endif++primPdep :: Word -> Word -> Word+primPdep src mask = fromIntegral (primPdep64 (fromIntegral src) (fromIntegral mask))+{-# INLINE primPdep #-}++primPdep64 :: Word64 -> Word64 -> Word64+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+primPdep64 (W64# src#) (W64# mask#) = W64# (pdep64# src# mask#)+#else+primPdep64 = slowPdep+#endif+{-# INLINE primPdep64 #-}++primPdep32 :: Word32 -> Word32 -> Word32+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+primPdep32 (W32# src#) (W32# mask#) = W32# (pdep32# src# mask#)+#else+primPdep32 = slowPdep+#endif+{-# INLINE primPdep32 #-}++primPdep16 :: Word16 -> Word16 -> Word16+primPdep16 src mask = fromIntegral (primPdep32 (fromIntegral src) (fromIntegral mask))+{-# INLINE primPdep16 #-}++primPdep8 :: Word8 -> Word8 -> Word8+primPdep8 src mask = fromIntegral (primPdep32 (fromIntegral src) (fromIntegral mask))+{-# INLINE primPdep8 #-}++-- | Runtime flag indicating whether the 'pdep' function is using the high-performance.+-- BMI2 instruction set. A value of `False` indicates that `pdep` is emulated.+fastPdepEnabled :: Bool+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+fastPdepEnabled = True+#else+fastPdepEnabled = False+#endif+{-# INLINE fastPdepEnabled #-}
src/Data/Bits/Pext.hs view
@@ -6,49 +6,37 @@ , fastPextEnabled ) where -import GHC.Prim import GHC.Word --- | Bitwise parallel extract. Extract bits from the source at the locations+import qualified Data.Bits.Pext.Prim as P++-- | Bitwise parallel extosit. extosits bits from the source at the locations -- described by the mask. class Pext a where pext :: a -> a -> a instance Pext Word where- pext (W# src#) (W# mask#) = W# (pext# src# mask#)+ pext = P.primPext {-# INLINE pext #-} instance Pext Word8 where- pext src mask = fromIntegral (pext (fromIntegral src) (fromIntegral mask) :: Word32)+ pext = P.primPext8 {-# INLINE pext #-} instance Pext Word16 where- pext src mask = fromIntegral (pext (fromIntegral src) (fromIntegral mask) :: Word32)+ pext = P.primPext16 {-# INLINE pext #-} -#if MIN_VERSION_base(4,11,0) instance Pext Word32 where- pext (W32# src#) (W32# mask#) = W32# (pext32# src# mask#)+ pext = P.primPext32 {-# INLINE pext #-} instance Pext Word64 where- pext (W64# src#) (W64# mask#) = W64# (pext64# src# mask#)- {-# INLINE pext #-}-#else-instance Pext Word32 where- pext = slowPext+ pext = P.primPext64 {-# INLINE pext #-} -instance Pext Word64 where- pext = slowPext- {-# INLINE pext #-}-#endif- -- | Runtime flag indicating whether the 'pext' function is using the high-performance. -- BMI2 instruction set. A value of `False` indicates that `pext` is emulated. fastPextEnabled :: Bool-#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)-fastPextEnabled = True-#else-fastPextEnabled = False-#endif+fastPextEnabled = P.fastPextEnabled+{-# INLINE fastPextEnabled #-}
+ src/Data/Bits/Pext/Prim.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}++module Data.Bits.Pext.Prim+ ( primPext+ , primPext8+ , primPext16+ , primPext32+ , primPext64+ , fastPextEnabled+ ) where++import GHC.Word++#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+import GHC.Prim+#else+import Data.Bits.Pext.Slow+#endif++primPext :: Word -> Word -> Word+primPext src mask = fromIntegral (primPext64 (fromIntegral src) (fromIntegral mask))+{-# INLINE primPext #-}++primPext64 :: Word64 -> Word64 -> Word64+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+primPext64 (W64# src#) (W64# mask#) = W64# (pext64# src# mask#)+#else+primPext64 = slowPext+#endif+{-# INLINE primPext64 #-}++primPext32 :: Word32 -> Word32 -> Word32+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+primPext32 (W32# src#) (W32# mask#) = W32# (pext32# src# mask#)+#else+primPext32 = slowPext+#endif+{-# INLINE primPext32 #-}++primPext16 :: Word16 -> Word16 -> Word16+primPext16 src mask = fromIntegral (primPext32 (fromIntegral src) (fromIntegral mask))+{-# INLINE primPext16 #-}++primPext8 :: Word8 -> Word8 -> Word8+primPext8 src mask = fromIntegral (primPext32 (fromIntegral src) (fromIntegral mask))+{-# INLINE primPext8 #-}++-- | Runtime flag indicating whether the 'pext' function is using the high-performance.+-- BMI2 instruction set. A value of `False` indicates that `pext` is emulated.+fastPextEnabled :: Bool+#if MIN_VERSION_base(4,11,0) && defined(BMI2_ENABLED)+fastPextEnabled = True+#else+fastPextEnabled = False+#endif+{-# INLINE fastPextEnabled #-}