1 {-# LANGUAGE MagicHash #-} 2 3 -- | 4 -- Module : Data.Text.UnsafeShift 5 -- Copyright : (c) Bryan O'Sullivan 2009 6 -- 7 -- License : BSD-style 8 -- Maintainer : bos@serpentine.com, rtomharper@googlemail.com, 9 -- duncan@haskell.org 10 -- Stability : experimental 11 -- Portability : GHC 12 -- 13 -- Fast, unchecked bit shifting functions. 14 15 module Data.Text.UnsafeShift 16 ( 17 UnsafeShift(..) 18 ) where 19 20 -- import qualified Data.Bits as Bits 21 import GHC.Base 22 import GHC.Word 23 24 -- | This is a workaround for poor optimisation in GHC 6.8.2. It 25 -- fails to notice constant-width shifts, and adds a test and branch 26 -- to every shift. This imposes about a 10% performance hit. 27 -- 28 -- These functions are undefined when the amount being shifted by is 29 -- greater than the size in bits of a machine Int#. 30 class UnsafeShift a where 31 shiftL :: a -> Int -> a 32 shiftR :: a -> Int -> a 33 34 instance UnsafeShift Word16 where 35 {-# INLINE shiftL #-} 36 -- entered 16,892 timesshiftL (W16# x#) (I# i#) = W16# (narrow16Word# (x# `uncheckedShiftL#` i#)) 37 38 {-# INLINE shiftR #-} 39 -- entered 100 timesshiftR (W16# x#) (I# i#) = W16# (x# `uncheckedShiftRL#` i#) 40 41 instance UnsafeShift Word32 where 42 {-# INLINE shiftL #-} 43 -- entered 10,966 timesshiftL (W32# x#) (I# i#) = W32# (narrow32Word# (x# `uncheckedShiftL#` i#)) 44 45 {-# INLINE shiftR #-} 46 -- entered 100 timesshiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#) 47 48 instance UnsafeShift Word64 where 49 {-# INLINE shiftL #-} 50 -- entered 247,675 timesshiftL (W64# x#) (I# i#) = W64# (x# `uncheckedShiftL64#` i#) 51 52 {-# INLINE shiftR #-} 53 -- never enteredshiftR (W64# x#) (I# i#) = W64# (x# `uncheckedShiftRL64#` i#) 54 55 instance UnsafeShift Int where 56 {-# INLINE shiftL #-} 57 -- entered 577,573 timesshiftL (I# x#) (I# i#) = I# (x# `iShiftL#` i#) 58 59 {-# INLINE shiftR #-} 60 -- entered 437,890 timesshiftR (I# x#) (I# i#) = I# (x# `iShiftRA#` i#) 61 62 {- 63 instance UnsafeShift Integer where 64 {-# INLINE shiftL #-} 65 shiftL = Bits.shiftL 66 67 {-# INLINE shiftR #-} 68 shiftR = Bits.shiftR 69 -}