Word.hs 30.9 KB
Newer Older
1
{-# LANGUAGE Trustworthy #-}
2
{-# LANGUAGE CPP, NoImplicitPrelude, BangPatterns, MagicHash, UnboxedTuples #-}
3
{-# OPTIONS_HADDOCK hide #-}
4

5 6 7 8 9
-----------------------------------------------------------------------------
-- |
-- Module      :  GHC.Word
-- Copyright   :  (c) The University of Glasgow, 1997-2002
-- License     :  see libraries/base/LICENSE
10
--
11 12 13 14 15 16 17 18
-- Maintainer  :  cvs-ghc@haskell.org
-- Stability   :  internal
-- Portability :  non-portable (GHC Extensions)
--
-- Sized unsigned integral types: 'Word', 'Word8', 'Word16', 'Word32', and
-- 'Word64'.
--
-----------------------------------------------------------------------------
19 20 21 22 23

#include "MachDeps.h"

module GHC.Word (
    Word(..), Word8(..), Word16(..), Word32(..), Word64(..),
24
    uncheckedShiftL64#,
25 26 27 28
    uncheckedShiftRL64#,
    byteSwap16,
    byteSwap32,
    byteSwap64
29
    ) where
30 31

import Data.Bits
32
import Data.Maybe
33

34 35 36 37
#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif

Simon Peyton Jones's avatar
Simon Peyton Jones committed
38
-- import {-# SOURCE #-} GHC.Exception
39 40 41 42 43 44 45
import GHC.Base
import GHC.Enum
import GHC.Num
import GHC.Real
import GHC.Read
import GHC.Arr
import GHC.Show
Daniel Fischer's avatar
Daniel Fischer committed
46
import GHC.Float ()     -- for RealFrac methods
47 48 49 50 51 52 53 54

------------------------------------------------------------------------
-- type Word8
------------------------------------------------------------------------

-- Word8 is represented in the same way as Word. Operations may assume
-- and must ensure that it holds only values from its logical range.

Ian Lynagh's avatar
Ian Lynagh committed
55
data {-# CTYPE "HsWord8" #-} Word8 = W8# Word# deriving (Eq, Ord)
56
-- ^ 8-bit unsigned integer type
57 58 59 60 61

instance Show Word8 where
    showsPrec p x = showsPrec p (fromIntegral x :: Int)

instance Num Word8 where
62 63 64 65
    (W8# x#) + (W8# y#)    = W8# (narrow8Word# (x# `plusWord#` y#))
    (W8# x#) - (W8# y#)    = W8# (narrow8Word# (x# `minusWord#` y#))
    (W8# x#) * (W8# y#)    = W8# (narrow8Word# (x# `timesWord#` y#))
    negate (W8# x#)        = W8# (narrow8Word# (int2Word# (negateInt# (word2Int# x#))))
66 67 68
    abs x                  = x
    signum 0               = 0
    signum _               = 1
69
    fromInteger i          = W8# (narrow8Word# (integerToWord i))
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

instance Real Word8 where
    toRational x = toInteger x % 1

instance Enum Word8 where
    succ x
        | x /= maxBound = x + 1
        | otherwise     = succError "Word8"
    pred x
        | x /= minBound = x - 1
        | otherwise     = predError "Word8"
    toEnum i@(I# i#)
        | i >= 0 && i <= fromIntegral (maxBound::Word8)
                        = W8# (int2Word# i#)
        | otherwise     = toEnumError "Word8" i (minBound::Word8, maxBound::Word8)
    fromEnum (W8# x#)   = I# (word2Int# x#)
    enumFrom            = boundedEnumFrom
    enumFromThen        = boundedEnumFromThen

instance Integral Word8 where
Ian Lynagh's avatar
Ian Lynagh committed
90
    quot    (W8# x#) y@(W8# y#)
91
        | y /= 0                  = W8# (x# `quotWord#` y#)
92
        | otherwise               = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
93
    rem     (W8# x#) y@(W8# y#)
94
        | y /= 0                  = W8# (x# `remWord#` y#)
95
        | otherwise               = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
96
    div     (W8# x#) y@(W8# y#)
97
        | y /= 0                  = W8# (x# `quotWord#` y#)
98
        | otherwise               = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
99
    mod     (W8# x#) y@(W8# y#)
100
        | y /= 0                  = W8# (x# `remWord#` y#)
101
        | otherwise               = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
102
    quotRem (W8# x#) y@(W8# y#)
103 104 105
        | y /= 0                  = case x# `quotRemWord#` y# of
                                    (# q, r #) ->
                                        (W8# q, W8# r)
106
        | otherwise               = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
107
    divMod  (W8# x#) y@(W8# y#)
108
        | y /= 0                  = (W8# (x# `quotWord#` y#), W8# (x# `remWord#` y#))
109
        | otherwise               = divZeroError
110
    toInteger (W8# x#)            = smallInteger (word2Int# x#)
111 112 113 114 115 116

instance Bounded Word8 where
    minBound = 0
    maxBound = 0xFF

instance Ix Word8 where
Ian Lynagh's avatar
Ian Lynagh committed
117 118 119
    range (m,n)         = [m..n]
    unsafeIndex (m,_) i = fromIntegral (i - m)
    inRange (m,n) i     = m <= i && i <= n
120 121 122 123 124

instance Read Word8 where
    readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]

instance Bits Word8 where
125
    {-# INLINE shift #-}
126 127
    {-# INLINE bit #-}
    {-# INLINE testBit #-}
128

129 130 131
    (W8# x#) .&.   (W8# y#)   = W8# (x# `and#` y#)
    (W8# x#) .|.   (W8# y#)   = W8# (x# `or#`  y#)
    (W8# x#) `xor` (W8# y#)   = W8# (x# `xor#` y#)
132 133
    complement (W8# x#)       = W8# (x# `xor#` mb#)
        where !(W8# mb#) = maxBound
134
    (W8# x#) `shift` (I# i#)
135
        | isTrue# (i# >=# 0#) = W8# (narrow8Word# (x# `shiftL#` i#))
136
        | otherwise           = W8# (x# `shiftRL#` negateInt# i#)
137
    (W8# x#) `shiftL`       (I# i#) = W8# (narrow8Word# (x# `shiftL#` i#))
tibbe's avatar
tibbe committed
138 139
    (W8# x#) `unsafeShiftL` (I# i#) =
        W8# (narrow8Word# (x# `uncheckedShiftL#` i#))
140
    (W8# x#) `shiftR`       (I# i#) = W8# (x# `shiftRL#` i#)
tibbe's avatar
tibbe committed
141
    (W8# x#) `unsafeShiftR` (I# i#) = W8# (x# `uncheckedShiftRL#` i#)
142 143
    (W8# x#) `rotate`       (I# i#)
        | isTrue# (i'# ==# 0#) = W8# x#
144 145
        | otherwise  = W8# (narrow8Word# ((x# `uncheckedShiftL#` i'#) `or#`
                                          (x# `uncheckedShiftRL#` (8# -# i'#))))
146
        where
147
        !i'# = word2Int# (int2Word# i# `and#` 7##)
148 149
    bitSizeMaybe i            = Just (finiteBitSize i)
    bitSize i                 = finiteBitSize i
150
    isSigned _                = False
tibbe's avatar
tibbe committed
151
    popCount (W8# x#)         = I# (word2Int# (popCnt8# x#))
152 153
    bit                       = bitDefault
    testBit                   = testBitDefault
154

155 156
instance FiniteBits Word8 where
    finiteBitSize _ = 8
157 158
    countLeadingZeros  (W8# x#) = I# (word2Int# (clz8# x#))
    countTrailingZeros (W8# x#) = I# (word2Int# (ctz8# x#))
159

160 161 162
{-# RULES
"fromIntegral/Word8->Word8"   fromIntegral = id :: Word8 -> Word8
"fromIntegral/Word8->Integer" fromIntegral = toInteger :: Word8 -> Integer
163
"fromIntegral/a->Word8"       fromIntegral = \x -> case fromIntegral x of W# x# -> W8# (narrow8Word# x#)
164 165 166
"fromIntegral/Word8->a"       fromIntegral = \(W8# x#) -> fromIntegral (W# x#)
  #-}

Daniel Fischer's avatar
Daniel Fischer committed
167 168
{-# RULES
"properFraction/Float->(Word8,Float)"
169
    properFraction = \x ->
Daniel Fischer's avatar
Daniel Fischer committed
170
                      case properFraction x of {
171
                        (n, y) -> ((fromIntegral :: Int -> Word8) n, y :: Float) }
Daniel Fischer's avatar
Daniel Fischer committed
172
"truncate/Float->Word8"
173
    truncate = (fromIntegral :: Int -> Word8) . (truncate :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
174
"floor/Float->Word8"
175
    floor    = (fromIntegral :: Int -> Word8) . (floor :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
176
"ceiling/Float->Word8"
177
    ceiling  = (fromIntegral :: Int -> Word8) . (ceiling :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
178
"round/Float->Word8"
179
    round    = (fromIntegral :: Int -> Word8) . (round  :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
180 181 182 183
  #-}

{-# RULES
"properFraction/Double->(Word8,Double)"
184
    properFraction = \x ->
Daniel Fischer's avatar
Daniel Fischer committed
185
                      case properFraction x of {
186
                        (n, y) -> ((fromIntegral :: Int -> Word8) n, y :: Double) }
Daniel Fischer's avatar
Daniel Fischer committed
187
"truncate/Double->Word8"
188
    truncate = (fromIntegral :: Int -> Word8) . (truncate :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
189
"floor/Double->Word8"
190
    floor    = (fromIntegral :: Int -> Word8) . (floor :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
191
"ceiling/Double->Word8"
192
    ceiling  = (fromIntegral :: Int -> Word8) . (ceiling :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
193
"round/Double->Word8"
194
    round    = (fromIntegral :: Int -> Word8) . (round  :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
195 196
  #-}

197 198 199 200 201 202 203
------------------------------------------------------------------------
-- type Word16
------------------------------------------------------------------------

-- Word16 is represented in the same way as Word. Operations may assume
-- and must ensure that it holds only values from its logical range.

Ian Lynagh's avatar
Ian Lynagh committed
204
data {-# CTYPE "HsWord16" #-} Word16 = W16# Word# deriving (Eq, Ord)
205
-- ^ 16-bit unsigned integer type
206 207 208 209 210

instance Show Word16 where
    showsPrec p x = showsPrec p (fromIntegral x :: Int)

instance Num Word16 where
211 212 213 214
    (W16# x#) + (W16# y#)  = W16# (narrow16Word# (x# `plusWord#` y#))
    (W16# x#) - (W16# y#)  = W16# (narrow16Word# (x# `minusWord#` y#))
    (W16# x#) * (W16# y#)  = W16# (narrow16Word# (x# `timesWord#` y#))
    negate (W16# x#)       = W16# (narrow16Word# (int2Word# (negateInt# (word2Int# x#))))
215 216 217
    abs x                  = x
    signum 0               = 0
    signum _               = 1
218
    fromInteger i          = W16# (narrow16Word# (integerToWord i))
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

instance Real Word16 where
    toRational x = toInteger x % 1

instance Enum Word16 where
    succ x
        | x /= maxBound = x + 1
        | otherwise     = succError "Word16"
    pred x
        | x /= minBound = x - 1
        | otherwise     = predError "Word16"
    toEnum i@(I# i#)
        | i >= 0 && i <= fromIntegral (maxBound::Word16)
                        = W16# (int2Word# i#)
        | otherwise     = toEnumError "Word16" i (minBound::Word16, maxBound::Word16)
    fromEnum (W16# x#)  = I# (word2Int# x#)
    enumFrom            = boundedEnumFrom
    enumFromThen        = boundedEnumFromThen

instance Integral Word16 where
Ian Lynagh's avatar
Ian Lynagh committed
239
    quot    (W16# x#) y@(W16# y#)
240
        | y /= 0                    = W16# (x# `quotWord#` y#)
241
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
242
    rem     (W16# x#) y@(W16# y#)
243
        | y /= 0                    = W16# (x# `remWord#` y#)
244
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
245
    div     (W16# x#) y@(W16# y#)
246
        | y /= 0                    = W16# (x# `quotWord#` y#)
247
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
248
    mod     (W16# x#) y@(W16# y#)
249
        | y /= 0                    = W16# (x# `remWord#` y#)
250
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
251
    quotRem (W16# x#) y@(W16# y#)
252 253 254
        | y /= 0                  = case x# `quotRemWord#` y# of
                                    (# q, r #) ->
                                        (W16# q, W16# r)
255
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
256
    divMod  (W16# x#) y@(W16# y#)
257
        | y /= 0                    = (W16# (x# `quotWord#` y#), W16# (x# `remWord#` y#))
258
        | otherwise                 = divZeroError
259
    toInteger (W16# x#)             = smallInteger (word2Int# x#)
260 261 262 263 264 265

instance Bounded Word16 where
    minBound = 0
    maxBound = 0xFFFF

instance Ix Word16 where
Ian Lynagh's avatar
Ian Lynagh committed
266 267 268
    range (m,n)         = [m..n]
    unsafeIndex (m,_) i = fromIntegral (i - m)
    inRange (m,n) i     = m <= i && i <= n
269 270 271 272 273

instance Read Word16 where
    readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]

instance Bits Word16 where
274
    {-# INLINE shift #-}
275 276
    {-# INLINE bit #-}
    {-# INLINE testBit #-}
277

278 279 280
    (W16# x#) .&.   (W16# y#)  = W16# (x# `and#` y#)
    (W16# x#) .|.   (W16# y#)  = W16# (x# `or#`  y#)
    (W16# x#) `xor` (W16# y#)  = W16# (x# `xor#` y#)
281 282
    complement (W16# x#)       = W16# (x# `xor#` mb#)
        where !(W16# mb#) = maxBound
283
    (W16# x#) `shift` (I# i#)
284
        | isTrue# (i# >=# 0#)  = W16# (narrow16Word# (x# `shiftL#` i#))
285
        | otherwise            = W16# (x# `shiftRL#` negateInt# i#)
286
    (W16# x#) `shiftL` (I# i#)       = W16# (narrow16Word# (x# `shiftL#` i#))
tibbe's avatar
tibbe committed
287 288
    (W16# x#) `unsafeShiftL` (I# i#) =
        W16# (narrow16Word# (x# `uncheckedShiftL#` i#))
289
    (W16# x#) `shiftR`       (I# i#) = W16# (x# `shiftRL#` i#)
tibbe's avatar
tibbe committed
290
    (W16# x#) `unsafeShiftR` (I# i#) = W16# (x# `uncheckedShiftRL#` i#)
291 292
    (W16# x#) `rotate`       (I# i#)
        | isTrue# (i'# ==# 0#) = W16# x#
293 294
        | otherwise  = W16# (narrow16Word# ((x# `uncheckedShiftL#` i'#) `or#`
                                            (x# `uncheckedShiftRL#` (16# -# i'#))))
295
        where
296
        !i'# = word2Int# (int2Word# i# `and#` 15##)
297 298
    bitSizeMaybe i            = Just (finiteBitSize i)
    bitSize i                 = finiteBitSize i
299
    isSigned _                = False
tibbe's avatar
tibbe committed
300
    popCount (W16# x#)        = I# (word2Int# (popCnt16# x#))
301 302
    bit                       = bitDefault
    testBit                   = testBitDefault
303

304 305
instance FiniteBits Word16 where
    finiteBitSize _ = 16
306 307
    countLeadingZeros  (W16# x#) = I# (word2Int# (clz16# x#))
    countTrailingZeros (W16# x#) = I# (word2Int# (ctz16# x#))
308

309 310 311
-- | Swap bytes in 'Word16'.
--
-- /Since: 4.7.0.0/
312
byteSwap16 :: Word16 -> Word16
313
byteSwap16 (W16# w#) = W16# (narrow16Word# (byteSwap16# w#))
314

315 316 317 318
{-# RULES
"fromIntegral/Word8->Word16"   fromIntegral = \(W8# x#) -> W16# x#
"fromIntegral/Word16->Word16"  fromIntegral = id :: Word16 -> Word16
"fromIntegral/Word16->Integer" fromIntegral = toInteger :: Word16 -> Integer
319
"fromIntegral/a->Word16"       fromIntegral = \x -> case fromIntegral x of W# x# -> W16# (narrow16Word# x#)
320 321 322
"fromIntegral/Word16->a"       fromIntegral = \(W16# x#) -> fromIntegral (W# x#)
  #-}

Daniel Fischer's avatar
Daniel Fischer committed
323 324
{-# RULES
"properFraction/Float->(Word16,Float)"
325
    properFraction = \x ->
Daniel Fischer's avatar
Daniel Fischer committed
326
                      case properFraction x of {
327
                        (n, y) -> ((fromIntegral :: Int -> Word16) n, y :: Float) }
Daniel Fischer's avatar
Daniel Fischer committed
328
"truncate/Float->Word16"
329
    truncate = (fromIntegral :: Int -> Word16) . (truncate :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
330
"floor/Float->Word16"
331
    floor    = (fromIntegral :: Int -> Word16) . (floor :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
332
"ceiling/Float->Word16"
333
    ceiling  = (fromIntegral :: Int -> Word16) . (ceiling :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
334
"round/Float->Word16"
335
    round    = (fromIntegral :: Int -> Word16) . (round  :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
336 337 338 339
  #-}

{-# RULES
"properFraction/Double->(Word16,Double)"
340
    properFraction = \x ->
Daniel Fischer's avatar
Daniel Fischer committed
341
                      case properFraction x of {
342
                        (n, y) -> ((fromIntegral :: Int -> Word16) n, y :: Double) }
Daniel Fischer's avatar
Daniel Fischer committed
343
"truncate/Double->Word16"
344
    truncate = (fromIntegral :: Int -> Word16) . (truncate :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
345
"floor/Double->Word16"
346
    floor    = (fromIntegral :: Int -> Word16) . (floor :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
347
"ceiling/Double->Word16"
348
    ceiling  = (fromIntegral :: Int -> Word16) . (ceiling :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
349
"round/Double->Word16"
350
    round    = (fromIntegral :: Int -> Word16) . (round  :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
351 352
  #-}

353 354 355 356 357
------------------------------------------------------------------------
-- type Word32
------------------------------------------------------------------------

-- Word32 is represented in the same way as Word.
358
#if WORD_SIZE_IN_BITS > 32
359 360
-- Operations may assume and must ensure that it holds only values
-- from its logical range.
Daniel Fischer's avatar
Daniel Fischer committed
361 362 363 364 365

-- We can use rewrite rules for the RealFrac methods

{-# RULES
"properFraction/Float->(Word32,Float)"
366
    properFraction = \x ->
Daniel Fischer's avatar
Daniel Fischer committed
367
                      case properFraction x of {
368
                        (n, y) -> ((fromIntegral :: Int -> Word32) n, y :: Float) }
Daniel Fischer's avatar
Daniel Fischer committed
369
"truncate/Float->Word32"
370
    truncate = (fromIntegral :: Int -> Word32) . (truncate :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
371
"floor/Float->Word32"
372
    floor    = (fromIntegral :: Int -> Word32) . (floor :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
373
"ceiling/Float->Word32"
374
    ceiling  = (fromIntegral :: Int -> Word32) . (ceiling :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
375
"round/Float->Word32"
376
    round    = (fromIntegral :: Int -> Word32) . (round  :: Float -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
377 378 379 380
  #-}

{-# RULES
"properFraction/Double->(Word32,Double)"
381
    properFraction = \x ->
Daniel Fischer's avatar
Daniel Fischer committed
382
                      case properFraction x of {
383
                        (n, y) -> ((fromIntegral :: Int -> Word32) n, y :: Double) }
Daniel Fischer's avatar
Daniel Fischer committed
384
"truncate/Double->Word32"
385
    truncate = (fromIntegral :: Int -> Word32) . (truncate :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
386
"floor/Double->Word32"
387
    floor    = (fromIntegral :: Int -> Word32) . (floor :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
388
"ceiling/Double->Word32"
389
    ceiling  = (fromIntegral :: Int -> Word32) . (ceiling :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
390
"round/Double->Word32"
391
    round    = (fromIntegral :: Int -> Word32) . (round  :: Double -> Int)
Daniel Fischer's avatar
Daniel Fischer committed
392 393
  #-}

394 395
#endif

Ian Lynagh's avatar
Ian Lynagh committed
396
data {-# CTYPE "HsWord32" #-} Word32 = W32# Word# deriving (Eq, Ord)
397
-- ^ 32-bit unsigned integer type
398 399

instance Num Word32 where
400 401 402 403
    (W32# x#) + (W32# y#)  = W32# (narrow32Word# (x# `plusWord#` y#))
    (W32# x#) - (W32# y#)  = W32# (narrow32Word# (x# `minusWord#` y#))
    (W32# x#) * (W32# y#)  = W32# (narrow32Word# (x# `timesWord#` y#))
    negate (W32# x#)       = W32# (narrow32Word# (int2Word# (negateInt# (word2Int# x#))))
404 405 406
    abs x                  = x
    signum 0               = 0
    signum _               = 1
407
    fromInteger i          = W32# (narrow32Word# (integerToWord i))
408 409 410 411 412 413 414 415 416 417

instance Enum Word32 where
    succ x
        | x /= maxBound = x + 1
        | otherwise     = succError "Word32"
    pred x
        | x /= minBound = x - 1
        | otherwise     = predError "Word32"
    toEnum i@(I# i#)
        | i >= 0
418
#if WORD_SIZE_IN_BITS > 32
419 420 421 422
          && i <= fromIntegral (maxBound::Word32)
#endif
                        = W32# (int2Word# i#)
        | otherwise     = toEnumError "Word32" i (minBound::Word32, maxBound::Word32)
423
#if WORD_SIZE_IN_BITS == 32
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
    fromEnum x@(W32# x#)
        | x <= fromIntegral (maxBound::Int)
                        = I# (word2Int# x#)
        | otherwise     = fromEnumError "Word32" x
    enumFrom            = integralEnumFrom
    enumFromThen        = integralEnumFromThen
    enumFromTo          = integralEnumFromTo
    enumFromThenTo      = integralEnumFromThenTo
#else
    fromEnum (W32# x#)  = I# (word2Int# x#)
    enumFrom            = boundedEnumFrom
    enumFromThen        = boundedEnumFromThen
#endif

instance Integral Word32 where
Ian Lynagh's avatar
Ian Lynagh committed
439
    quot    (W32# x#) y@(W32# y#)
440
        | y /= 0                    = W32# (x# `quotWord#` y#)
441
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
442
    rem     (W32# x#) y@(W32# y#)
443
        | y /= 0                    = W32# (x# `remWord#` y#)
444
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
445
    div     (W32# x#) y@(W32# y#)
446
        | y /= 0                    = W32# (x# `quotWord#` y#)
447
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
448
    mod     (W32# x#) y@(W32# y#)
449
        | y /= 0                    = W32# (x# `remWord#` y#)
450
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
451
    quotRem (W32# x#) y@(W32# y#)
452 453 454
        | y /= 0                  = case x# `quotRemWord#` y# of
                                    (# q, r #) ->
                                        (W32# q, W32# r)
455
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
456
    divMod  (W32# x#) y@(W32# y#)
457
        | y /= 0                    = (W32# (x# `quotWord#` y#), W32# (x# `remWord#` y#))
458
        | otherwise                 = divZeroError
459
    toInteger (W32# x#)
460
#if WORD_SIZE_IN_BITS == 32
461
        | isTrue# (i# >=# 0#)       = smallInteger i#
462
        | otherwise                 = wordToInteger x#
463
        where
464
        !i# = word2Int# x#
465
#else
466
                                    = smallInteger (word2Int# x#)
467 468 469
#endif

instance Bits Word32 where
470
    {-# INLINE shift #-}
471 472
    {-# INLINE bit #-}
    {-# INLINE testBit #-}
473

474 475 476
    (W32# x#) .&.   (W32# y#)  = W32# (x# `and#` y#)
    (W32# x#) .|.   (W32# y#)  = W32# (x# `or#`  y#)
    (W32# x#) `xor` (W32# y#)  = W32# (x# `xor#` y#)
477 478
    complement (W32# x#)       = W32# (x# `xor#` mb#)
        where !(W32# mb#) = maxBound
479
    (W32# x#) `shift` (I# i#)
480
        | isTrue# (i# >=# 0#)  = W32# (narrow32Word# (x# `shiftL#` i#))
481
        | otherwise            = W32# (x# `shiftRL#` negateInt# i#)
482
    (W32# x#) `shiftL`       (I# i#) = W32# (narrow32Word# (x# `shiftL#` i#))
tibbe's avatar
tibbe committed
483 484
    (W32# x#) `unsafeShiftL` (I# i#) =
        W32# (narrow32Word# (x# `uncheckedShiftL#` i#))
485
    (W32# x#) `shiftR`       (I# i#) = W32# (x# `shiftRL#` i#)
tibbe's avatar
tibbe committed
486
    (W32# x#) `unsafeShiftR` (I# i#) = W32# (x# `uncheckedShiftRL#` i#)
487 488 489
    (W32# x#) `rotate`       (I# i#)
        | isTrue# (i'# ==# 0#) = W32# x#
        | otherwise   = W32# (narrow32Word# ((x# `uncheckedShiftL#` i'#) `or#`
490
                                            (x# `uncheckedShiftRL#` (32# -# i'#))))
491
        where
492
        !i'# = word2Int# (int2Word# i# `and#` 31##)
493 494
    bitSizeMaybe i            = Just (finiteBitSize i)
    bitSize i                 = finiteBitSize i
495
    isSigned _                = False
tibbe's avatar
tibbe committed
496
    popCount (W32# x#)        = I# (word2Int# (popCnt32# x#))
497 498
    bit                       = bitDefault
    testBit                   = testBitDefault
499

500 501
instance FiniteBits Word32 where
    finiteBitSize _ = 32
502 503
    countLeadingZeros  (W32# x#) = I# (word2Int# (clz32# x#))
    countTrailingZeros (W32# x#) = I# (word2Int# (ctz32# x#))
504

505 506 507 508 509
{-# RULES
"fromIntegral/Word8->Word32"   fromIntegral = \(W8# x#) -> W32# x#
"fromIntegral/Word16->Word32"  fromIntegral = \(W16# x#) -> W32# x#
"fromIntegral/Word32->Word32"  fromIntegral = id :: Word32 -> Word32
"fromIntegral/Word32->Integer" fromIntegral = toInteger :: Word32 -> Integer
510
"fromIntegral/a->Word32"       fromIntegral = \x -> case fromIntegral x of W# x# -> W32# (narrow32Word# x#)
511 512 513
"fromIntegral/Word32->a"       fromIntegral = \(W32# x#) -> fromIntegral (W# x#)
  #-}

514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
instance Show Word32 where
#if WORD_SIZE_IN_BITS < 33
    showsPrec p x = showsPrec p (toInteger x)
#else
    showsPrec p x = showsPrec p (fromIntegral x :: Int)
#endif


instance Real Word32 where
    toRational x = toInteger x % 1

instance Bounded Word32 where
    minBound = 0
    maxBound = 0xFFFFFFFF

instance Ix Word32 where
Ian Lynagh's avatar
Ian Lynagh committed
530 531 532
    range (m,n)         = [m..n]
    unsafeIndex (m,_) i = fromIntegral (i - m)
    inRange (m,n) i     = m <= i && i <= n
533

534
instance Read Word32 where
535 536 537 538 539 540
#if WORD_SIZE_IN_BITS < 33
    readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
#else
    readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
#endif

541 542 543
-- | Reverse order of bytes in 'Word32'.
--
-- /Since: 4.7.0.0/
544
byteSwap32 :: Word32 -> Word32
545
byteSwap32 (W32# w#) = W32# (narrow32Word# (byteSwap32# w#))
546

547 548 549 550
------------------------------------------------------------------------
-- type Word64
------------------------------------------------------------------------

551
#if WORD_SIZE_IN_BITS < 64
552

Ian Lynagh's avatar
Ian Lynagh committed
553
data {-# CTYPE "HsWord64" #-} Word64 = W64# Word64#
554
-- ^ 64-bit unsigned integer type
555 556

instance Eq Word64 where
557 558
    (W64# x#) == (W64# y#) = isTrue# (x# `eqWord64#` y#)
    (W64# x#) /= (W64# y#) = isTrue# (x# `neWord64#` y#)
559 560

instance Ord Word64 where
561 562 563 564
    (W64# x#) <  (W64# y#) = isTrue# (x# `ltWord64#` y#)
    (W64# x#) <= (W64# y#) = isTrue# (x# `leWord64#` y#)
    (W64# x#) >  (W64# y#) = isTrue# (x# `gtWord64#` y#)
    (W64# x#) >= (W64# y#) = isTrue# (x# `geWord64#` y#)
565 566 567 568 569 570 571 572 573

instance Num Word64 where
    (W64# x#) + (W64# y#)  = W64# (int64ToWord64# (word64ToInt64# x# `plusInt64#` word64ToInt64# y#))
    (W64# x#) - (W64# y#)  = W64# (int64ToWord64# (word64ToInt64# x# `minusInt64#` word64ToInt64# y#))
    (W64# x#) * (W64# y#)  = W64# (int64ToWord64# (word64ToInt64# x# `timesInt64#` word64ToInt64# y#))
    negate (W64# x#)       = W64# (int64ToWord64# (negateInt64# (word64ToInt64# x#)))
    abs x                  = x
    signum 0               = 0
    signum _               = 1
574
    fromInteger i          = W64# (integerToWord64 i)
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595

instance Enum Word64 where
    succ x
        | x /= maxBound = x + 1
        | otherwise     = succError "Word64"
    pred x
        | x /= minBound = x - 1
        | otherwise     = predError "Word64"
    toEnum i@(I# i#)
        | i >= 0        = W64# (wordToWord64# (int2Word# i#))
        | otherwise     = toEnumError "Word64" i (minBound::Word64, maxBound::Word64)
    fromEnum x@(W64# x#)
        | x <= fromIntegral (maxBound::Int)
                        = I# (word2Int# (word64ToWord# x#))
        | otherwise     = fromEnumError "Word64" x
    enumFrom            = integralEnumFrom
    enumFromThen        = integralEnumFromThen
    enumFromTo          = integralEnumFromTo
    enumFromThenTo      = integralEnumFromThenTo

instance Integral Word64 where
Ian Lynagh's avatar
Ian Lynagh committed
596
    quot    (W64# x#) y@(W64# y#)
597
        | y /= 0                    = W64# (x# `quotWord64#` y#)
598
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
599
    rem     (W64# x#) y@(W64# y#)
600
        | y /= 0                    = W64# (x# `remWord64#` y#)
601
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
602
    div     (W64# x#) y@(W64# y#)
603
        | y /= 0                    = W64# (x# `quotWord64#` y#)
604
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
605
    mod     (W64# x#) y@(W64# y#)
606
        | y /= 0                    = W64# (x# `remWord64#` y#)
607
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
608
    quotRem (W64# x#) y@(W64# y#)
Ian Lynagh's avatar
Ian Lynagh committed
609
        | y /= 0                    = (W64# (x# `quotWord64#` y#), W64# (x# `remWord64#` y#))
610
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
611
    divMod  (W64# x#) y@(W64# y#)
612
        | y /= 0                    = (W64# (x# `quotWord64#` y#), W64# (x# `remWord64#` y#))
613
        | otherwise                 = divZeroError
614
    toInteger (W64# x#)             = word64ToInteger x#
615 616

instance Bits Word64 where
617
    {-# INLINE shift #-}
618 619
    {-# INLINE bit #-}
    {-# INLINE testBit #-}
620

621 622 623 624 625
    (W64# x#) .&.   (W64# y#)  = W64# (x# `and64#` y#)
    (W64# x#) .|.   (W64# y#)  = W64# (x# `or64#`  y#)
    (W64# x#) `xor` (W64# y#)  = W64# (x# `xor64#` y#)
    complement (W64# x#)       = W64# (not64# x#)
    (W64# x#) `shift` (I# i#)
626
        | isTrue# (i# >=# 0#)  = W64# (x# `shiftL64#` i#)
627
        | otherwise            = W64# (x# `shiftRL64#` negateInt# i#)
628
    (W64# x#) `shiftL`       (I# i#) = W64# (x# `shiftL64#` i#)
tibbe's avatar
tibbe committed
629
    (W64# x#) `unsafeShiftL` (I# i#) = W64# (x# `uncheckedShiftL64#` i#)
630
    (W64# x#) `shiftR`       (I# i#) = W64# (x# `shiftRL64#` i#)
tibbe's avatar
tibbe committed
631
    (W64# x#) `unsafeShiftR` (I# i#) = W64# (x# `uncheckedShiftRL64#` i#)
632
    (W64# x#) `rotate` (I# i#)
633 634 635
        | isTrue# (i'# ==# 0#) = W64# x#
        | otherwise            = W64# ((x# `uncheckedShiftL64#` i'#) `or64#`
                                       (x# `uncheckedShiftRL64#` (64# -# i'#)))
636
        where
637
        !i'# = word2Int# (int2Word# i# `and#` 63##)
638 639
    bitSizeMaybe i            = Just (finiteBitSize i)
    bitSize i                 = finiteBitSize i
640
    isSigned _                = False
tibbe's avatar
tibbe committed
641
    popCount (W64# x#)        = I# (word2Int# (popCnt64# x#))
642 643
    bit                       = bitDefault
    testBit                   = testBitDefault
644

645 646 647 648 649 650 651
-- give the 64-bit shift operations the same treatment as the 32-bit
-- ones (see GHC.Base), namely we wrap them in tests to catch the
-- cases when we're shifting more than 64 bits to avoid unspecified
-- behaviour in the C shift operations.

shiftL64#, shiftRL64# :: Word64# -> Int# -> Word64#

652 653
a `shiftL64#` b  | isTrue# (b >=# 64#) = wordToWord64# 0##
                 | otherwise           = a `uncheckedShiftL64#` b
654

655 656
a `shiftRL64#` b | isTrue# (b >=# 64#) = wordToWord64# 0##
                 | otherwise           = a `uncheckedShiftRL64#` b
657

658 659 660 661 662 663 664 665 666 667
{-# RULES
"fromIntegral/Int->Word64"    fromIntegral = \(I#   x#) -> W64# (int64ToWord64# (intToInt64# x#))
"fromIntegral/Word->Word64"   fromIntegral = \(W#   x#) -> W64# (wordToWord64# x#)
"fromIntegral/Word64->Int"    fromIntegral = \(W64# x#) -> I#   (word2Int# (word64ToWord# x#))
"fromIntegral/Word64->Word"   fromIntegral = \(W64# x#) -> W#   (word64ToWord# x#)
"fromIntegral/Word64->Word64" fromIntegral = id :: Word64 -> Word64
  #-}

#else

668 669 670 671
-- Word64 is represented in the same way as Word.
-- Operations may assume and must ensure that it holds only values
-- from its logical range.

Ian Lynagh's avatar
Ian Lynagh committed
672
data {-# CTYPE "HsWord64" #-} Word64 = W64# Word# deriving (Eq, Ord)
673
-- ^ 64-bit unsigned integer type
674 675 676 677 678 679 680 681 682

instance Num Word64 where
    (W64# x#) + (W64# y#)  = W64# (x# `plusWord#` y#)
    (W64# x#) - (W64# y#)  = W64# (x# `minusWord#` y#)
    (W64# x#) * (W64# y#)  = W64# (x# `timesWord#` y#)
    negate (W64# x#)       = W64# (int2Word# (negateInt# (word2Int# x#)))
    abs x                  = x
    signum 0               = 0
    signum _               = 1
683
    fromInteger i          = W64# (integerToWord i)
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704

instance Enum Word64 where
    succ x
        | x /= maxBound = x + 1
        | otherwise     = succError "Word64"
    pred x
        | x /= minBound = x - 1
        | otherwise     = predError "Word64"
    toEnum i@(I# i#)
        | i >= 0        = W64# (int2Word# i#)
        | otherwise     = toEnumError "Word64" i (minBound::Word64, maxBound::Word64)
    fromEnum x@(W64# x#)
        | x <= fromIntegral (maxBound::Int)
                        = I# (word2Int# x#)
        | otherwise     = fromEnumError "Word64" x
    enumFrom            = integralEnumFrom
    enumFromThen        = integralEnumFromThen
    enumFromTo          = integralEnumFromTo
    enumFromThenTo      = integralEnumFromThenTo

instance Integral Word64 where
Ian Lynagh's avatar
Ian Lynagh committed
705
    quot    (W64# x#) y@(W64# y#)
706
        | y /= 0                    = W64# (x# `quotWord#` y#)
707
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
708
    rem     (W64# x#) y@(W64# y#)
709
        | y /= 0                    = W64# (x# `remWord#` y#)
710
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
711
    div     (W64# x#) y@(W64# y#)
712
        | y /= 0                    = W64# (x# `quotWord#` y#)
713
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
714
    mod     (W64# x#) y@(W64# y#)
715
        | y /= 0                    = W64# (x# `remWord#` y#)
716
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
717
    quotRem (W64# x#) y@(W64# y#)
718 719 720
        | y /= 0                  = case x# `quotRemWord#` y# of
                                    (# q, r #) ->
                                        (W64# q, W64# r)
721
        | otherwise                 = divZeroError
Ian Lynagh's avatar
Ian Lynagh committed
722
    divMod  (W64# x#) y@(W64# y#)
723
        | y /= 0                    = (W64# (x# `quotWord#` y#), W64# (x# `remWord#` y#))
724
        | otherwise                 = divZeroError
725
    toInteger (W64# x#)
726
        | isTrue# (i# >=# 0#)       = smallInteger i#
727
        | otherwise                 = wordToInteger x#
728
        where
729
        !i# = word2Int# x#
730 731

instance Bits Word64 where
732
    {-# INLINE shift #-}
733 734
    {-# INLINE bit #-}
    {-# INLINE testBit #-}
735

736 737 738
    (W64# x#) .&.   (W64# y#)  = W64# (x# `and#` y#)
    (W64# x#) .|.   (W64# y#)  = W64# (x# `or#`  y#)
    (W64# x#) `xor` (W64# y#)  = W64# (x# `xor#` y#)
739 740
    complement (W64# x#)       = W64# (x# `xor#` mb#)
        where !(W64# mb#) = maxBound
741
    (W64# x#) `shift` (I# i#)
742
        | isTrue# (i# >=# 0#)  = W64# (x# `shiftL#` i#)
743
        | otherwise            = W64# (x# `shiftRL#` negateInt# i#)
744
    (W64# x#) `shiftL`       (I# i#) = W64# (x# `shiftL#` i#)
tibbe's avatar
tibbe committed
745
    (W64# x#) `unsafeShiftL` (I# i#) = W64# (x# `uncheckedShiftL#` i#)
746
    (W64# x#) `shiftR`       (I# i#) = W64# (x# `shiftRL#` i#)
tibbe's avatar
tibbe committed
747
    (W64# x#) `unsafeShiftR` (I# i#) = W64# (x# `uncheckedShiftRL#` i#)
748
    (W64# x#) `rotate` (I# i#)
749 750 751
        | isTrue# (i'# ==# 0#) = W64# x#
        | otherwise            = W64# ((x# `uncheckedShiftL#` i'#) `or#`
                                       (x# `uncheckedShiftRL#` (64# -# i'#)))
752
        where
753
        !i'# = word2Int# (int2Word# i# `and#` 63##)
754 755
    bitSizeMaybe i            = Just (finiteBitSize i)
    bitSize i                 = finiteBitSize i
756
    isSigned _                = False
tibbe's avatar
tibbe committed
757
    popCount (W64# x#)        = I# (word2Int# (popCnt64# x#))
758 759
    bit                       = bitDefault
    testBit                   = testBitDefault
760 761 762 763 764 765

{-# RULES
"fromIntegral/a->Word64" fromIntegral = \x -> case fromIntegral x of W# x# -> W64# x#
"fromIntegral/Word64->a" fromIntegral = \(W64# x#) -> fromIntegral (W# x#)
  #-}

Ian Lynagh's avatar
Ian Lynagh committed
766
uncheckedShiftL64# :: Word# -> Int# -> Word#
767
uncheckedShiftL64#  = uncheckedShiftL#
Ian Lynagh's avatar
Ian Lynagh committed
768 769

uncheckedShiftRL64# :: Word# -> Int# -> Word#
770 771
uncheckedShiftRL64# = uncheckedShiftRL#

772 773
#endif

774 775
instance FiniteBits Word64 where
    finiteBitSize _ = 64
776 777
    countLeadingZeros  (W64# x#) = I# (word2Int# (clz64# x#))
    countTrailingZeros (W64# x#) = I# (word2Int# (ctz64# x#))