1{-# LANGUAGE MagicHash #-}
2
3-- |
4-- Module      : Data.Text.Internal.Unsafe.Shift
5-- Copyright   : (c) Bryan O'Sullivan 2009
6--
7-- License     : BSD-style
8-- Maintainer  : bos@serpentine.com
9-- Stability   : experimental
10-- Portability : GHC
11--
12-- /Warning/: this is an internal module, and does not have a stable
13-- API or name. Functions in this module may not check or enforce
14-- preconditions expected by public modules. Use at your own risk!
15--
16-- Fast, unchecked bit shifting functions.
17
18module Data.Text.Internal.Unsafe.Shift
19    (
20      UnsafeShift(..)
21    ) where
22
23-- import qualified Data.Bits as Bits
24import GHC.Base
25import GHC.Word
26
27-- | This is a workaround for poor optimisation in GHC 6.8.2.  It
28-- fails to notice constant-width shifts, and adds a test and branch
29-- to every shift.  This imposes about a 10% performance hit.
30--
31-- These functions are undefined when the amount being shifted by is
32-- greater than the size in bits of a machine Int#.
33class UnsafeShift a where
34    shiftL :: a -> Int -> a
35    shiftR :: a -> Int -> a
36
37instance UnsafeShift Word16 where
38    {-# INLINE shiftL #-}
39    shiftL (W16# x#) (I# i#) = W16# (narrow16Word# (x# `uncheckedShiftL#` i#))
40
41    {-# INLINE shiftR #-}
42    shiftR (W16# x#) (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
43
44instance UnsafeShift Word32 where
45    {-# INLINE shiftL #-}
46    shiftL (W32# x#) (I# i#) = W32# (narrow32Word# (x# `uncheckedShiftL#` i#))
47
48    {-# INLINE shiftR #-}
49    shiftR (W32# x#) (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
50
51instance UnsafeShift Word64 where
52    {-# INLINE shiftL #-}
53    shiftL (W64# x#) (I# i#) = W64# (x# `uncheckedShiftL64#` i#)
54
55    {-# INLINE shiftR #-}
56    shiftR (W64# x#) (I# i#) = W64# (x# `uncheckedShiftRL64#` i#)
57
58instance UnsafeShift Int where
59    {-# INLINE shiftL #-}
60    shiftL (I# x#) (I# i#) = I# (x# `iShiftL#` i#)
61
62    {-# INLINE shiftR #-}
63    shiftR (I# x#) (I# i#) = I# (x# `iShiftRA#` i#)
64
65{-
66instance UnsafeShift Integer where
67    {-# INLINE shiftL #-}
68    shiftL = Bits.shiftL
69
70    {-# INLINE shiftR #-}
71    shiftR = Bits.shiftR
72-}
73