+
+word64ToInteger :: Word64 -> Integer
+word64ToInteger (W64# w#) =
+ case word64ToInteger# w# of
+ (# a#, s#, p# #) -> J# a# s# p#
+
+word64ToInt :: Word64 -> Int
+word64ToInt w =
+ case w `quotRem` 0x100000000 of
+ (_,l) -> toInt (word64ToWord32 l)
+
+intToWord64# :: Int# -> Word64#
+intToWord64# i# = wordToWord64# (int2Word# i#)
+
+intToWord64 :: Int -> Word64
+intToWord64 (I# i#) = W64# (intToWord64# i#)
+
+integerToWord64 :: Integer -> Word64
+integerToWord64 (J# a# s# d#) = W64# (integerToWord64# a# s# d#)
+
+instance Eq Word64 where
+ (W64# x) == (W64# y) = x `eqWord64#` y
+ (W64# x) /= (W64# y) = not (x `eqWord64#` y)
+
+instance Ord Word64 where
+ compare (W64# x#) (W64# y#) = compareWord64# x# y#
+ (<) (W64# x) (W64# y) = x `ltWord64#` y
+ (<=) (W64# x) (W64# y) = x `leWord64#` y
+ (>=) (W64# x) (W64# y) = x `geWord64#` y
+ (>) (W64# x) (W64# y) = x `gtWord64#` y
+ max x@(W64# x#) y@(W64# y#) =
+ case (compareWord64# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
+ min x@(W64# x#) y@(W64# y#) =
+ case (compareWord64# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
+
+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 w
+ | w == 0 = w
+ | otherwise = maxBound - w
+
+ abs x = x
+ signum = signumReal
+ fromInteger i = integerToWord64 i
+ fromInt = intToWord64
+
+-- Note: no need to mask results here
+-- as they cannot overflow.
+-- ToDo: protect against div by zero.
+instance Integral Word64 where
+ div (W64# x) (W64# y) = W64# (x `quotWord64#` y)
+ quot (W64# x) (W64# y) = W64# (x `quotWord64#` y)
+ rem (W64# x) (W64# y) = W64# (x `remWord64#` y)
+ mod (W64# x) (W64# y) = W64# (x `remWord64#` y)
+ quotRem (W64# x) (W64# y) = (W64# (x `quotWord64#` y), W64# (x `remWord64#` y))
+ divMod (W64# x) (W64# y) = (W64# (x `quotWord64#` y), W64# (x `remWord64#` y))
+ toInteger w64 = word64ToInteger w64
+ toInt x = word64ToInt x
+
+
+instance Bits Word64 where
+ (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# (x `xor64#` (case (maxBound::Word64) of W64# x# -> x#))
+ shift (W64# x#) i@(I# i#)
+ | i > 0 = W64# (shiftL64# x# i#)
+ | otherwise = W64# (shiftRL64# x# (negateInt# i#))
+
+ w@(W64# x) `rotate` (I# i)
+ | i ==# 0# = w
+ | i ># 0# = W64# ((shiftL64# x i') `or64#`
+ (shiftRL64# (x `and64#`
+ (int64ToWord64# ((word64ToInt64# maxBound#) `minusInt64#`
+ (pow2_64# i2 `plusInt64#` (intToInt64# 1#))))))
+ i2)
+ | otherwise = rotate w (I# (64# +# i))
+ where
+ i' = word2Int# (int2Word# i `and#` int2Word# 63#)
+ i2 = 64# -# i'
+ (W64# maxBound#) = maxBound
+
+ bit (I# i#)
+ | i# >=# 0# && i# <=# 63# = W64# (shiftL64# (wordToWord64# (int2Word# 1#)) i#)
+ | otherwise = 0 -- We'll be overbearing, for now..
+
+ setBit x i = x .|. bit i
+ clearBit x i = x .&. complement (bit i)
+ complementBit x i = x `xor` bit i
+
+ testBit (W64# x#) (I# i#)
+ | i# <# 64# && i# >=# 0# = (word2Int# (word64ToWord# (x# `and64#` (shiftL64# (wordToWord64# (int2Word# 1#)) i#)))) /=# 0#
+ | otherwise = False -- for now, this is really an error.
+
+ bitSize _ = 64
+ isSigned _ = False
+
+compareWord64# :: Word64# -> Word64# -> Ordering
+compareWord64# i# j#
+ | i# `ltWord64#` j# = LT
+ | i# `eqWord64#` j# = EQ
+ | otherwise = GT
+
+-- Word64# primop wrappers:
+
+ltWord64# :: Word64# -> Word64# -> Bool
+ltWord64# x# y# = unsafePerformIO $ do
+ v <- _ccall_ stg_ltWord64 x# y#
+ case (v::Int) of
+ 0 -> return False
+ _ -> return True
+
+leWord64# :: Word64# -> Word64# -> Bool
+leWord64# x# y# = unsafePerformIO $ do
+ v <- _ccall_ stg_leWord64 x# y#
+ case (v::Int) of
+ 0 -> return False
+ _ -> return True
+
+eqWord64# :: Word64# -> Word64# -> Bool
+eqWord64# x# y# = unsafePerformIO $ do
+ v <- _ccall_ stg_eqWord64 x# y#
+ case (v::Int) of
+ 0 -> return False
+ _ -> return True
+
+neWord64# :: Word64# -> Word64# -> Bool
+neWord64# x# y# = unsafePerformIO $ do
+ v <- _ccall_ stg_neWord64 x# y#
+ case (v::Int) of
+ 0 -> return False
+ _ -> return True
+
+geWord64# :: Word64# -> Word64# -> Bool
+geWord64# x# y# = unsafePerformIO $ do
+ v <- _ccall_ stg_geWord64 x# y#
+ case (v::Int) of
+ 0 -> return False
+ _ -> return True
+
+gtWord64# :: Word64# -> Word64# -> Bool
+gtWord64# x# y# = unsafePerformIO $ do
+ v <- _ccall_ stg_gtWord64 x# y#
+ case (v::Int) of
+ 0 -> return False
+ _ -> return True
+
+plusInt64# :: Int64# -> Int64# -> Int64#
+plusInt64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_plusInt64 a# b#)) of
+ I64# i# -> i#
+
+minusInt64# :: Int64# -> Int64# -> Int64#
+minusInt64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_minusInt64 a# b#)) of
+ I64# i# -> i#
+
+timesInt64# :: Int64# -> Int64# -> Int64#
+timesInt64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_timesInt64 a# b#)) of
+ I64# i# -> i#
+
+quotWord64# :: Word64# -> Word64# -> Word64#
+quotWord64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_quotWord64 a# b#)) of
+ W64# w# -> w#
+
+remWord64# :: Word64# -> Word64# -> Word64#
+remWord64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_remWord64 a# b#)) of
+ W64# w# -> w#
+
+negateInt64# :: Int64# -> Int64#
+negateInt64# a# =
+ case (unsafePerformIO (_ccall_ stg_negateInt64 a#)) of
+ I64# i# -> i#
+
+and64# :: Word64# -> Word64# -> Word64#
+and64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_and64 a# b#)) of
+ W64# w# -> w#
+
+or64# :: Word64# -> Word64# -> Word64#
+or64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_or64 a# b#)) of
+ W64# w# -> w#
+
+xor64# :: Word64# -> Word64# -> Word64#
+xor64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_xor64 a# b#)) of
+ W64# w# -> w#
+
+not64# :: Word64# -> Word64#
+not64# a# =
+ case (unsafePerformIO (_ccall_ stg_not64 a#)) of
+ W64# w# -> w#
+
+shiftL64# :: Word64# -> Int# -> Word64#
+shiftL64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_shiftL64 a# b#)) of
+ W64# w# -> w#
+
+shiftRL64# :: Word64# -> Int# -> Word64#
+shiftRL64# a# b# =
+ case (unsafePerformIO (_ccall_ stg_shiftRL64 a# b#)) of
+ W64# w# -> w#
+
+word64ToWord# :: Word64# -> Word#
+word64ToWord# w64# =
+ case (unsafePerformIO (_ccall_ stg_word64ToWord w64#)) of
+ W# w# -> w#
+
+wordToWord64# :: Word# -> Word64#
+wordToWord64# w# =
+ case (unsafePerformIO (_ccall_ stg_wordToWord64 w#)) of
+ W64# w64# -> w64#
+
+word64ToInt64# :: Word64# -> Int64#
+word64ToInt64# w64# =
+ case (unsafePerformIO (_ccall_ stg_word64ToInt64 w64#)) of
+ I64# i# -> i#
+
+int64ToWord64# :: Int64# -> Word64#
+int64ToWord64# i64# =
+ case (unsafePerformIO (_ccall_ stg_int64ToWord64 i64#)) of
+ W64# w# -> w#
+
+intToInt64# :: Int# -> Int64#
+intToInt64# i# =
+ case (unsafePerformIO (_ccall_ stg_intToInt64 i#)) of
+ I64# i64# -> i64#
+
+#endif
+
+instance Enum Word64 where
+ succ w
+ | w == maxBound = succError "Word64"
+ | otherwise = w+1
+ pred w
+ | w == minBound = predError "Word64"
+ | otherwise = w-1
+
+ toEnum i
+ | i >= 0 = intToWord64 i
+ | otherwise
+ = toEnumError "Word64" i (minBound::Word64,maxBound::Word64)
+
+ fromEnum w
+ | w <= intToWord64 (maxBound::Int)
+ = word64ToInt w
+ | otherwise
+ = fromEnumError "Word64" w
+
+ enumFrom e1 = map integerToWord64 [word64ToInteger e1 .. word64ToInteger maxBound]
+ enumFromTo e1 e2 = map integerToWord64 [word64ToInteger e1 .. word64ToInteger e2]
+ enumFromThen e1 e2 = map integerToWord64 [word64ToInteger e1, word64ToInteger e2 .. word64ToInteger last]
+ where
+ last :: Word64
+ last
+ | e2 < e1 = minBound
+ | otherwise = maxBound
+
+ enumFromThenTo e1 e2 e3 = map integerToWord64 [word64ToInteger e1, word64ToInteger e2 .. word64ToInteger e3]