d2bf5c2f8cdefddf92f407d5ecba302014a67985
[haskell-directory.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'# `shiftL64#` i'#) `or64#`
619                                 (x'# `shiftRL64#` (64# -# i'#))))
620         where
621         x'# = int64ToWord64# x#
622         i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
623     bitSize  _                 = 64
624     isSigned _                 = True
625
626 foreign import "stg_eqInt64"       unsafe eqInt64#       :: Int64# -> Int64# -> Bool
627 foreign import "stg_neInt64"       unsafe neInt64#       :: Int64# -> Int64# -> Bool
628 foreign import "stg_ltInt64"       unsafe ltInt64#       :: Int64# -> Int64# -> Bool
629 foreign import "stg_leInt64"       unsafe leInt64#       :: Int64# -> Int64# -> Bool
630 foreign import "stg_gtInt64"       unsafe gtInt64#       :: Int64# -> Int64# -> Bool
631 foreign import "stg_geInt64"       unsafe geInt64#       :: Int64# -> Int64# -> Bool
632 foreign import "stg_plusInt64"     unsafe plusInt64#     :: Int64# -> Int64# -> Int64#
633 foreign import "stg_minusInt64"    unsafe minusInt64#    :: Int64# -> Int64# -> Int64#
634 foreign import "stg_timesInt64"    unsafe timesInt64#    :: Int64# -> Int64# -> Int64#
635 foreign import "stg_negateInt64"   unsafe negateInt64#   :: Int64# -> Int64#
636 foreign import "stg_quotInt64"     unsafe quotInt64#     :: Int64# -> Int64# -> Int64#
637 foreign import "stg_remInt64"      unsafe remInt64#      :: Int64# -> Int64# -> Int64#
638 foreign import "stg_intToInt64"    unsafe intToInt64#    :: Int# -> Int64#
639 foreign import "stg_int64ToInt"    unsafe int64ToInt#    :: Int64# -> Int#
640 foreign import "stg_wordToWord64"  unsafe wordToWord64#  :: Word# -> Word64#
641 foreign import "stg_int64ToWord64" unsafe int64ToWord64# :: Int64# -> Word64#
642 foreign import "stg_word64ToInt64" unsafe word64ToInt64# :: Word64# -> Int64#
643 foreign import "stg_and64"         unsafe and64#         :: Word64# -> Word64# -> Word64#
644 foreign import "stg_or64"          unsafe or64#          :: Word64# -> Word64# -> Word64#
645 foreign import "stg_xor64"         unsafe xor64#         :: Word64# -> Word64# -> Word64#
646 foreign import "stg_not64"         unsafe not64#         :: Word64# -> Word64#
647 foreign import "stg_iShiftL64"     unsafe iShiftL64#     :: Int64# -> Int# -> Int64#
648 foreign import "stg_iShiftRA64"    unsafe iShiftRA64#    :: Int64# -> Int# -> Int64#
649 foreign import "stg_shiftL64"      unsafe shiftL64#      :: Word64# -> Int# -> Word64#
650 foreign import "stg_shiftRL64"     unsafe shiftRL64#     :: Word64# -> Int# -> Word64#
651
652 foreign import "stg_integerToInt64"  unsafe integerToInt64#  :: Int# -> ByteArray# -> Int64#
653
654 {-# RULES
655 "fromIntegral/Int->Int64"    fromIntegral = \(I#   x#) -> I64# (intToInt64# x#)
656 "fromIntegral/Word->Int64"   fromIntegral = \(W#   x#) -> I64# (word64ToInt64# (wordToWord64# x#))
657 "fromIntegral/Word64->Int64" fromIntegral = \(W64# x#) -> I64# (word64ToInt64# x#)
658 "fromIntegral/Int64->Int"    fromIntegral = \(I64# x#) -> I#   (int64ToInt# x#)
659 "fromIntegral/Int64->Word"   fromIntegral = \(I64# x#) -> W#   (int2Word# (int64ToInt# x#))
660 "fromIntegral/Int64->Word64" fromIntegral = \(I64# x#) -> W64# (int64ToWord64# x#)
661 "fromIntegral/Int64->Int64"  fromIntegral = id :: Int64 -> Int64
662   #-}
663
664 #else 
665
666 -- Int64 is represented in the same way as Int.
667 -- Operations may assume and must ensure that it holds only values
668 -- from its logical range.
669
670 data Int64 = I64# Int# deriving (Eq, Ord)
671
672 instance Show Int64 where
673     showsPrec p x = showsPrec p (fromIntegral x :: Int)
674
675 instance Num Int64 where
676     (I64# x#) + (I64# y#)  = I64# (x# +# y#)
677     (I64# x#) - (I64# y#)  = I64# (x# -# y#)
678     (I64# x#) * (I64# y#)  = I64# (x# *# y#)
679     negate (I64# x#)       = I64# (negateInt# x#)
680     abs x | x >= 0         = x
681           | otherwise      = negate x
682     signum x | x > 0       = 1
683     signum 0               = 0
684     signum _               = -1
685     fromInteger (S# i#)    = I64# i#
686     fromInteger (J# s# d#) = I64# (integer2Int# s# d#)
687
688 instance Enum Int64 where
689     succ x
690         | x /= maxBound = x + 1
691         | otherwise     = succError "Int64"
692     pred x
693         | x /= minBound = x - 1
694         | otherwise     = predError "Int64"
695     toEnum (I# i#)      = I64# i#
696     fromEnum (I64# x#)  = I# x#
697     enumFrom            = boundedEnumFrom
698     enumFromThen        = boundedEnumFromThen
699
700 instance Integral Int64 where
701     quot    x@(I64# x#) y@(I64# y#)
702         | y /= 0                  = I64# (x# `quotInt#` y#)
703         | otherwise               = divZeroError "quot{Int64}" x
704     rem     x@(I64# x#) y@(I64# y#)
705         | y /= 0                  = I64# (x# `remInt#` y#)
706         | otherwise               = divZeroError "rem{Int64}" x
707     div     x@(I64# x#) y@(I64# y#)
708         | y /= 0                  = I64# (x# `divInt#` y#)
709         | otherwise               = divZeroError "div{Int64}" x
710     mod     x@(I64# x#) y@(I64# y#)
711         | y /= 0                  = I64# (x# `modInt#` y#)
712         | otherwise               = divZeroError "mod{Int64}" x
713     quotRem x@(I64# x#) y@(I64# y#)
714         | y /= 0                  = (I64# (x# `quotInt#` y#), I64# (x# `remInt#` y#))
715         | otherwise               = divZeroError "quotRem{Int64}" x
716     divMod  x@(I64# x#) y@(I64# y#)
717         | y /= 0                  = (I64# (x# `divInt#` y#), I64# (x# `modInt#` y#))
718         | otherwise               = divZeroError "divMod{Int64}" x
719     toInteger (I64# x#)           = S# x#
720
721 instance Read Int64 where
722     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
723
724 instance Bits Int64 where
725     (I64# x#) .&.   (I64# y#)  = I64# (word2Int# (int2Word# x# `and#` int2Word# y#))
726     (I64# x#) .|.   (I64# y#)  = I64# (word2Int# (int2Word# x# `or#`  int2Word# y#))
727     (I64# x#) `xor` (I64# y#)  = I64# (word2Int# (int2Word# x# `xor#` int2Word# y#))
728     complement (I64# x#)       = I64# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
729     (I64# x#) `shift` (I# i#)
730         | i# >=# 0#            = I64# (x# `iShiftL#` i#)
731         | otherwise            = I64# (x# `iShiftRA#` negateInt# i#)
732     (I64# x#) `rotate` (I# i#)
733         | i'# ==# 0# 
734         = I64# x#
735         | otherwise
736         = I64# (word2Int# ((x'# `shiftL#` i'#) `or#`
737                            (x'# `shiftRL#` (64# -# i'#))))
738         where
739         x'# = int2Word# x#
740         i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
741     bitSize  _                 = 64
742     isSigned _                 = True
743
744 {-# RULES
745 "fromIntegral/a->Int64" fromIntegral = \x -> case fromIntegral x of I# x# -> I64# x#
746 "fromIntegral/Int64->a" fromIntegral = \(I64# x#) -> fromIntegral (I# x#)
747   #-}
748
749 #endif
750
751 instance CCallable Int64
752 instance CReturnable Int64
753
754 instance Real Int64 where
755     toRational x = toInteger x % 1
756
757 instance Bounded Int64 where
758     minBound = -0x8000000000000000
759     maxBound =  0x7FFFFFFFFFFFFFFF
760
761 instance Ix Int64 where
762     range (m,n)              = [m..n]
763     unsafeIndex b@(m,_) i    = fromIntegral (i - m)
764     inRange (m,n) i          = m <= i && i <= n
765     unsafeRangeSize b@(_l,h) = unsafeIndex b h + 1
766 \end{code}