2 % (c) The AQUA Project, Glasgow University, 1997
4 \section[Word]{Module @Word@}
6 GHC implementation of the standard Hugs/GHC @Word@
7 interface, types and operations over unsigned, sized
14 ( Word8 -- all abstract.
15 , Word16 -- instances: Eq, Ord
16 , Word32 -- Num, Bounded, Real,
17 , Word64 -- Integral, Ix, Enum,
19 -- CCallable, CReturnable
22 , word8ToWord32 -- :: Word8 -> Word32
23 , word32ToWord8 -- :: Word32 -> Word8
24 , word16ToWord32 -- :: Word16 -> Word32
25 , word32ToWord16 -- :: Word32 -> Word16
27 , word8ToInt -- :: Word8 -> Int
28 , intToWord8 -- :: Int -> Word8
29 , word16ToInt -- :: Word16 -> Int
30 , intToWord16 -- :: Int -> Word16
31 , word32ToInt -- :: Word32 -> Int
32 , intToWord32 -- :: Int -> Word32
34 , word32ToWord64 -- :: Word32 -> Word64
35 , word64ToWord32 -- :: Word64 -> Word32
37 , word64ToInteger -- :: Word64 -> Integer
38 , integerToWord64 -- :: Integer -> Word64
41 , wordToWord8 -- :: Word -> Word8
42 , word8ToWord -- :: Word8 -> Word
43 , wordToWord16 -- :: Word -> Word16
44 , word16ToWord -- :: Word16 -> Word
45 , wordToWord32 -- :: Word -> Word32
46 , word32ToWord -- :: Word32 -> Word
47 , wordToWord64 -- :: Word -> Word64
48 , word64ToWord -- :: Word64 -> Word
50 -- The "official" place to get these from is Addr.
71 -- The "official" place to get these from is Foreign
72 #ifndef __PARALLEL_HASKELL__
73 , indexWord8OffForeignObj
74 , indexWord16OffForeignObj
75 , indexWord32OffForeignObj
76 , indexWord64OffForeignObj
78 , readWord8OffForeignObj
79 , readWord16OffForeignObj
80 , readWord32OffForeignObj
81 , readWord64OffForeignObj
83 , writeWord8OffForeignObj
84 , writeWord16OffForeignObj
85 , writeWord32OffForeignObj
86 , writeWord64OffForeignObj
89 -- non-standard, GHC specific
106 import Numeric (readDec, showInt)
108 -----------------------------------------------------------------------------
109 -- The "official" coercion functions
110 -----------------------------------------------------------------------------
112 word8ToWord32 :: Word8 -> Word32
113 word32ToWord8 :: Word32 -> Word8
114 word16ToWord32 :: Word16 -> Word32
115 word32ToWord16 :: Word32 -> Word16
117 word8ToInt :: Word8 -> Int
118 intToWord8 :: Int -> Word8
119 word16ToInt :: Word16 -> Int
120 intToWord16 :: Int -> Word16
122 word8ToInt = word32ToInt . word8ToWord32
123 intToWord8 = word32ToWord8 . intToWord32
124 word16ToInt = word32ToInt . word16ToWord32
125 intToWord16 = word32ToWord16 . intToWord32
127 intToWord32 :: Int -> Word32
128 intToWord32 (I# x) = W32# ((int2Word# x) `and#` (case (maxBound::Word32) of W32# x# -> x#))
129 --intToWord32 (I# x) = W32# (int2Word# x)
131 word32ToInt :: Word32 -> Int
132 word32ToInt (W32# x) = I# (word2Int# x)
134 wordToInt :: Word -> Int
135 wordToInt (W# w#) = I# (word2Int# w#)
139 \subsection[Word8]{The @Word8@ interface}
141 The byte type @Word8@ is represented in the Haskell
142 heap by boxing up a 32-bit quantity, @Word#@. An invariant
143 for this representation is that the higher 24 bits are
144 *always* zeroed out. A consequence of this is that
145 operations that could possibly overflow have to mask
146 out the top three bytes before building the resulting @Word8@.
149 data Word8 = W8# Word#
151 instance CCallable Word8
152 instance CReturnable Word8
154 word8ToWord32 (W8# x) = W32# x
155 word32ToWord8 (W32# x) = W8# (wordToWord8# x)
157 -- mask out upper three bytes.
158 intToWord8# :: Int# -> Word#
159 intToWord8# i# = (int2Word# i#) `and#` (int2Word# 0xff#)
161 wordToWord8# :: Word# -> Word#
162 wordToWord8# w# = w# `and#` (int2Word# 0xff#)
164 instance Eq Word8 where
165 (W8# x) == (W8# y) = x `eqWord#` y
166 (W8# x) /= (W8# y) = x `neWord#` y
168 instance Ord Word8 where
169 compare (W8# x#) (W8# y#) = compareWord# x# y#
170 (<) (W8# x) (W8# y) = x `ltWord#` y
171 (<=) (W8# x) (W8# y) = x `leWord#` y
172 (>=) (W8# x) (W8# y) = x `geWord#` y
173 (>) (W8# x) (W8# y) = x `gtWord#` y
174 max x@(W8# x#) y@(W8# y#) =
175 case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
176 min x@(W8# x#) y@(W8# y#) =
177 case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
179 -- Helper function, used by Ord Word* instances.
180 compareWord# :: Word# -> Word# -> Ordering
182 | x# `ltWord#` y# = LT
183 | x# `eqWord#` y# = EQ
186 instance Num Word8 where
188 W8# (intToWord8# (word2Int# x +# word2Int# y))
190 W8# (intToWord8# (word2Int# x -# word2Int# y))
192 W8# (intToWord8# (word2Int# x *# word2Int# y))
196 else W8# (int2Word# (0x100# -# x'))
201 fromInteger (J# a# s# d#) = W8# (wordToWord8# (integer2Word# a# s# d#))
204 instance Bounded Word8 where
208 instance Real Word8 where
209 toRational x = toInteger x % 1
211 -- Note: no need to mask results here
212 -- as they cannot overflow.
213 instance Integral Word8 where
214 div (W8# x) (W8# y) = W8# (x `quotWord#` y)
215 quot (W8# x) (W8# y) = W8# (x `quotWord#` y)
216 rem (W8# x) (W8# y) = W8# (x `remWord#` y)
217 mod (W8# x) (W8# y) = W8# (x `remWord#` y)
218 quotRem (W8# x) (W8# y) = (W8# (x `quotWord#` y), W8# (x `remWord#` y))
219 divMod (W8# x) (W8# y) = (W8# (x `quotWord#` y), W8# (x `remWord#` y))
220 toInteger (W8# x) = word2Integer x
221 toInt x = word8ToInt x
223 instance Ix Word8 where
226 | inRange b i = word8ToInt (i-m)
227 | otherwise = indexError i b "Word8"
228 inRange (m,n) i = m <= i && i <= n
230 instance Enum Word8 where
232 | w == maxBound = error ("Enum{Word8}.succ: tried to take `succ' of " ++ show w)
235 | w == minBound = error ("Enum{Word8}.pred: tried to take `pred' of " ++ show w)
238 toEnum (I# i) = W8# (intToWord8# i)
239 fromEnum (W8# w) = I# (word2Int# w)
240 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word8)]
241 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word8)]
242 where last = if d < c then minBound else maxBound
244 instance Read Word8 where
245 readsPrec _ = readDec
247 instance Show Word8 where
248 showsPrec _ = showInt
251 -- Word8s are represented by an (unboxed) 32-bit Word.
252 -- The invariant is that the upper 24 bits are always zeroed out.
254 instance Bits Word8 where
255 (W8# x) .&. (W8# y) = W8# (x `and#` y)
256 (W8# x) .|. (W8# y) = W8# (x `or#` y)
257 (W8# x) `xor` (W8# y) = W8# (x `xor#` y)
258 complement (W8# x) = W8# (x `xor#` int2Word# 0xff#)
259 shift (W8# x#) i@(I# i#)
260 | i > 0 = W8# (wordToWord8# (shiftL# x# i#))
261 | otherwise = W8# (wordToWord8# (shiftRL# x# (negateInt# i#)))
262 w@(W8# x) `rotate` (I# i)
264 | i ># 0# = W8# ((wordToWord8# (shiftL# x i')) `or#`
266 (int2Word# (0x100# -# pow2# i2)))
268 | otherwise = rotate w (I# (8# +# i))
270 i' = word2Int# (int2Word# i `and#` int2Word# 7#)
274 | i# >=# 0# && i# <=# 7# = W8# (wordToWord8# (shiftL# (int2Word# 1#) i#))
275 | otherwise = 0 -- We'll be overbearing, for now..
277 setBit x i = x .|. bit i
278 clearBit x i = x .&. complement (bit i)
279 complementBit x i = x `xor` bit i
281 testBit (W8# x#) (I# i#)
282 | i# <# 8# && i# >=# 0# = (word2Int# (x# `and#` (shiftL# (int2Word# 1#) i#))) /=# 0#
283 | otherwise = False -- for now, this is really an error.
288 pow2# :: Int# -> Int#
289 pow2# x# = word2Int# (shiftL# (int2Word# 1#) x#)
291 word2Integer :: Word# -> Integer
292 word2Integer w = case word2Integer# w of
293 (# a, s, d #) -> J# a s d
295 pow2_64# :: Int# -> Int64#
296 pow2_64# x# = word64ToInt64# (shiftL64# (wordToWord64# (int2Word# 1#)) x#)
298 sizeofWord8 :: Word32
303 \subsection[Word16]{The @Word16@ interface}
305 The double byte type @Word16@ is represented in the Haskell
306 heap by boxing up a machine word, @Word#@. An invariant
307 for this representation is that only the lower 16 bits are
308 `active', any bits above are {\em always} zeroed out.
309 A consequence of this is that operations that could possibly
310 overflow have to mask out anything above the lower two bytes
311 before putting together the resulting @Word16@.
314 data Word16 = W16# Word#
315 instance CCallable Word16
316 instance CReturnable Word16
318 word16ToWord32 (W16# x) = W32# x
319 word32ToWord16 (W32# x) = W16# (wordToWord16# x)
321 -- mask out upper 16 bits.
322 intToWord16# :: Int# -> Word#
323 intToWord16# i# = ((int2Word# i#) `and#` (int2Word# 0xffff#))
325 wordToWord16# :: Word# -> Word#
326 wordToWord16# w# = w# `and#` (int2Word# 0xffff#)
328 instance Eq Word16 where
329 (W16# x) == (W16# y) = x `eqWord#` y
330 (W16# x) /= (W16# y) = x `neWord#` y
332 instance Ord Word16 where
333 compare (W16# x#) (W16# y#) = compareWord# x# y#
334 (<) (W16# x) (W16# y) = x `ltWord#` y
335 (<=) (W16# x) (W16# y) = x `leWord#` y
336 (>=) (W16# x) (W16# y) = x `geWord#` y
337 (>) (W16# x) (W16# y) = x `gtWord#` y
338 max x@(W16# x#) y@(W16# y#) =
339 case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
340 min x@(W16# x#) y@(W16# y#) =
341 case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
343 instance Num Word16 where
344 (W16# x) + (W16# y) =
345 W16# (intToWord16# (word2Int# x +# word2Int# y))
346 (W16# x) - (W16# y) =
347 W16# (intToWord16# (word2Int# x -# word2Int# y))
348 (W16# x) * (W16# y) =
349 W16# (intToWord16# (word2Int# x *# word2Int# y))
353 else W16# (int2Word# (0x10000# -# x'))
358 fromInteger (J# a# s# d#) = W16# (wordToWord16# (integer2Word# a# s# d#))
359 fromInt = intToWord16
361 instance Bounded Word16 where
365 instance Real Word16 where
366 toRational x = toInteger x % 1
368 instance Integral Word16 where
369 div (W16# x) (W16# y) = W16# (x `quotWord#` y)
370 quot (W16# x) (W16# y) = W16# (x `quotWord#` y)
371 rem (W16# x) (W16# y) = W16# (x `remWord#` y)
372 mod (W16# x) (W16# y) = W16# (x `remWord#` y)
373 quotRem (W16# x) (W16# y) = (W16# (x `quotWord#` y), W16# (x `remWord#` y))
374 divMod (W16# x) (W16# y) = (W16# (x `quotWord#` y), W16# (x `remWord#` y))
375 toInteger (W16# x) = word2Integer x
376 toInt x = word16ToInt x
378 instance Ix Word16 where
381 | inRange b i = word16ToInt (i - m)
382 | otherwise = indexError i b "Word16"
383 inRange (m,n) i = m <= i && i <= n
385 instance Enum Word16 where
387 | w == maxBound = error ("Enum{Word16}.succ: tried to take `succ' of " ++ show w)
390 | w == minBound = error ("Enum{Word16}.pred: tried to take `pred' of " ++ show w)
392 toEnum (I# i) = W16# (intToWord16# i)
393 fromEnum (W16# w) = I# (word2Int# w)
394 enumFrom c = map toEnum [fromEnum c .. fromEnum (maxBound::Word16)]
395 enumFromThen c d = map toEnum [fromEnum c, fromEnum d .. fromEnum (last::Word16)]
396 where last = if d < c then minBound else maxBound
398 instance Read Word16 where
399 readsPrec _ = readDec
401 instance Show Word16 where
402 showsPrec _ = showInt
404 instance Bits Word16 where
405 (W16# x) .&. (W16# y) = W16# (x `and#` y)
406 (W16# x) .|. (W16# y) = W16# (x `or#` y)
407 (W16# x) `xor` (W16# y) = W16# (x `xor#` y)
408 complement (W16# x) = W16# (x `xor#` int2Word# 0xffff#)
409 shift (W16# x#) i@(I# i#)
410 | i > 0 = W16# (wordToWord16# (shiftL# x# i#))
411 | otherwise = W16# (shiftRL# x# (negateInt# i#))
412 w@(W16# x) `rotate` (I# i)
414 | i ># 0# = W16# ((wordToWord16# (shiftL# x i')) `or#`
416 (int2Word# (0x10000# -# pow2# i2)))
418 | otherwise = rotate w (I# (16# +# i'))
420 i' = word2Int# (int2Word# i `and#` int2Word# 15#)
423 | i# >=# 0# && i# <=# 15# = W16# (shiftL# (int2Word# 1#) i#)
424 | otherwise = 0 -- We'll be overbearing, for now..
426 setBit x i = x .|. bit i
427 clearBit x i = x .&. complement (bit i)
428 complementBit x i = x `xor` bit i
430 testBit (W16# x#) (I# i#)
431 | i# <# 16# && i# >=# 0# = (word2Int# (x# `and#` (shiftL# (int2Word# 1#) i#))) /=# 0#
432 | otherwise = False -- for now, this is really an error.
438 sizeofWord16 :: Word32
443 \subsection[Word32]{The @Word32@ interface}
445 The quad byte type @Word32@ is represented in the Haskell
446 heap by boxing up a machine word, @Word#@. An invariant
447 for this representation is that any bits above the lower
448 32 are {\em always} zeroed out. A consequence of this is that
449 operations that could possibly overflow have to mask
450 the result before building the resulting @Word16@.
453 data Word32 = W32# Word#
455 instance CCallable Word32
456 instance CReturnable Word32
458 instance Eq Word32 where
459 (W32# x) == (W32# y) = x `eqWord#` y
460 (W32# x) /= (W32# y) = x `neWord#` y
462 instance Ord Word32 where
463 compare (W32# x#) (W32# y#) = compareWord# x# y#
464 (<) (W32# x) (W32# y) = x `ltWord#` y
465 (<=) (W32# x) (W32# y) = x `leWord#` y
466 (>=) (W32# x) (W32# y) = x `geWord#` y
467 (>) (W32# x) (W32# y) = x `gtWord#` y
468 max x@(W32# x#) y@(W32# y#) =
469 case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
470 min x@(W32# x#) y@(W32# y#) =
471 case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
473 instance Num Word32 where
474 (W32# x) + (W32# y) =
475 W32# (intToWord32# (word2Int# x +# word2Int# y))
476 (W32# x) - (W32# y) =
477 W32# (intToWord32# (word2Int# x -# word2Int# y))
478 (W32# x) * (W32# y) =
479 W32# (intToWord32# (word2Int# x *# word2Int# y))
480 #if WORD_SIZE_IN_BYTES == 8
484 else W32# (intToWord32# (0x100000000# -# x'))
488 negate (W32# x) = W32# (intToWord32# (negateInt# (word2Int# x)))
492 fromInteger (J# a# s# d#) = W32# (integer2Word# a# s# d#)
493 fromInt (I# x) = W32# (intToWord32# x)
494 -- ToDo: restrict fromInt{eger} range.
496 intToWord32# :: Int# -> Word#
497 wordToWord32# :: Word# -> Word#
499 #if WORD_SIZE_IN_BYTES == 8
500 intToWord32# i# = (int2Word# i#) `and#` (int2Word# 0xffffffff)
501 wordToWord32# w# = w# `and#` (int2Word# 0xffffffff)
502 wordToWord64# w# = w#
504 intToWord32# i# = int2Word# i#
505 wordToWord32# w# = w#
509 instance Bounded Word32 where
511 #if WORD_SIZE_IN_BYTES == 8
512 maxBound = 0xffffffff
514 maxBound = minBound - 1
517 instance Real Word32 where
518 toRational x = toInteger x % 1
520 instance Integral Word32 where
521 div x y = quotWord32 x y
522 quot x y = quotWord32 x y
523 rem x y = remWord32 x y
524 mod x y = remWord32 x y
525 quotRem a b = (a `quotWord32` b, a `remWord32` b)
526 divMod x y = quotRem x y
527 toInteger (W32# x) = word2Integer x
528 toInt (W32# x) = I# (word2Int# x)
530 {-# INLINE quotWord32 #-}
531 {-# INLINE remWord32 #-}
532 remWord32, quotWord32 :: Word32 -> Word32 -> Word32
533 (W32# x) `quotWord32` (W32# y) = W32# (x `quotWord#` y)
534 (W32# x) `remWord32` (W32# y) = W32# (x `remWord#` y)
536 instance Ix Word32 where
539 | inRange b i = word32ToInt (i - m)
540 | otherwise = indexError i b "Word32"
541 inRange (m,n) i = m <= i && i <= n
543 instance Enum Word32 where
545 | w == maxBound = error ("Enum{Word32}.succ: tried to take `succ' of " ++ show w)
548 | w == minBound = error ("Enum{Word32}.pred: tried to take `pred' of " ++ show w)
551 fromEnum = word32ToInt -- lossy, don't use.
552 enumFrom w = [w .. maxBound]
555 | otherwise = eft32 w1 w2
557 enumFromThen w1 w2 = [w1,w2 .. last]
560 | w1 < w2 = maxBound::Word32
561 | otherwise = minBound
563 enumFromThenTo w1 w2 wend = eftt32 w1 stepWith
570 stepWith :: Word32 -> Maybe Word32
572 | increasing && x > nxt = Nothing --oflow.
573 | wend <= x = Nothing
574 | otherwise = Just nxt
577 | increasing = x + diff1
578 | otherwise = x - diff2
580 eftt32 :: Word32 -> (Word32 -> Maybe Word32) -> [Word32]
581 eftt32 init stepper = go init
588 eft32 :: Word32 -> Word32 -> [Word32]
589 eft32 now last = go now
593 | otherwise = x:go (x+1)
595 instance Read Word32 where
596 readsPrec _ = readDec
598 instance Show Word32 where
599 showsPrec _ = showInt
601 instance Bits Word32 where
602 (W32# x) .&. (W32# y) = W32# (x `and#` y)
603 (W32# x) .|. (W32# y) = W32# (x `or#` y)
604 (W32# x) `xor` (W32# y) = W32# (x `xor#` y)
605 complement (W32# x) = W32# (x `xor#` mb#) where (W32# mb#) = maxBound
606 shift (W32# x) i@(I# i#)
607 | i > 0 = W32# (wordToWord32# (shiftL# x i#))
608 | otherwise = W32# (shiftRL# x (negateInt# i#))
609 w@(W32# x) `rotate` (I# i)
611 | i ># 0# = W32# ((wordToWord32# (shiftL# x i')) `or#`
613 (int2Word# (word2Int# maxBound# -# pow2# i2 +# 1#)))
615 | otherwise = rotate w (I# (32# +# i))
617 i' = word2Int# (int2Word# i `and#` int2Word# 31#)
619 (W32# maxBound#) = maxBound
622 | i# >=# 0# && i# <=# 31# = W32# (shiftL# (int2Word# 1#) i#)
623 | otherwise = 0 -- We'll be overbearing, for now..
625 setBit x i = x .|. bit i
626 clearBit x i = x .&. complement (bit i)
627 complementBit x i = x `xor` bit i
629 testBit (W32# x#) (I# i#)
630 | i# <# 32# && i# >=# 0# = (word2Int# (x# `and#` (shiftL# (int2Word# 1#) i#))) /=# 0#
631 | otherwise = False -- for now, this is really an error.
635 sizeofWord32 :: Word32
639 \subsection[Word64]{The @Word64@ interface}
642 #if WORD_SIZE_IN_BYTES == 8
643 --data Word64 = W64# Word#
645 word32ToWord64 :: Word32 -> Word64
646 word32ToWord64 (W32 w#) = W64# w#
648 wordToWord32# :: Word# -> Word#
649 wordToWord32# w# = w# `and#` (case (maxBound::Word32) of W# x# -> x#)
651 word64ToWord32 :: Word64 -> Word32
652 word64ToWord32 (W64# w#) = W32# (wordToWord32# w#)
654 wordToWord64# w# = w#
655 word64ToWord# w# = w#
657 instance Eq Word64 where
658 (W64# x) == (W64# y) = x `eqWord#` y
659 (W64# x) /= (W64# y) = x `neWord#` y
661 instance Ord Word64 where
662 compare (W64# x#) (W64# y#) = compareWord# x# y#
663 (<) (W64# x) (W64# y) = x `ltWord#` y
664 (<=) (W64# x) (W64# y) = x `leWord#` y
665 (>=) (W64# x) (W64# y) = x `geWord#` y
666 (>) (W64# x) (W64# y) = x `gtWord#` y
667 max x@(W64# x#) y@(W64# y#) =
668 case (compareWord# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
669 min x@(W64# x#) y@(W64# y#) =
670 case (compareWord# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
672 instance Num Word64 where
673 (W64# x) + (W64# y) =
674 W64# (intToWord64# (word2Int# x +# word2Int# y))
675 (W64# x) - (W64# y) =
676 W64# (intToWord64# (word2Int# x -# word2Int# y))
677 (W64# x) * (W64# y) =
678 W64# (intToWord64# (word2Int# x *# word2Int# y))
682 else W64# (int2Word# (0x100# -# x'))
687 fromInteger (J# a# s# d#) = W64# (integer2Word# a# s# d#)
688 fromInt = intToWord64
690 instance Bounded Word64 where
692 maxBound = minBound - 1
694 instance Real Word64 where
695 toRational x = toInteger x % 1
697 -- Note: no need to mask results here
698 -- as they cannot overflow.
699 instance Integral Word64 where
700 div (W64# x) (W64# y) = W64# (x `quotWord#` y)
701 quot (W64# x) (W64# y) = W64# (x `quotWord#` y)
702 rem (W64# x) (W64# y) = W64# (x `remWord#` y)
703 mod (W64# x) (W64# y) = W64# (x `remWord#` y)
704 quotRem (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
705 divMod (W64# x) (W64# y) = (W64# (x `quotWord#` y), W64# (x `remWord#` y))
706 toInteger (W64# x) = word2Integer# x
707 toInt x = word64ToInt x
709 instance Ix Word64 where
712 | inRange b i = word64ToInt (i-m)
713 | otherwise = indexError i b "Word64"
714 inRange (m,n) i = m <= i && i <= n
716 instance Enum Word64 where
718 | w == maxBound = error ("Enum{Word64}.succ: tried to take `succ' of " ++ show w)
721 | w == minBound = error ("Enum{Word64}.pred: tried to take `pred' of " ++ show w)
723 toEnum (I# i) = W64# (intToWord# i)
724 fromEnum (W64# w) = I# (word2Int# w) -- lossy, don't use.
725 enumFrom w = eft64 w 1
726 enumFromTo w1 w2 = eftt64 w1 1 (> w2)
727 enumFromThen w1 w2 = eftt64 w1 (w2 - w1) (>last)
730 | w1 < w2 = maxBound::Word64
731 | otherwise = minBound
733 instance Read Word64 where
734 readsPrec _ = readDec
736 instance Show Word64 where
737 showsPrec _ = showInt
740 instance Bits Word64 where
741 (W64# x) .&. (W64# y) = W64# (x `and#` y)
742 (W64# x) .|. (W64# y) = W64# (x `or#` y)
743 (W64# x) `xor` (W64# y) = W64# (x `xor#` y)
744 complement (W64# x) = W64# (x `xor#` (case (maxBound::Word64) of W64# x# -> x#))
745 shift (W64# x#) i@(I# i#)
746 | i > 0 = W64# (shiftL# x# i#)
747 | otherwise = W64# (shiftRL# x# (negateInt# i#))
749 w@(W64# x) `rotate` (I# i)
751 | i ># 0# = W64# (shiftL# x i') `or#`
753 (int2Word# (word2Int# maxBound# -# pow2# i2 +# 1#)))
755 | otherwise = rotate w (I# (64# +# i))
757 i' = word2Int# (int2Word# i `and#` int2Word# 63#)
759 (W64# maxBound#) = maxBound
762 | i# >=# 0# && i# <=# 63# = W64# (shiftL# (int2Word# 1#) i#)
763 | otherwise = 0 -- We'll be overbearing, for now..
765 setBit x i = x .|. bit i
766 clearBit x i = x .&. complement (bit i)
767 complementBit x i = x `xor` bit i
769 testBit (W64# x#) (I# i#)
770 | i# <# 64# && i# >=# 0# = (word2Int# (x# `and#` (shiftL# (int2Word# 1#) i#))) /=# 0#
771 | otherwise = False -- for now, this is really an error.
777 --defined in PrelCCall: data Word64 = W64 Word64# deriving (Eq, Ord, Bounded)
779 -- for completeness sake
780 word32ToWord64 :: Word32 -> Word64
781 word32ToWord64 (W32# w#) = W64# (wordToWord64# w#)
783 word64ToWord32 :: Word64 -> Word32
784 word64ToWord32 (W64# w#) = W32# (word64ToWord# w#)
786 word64ToInteger :: Word64 -> Integer
787 word64ToInteger (W64# w#) =
788 case word64ToInteger# w# of
789 (# a#, s#, p# #) -> J# a# s# p#
791 word64ToInt :: Word64 -> Int
793 case w `quotRem` 0x100000000 of
794 (_,l) -> toInt (word64ToWord32 l)
796 intToWord64# :: Int# -> Word64#
797 intToWord64# i# = wordToWord64# (int2Word# i#)
799 intToWord64 :: Int -> Word64
800 intToWord64 (I# i#) = W64# (intToWord64# i#)
802 integerToWord64 :: Integer -> Word64
803 integerToWord64 (J# a# s# d#) = W64# (integerToWord64# a# s# d#)
805 instance Show Word64 where
806 showsPrec p x = showsPrec p (word64ToInteger x)
808 instance Read Word64 where
809 readsPrec _ s = [ (integerToWord64 x,r) | (x,r) <- readDec s ]
811 instance Eq Word64 where
812 (W64# x) == (W64# y) = x `eqWord64#` y
813 (W64# x) /= (W64# y) = not (x `eqWord64#` y)
815 instance Ord Word64 where
816 compare (W64# x#) (W64# y#) = compareWord64# x# y#
817 (<) (W64# x) (W64# y) = x `ltWord64#` y
818 (<=) (W64# x) (W64# y) = x `leWord64#` y
819 (>=) (W64# x) (W64# y) = x `geWord64#` y
820 (>) (W64# x) (W64# y) = x `gtWord64#` y
821 max x@(W64# x#) y@(W64# y#) =
822 case (compareWord64# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
823 min x@(W64# x#) y@(W64# y#) =
824 case (compareWord64# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
826 instance Num Word64 where
827 (W64# x) + (W64# y) =
828 W64# (int64ToWord64# (word64ToInt64# x `plusInt64#` word64ToInt64# y))
829 (W64# x) - (W64# y) =
830 W64# (int64ToWord64# (word64ToInt64# x `minusInt64#` word64ToInt64# y))
831 (W64# x) * (W64# y) =
832 W64# (int64ToWord64# (word64ToInt64# x `timesInt64#` word64ToInt64# y))
835 | otherwise = maxBound - w
839 fromInteger i = integerToWord64 i
840 fromInt = intToWord64
842 instance Bounded Word64 where
844 maxBound = minBound - 1
846 instance Real Word64 where
847 toRational x = toInteger x % 1
849 -- Note: no need to mask results here
850 -- as they cannot overflow.
851 instance Integral Word64 where
852 div (W64# x) (W64# y) = W64# (x `quotWord64#` y)
853 quot (W64# x) (W64# y) = W64# (x `quotWord64#` y)
854 rem (W64# x) (W64# y) = W64# (x `remWord64#` y)
855 mod (W64# x) (W64# y) = W64# (x `remWord64#` y)
856 quotRem (W64# x) (W64# y) = (W64# (x `quotWord64#` y), W64# (x `remWord64#` y))
857 divMod (W64# x) (W64# y) = (W64# (x `quotWord64#` y), W64# (x `remWord64#` y))
858 toInteger w64 = word64ToInteger w64
859 toInt x = word64ToInt x
862 instance Ix Word64 where
865 | inRange b i = word64ToInt (i-m)
866 | otherwise = indexError i b "Word64"
867 inRange (m,n) i = m <= i && i <= n
869 instance Enum Word64 where
871 | w == maxBound = error ("Enum{Word64}.succ: tried to take `succ' of " ++ show w)
874 | w == minBound = error ("Enum{Word64}.pred: tried to take `pred' of " ++ show w)
876 toEnum (I# i) = W64# (intToWord64# i)
877 fromEnum (W64# w) = I# (word2Int# (word64ToWord# w)) -- lossy, don't use.
878 enumFrom w = eft64 w 1
879 enumFromTo w1 w2 = eftt64 w1 1 (> w2)
880 enumFromThen w1 w2 = eftt64 w1 (w2 - w1) (>last)
883 | w1 < w2 = maxBound::Word64
884 | otherwise = minBound
886 instance Bits Word64 where
887 (W64# x) .&. (W64# y) = W64# (x `and64#` y)
888 (W64# x) .|. (W64# y) = W64# (x `or64#` y)
889 (W64# x) `xor` (W64# y) = W64# (x `xor64#` y)
890 complement (W64# x) = W64# (x `xor64#` (case (maxBound::Word64) of W64# x# -> x#))
891 shift (W64# x#) i@(I# i#)
892 | i > 0 = W64# (shiftL64# x# i#)
893 | otherwise = W64# (shiftRL64# x# (negateInt# i#))
895 w@(W64# x) `rotate` (I# i)
897 | i ># 0# = W64# ((shiftL64# x i') `or64#`
898 (shiftRL64# (x `and64#`
899 (int64ToWord64# ((word64ToInt64# maxBound#) `minusInt64#`
900 (pow2_64# i2 `plusInt64#` (intToInt64# 1#))))))
902 | otherwise = rotate w (I# (64# +# i))
904 i' = word2Int# (int2Word# i `and#` int2Word# 63#)
906 (W64# maxBound#) = maxBound
909 | i# >=# 0# && i# <=# 63# = W64# (shiftL64# (wordToWord64# (int2Word# 1#)) i#)
910 | otherwise = 0 -- We'll be overbearing, for now..
912 setBit x i = x .|. bit i
913 clearBit x i = x .&. complement (bit i)
914 complementBit x i = x `xor` bit i
916 testBit (W64# x#) (I# i#)
917 | i# <# 64# && i# >=# 0# = (word2Int# (word64ToWord# (x# `and64#` (shiftL64# (wordToWord64# (int2Word# 1#)) i#)))) /=# 0#
918 | otherwise = False -- for now, this is really an error.
923 compareWord64# :: Word64# -> Word64# -> Ordering
925 | i# `ltWord64#` j# = LT
926 | i# `eqWord64#` j# = EQ
929 -- Word64# primop wrappers:
931 ltWord64# :: Word64# -> Word64# -> Bool
932 ltWord64# x# y# = unsafePerformIO $ do
933 v <- _ccall_ stg_ltWord64 x# y#
938 leWord64# :: Word64# -> Word64# -> Bool
939 leWord64# x# y# = unsafePerformIO $ do
940 v <- _ccall_ stg_leWord64 x# y#
945 eqWord64# :: Word64# -> Word64# -> Bool
946 eqWord64# x# y# = unsafePerformIO $ do
947 v <- _ccall_ stg_eqWord64 x# y#
952 neWord64# :: Word64# -> Word64# -> Bool
953 neWord64# x# y# = unsafePerformIO $ do
954 v <- _ccall_ stg_neWord64 x# y#
959 geWord64# :: Word64# -> Word64# -> Bool
960 geWord64# x# y# = unsafePerformIO $ do
961 v <- _ccall_ stg_geWord64 x# y#
966 gtWord64# :: Word64# -> Word64# -> Bool
967 gtWord64# x# y# = unsafePerformIO $ do
968 v <- _ccall_ stg_gtWord64 x# y#
973 plusInt64# :: Int64# -> Int64# -> Int64#
975 case (unsafePerformIO (_ccall_ stg_plusInt64 a# b#)) of
978 minusInt64# :: Int64# -> Int64# -> Int64#
980 case (unsafePerformIO (_ccall_ stg_minusInt64 a# b#)) of
983 timesInt64# :: Int64# -> Int64# -> Int64#
985 case (unsafePerformIO (_ccall_ stg_timesInt64 a# b#)) of
988 quotWord64# :: Word64# -> Word64# -> Word64#
990 case (unsafePerformIO (_ccall_ stg_quotWord64 a# b#)) of
993 remWord64# :: Word64# -> Word64# -> Word64#
995 case (unsafePerformIO (_ccall_ stg_remWord64 a# b#)) of
998 negateInt64# :: Int64# -> Int64#
1000 case (unsafePerformIO (_ccall_ stg_negateInt64 a#)) of
1003 and64# :: Word64# -> Word64# -> Word64#
1005 case (unsafePerformIO (_ccall_ stg_and64 a# b#)) of
1008 or64# :: Word64# -> Word64# -> Word64#
1010 case (unsafePerformIO (_ccall_ stg_or64 a# b#)) of
1013 xor64# :: Word64# -> Word64# -> Word64#
1015 case (unsafePerformIO (_ccall_ stg_xor64 a# b#)) of
1018 not64# :: Word64# -> Word64#
1020 case (unsafePerformIO (_ccall_ stg_not64 a#)) of
1023 shiftL64# :: Word64# -> Int# -> Word64#
1025 case (unsafePerformIO (_ccall_ stg_shiftL64 a# b#)) of
1028 shiftRL64# :: Word64# -> Int# -> Word64#
1030 case (unsafePerformIO (_ccall_ stg_shiftRL64 a# b#)) of
1033 word64ToWord# :: Word64# -> Word#
1034 word64ToWord# w64# =
1035 case (unsafePerformIO (_ccall_ stg_word64ToWord w64#)) of
1038 wordToWord64# :: Word# -> Word64#
1040 case (unsafePerformIO (_ccall_ stg_wordToWord64 w#)) of
1043 word64ToInt64# :: Word64# -> Int64#
1044 word64ToInt64# w64# =
1045 case (unsafePerformIO (_ccall_ stg_word64ToInt64 w64#)) of
1048 int64ToWord64# :: Int64# -> Word64#
1049 int64ToWord64# i64# =
1050 case (unsafePerformIO (_ccall_ stg_int64ToWord64 i64#)) of
1053 intToInt64# :: Int# -> Int64#
1055 case (unsafePerformIO (_ccall_ stg_intToInt64 i#)) of
1060 sizeofWord64 :: Word32
1063 -- Enum Word64 helper funs:
1065 eftt64 :: Word64 -> Word64 -> (Word64->Bool) -> [Word64]
1066 eftt64 init step done = go init
1070 | otherwise = now : go (now+step)
1072 eft64 :: Word64 -> Word64 -> [Word64]
1073 eft64 now step = go now
1076 | x == maxBound = [x]
1077 | otherwise = x:go (x+step)
1082 The Hugs-GHC extension libraries provide functions for going between
1083 Int and the various (un)signed ints. Here we provide the same for
1084 the GHC specific Word type:
1087 wordToWord8 :: Word -> Word8
1088 word8ToWord :: Word8 -> Word
1089 wordToWord16 :: Word -> Word16
1090 word16ToWord :: Word16 -> Word
1091 wordToWord32 :: Word -> Word32
1092 word32ToWord :: Word32 -> Word
1094 word8ToWord (W8# w#) = W# w#
1095 wordToWord8 (W# w#) = W8# (w# `and#` (case (maxBound::Word8) of W8# x# -> x#))
1096 word16ToWord (W16# w#) = W# w#
1097 wordToWord16 (W# w#) = W16# (w# `and#` (case (maxBound::Word16) of W16# x# -> x#))
1098 word32ToWord (W32# w#) = W# w#
1099 wordToWord32 (W# w#) = W32# (w# `and#` (case (maxBound::Word32) of W32# x# -> x#))
1101 wordToWord64 :: Word -> Word64
1102 wordToWord64 (W# w#) = W64# (wordToWord64# w#)
1104 -- lossy on 32-bit platforms, but provided nontheless.
1105 word64ToWord :: Word64 -> Word
1106 word64ToWord (W64# w#) = W# (word64ToWord# w#)
1111 --End of exported definitions
1113 The remainder of this file consists of definitions which are only
1114 used in the implementation.
1117 signumReal :: (Ord a, Num a) => a -> a
1118 signumReal x | x == 0 = 0
1124 NOTE: the index is in units of the size of the type, *not* bytes.
1127 indexWord8OffAddr :: Addr -> Int -> Word8
1128 indexWord8OffAddr (A# a#) (I# i#) = intToWord8 (I# (ord# (indexCharOffAddr# a# i#)))
1130 indexWord16OffAddr :: Addr -> Int -> Word16
1131 indexWord16OffAddr a i =
1132 #ifdef WORDS_BIGENDIAN
1133 intToWord16 ( word8ToInt l + (word8ToInt maxBound) * word8ToInt h)
1135 intToWord16 ( word8ToInt h + (word8ToInt maxBound) * word8ToInt l)
1139 l = indexWord8OffAddr a byte_idx
1140 h = indexWord8OffAddr a (byte_idx+1)
1142 indexWord32OffAddr :: Addr -> Int -> Word32
1143 indexWord32OffAddr (A# a#) i = wordToWord32 (W# (indexWordOffAddr# a# i'#))
1145 -- adjust index to be in Word units, not Word32 ones.
1147 #if WORD_SIZE_IN_BYTES==8
1153 indexWord64OffAddr :: Addr -> Int -> Word64
1154 indexWord64OffAddr (A# a#) (I# i#)
1155 #if WORD_SIZE_IN_BYTES==8
1156 = W64# (indexWordOffAddr# a# i#)
1158 = W64# (indexWord64OffAddr# a# i#)
1161 #ifndef __PARALLEL_HASKELL__
1163 indexWord8OffForeignObj :: ForeignObj -> Int -> Word8
1164 indexWord8OffForeignObj (ForeignObj fo#) (I# i#) = intToWord8 (I# (ord# (indexCharOffForeignObj# fo# i#)))
1166 indexWord16OffForeignObj :: ForeignObj -> Int -> Word16
1167 indexWord16OffForeignObj fo i =
1168 #ifdef WORDS_BIGENDIAN
1169 intToWord16 ( word8ToInt l + (word8ToInt maxBound) * word8ToInt h)
1171 intToWord16 ( word8ToInt h + (word8ToInt maxBound) * word8ToInt l)
1175 l = indexWord8OffForeignObj fo byte_idx
1176 h = indexWord8OffForeignObj fo (byte_idx+1)
1178 indexWord32OffForeignObj :: ForeignObj -> Int -> Word32
1179 indexWord32OffForeignObj (ForeignObj fo#) i = wordToWord32 (W# (indexWordOffForeignObj# fo# i'#))
1181 -- adjust index to be in Word units, not Word32 ones.
1183 #if WORD_SIZE_IN_BYTES==8
1189 indexWord64OffForeignObj :: ForeignObj -> Int -> Word64
1190 indexWord64OffForeignObj (ForeignObj fo#) (I# i#)
1191 #if WORD_SIZE_IN_BYTES==8
1192 = W64# (indexWordOffForeignObj# fo# i#)
1194 = W64# (indexWord64OffForeignObj# fo# i#)
1200 Read words out of mutable memory:
1203 readWord8OffAddr :: Addr -> Int -> IO Word8
1204 readWord8OffAddr a i = _casm_ `` %r=(StgNat8)(((StgNat8*)%0)[(StgInt)%1]); '' a i
1206 readWord16OffAddr :: Addr -> Int -> IO Word16
1207 readWord16OffAddr a i = _casm_ `` %r=(StgNat16)(((StgNat16*)%0)[(StgInt)%1]); '' a i
1209 readWord32OffAddr :: Addr -> Int -> IO Word32
1210 readWord32OffAddr a i = _casm_ `` %r=(StgNat32)(((StgNat32*)%0)[(StgInt)%1]); '' a i
1212 readWord64OffAddr :: Addr -> Int -> IO Word64
1213 #if WORD_SIZE_IN_BYTES==8
1214 readWord64OffAddr a i = _casm_ `` %r=(StgWord)(((StgWord*)%0)[(StgInt)%1]); '' a i
1216 readWord64OffAddr a i = _casm_ `` %r=(StgNat64)(((StgNat64*)%0)[(StgInt)%1]); '' a i
1219 #ifndef __PARALLEL_HASKELL__
1220 readWord8OffForeignObj :: ForeignObj -> Int -> IO Word8
1221 readWord8OffForeignObj fo i = _casm_ `` %r=(StgNat8)(((StgNat8*)%0)[(StgInt)%1]); '' fo i
1223 readWord16OffForeignObj :: ForeignObj -> Int -> IO Word16
1224 readWord16OffForeignObj fo i = _casm_ `` %r=(StgNat16)(((StgNat16*)%0)[(StgInt)%1]); '' fo i
1226 readWord32OffForeignObj :: ForeignObj -> Int -> IO Word32
1227 readWord32OffForeignObj fo i = _casm_ `` %r=(StgNat32)(((StgNat32*)%0)[(StgInt)%1]); '' fo i
1229 readWord64OffForeignObj :: ForeignObj -> Int -> IO Word64
1230 #if WORD_SIZE_IN_BYTES==8
1231 readWord64OffForeignObj fo i = _casm_ `` %r=(StgWord)(((StgWord*)%0)[(StgInt)%1]); '' fo i
1233 readWord64OffForeignObj fo i = _casm_ `` %r=(StgNat64)(((StgNat64*)%0)[(StgInt)%1]); '' fo i
1240 Note: we provide primops for the writing via Addrs since that's used
1241 in the IO implementation (a place where we *really* do care about cycles.)
1244 writeWord8OffAddr :: Addr -> Int -> Word8 -> IO ()
1245 writeWord8OffAddr (A# a#) (I# i#) (W8# w#) = IO $ \ s# ->
1246 case (writeCharOffAddr# a# i# (chr# (word2Int# w#)) s#) of s2# -> (# s2#, () #)
1248 writeWord16OffAddr :: Addr -> Int -> Word16 -> IO ()
1249 writeWord16OffAddr a i e = _casm_ `` (((StgNat16*)%0)[(StgInt)%1])=(StgNat16)%2; '' a i e
1251 writeWord32OffAddr :: Addr -> Int -> Word32 -> IO ()
1252 writeWord32OffAddr (A# a#) i (W32# w#) = IO $ \ s# ->
1253 case (writeWordOffAddr# a# i'# w# s#) of s2# -> (# s2#, () #)
1255 -- adjust index to be in Word units, not Word32 ones.
1257 #if WORD_SIZE_IN_BYTES==8
1263 writeWord64OffAddr :: Addr -> Int -> Word64 -> IO ()
1264 #if WORD_SIZE_IN_BYTES==8
1265 writeWord64OffAddr (A# a#) (I# i#) (W64# w#) = IO $ \ s# ->
1266 case (writeWordOffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
1268 writeWord64OffAddr (A# a#) (I# i#) (W64# w#) = IO $ \ s# ->
1269 case (writeWord64OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
1272 #ifndef __PARALLEL_HASKELL__
1274 writeWord8OffForeignObj :: ForeignObj -> Int -> Word8 -> IO ()
1275 writeWord8OffForeignObj fo i w = _casm_ `` (((StgNat16*)%0)[(StgInt)%1])=(StgNat16)%2; '' fo i w
1277 writeWord16OffForeignObj :: ForeignObj -> Int -> Word16 -> IO ()
1278 writeWord16OffForeignObj fo i w = _casm_ `` (((StgNat16*)%0)[(StgInt)%1])=(StgNat16)%2; '' fo i w
1280 writeWord32OffForeignObj :: ForeignObj -> Int -> Word32 -> IO ()
1281 writeWord32OffForeignObj fo i w = _casm_ `` (((StgNat16*)%0)[(StgInt)%1])=(StgNat16)%2; '' fo i' w
1283 -- adjust index to be in Word units, not Word32 ones.
1285 #if WORD_SIZE_IN_BYTES==8
1291 writeWord64OffForeignObj :: ForeignObj -> Int -> Word64 -> IO ()
1292 # if WORD_SIZE_IN_BYTES==8
1293 writeWord64OffForeignObj fo i e = _casm_ `` (((StgWord*)%0)[(StgInt)%1])=(StgWord)%2; '' fo i e
1295 writeWord64OffForeignObj fo i e = _casm_ `` (((StgNat64*)%0)[(StgInt)%1])=(StgNat64)%2; '' fo i e
1305 {-# NOINLINE indexError #-}
1306 indexError :: Show a => a -> (a,a) -> String -> b
1308 = error (showString "Ix{" . showString tp . showString "}.index: Index " .
1309 showParen True (showsPrec 0 i) .
1310 showString " out of range " $
1311 showParen True (showsPrec 0 rng) "")