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