[project @ 2002-03-19 11:24:51 by simonmar]
[ghc-base.git] / GHC / Int.lhs
1 %
2 % (c) The University of Glasgow, 1997-2001
3 %
4 \section[GHC.Int]{Module @GHC.Int@}
5
6 \begin{code}
7 {-# OPTIONS -fno-implicit-prelude #-}
8
9 #include "MachDeps.h"
10
11 module GHC.Int (
12     Int8(..), Int16(..), Int32(..), Int64(..))
13     where
14
15 import Data.Bits
16
17 import GHC.Base
18 import GHC.Enum
19 import GHC.Num
20 import GHC.Real
21 import GHC.Read
22 import GHC.Arr
23 import GHC.Word
24 import GHC.Show
25
26 ------------------------------------------------------------------------
27 -- type Int8
28 ------------------------------------------------------------------------
29
30 -- Int8 is represented in the same way as Int. Operations may assume
31 -- and must ensure that it holds only values from its logical range.
32
33 data Int8 = I8# Int# deriving (Eq, Ord)
34
35 instance CCallable Int8
36 instance CReturnable Int8
37
38 instance Show Int8 where
39     showsPrec p x = showsPrec p (fromIntegral x :: Int)
40
41 instance Num Int8 where
42     (I8# x#) + (I8# y#)    = I8# (narrow8Int# (x# +# y#))
43     (I8# x#) - (I8# y#)    = I8# (narrow8Int# (x# -# y#))
44     (I8# x#) * (I8# y#)    = I8# (narrow8Int# (x# *# y#))
45     negate (I8# x#)        = I8# (narrow8Int# (negateInt# x#))
46     abs x | x >= 0         = x
47           | otherwise      = negate x
48     signum x | x > 0       = 1
49     signum 0               = 0
50     signum _               = -1
51     fromInteger (S# i#)    = I8# (narrow8Int# i#)
52     fromInteger (J# s# d#) = I8# (narrow8Int# (integer2Int# s# d#))
53
54 instance Real Int8 where
55     toRational x = toInteger x % 1
56
57 instance Enum Int8 where
58     succ x
59         | x /= maxBound = x + 1
60         | otherwise     = succError "Int8"
61     pred x
62         | x /= minBound = x - 1
63         | otherwise     = predError "Int8"
64     toEnum i@(I# i#)
65         | i >= fromIntegral (minBound::Int8) && i <= fromIntegral (maxBound::Int8)
66                         = I8# i#
67         | otherwise     = toEnumError "Int8" i (minBound::Int8, maxBound::Int8)
68     fromEnum (I8# x#)   = I# x#
69     enumFrom            = boundedEnumFrom
70     enumFromThen        = boundedEnumFromThen
71
72 instance Integral Int8 where
73     quot    x@(I8# x#) y@(I8# y#)
74         | y /= 0                  = I8# (narrow8Int# (x# `quotInt#` y#))
75         | otherwise               = divZeroError "quot{Int8}" x
76     rem     x@(I8# x#) y@(I8# y#)
77         | y /= 0                  = I8# (narrow8Int# (x# `remInt#` y#))
78         | otherwise               = divZeroError "rem{Int8}" x
79     div     x@(I8# x#) y@(I8# y#)
80         | y /= 0                  = I8# (narrow8Int# (x# `divInt#` y#))
81         | otherwise               = divZeroError "div{Int8}" x
82     mod     x@(I8# x#) y@(I8# y#)
83         | y /= 0                  = I8# (narrow8Int# (x# `modInt#` y#))
84         | otherwise               = divZeroError "mod{Int8}" x
85     quotRem x@(I8# x#) y@(I8# y#)
86         | y /= 0                  = (I8# (narrow8Int# (x# `quotInt#` y#)),
87                                     I8# (narrow8Int# (x# `remInt#` y#)))
88         | otherwise               = divZeroError "quotRem{Int8}" x
89     divMod  x@(I8# x#) y@(I8# y#)
90         | y /= 0                  = (I8# (narrow8Int# (x# `divInt#` y#)),
91                                     I8# (narrow8Int# (x# `modInt#` y#)))
92         | otherwise               = divZeroError "divMod{Int8}" x
93     toInteger (I8# x#)            = S# x#
94
95 instance Bounded Int8 where
96     minBound = -0x80
97     maxBound =  0x7F
98
99 instance Ix Int8 where
100     range (m,n)              = [m..n]
101     unsafeIndex b@(m,_) i    = fromIntegral (i - m)
102     inRange (m,n) i          = m <= i && i <= n
103     unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
104
105 instance Read Int8 where
106     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
107
108 instance Bits Int8 where
109     (I8# x#) .&.   (I8# y#)   = I8# (word2Int# (int2Word# x# `and#` int2Word# y#))
110     (I8# x#) .|.   (I8# y#)   = I8# (word2Int# (int2Word# x# `or#`  int2Word# y#))
111     (I8# x#) `xor` (I8# y#)   = I8# (word2Int# (int2Word# x# `xor#` int2Word# y#))
112     complement (I8# x#)       = I8# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
113     (I8# x#) `shift` (I# i#)
114         | i# >=# 0#           = I8# (narrow8Int# (x# `iShiftL#` i#))
115         | otherwise           = I8# (x# `iShiftRA#` negateInt# i#)
116     (I8# x#) `rotate` (I# i#)
117         | i'# ==# 0# 
118         = I8# x#
119         | otherwise
120         = I8# (narrow8Int# (word2Int# ((x'# `shiftL#` i'#) `or#`
121                                        (x'# `shiftRL#` (8# -# i'#)))))
122         where
123         x'# = narrow8Word# (int2Word# x#)
124         i'# = word2Int# (int2Word# i# `and#` int2Word# 7#)
125     bitSize  _                = 8
126     isSigned _                = True
127
128 {-# RULES
129 "fromIntegral/Int8->Int8" fromIntegral = id :: Int8 -> Int8
130 "fromIntegral/a->Int8"    fromIntegral = \x -> case fromIntegral x of I# x# -> I8# (narrow8Int# x#)
131 "fromIntegral/Int8->a"    fromIntegral = \(I8# x#) -> fromIntegral (I# x#)
132   #-}
133
134 ------------------------------------------------------------------------
135 -- type Int16
136 ------------------------------------------------------------------------
137
138 -- Int16 is represented in the same way as Int. Operations may assume
139 -- and must ensure that it holds only values from its logical range.
140
141 data Int16 = I16# Int# deriving (Eq, Ord)
142
143 instance CCallable Int16
144 instance CReturnable Int16
145
146 instance Show Int16 where
147     showsPrec p x = showsPrec p (fromIntegral x :: Int)
148
149 instance Num Int16 where
150     (I16# x#) + (I16# y#)  = I16# (narrow16Int# (x# +# y#))
151     (I16# x#) - (I16# y#)  = I16# (narrow16Int# (x# -# y#))
152     (I16# x#) * (I16# y#)  = I16# (narrow16Int# (x# *# y#))
153     negate (I16# x#)       = I16# (narrow16Int# (negateInt# x#))
154     abs x | x >= 0         = x
155           | otherwise      = negate x
156     signum x | x > 0       = 1
157     signum 0               = 0
158     signum _               = -1
159     fromInteger (S# i#)    = I16# (narrow16Int# i#)
160     fromInteger (J# s# d#) = I16# (narrow16Int# (integer2Int# s# d#))
161
162 instance Real Int16 where
163     toRational x = toInteger x % 1
164
165 instance Enum Int16 where
166     succ x
167         | x /= maxBound = x + 1
168         | otherwise     = succError "Int16"
169     pred x
170         | x /= minBound = x - 1
171         | otherwise     = predError "Int16"
172     toEnum i@(I# i#)
173         | i >= fromIntegral (minBound::Int16) && i <= fromIntegral (maxBound::Int16)
174                         = I16# i#
175         | otherwise     = toEnumError "Int16" i (minBound::Int16, maxBound::Int16)
176     fromEnum (I16# x#)  = I# x#
177     enumFrom            = boundedEnumFrom
178     enumFromThen        = boundedEnumFromThen
179
180 instance Integral Int16 where
181     quot    x@(I16# x#) y@(I16# y#)
182         | y /= 0                  = I16# (narrow16Int# (x# `quotInt#` y#))
183         | otherwise               = divZeroError "quot{Int16}" x
184     rem     x@(I16# x#) y@(I16# y#)
185         | y /= 0                  = I16# (narrow16Int# (x# `remInt#` y#))
186         | otherwise               = divZeroError "rem{Int16}" x
187     div     x@(I16# x#) y@(I16# y#)
188         | y /= 0                  = I16# (narrow16Int# (x# `divInt#` y#))
189         | otherwise               = divZeroError "div{Int16}" x
190     mod     x@(I16# x#) y@(I16# y#)
191         | y /= 0                  = I16# (narrow16Int# (x# `modInt#` y#))
192         | otherwise               = divZeroError "mod{Int16}" x
193     quotRem x@(I16# x#) y@(I16# y#)
194         | y /= 0                  = (I16# (narrow16Int# (x# `quotInt#` y#)),
195                                     I16# (narrow16Int# (x# `remInt#` y#)))
196         | otherwise               = divZeroError "quotRem{Int16}" x
197     divMod  x@(I16# x#) y@(I16# y#)
198         | y /= 0                  = (I16# (narrow16Int# (x# `divInt#` y#)),
199                                     I16# (narrow16Int# (x# `modInt#` y#)))
200         | otherwise               = divZeroError "divMod{Int16}" x
201     toInteger (I16# x#)           = S# x#
202
203 instance Bounded Int16 where
204     minBound = -0x8000
205     maxBound =  0x7FFF
206
207 instance Ix Int16 where
208     range (m,n)              = [m..n]
209     unsafeIndex b@(m,_) i    = fromIntegral (i - m)
210     inRange (m,n) i          = m <= i && i <= n
211     unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
212
213 instance Read Int16 where
214     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
215
216 instance Bits Int16 where
217     (I16# x#) .&.   (I16# y#)  = I16# (word2Int# (int2Word# x# `and#` int2Word# y#))
218     (I16# x#) .|.   (I16# y#)  = I16# (word2Int# (int2Word# x# `or#`  int2Word# y#))
219     (I16# x#) `xor` (I16# y#)  = I16# (word2Int# (int2Word# x# `xor#` int2Word# y#))
220     complement (I16# x#)       = I16# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
221     (I16# x#) `shift` (I# i#)
222         | i# >=# 0#            = I16# (narrow16Int# (x# `iShiftL#` i#))
223         | otherwise            = I16# (x# `iShiftRA#` negateInt# i#)
224     (I16# x#) `rotate` (I# i#)
225         | i'# ==# 0# 
226         = I16# x#
227         | otherwise
228         = I16# (narrow16Int# (word2Int# ((x'# `shiftL#` i'#) `or#`
229                                          (x'# `shiftRL#` (16# -# i'#)))))
230         where
231         x'# = narrow16Word# (int2Word# x#)
232         i'# = word2Int# (int2Word# i# `and#` int2Word# 15#)
233     bitSize  _                 = 16
234     isSigned _                 = True
235
236 {-# RULES
237 "fromIntegral/Word8->Int16"  fromIntegral = \(W8# x#) -> I16# (word2Int# x#)
238 "fromIntegral/Int8->Int16"   fromIntegral = \(I8# x#) -> I16# x#
239 "fromIntegral/Int16->Int16"  fromIntegral = id :: Int16 -> Int16
240 "fromIntegral/a->Int16"      fromIntegral = \x -> case fromIntegral x of I# x# -> I16# (narrow16Int# x#)
241 "fromIntegral/Int16->a"      fromIntegral = \(I16# x#) -> fromIntegral (I# x#)
242   #-}
243
244 ------------------------------------------------------------------------
245 -- type Int32
246 ------------------------------------------------------------------------
247
248 #if WORD_SIZE_IN_BITS < 32
249
250 data Int32 = I32# Int32#
251
252 instance Eq Int32 where
253     (I32# x#) == (I32# y#) = x# `eqInt32#` y#
254     (I32# x#) /= (I32# y#) = x# `neInt32#` y#
255
256 instance Ord Int32 where
257     (I32# x#) <  (I32# y#) = x# `ltInt32#` y#
258     (I32# x#) <= (I32# y#) = x# `leInt32#` y#
259     (I32# x#) >  (I32# y#) = x# `gtInt32#` y#
260     (I32# x#) >= (I32# y#) = x# `geInt32#` y#
261
262 instance Show Int32 where
263     showsPrec p x = showsPrec p (toInteger x)
264
265 instance Num Int32 where
266     (I32# x#) + (I32# y#)  = I32# (x# `plusInt32#`  y#)
267     (I32# x#) - (I32# y#)  = I32# (x# `minusInt32#` y#)
268     (I32# x#) * (I32# y#)  = I32# (x# `timesInt32#` y#)
269     negate (I32# x#)       = I32# (negateInt32# x#)
270     abs x | x >= 0         = x
271           | otherwise      = negate x
272     signum x | x > 0       = 1
273     signum 0               = 0
274     signum _               = -1
275     fromInteger (S# i#)    = I32# (intToInt32# i#)
276     fromInteger (J# s# d#) = I32# (integerToInt32# s# d#)
277
278 instance Enum Int32 where
279     succ x
280         | x /= maxBound = x + 1
281         | otherwise     = succError "Int32"
282     pred x
283         | x /= minBound = x - 1
284         | otherwise     = predError "Int32"
285     toEnum (I# i#)      = I32# (intToInt32# i#)
286     fromEnum x@(I32# x#)
287         | x >= fromIntegral (minBound::Int) && x <= fromIntegral (maxBound::Int)
288                         = I# (int32ToInt# x#)
289         | otherwise     = fromEnumError "Int32" x
290     enumFrom            = integralEnumFrom
291     enumFromThen        = integralEnumFromThen
292     enumFromTo          = integralEnumFromTo
293     enumFromThenTo      = integralEnumFromThenTo
294
295 instance Integral Int32 where
296     quot    x@(I32# x#) y@(I32# y#)
297         | y /= 0                  = I32# (x# `quotInt32#` y#)
298         | otherwise               = divZeroError "quot{Int32}" x
299     rem     x@(I32# x#) y@(I32# y#)
300         | y /= 0                  = I32# (x# `remInt32#` y#)
301         | otherwise               = divZeroError "rem{Int32}" x
302     div     x@(I32# x#) y@(I32# y#)
303         | y /= 0                  = I32# (x# `divInt32#` y#)
304         | otherwise               = divZeroError "div{Int32}" x
305     mod     x@(I32# x#) y@(I32# y#)
306         | y /= 0                  = I32# (x# `modInt32#` y#)
307         | otherwise               = divZeroError "mod{Int32}" x
308     quotRem x@(I32# x#) y@(I32# y#)
309         | y /= 0                  = (I32# (x# `quotInt32#` y#), I32# (x# `remInt32#` y#))
310         | otherwise               = divZeroError "quotRem{Int32}" x
311     divMod  x@(I32# x#) y@(I32# y#)
312         | y /= 0                  = (I32# (x# `divInt32#` y#), I32# (x# `modInt32#` y#))
313         | otherwise               = divZeroError "divMod{Int32}" x
314     toInteger x@(I32# x#)
315         | x >= fromIntegral (minBound::Int) && x <= fromIntegral (maxBound::Int)
316                                   = S# (int32ToInt# x#)
317         | otherwise               = case int32ToInteger# x# of (# s, d #) -> J# s d
318
319 divInt32#, modInt32# :: Int32# -> Int32# -> Int32#
320 x# `divInt32#` y#
321     | (x# `gtInt32#` intToInt32# 0#) && (y# `ltInt32#` intToInt32# 0#)
322         = ((x# `minusInt32#` y#) `minusInt32#` intToInt32# 1#) `quotInt32#` y#
323     | (x# `ltInt32#` intToInt32# 0#) && (y# `gtInt32#` intToInt32# 0#)
324         = ((x# `minusInt32#` y#) `plusInt32#` intToInt32# 1#) `quotInt32#` y#
325     | otherwise                = x# `quotInt32#` y#
326 x# `modInt32#` y#
327     | (x# `gtInt32#` intToInt32# 0#) && (y# `ltInt32#` intToInt32# 0#) ||
328       (x# `ltInt32#` intToInt32# 0#) && (y# `gtInt32#` intToInt32# 0#)
329         = if r# `neInt32#` intToInt32# 0# then r# `plusInt32#` y# else intToInt32# 0#
330     | otherwise = r#
331     where
332     r# = x# `remInt32#` y#
333
334 instance Read Int32 where
335     readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
336
337 instance Bits Int32 where
338     (I32# x#) .&.   (I32# y#)  = I32# (word32ToInt32# (int32ToWord32# x# `and32#` int32ToWord32# y#))
339     (I32# x#) .|.   (I32# y#)  = I32# (word32ToInt32# (int32ToWord32# x# `or32#`  int32ToWord32# y#))
340     (I32# x#) `xor` (I32# y#)  = I32# (word32ToInt32# (int32ToWord32# x# `xor32#` int32ToWord32# y#))
341     complement (I32# x#)       = I32# (word32ToInt32# (not32# (int32ToWord32# x#)))
342     (I32# x#) `shift` (I# i#)
343         | i# >=# 0#            = I32# (x# `iShiftL32#` i#)
344         | otherwise            = I32# (x# `iShiftRA32#` negateInt# i#)
345     (I32# x#) `rotate` (I# i#)
346         | i'# ==# 0# 
347         = I32# x#
348         | otherwise
349         = I32# (word32ToInt32# ((x'# `shiftL32#` i'#) `or32#`
350                                 (x'# `shiftRL32#` (32# -# i'#))))
351         where
352         x'# = int32ToWord32# x#
353         i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
354     bitSize  _                 = 32
355     isSigned _                 = True
356
357 foreign import "stg_eqInt32"       unsafe eqInt32#       :: Int32# -> Int32# -> Bool
358 foreign import "stg_neInt32"       unsafe neInt32#       :: Int32# -> Int32# -> Bool
359 foreign import "stg_ltInt32"       unsafe ltInt32#       :: Int32# -> Int32# -> Bool
360 foreign import "stg_leInt32"       unsafe leInt32#       :: Int32# -> Int32# -> Bool
361 foreign import "stg_gtInt32"       unsafe gtInt32#       :: Int32# -> Int32# -> Bool
362 foreign import "stg_geInt32"       unsafe geInt32#       :: Int32# -> Int32# -> Bool
363 foreign import "stg_plusInt32"     unsafe plusInt32#     :: Int32# -> Int32# -> Int32#
364 foreign import "stg_minusInt32"    unsafe minusInt32#    :: Int32# -> Int32# -> Int32#
365 foreign import "stg_timesInt32"    unsafe timesInt32#    :: Int32# -> Int32# -> Int32#
366 foreign import "stg_negateInt32"   unsafe negateInt32#   :: Int32# -> Int32#
367 foreign import "stg_quotInt32"     unsafe quotInt32#     :: Int32# -> Int32# -> Int32#
368 foreign import "stg_remInt32"      unsafe remInt32#      :: Int32# -> Int32# -> Int32#
369 foreign import "stg_intToInt32"    unsafe intToInt32#    :: Int# -> Int32#
370 foreign import "stg_int32ToInt"    unsafe int32ToInt#    :: Int32# -> Int#
371 foreign import "stg_wordToWord32"  unsafe wordToWord32#  :: Word# -> Word32#
372 foreign import "stg_int32ToWord32" unsafe int32ToWord32# :: Int32# -> Word32#
373 foreign import "stg_word32ToInt32" unsafe word32ToInt32# :: Word32# -> Int32#
374 foreign import "stg_and32"         unsafe and32#         :: Word32# -> Word32# -> Word32#
375 foreign import "stg_or32"          unsafe or32#          :: Word32# -> Word32# -> Word32#
376 foreign import "stg_xor32"         unsafe xor32#         :: Word32# -> Word32# -> Word32#
377 foreign import "stg_not32"         unsafe not32#         :: Word32# -> Word32#
378 foreign import "stg_iShiftL32"     unsafe iShiftL32#     :: Int32# -> Int# -> Int32#
379 foreign import "stg_iShiftRA32"    unsafe iShiftRA32#    :: Int32# -> Int# -> Int32#
380 foreign import "stg_shiftL32"      unsafe shiftL32#      :: Word32# -> Int# -> Word32#
381 foreign import "stg_shiftRL32"     unsafe shiftRL32#     :: Word32# -> Int# -> Word32#
382
383 {-# RULES
384 "fromIntegral/Int->Int32"    fromIntegral = \(I#   x#) -> I32# (intToInt32# x#)
385 "fromIntegral/Word->Int32"   fromIntegral = \(W#   x#) -> I32# (word32ToInt32# (wordToWord32# x#))
386 "fromIntegral/Word32->Int32" fromIntegral = \(W32# x#) -> I32# (word32ToInt32# x#)
387 "fromIntegral/Int32->Int"    fromIntegral = \(I32# x#) -> I#   (int32ToInt# x#)
388 "fromIntegral/Int32->Word"   fromIntegral = \(I32# x#) -> W#   (int2Word# (int32ToInt# x#))
389 "fromIntegral/Int32->Word32" fromIntegral = \(I32# x#) -> W32# (int32ToWord32# x#)
390 "fromIntegral/Int32->Int32"  fromIntegral = id :: Int32 -> Int32
391   #-}
392
393 #else 
394
395 -- Int32 is represented in the same way as Int.
396 #if WORD_SIZE_IN_BITS > 32
397 -- Operations may assume and must ensure that it holds only values
398 -- from its logical range.
399 #endif
400
401 data Int32 = I32# Int# deriving (Eq, Ord)
402
403 instance Show Int32 where
404     showsPrec p x = showsPrec p (fromIntegral x :: Int)
405
406 instance Num Int32 where
407     (I32# x#) + (I32# y#)  = I32# (narrow32Int# (x# +# y#))
408     (I32# x#) - (I32# y#)  = I32# (narrow32Int# (x# -# y#))
409     (I32# x#) * (I32# y#)  = I32# (narrow32Int# (x# *# y#))
410     negate (I32# x#)       = I32# (narrow32Int# (negateInt# x#))
411     abs x | x >= 0         = x
412           | otherwise      = negate x
413     signum x | x > 0       = 1
414     signum 0               = 0
415     signum _               = -1
416     fromInteger (S# i#)    = I32# (narrow32Int# i#)
417     fromInteger (J# s# d#) = I32# (narrow32Int# (integer2Int# s# d#))
418
419 instance Enum Int32 where
420     succ x
421         | x /= maxBound = x + 1
422         | otherwise     = succError "Int32"
423     pred x
424         | x /= minBound = x - 1
425         | otherwise     = predError "Int32"
426 #if WORD_SIZE_IN_BITS == 32
427     toEnum (I# i#)      = I32# i#
428 #else
429     toEnum i@(I# i#)
430         | i >= fromIntegral (minBound::Int32) && i <= fromIntegral (maxBound::Int32)
431                         = I32# i#
432         | otherwise     = toEnumError "Int32" i (minBound::Int32, maxBound::Int32)
433 #endif
434     fromEnum (I32# x#)  = I# x#
435     enumFrom            = boundedEnumFrom
436     enumFromThen        = boundedEnumFromThen
437
438 instance Integral Int32 where
439     quot    x@(I32# x#) y@(I32# y#)
440         | y /= 0                  = I32# (narrow32Int# (x# `quotInt#` y#))
441         | otherwise               = divZeroError "quot{Int32}" x
442     rem     x@(I32# x#) y@(I32# y#)
443         | y /= 0                  = I32# (narrow32Int# (x# `remInt#` y#))
444         | otherwise               = divZeroError "rem{Int32}" x
445     div     x@(I32# x#) y@(I32# y#)
446         | y /= 0                  = I32# (narrow32Int# (x# `divInt#` y#))
447         | otherwise               = divZeroError "div{Int32}" x
448     mod     x@(I32# x#) y@(I32# y#)
449         | y /= 0                  = I32# (narrow32Int# (x# `modInt#` y#))
450         | otherwise               = divZeroError "mod{Int32}" x
451     quotRem x@(I32# x#) y@(I32# y#)
452         | y /= 0                  = (I32# (narrow32Int# (x# `quotInt#` y#)),
453                                     I32# (narrow32Int# (x# `remInt#` y#)))
454         | otherwise               = divZeroError "quotRem{Int32}" x
455     divMod  x@(I32# x#) y@(I32# y#)
456         | y /= 0                  = (I32# (narrow32Int# (x# `divInt#` y#)),
457                                     I32# (narrow32Int# (x# `modInt#` y#)))
458         | otherwise               = divZeroError "divMod{Int32}" x
459     toInteger (I32# x#)           = S# x#
460
461 instance Read Int32 where
462     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
463
464 instance Bits Int32 where
465     (I32# x#) .&.   (I32# y#)  = I32# (word2Int# (int2Word# x# `and#` int2Word# y#))
466     (I32# x#) .|.   (I32# y#)  = I32# (word2Int# (int2Word# x# `or#`  int2Word# y#))
467     (I32# x#) `xor` (I32# y#)  = I32# (word2Int# (int2Word# x# `xor#` int2Word# y#))
468     complement (I32# x#)       = I32# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
469     (I32# x#) `shift` (I# i#)
470         | i# >=# 0#            = I32# (narrow32Int# (x# `iShiftL#` i#))
471         | otherwise            = I32# (x# `iShiftRA#` negateInt# i#)
472     (I32# x#) `rotate` (I# i#)
473         | i'# ==# 0# 
474         = I32# x#
475         | otherwise
476         = I32# (narrow32Int# (word2Int# ((x'# `shiftL#` i'#) `or#`
477                                         (x'# `shiftRL#` (32# -# i'#)))))
478         where
479         x'# = narrow32Word# (int2Word# x#)
480         i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
481     bitSize  _                 = 32
482     isSigned _                 = True
483
484 {-# RULES
485 "fromIntegral/Word8->Int32"  fromIntegral = \(W8# x#) -> I32# (word2Int# x#)
486 "fromIntegral/Word16->Int32" fromIntegral = \(W16# x#) -> I32# (word2Int# x#)
487 "fromIntegral/Int8->Int32"   fromIntegral = \(I8# x#) -> I32# x#
488 "fromIntegral/Int16->Int32"  fromIntegral = \(I16# x#) -> I32# x#
489 "fromIntegral/Int32->Int32"  fromIntegral = id :: Int32 -> Int32
490 "fromIntegral/a->Int32"      fromIntegral = \x -> case fromIntegral x of I# x# -> I32# (narrow32Int# x#)
491 "fromIntegral/Int32->a"      fromIntegral = \(I32# x#) -> fromIntegral (I# x#)
492   #-}
493
494 #endif 
495
496 instance CCallable Int32
497 instance CReturnable Int32
498
499 instance Real Int32 where
500     toRational x = toInteger x % 1
501
502 instance Bounded Int32 where
503     minBound = -0x80000000
504     maxBound =  0x7FFFFFFF
505
506 instance Ix Int32 where
507     range (m,n)              = [m..n]
508     unsafeIndex b@(m,_) i    = fromIntegral (i - m)
509     inRange (m,n) i          = m <= i && i <= n
510     unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
511
512 ------------------------------------------------------------------------
513 -- type Int64
514 ------------------------------------------------------------------------
515
516 #if WORD_SIZE_IN_BITS < 64
517
518 data Int64 = I64# Int64#
519
520 instance Eq Int64 where
521     (I64# x#) == (I64# y#) = x# `eqInt64#` y#
522     (I64# x#) /= (I64# y#) = x# `neInt64#` y#
523
524 instance Ord Int64 where
525     (I64# x#) <  (I64# y#) = x# `ltInt64#` y#
526     (I64# x#) <= (I64# y#) = x# `leInt64#` y#
527     (I64# x#) >  (I64# y#) = x# `gtInt64#` y#
528     (I64# x#) >= (I64# y#) = x# `geInt64#` y#
529
530 instance Show Int64 where
531     showsPrec p x = showsPrec p (toInteger x)
532
533 instance Num Int64 where
534     (I64# x#) + (I64# y#)  = I64# (x# `plusInt64#`  y#)
535     (I64# x#) - (I64# y#)  = I64# (x# `minusInt64#` y#)
536     (I64# x#) * (I64# y#)  = I64# (x# `timesInt64#` y#)
537     negate (I64# x#)       = I64# (negateInt64# x#)
538     abs x | x >= 0         = x
539           | otherwise      = negate x
540     signum x | x > 0       = 1
541     signum 0               = 0
542     signum _               = -1
543     fromInteger (S# i#)    = I64# (intToInt64# i#)
544     fromInteger (J# s# d#) = I64# (integerToInt64# s# d#)
545
546 instance Enum Int64 where
547     succ x
548         | x /= maxBound = x + 1
549         | otherwise     = succError "Int64"
550     pred x
551         | x /= minBound = x - 1
552         | otherwise     = predError "Int64"
553     toEnum (I# i#)      = I64# (intToInt64# i#)
554     fromEnum x@(I64# x#)
555         | x >= fromIntegral (minBound::Int) && x <= fromIntegral (maxBound::Int)
556                         = I# (int64ToInt# x#)
557         | otherwise     = fromEnumError "Int64" x
558     enumFrom            = integralEnumFrom
559     enumFromThen        = integralEnumFromThen
560     enumFromTo          = integralEnumFromTo
561     enumFromThenTo      = integralEnumFromThenTo
562
563 instance Integral Int64 where
564     quot    x@(I64# x#) y@(I64# y#)
565         | y /= 0                  = I64# (x# `quotInt64#` y#)
566         | otherwise               = divZeroError "quot{Int64}" x
567     rem     x@(I64# x#) y@(I64# y#)
568         | y /= 0                  = I64# (x# `remInt64#` y#)
569         | otherwise               = divZeroError "rem{Int64}" x
570     div     x@(I64# x#) y@(I64# y#)
571         | y /= 0                  = I64# (x# `divInt64#` y#)
572         | otherwise               = divZeroError "div{Int64}" x
573     mod     x@(I64# x#) y@(I64# y#)
574         | y /= 0                  = I64# (x# `modInt64#` y#)
575         | otherwise               = divZeroError "mod{Int64}" x
576     quotRem x@(I64# x#) y@(I64# y#)
577         | y /= 0                  = (I64# (x# `quotInt64#` y#), I64# (x# `remInt64#` y#))
578         | otherwise               = divZeroError "quotRem{Int64}" x
579     divMod  x@(I64# x#) y@(I64# y#)
580         | y /= 0                  = (I64# (x# `divInt64#` y#), I64# (x# `modInt64#` y#))
581         | otherwise               = divZeroError "divMod{Int64}" x
582     toInteger x@(I64# x#)
583         | x >= fromIntegral (minBound::Int) && x <= fromIntegral (maxBound::Int)
584                                   = S# (int64ToInt# x#)
585         | otherwise               = case int64ToInteger# x# of (# s, d #) -> J# s d
586
587
588 divInt64#, modInt64# :: Int64# -> Int64# -> Int64#
589 x# `divInt64#` y#
590     | (x# `gtInt64#` intToInt64# 0#) && (y# `ltInt64#` intToInt64# 0#)
591         = ((x# `minusInt64#` y#) `minusInt64#` intToInt64# 1#) `quotInt64#` y#
592     | (x# `ltInt64#` intToInt64# 0#) && (y# `gtInt64#` intToInt64# 0#)
593         = ((x# `minusInt64#` y#) `plusInt64#` intToInt64# 1#) `quotInt64#` y#
594     | otherwise                = x# `quotInt64#` y#
595 x# `modInt64#` y#
596     | (x# `gtInt64#` intToInt64# 0#) && (y# `ltInt64#` intToInt64# 0#) ||
597       (x# `ltInt64#` intToInt64# 0#) && (y# `gtInt64#` intToInt64# 0#)
598         = if r# `neInt64#` intToInt64# 0# then r# `plusInt64#` y# else intToInt64# 0#
599     | otherwise = r#
600     where
601     r# = x# `remInt64#` y#
602
603 instance Read Int64 where
604     readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
605
606 instance Bits Int64 where
607     (I64# x#) .&.   (I64# y#)  = I64# (word64ToInt64# (int64ToWord64# x# `and64#` int64ToWord64# y#))
608     (I64# x#) .|.   (I64# y#)  = I64# (word64ToInt64# (int64ToWord64# x# `or64#`  int64ToWord64# y#))
609     (I64# x#) `xor` (I64# y#)  = I64# (word64ToInt64# (int64ToWord64# x# `xor64#` int64ToWord64# y#))
610     complement (I64# x#)       = I64# (word64ToInt64# (not64# (int64ToWord64# x#)))
611     (I64# x#) `shift` (I# i#)
612         | i# >=# 0#            = I64# (x# `iShiftL64#` i#)
613         | otherwise            = I64# (x# `iShiftRA64#` negateInt# i#)
614     (I64# x#) `rotate` (I# i#)
615         | i'# ==# 0# 
616         = I64# x#
617         | otherwise
618         = I64# (word64ToInt64# ((x'# `uncheckedShiftL64#` i'#) `or64#`
619                                 (x'# `uncheckedShiftRL64#` (64# -# i'#))))
620         where
621         x'# = int64ToWord64# x#
622         i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
623     bitSize  _                 = 64
624     isSigned _                 = True
625
626
627 -- give the 64-bit shift operations the same treatment as the 32-bit
628 -- ones (see GHC.Base), namely we wrap them in tests to catch the
629 -- cases when we're shifting more than 64 bits to avoid unspecified
630 -- behaviour in the C shift operations.
631
632 iShiftL64#, iShiftRA64# :: Int64# -> Int# -> Int64#
633
634 a `iShiftL64#` b  | b >=# 64# = intToInt64# 0#
635                   | otherwise = a `uncheckedIShiftL64#` b
636
637 a `iShiftRA64#` b | b >=# 64# = if a `ltInt64#` (intToInt64# 0#) 
638                                         then intToInt64# (-1#) 
639                                         else intToInt64# 0#
640                   | otherwise = a `uncheckedIShiftRA64#` b
641
642
643 foreign import ccall unsafe "stg_eqInt64"       eqInt64#       :: Int64# -> Int64# -> Bool
644 foreign import ccall unsafe "stg_neInt64"       neInt64#       :: Int64# -> Int64# -> Bool
645 foreign import ccall unsafe "stg_ltInt64"       ltInt64#       :: Int64# -> Int64# -> Bool
646 foreign import ccall unsafe "stg_leInt64"       leInt64#       :: Int64# -> Int64# -> Bool
647 foreign import ccall unsafe "stg_gtInt64"       gtInt64#       :: Int64# -> Int64# -> Bool
648 foreign import ccall unsafe "stg_geInt64"       geInt64#       :: Int64# -> Int64# -> Bool
649 foreign import ccall unsafe "stg_plusInt64"     plusInt64#     :: Int64# -> Int64# -> Int64#
650 foreign import ccall unsafe "stg_minusInt64"    minusInt64#    :: Int64# -> Int64# -> Int64#
651 foreign import ccall unsafe "stg_timesInt64"    timesInt64#    :: Int64# -> Int64# -> Int64#
652 foreign import ccall unsafe "stg_negateInt64"   negateInt64#   :: Int64# -> Int64#
653 foreign import ccall unsafe "stg_quotInt64"     quotInt64#     :: Int64# -> Int64# -> Int64#
654 foreign import ccall unsafe "stg_remInt64"      remInt64#      :: Int64# -> Int64# -> Int64#
655 foreign import ccall unsafe "stg_intToInt64"    intToInt64#    :: Int# -> Int64#
656 foreign import ccall unsafe "stg_int64ToInt"    int64ToInt#    :: Int64# -> Int#
657 foreign import ccall unsafe "stg_wordToWord64"  wordToWord64#  :: Word# -> Word64#
658 foreign import ccall unsafe "stg_int64ToWord64" int64ToWord64# :: Int64# -> Word64#
659 foreign import ccall unsafe "stg_word64ToInt64" word64ToInt64# :: Word64# -> Int64#
660 foreign import ccall unsafe "stg_and64"         and64#         :: Word64# -> Word64# -> Word64#
661 foreign import ccall unsafe "stg_or64"          or64#          :: Word64# -> Word64# -> Word64#
662 foreign import ccall unsafe "stg_xor64"         xor64#         :: Word64# -> Word64# -> Word64#
663 foreign import ccall unsafe "stg_not64"         not64#         :: Word64# -> Word64#
664 foreign import ccall unsafe "stg_uncheckedShiftL64"      uncheckedShiftL64#      :: Word64# -> Int# -> Word64#
665 foreign import ccall unsafe "stg_uncheckedShiftRL64"     uncheckedShiftRL64#     :: Word64# -> Int# -> Word64#
666 foreign import ccall unsafe "stg_uncheckedIShiftL64"     uncheckedIShiftL64#     :: Int64# -> Int# -> Int64#
667 foreign import ccall unsafe "stg_uncheckedIShiftRA64"    uncheckedIShiftRA64#    :: Int64# -> Int# -> Int64#
668
669 foreign import ccall unsafe "stg_integerToInt64"  integerToInt64#  :: Int# -> ByteArray# -> Int64#
670
671 {-# RULES
672 "fromIntegral/Int->Int64"    fromIntegral = \(I#   x#) -> I64# (intToInt64# x#)
673 "fromIntegral/Word->Int64"   fromIntegral = \(W#   x#) -> I64# (word64ToInt64# (wordToWord64# x#))
674 "fromIntegral/Word64->Int64" fromIntegral = \(W64# x#) -> I64# (word64ToInt64# x#)
675 "fromIntegral/Int64->Int"    fromIntegral = \(I64# x#) -> I#   (int64ToInt# x#)
676 "fromIntegral/Int64->Word"   fromIntegral = \(I64# x#) -> W#   (int2Word# (int64ToInt# x#))
677 "fromIntegral/Int64->Word64" fromIntegral = \(I64# x#) -> W64# (int64ToWord64# x#)
678 "fromIntegral/Int64->Int64"  fromIntegral = id :: Int64 -> Int64
679   #-}
680
681 #else 
682
683 -- Int64 is represented in the same way as Int.
684 -- Operations may assume and must ensure that it holds only values
685 -- from its logical range.
686
687 data Int64 = I64# Int# deriving (Eq, Ord)
688
689 instance Show Int64 where
690     showsPrec p x = showsPrec p (fromIntegral x :: Int)
691
692 instance Num Int64 where
693     (I64# x#) + (I64# y#)  = I64# (x# +# y#)
694     (I64# x#) - (I64# y#)  = I64# (x# -# y#)
695     (I64# x#) * (I64# y#)  = I64# (x# *# y#)
696     negate (I64# x#)       = I64# (negateInt# x#)
697     abs x | x >= 0         = x
698           | otherwise      = negate x
699     signum x | x > 0       = 1
700     signum 0               = 0
701     signum _               = -1
702     fromInteger (S# i#)    = I64# i#
703     fromInteger (J# s# d#) = I64# (integer2Int# s# d#)
704
705 instance Enum Int64 where
706     succ x
707         | x /= maxBound = x + 1
708         | otherwise     = succError "Int64"
709     pred x
710         | x /= minBound = x - 1
711         | otherwise     = predError "Int64"
712     toEnum (I# i#)      = I64# i#
713     fromEnum (I64# x#)  = I# x#
714     enumFrom            = boundedEnumFrom
715     enumFromThen        = boundedEnumFromThen
716
717 instance Integral Int64 where
718     quot    x@(I64# x#) y@(I64# y#)
719         | y /= 0                  = I64# (x# `quotInt#` y#)
720         | otherwise               = divZeroError "quot{Int64}" x
721     rem     x@(I64# x#) y@(I64# y#)
722         | y /= 0                  = I64# (x# `remInt#` y#)
723         | otherwise               = divZeroError "rem{Int64}" x
724     div     x@(I64# x#) y@(I64# y#)
725         | y /= 0                  = I64# (x# `divInt#` y#)
726         | otherwise               = divZeroError "div{Int64}" x
727     mod     x@(I64# x#) y@(I64# y#)
728         | y /= 0                  = I64# (x# `modInt#` y#)
729         | otherwise               = divZeroError "mod{Int64}" x
730     quotRem x@(I64# x#) y@(I64# y#)
731         | y /= 0                  = (I64# (x# `quotInt#` y#), I64# (x# `remInt#` y#))
732         | otherwise               = divZeroError "quotRem{Int64}" x
733     divMod  x@(I64# x#) y@(I64# y#)
734         | y /= 0                  = (I64# (x# `divInt#` y#), I64# (x# `modInt#` y#))
735         | otherwise               = divZeroError "divMod{Int64}" x
736     toInteger (I64# x#)           = S# x#
737
738 instance Read Int64 where
739     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
740
741 instance Bits Int64 where
742     (I64# x#) .&.   (I64# y#)  = I64# (word2Int# (int2Word# x# `and#` int2Word# y#))
743     (I64# x#) .|.   (I64# y#)  = I64# (word2Int# (int2Word# x# `or#`  int2Word# y#))
744     (I64# x#) `xor` (I64# y#)  = I64# (word2Int# (int2Word# x# `xor#` int2Word# y#))
745     complement (I64# x#)       = I64# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
746     (I64# x#) `shift` (I# i#)
747         | i# >=# 0#            = I64# (x# `iShiftL#` i#)
748         | otherwise            = I64# (x# `iShiftRA#` negateInt# i#)
749     (I64# x#) `rotate` (I# i#)
750         | i'# ==# 0# 
751         = I64# x#
752         | otherwise
753         = I64# (word2Int# ((x'# `shiftL#` i'#) `or#`
754                            (x'# `shiftRL#` (64# -# i'#))))
755         where
756         x'# = int2Word# x#
757         i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
758     bitSize  _                 = 64
759     isSigned _                 = True
760
761 {-# RULES
762 "fromIntegral/a->Int64" fromIntegral = \x -> case fromIntegral x of I# x# -> I64# x#
763 "fromIntegral/Int64->a" fromIntegral = \(I64# x#) -> fromIntegral (I# x#)
764   #-}
765
766 #endif
767
768 instance CCallable Int64
769 instance CReturnable Int64
770
771 instance Real Int64 where
772     toRational x = toInteger x % 1
773
774 instance Bounded Int64 where
775     minBound = -0x8000000000000000
776     maxBound =  0x7FFFFFFFFFFFFFFF
777
778 instance Ix Int64 where
779     range (m,n)              = [m..n]
780     unsafeIndex b@(m,_) i    = fromIntegral (i - m)
781     inRange (m,n) i          = m <= i && i <= n
782     unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
783 \end{code}