[project @ 2001-08-04 06:11:24 by ken]
[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# (intToInt8# (x# +# y#))
42     (I8# x#) - (I8# y#)    = I8# (intToInt8# (x# -# y#))
43     (I8# x#) * (I8# y#)    = I8# (intToInt8# (x# *# y#))
44     negate (I8# x#)        = I8# (intToInt8# (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# (intToInt8# i#)
51     fromInteger (J# s# d#) = I8# (intToInt8# (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# (intToInt8# (x# `quotInt#` y#))
74         | otherwise               = divZeroError "quot{Int8}" x
75     rem     x@(I8# x#) y@(I8# y#)
76         | y /= 0                  = I8# (intToInt8# (x# `remInt#` y#))
77         | otherwise               = divZeroError "rem{Int8}" x
78     div     x@(I8# x#) y@(I8# y#)
79         | y /= 0                  = I8# (intToInt8# (x# `divInt#` y#))
80         | otherwise               = divZeroError "div{Int8}" x
81     mod     x@(I8# x#) y@(I8# y#)
82         | y /= 0                  = I8# (intToInt8# (x# `modInt#` y#))
83         | otherwise               = divZeroError "mod{Int8}" x
84     quotRem x@(I8# x#) y@(I8# y#)
85         | y /= 0                  = (I8# (intToInt8# (x# `quotInt#` y#)),
86                                     I8# (intToInt8# (x# `remInt#` y#)))
87         | otherwise               = divZeroError "quotRem{Int8}" x
88     divMod  x@(I8# x#) y@(I8# y#)
89         | y /= 0                  = (I8# (intToInt8# (x# `divInt#` y#)),
90                                     I8# (intToInt8# (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     index b@(m,_) i
101         | inRange b i = fromIntegral (i - m)
102         | otherwise   = indexError b i "Int8"
103     inRange (m,n) i   = m <= i && i <= n
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# (intToInt8# (x# `iShiftL#` i#))
115         | otherwise           = I8# (x# `iShiftRA#` negateInt# i#)
116     (I8# x#) `rotate` (I# i#) =
117         I8# (intToInt8# (word2Int# ((x'# `shiftL#` i'#) `or#`
118                                     (x'# `shiftRL#` (8# -# i'#)))))
119         where
120         x'# = wordToWord8# (int2Word# x#)
121         i'# = word2Int# (int2Word# i# `and#` int2Word# 7#)
122     bitSize  _                = 8
123     isSigned _                = True
124
125 {-# RULES
126 "fromIntegral/Int8->Int8" fromIntegral = id :: Int8 -> Int8
127 "fromIntegral/a->Int8"    fromIntegral = \x -> case fromIntegral x of I# x# -> I8# (intToInt8# x#)
128 "fromIntegral/Int8->a"    fromIntegral = \(I8# x#) -> fromIntegral (I# x#)
129   #-}
130
131 ------------------------------------------------------------------------
132 -- type Int16
133 ------------------------------------------------------------------------
134
135 -- Int16 is represented in the same way as Int. Operations may assume
136 -- and must ensure that it holds only values from its logical range.
137
138 data Int16 = I16# Int# deriving (Eq, Ord)
139
140 instance CCallable Int16
141 instance CReturnable Int16
142
143 instance Show Int16 where
144     showsPrec p x = showsPrec p (fromIntegral x :: Int)
145
146 instance Num Int16 where
147     (I16# x#) + (I16# y#)  = I16# (intToInt16# (x# +# y#))
148     (I16# x#) - (I16# y#)  = I16# (intToInt16# (x# -# y#))
149     (I16# x#) * (I16# y#)  = I16# (intToInt16# (x# *# y#))
150     negate (I16# x#)       = I16# (intToInt16# (negateInt# x#))
151     abs x | x >= 0         = x
152           | otherwise      = negate x
153     signum x | x > 0       = 1
154     signum 0               = 0
155     signum _               = -1
156     fromInteger (S# i#)    = I16# (intToInt16# i#)
157     fromInteger (J# s# d#) = I16# (intToInt16# (integer2Int# s# d#))
158
159 instance Real Int16 where
160     toRational x = toInteger x % 1
161
162 instance Enum Int16 where
163     succ x
164         | x /= maxBound = x + 1
165         | otherwise     = succError "Int16"
166     pred x
167         | x /= minBound = x - 1
168         | otherwise     = predError "Int16"
169     toEnum i@(I# i#)
170         | i >= fromIntegral (minBound::Int16) && i <= fromIntegral (maxBound::Int16)
171                         = I16# i#
172         | otherwise     = toEnumError "Int16" i (minBound::Int16, maxBound::Int16)
173     fromEnum (I16# x#)  = I# x#
174     enumFrom            = boundedEnumFrom
175     enumFromThen        = boundedEnumFromThen
176
177 instance Integral Int16 where
178     quot    x@(I16# x#) y@(I16# y#)
179         | y /= 0                  = I16# (intToInt16# (x# `quotInt#` y#))
180         | otherwise               = divZeroError "quot{Int16}" x
181     rem     x@(I16# x#) y@(I16# y#)
182         | y /= 0                  = I16# (intToInt16# (x# `remInt#` y#))
183         | otherwise               = divZeroError "rem{Int16}" x
184     div     x@(I16# x#) y@(I16# y#)
185         | y /= 0                  = I16# (intToInt16# (x# `divInt#` y#))
186         | otherwise               = divZeroError "div{Int16}" x
187     mod     x@(I16# x#) y@(I16# y#)
188         | y /= 0                  = I16# (intToInt16# (x# `modInt#` y#))
189         | otherwise               = divZeroError "mod{Int16}" x
190     quotRem x@(I16# x#) y@(I16# y#)
191         | y /= 0                  = (I16# (intToInt16# (x# `quotInt#` y#)),
192                                     I16# (intToInt16# (x# `remInt#` y#)))
193         | otherwise               = divZeroError "quotRem{Int16}" x
194     divMod  x@(I16# x#) y@(I16# y#)
195         | y /= 0                  = (I16# (intToInt16# (x# `divInt#` y#)),
196                                     I16# (intToInt16# (x# `modInt#` y#)))
197         | otherwise               = divZeroError "divMod{Int16}" x
198     toInteger (I16# x#)           = S# x#
199
200 instance Bounded Int16 where
201     minBound = -0x8000
202     maxBound =  0x7FFF
203
204 instance Ix Int16 where
205     range (m,n)       = [m..n]
206     index b@(m,_) i
207         | inRange b i = fromIntegral (i - m)
208         | otherwise   = indexError b i "Int16"
209     inRange (m,n) i   = m <= i && i <= n
210
211 instance Read Int16 where
212     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
213
214 instance Bits Int16 where
215     (I16# x#) .&.   (I16# y#)  = I16# (word2Int# (int2Word# x# `and#` int2Word# y#))
216     (I16# x#) .|.   (I16# y#)  = I16# (word2Int# (int2Word# x# `or#`  int2Word# y#))
217     (I16# x#) `xor` (I16# y#)  = I16# (word2Int# (int2Word# x# `xor#` int2Word# y#))
218     complement (I16# x#)       = I16# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
219     (I16# x#) `shift` (I# i#)
220         | i# >=# 0#            = I16# (intToInt16# (x# `iShiftL#` i#))
221         | otherwise            = I16# (x# `iShiftRA#` negateInt# i#)
222     (I16# x#) `rotate` (I# i#) =
223         I16# (intToInt16# (word2Int# ((x'# `shiftL#` i'#) `or#`
224                                       (x'# `shiftRL#` (16# -# i'#)))))
225         where
226         x'# = wordToWord16# (int2Word# x#)
227         i'# = word2Int# (int2Word# i# `and#` int2Word# 15#)
228     bitSize  _                 = 16
229     isSigned _                 = True
230
231 {-# RULES
232 "fromIntegral/Word8->Int16"  fromIntegral = \(W8# x#) -> I16# (word2Int# x#)
233 "fromIntegral/Int8->Int16"   fromIntegral = \(I8# x#) -> I16# x#
234 "fromIntegral/Int16->Int16"  fromIntegral = id :: Int16 -> Int16
235 "fromIntegral/a->Int16"      fromIntegral = \x -> case fromIntegral x of I# x# -> I16# (intToInt16# x#)
236 "fromIntegral/Int16->a"      fromIntegral = \(I16# x#) -> fromIntegral (I# x#)
237   #-}
238
239 ------------------------------------------------------------------------
240 -- type Int32
241 ------------------------------------------------------------------------
242
243 -- Int32 is represented in the same way as Int.
244 #if WORD_SIZE_IN_BYTES == 8
245 -- Operations may assume and must ensure that it holds only values
246 -- from its logical range.
247 #endif
248
249 data Int32 = I32# Int# deriving (Eq, Ord)
250
251 instance CCallable Int32
252 instance CReturnable Int32
253
254 instance Show Int32 where
255     showsPrec p x = showsPrec p (fromIntegral x :: Int)
256
257 instance Num Int32 where
258     (I32# x#) + (I32# y#)  = I32# (intToInt32# (x# +# y#))
259     (I32# x#) - (I32# y#)  = I32# (intToInt32# (x# -# y#))
260     (I32# x#) * (I32# y#)  = I32# (intToInt32# (x# *# y#))
261     negate (I32# x#)       = I32# (intToInt32# (negateInt# x#))
262     abs x | x >= 0         = x
263           | otherwise      = negate x
264     signum x | x > 0       = 1
265     signum 0               = 0
266     signum _               = -1
267     fromInteger (S# i#)    = I32# (intToInt32# i#)
268     fromInteger (J# s# d#) = I32# (intToInt32# (integer2Int# s# d#))
269
270 instance Real Int32 where
271     toRational x = toInteger x % 1
272
273 instance Enum Int32 where
274     succ x
275         | x /= maxBound = x + 1
276         | otherwise     = succError "Int32"
277     pred x
278         | x /= minBound = x - 1
279         | otherwise     = predError "Int32"
280 #if WORD_SIZE_IN_BYTES == 4
281     toEnum (I# i#)      = I32# i#
282 #else
283     toEnum i@(I# i#)
284         | i >= fromIntegral (minBound::Int32) && i <= fromIntegral (maxBound::Int32)
285                         = I32# i#
286         | otherwise     = toEnumError "Int32" i (minBound::Int32, maxBound::Int32)
287 #endif
288     fromEnum (I32# x#)  = I# x#
289     enumFrom            = boundedEnumFrom
290     enumFromThen        = boundedEnumFromThen
291
292 instance Integral Int32 where
293     quot    x@(I32# x#) y@(I32# y#)
294         | y /= 0                  = I32# (intToInt32# (x# `quotInt#` y#))
295         | otherwise               = divZeroError "quot{Int32}" x
296     rem     x@(I32# x#) y@(I32# y#)
297         | y /= 0                  = I32# (intToInt32# (x# `remInt#` y#))
298         | otherwise               = divZeroError "rem{Int32}" x
299     div     x@(I32# x#) y@(I32# y#)
300         | y /= 0                  = I32# (intToInt32# (x# `divInt#` y#))
301         | otherwise               = divZeroError "div{Int32}" x
302     mod     x@(I32# x#) y@(I32# y#)
303         | y /= 0                  = I32# (intToInt32# (x# `modInt#` y#))
304         | otherwise               = divZeroError "mod{Int32}" x
305     quotRem x@(I32# x#) y@(I32# y#)
306         | y /= 0                  = (I32# (intToInt32# (x# `quotInt#` y#)),
307                                     I32# (intToInt32# (x# `remInt#` y#)))
308         | otherwise               = divZeroError "quotRem{Int32}" x
309     divMod  x@(I32# x#) y@(I32# y#)
310         | y /= 0                  = (I32# (intToInt32# (x# `divInt#` y#)),
311                                     I32# (intToInt32# (x# `modInt#` y#)))
312         | otherwise               = divZeroError "divMod{Int32}" x
313     toInteger (I32# x#)           = S# x#
314
315 instance Bounded Int32 where
316     minBound = -0x80000000
317     maxBound =  0x7FFFFFFF
318
319 instance Ix Int32 where
320     range (m,n)       = [m..n]
321     index b@(m,_) i
322         | inRange b i = fromIntegral (i - m)
323         | otherwise   = indexError b i "Int32"
324     inRange (m,n) i   = m <= i && i <= n
325
326 instance Read Int32 where
327     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
328
329 instance Bits Int32 where
330     (I32# x#) .&.   (I32# y#)  = I32# (word2Int# (int2Word# x# `and#` int2Word# y#))
331     (I32# x#) .|.   (I32# y#)  = I32# (word2Int# (int2Word# x# `or#`  int2Word# y#))
332     (I32# x#) `xor` (I32# y#)  = I32# (word2Int# (int2Word# x# `xor#` int2Word# y#))
333     complement (I32# x#)       = I32# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
334     (I32# x#) `shift` (I# i#)
335         | i# >=# 0#            = I32# (intToInt32# (x# `iShiftL#` i#))
336         | otherwise            = I32# (x# `iShiftRA#` negateInt# i#)
337     (I32# x#) `rotate` (I# i#) =
338         I32# (intToInt32# (word2Int# ((x'# `shiftL#` i'#) `or#`
339                                       (x'# `shiftRL#` (32# -# i'#)))))
340         where
341         x'# = wordToWord32# (int2Word# x#)
342         i'# = word2Int# (int2Word# i# `and#` int2Word# 31#)
343     bitSize  _                 = 32
344     isSigned _                 = True
345
346 {-# RULES
347 "fromIntegral/Word8->Int32"  fromIntegral = \(W8# x#) -> I32# (word2Int# x#)
348 "fromIntegral/Word16->Int32" fromIntegral = \(W16# x#) -> I32# (word2Int# x#)
349 "fromIntegral/Int8->Int32"   fromIntegral = \(I8# x#) -> I32# x#
350 "fromIntegral/Int16->Int32"  fromIntegral = \(I16# x#) -> I32# x#
351 "fromIntegral/Int32->Int32"  fromIntegral = id :: Int32 -> Int32
352 "fromIntegral/a->Int32"      fromIntegral = \x -> case fromIntegral x of I# x# -> I32# (intToInt32# x#)
353 "fromIntegral/Int32->a"      fromIntegral = \(I32# x#) -> fromIntegral (I# x#)
354   #-}
355
356 ------------------------------------------------------------------------
357 -- type Int64
358 ------------------------------------------------------------------------
359
360 #if WORD_SIZE_IN_BYTES == 4
361
362 data Int64 = I64# Int64#
363
364 instance Eq Int64 where
365     (I64# x#) == (I64# y#) = x# `eqInt64#` y#
366     (I64# x#) /= (I64# y#) = x# `neInt64#` y#
367
368 instance Ord Int64 where
369     (I64# x#) <  (I64# y#) = x# `ltInt64#` y#
370     (I64# x#) <= (I64# y#) = x# `leInt64#` y#
371     (I64# x#) >  (I64# y#) = x# `gtInt64#` y#
372     (I64# x#) >= (I64# y#) = x# `geInt64#` y#
373
374 instance Show Int64 where
375     showsPrec p x = showsPrec p (toInteger x)
376
377 instance Num Int64 where
378     (I64# x#) + (I64# y#)  = I64# (x# `plusInt64#`  y#)
379     (I64# x#) - (I64# y#)  = I64# (x# `minusInt64#` y#)
380     (I64# x#) * (I64# y#)  = I64# (x# `timesInt64#` y#)
381     negate (I64# x#)       = I64# (negateInt64# x#)
382     abs x | x >= 0         = x
383           | otherwise      = negate x
384     signum x | x > 0       = 1
385     signum 0               = 0
386     signum _               = -1
387     fromInteger (S# i#)    = I64# (intToInt64# i#)
388     fromInteger (J# s# d#) = I64# (integerToInt64# s# d#)
389
390 instance Enum Int64 where
391     succ x
392         | x /= maxBound = x + 1
393         | otherwise     = succError "Int64"
394     pred x
395         | x /= minBound = x - 1
396         | otherwise     = predError "Int64"
397     toEnum (I# i#)      = I64# (intToInt64# i#)
398     fromEnum x@(I64# x#)
399         | x >= fromIntegral (minBound::Int) && x <= fromIntegral (maxBound::Int)
400                         = I# (int64ToInt# x#)
401         | otherwise     = fromEnumError "Int64" x
402     enumFrom            = integralEnumFrom
403     enumFromThen        = integralEnumFromThen
404     enumFromTo          = integralEnumFromTo
405     enumFromThenTo      = integralEnumFromThenTo
406
407 instance Integral Int64 where
408     quot    x@(I64# x#) y@(I64# y#)
409         | y /= 0                  = I64# (x# `quotInt64#` y#)
410         | otherwise               = divZeroError "quot{Int64}" x
411     rem     x@(I64# x#) y@(I64# y#)
412         | y /= 0                  = I64# (x# `remInt64#` y#)
413         | otherwise               = divZeroError "rem{Int64}" x
414     div     x@(I64# x#) y@(I64# y#)
415         | y /= 0                  = I64# (x# `divInt64#` y#)
416         | otherwise               = divZeroError "div{Int64}" x
417     mod     x@(I64# x#) y@(I64# y#)
418         | y /= 0                  = I64# (x# `modInt64#` y#)
419         | otherwise               = divZeroError "mod{Int64}" x
420     quotRem x@(I64# x#) y@(I64# y#)
421         | y /= 0                  = (I64# (x# `quotInt64#` y#), I64# (x# `remInt64#` y#))
422         | otherwise               = divZeroError "quotRem{Int64}" x
423     divMod  x@(I64# x#) y@(I64# y#)
424         | y /= 0                  = (I64# (x# `divInt64#` y#), I64# (x# `modInt64#` y#))
425         | otherwise               = divZeroError "divMod{Int64}" x
426     toInteger x@(I64# x#)
427         | x >= -0x80000000 && x <= 0x7FFFFFFF
428                                   = S# (int64ToInt# x#)
429         | otherwise               = case int64ToInteger# x# of (# s, d #) -> J# s d
430
431 divInt64#, modInt64# :: Int64# -> Int64# -> Int64#
432 x# `divInt64#` y#
433     | (x# `gtInt64#` intToInt64# 0#) && (y# `ltInt64#` intToInt64# 0#)
434         = ((x# `minusInt64#` y#) `minusInt64#` intToInt64# 1#) `quotInt64#` y#
435     | (x# `ltInt64#` intToInt64# 0#) && (y# `gtInt64#` intToInt64# 0#)
436         = ((x# `minusInt64#` y#) `plusInt64#` intToInt64# 1#) `quotInt64#` y#
437     | otherwise                = x# `quotInt64#` y#
438 x# `modInt64#` y#
439     | (x# `gtInt64#` intToInt64# 0#) && (y# `ltInt64#` intToInt64# 0#) ||
440       (x# `ltInt64#` intToInt64# 0#) && (y# `gtInt64#` intToInt64# 0#)
441         = if r# `neInt64#` intToInt64# 0# then r# `plusInt64#` y# else intToInt64# 0#
442     | otherwise = r#
443     where
444     r# = x# `remInt64#` y#
445
446 instance Read Int64 where
447     readsPrec p s = [(fromInteger x, r) | (x, r) <- readsPrec p s]
448
449 instance Bits Int64 where
450     (I64# x#) .&.   (I64# y#)  = I64# (word64ToInt64# (int64ToWord64# x# `and64#` int64ToWord64# y#))
451     (I64# x#) .|.   (I64# y#)  = I64# (word64ToInt64# (int64ToWord64# x# `or64#`  int64ToWord64# y#))
452     (I64# x#) `xor` (I64# y#)  = I64# (word64ToInt64# (int64ToWord64# x# `xor64#` int64ToWord64# y#))
453     complement (I64# x#)       = I64# (word64ToInt64# (not64# (int64ToWord64# x#)))
454     (I64# x#) `shift` (I# i#)
455         | i# >=# 0#            = I64# (x# `iShiftL64#` i#)
456         | otherwise            = I64# (x# `iShiftRA64#` negateInt# i#)
457     (I64# x#) `rotate` (I# i#) =
458         I64# (word64ToInt64# ((x'# `shiftL64#` i'#) `or64#`
459                               (x'# `shiftRL64#` (64# -# i'#))))
460         where
461         x'# = int64ToWord64# x#
462         i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
463     bitSize  _                 = 64
464     isSigned _                 = True
465
466 foreign import "stg_eqInt64"       unsafe eqInt64#       :: Int64# -> Int64# -> Bool
467 foreign import "stg_neInt64"       unsafe neInt64#       :: Int64# -> Int64# -> Bool
468 foreign import "stg_ltInt64"       unsafe ltInt64#       :: Int64# -> Int64# -> Bool
469 foreign import "stg_leInt64"       unsafe leInt64#       :: Int64# -> Int64# -> Bool
470 foreign import "stg_gtInt64"       unsafe gtInt64#       :: Int64# -> Int64# -> Bool
471 foreign import "stg_geInt64"       unsafe geInt64#       :: Int64# -> Int64# -> Bool
472 foreign import "stg_plusInt64"     unsafe plusInt64#     :: Int64# -> Int64# -> Int64#
473 foreign import "stg_minusInt64"    unsafe minusInt64#    :: Int64# -> Int64# -> Int64#
474 foreign import "stg_timesInt64"    unsafe timesInt64#    :: Int64# -> Int64# -> Int64#
475 foreign import "stg_negateInt64"   unsafe negateInt64#   :: Int64# -> Int64#
476 foreign import "stg_quotInt64"     unsafe quotInt64#     :: Int64# -> Int64# -> Int64#
477 foreign import "stg_remInt64"      unsafe remInt64#      :: Int64# -> Int64# -> Int64#
478 foreign import "stg_intToInt64"    unsafe intToInt64#    :: Int# -> Int64#
479 foreign import "stg_int64ToInt"    unsafe int64ToInt#    :: Int64# -> Int#
480 foreign import "stg_wordToWord64"  unsafe wordToWord64#  :: Word# -> Word64#
481 foreign import "stg_int64ToWord64" unsafe int64ToWord64# :: Int64# -> Word64#
482 foreign import "stg_word64ToInt64" unsafe word64ToInt64# :: Word64# -> Int64#
483 foreign import "stg_and64"         unsafe and64#         :: Word64# -> Word64# -> Word64#
484 foreign import "stg_or64"          unsafe or64#          :: Word64# -> Word64# -> Word64#
485 foreign import "stg_xor64"         unsafe xor64#         :: Word64# -> Word64# -> Word64#
486 foreign import "stg_not64"         unsafe not64#         :: Word64# -> Word64#
487 foreign import "stg_iShiftL64"     unsafe iShiftL64#     :: Int64# -> Int# -> Int64#
488 foreign import "stg_iShiftRA64"    unsafe iShiftRA64#    :: Int64# -> Int# -> Int64#
489 foreign import "stg_shiftL64"      unsafe shiftL64#      :: Word64# -> Int# -> Word64#
490 foreign import "stg_shiftRL64"     unsafe shiftRL64#     :: Word64# -> Int# -> Word64#
491
492 {-# RULES
493 "fromIntegral/Int->Int64"    fromIntegral = \(I#   x#) -> I64# (intToInt64# x#)
494 "fromIntegral/Word->Int64"   fromIntegral = \(W#   x#) -> I64# (word64ToInt64# (wordToWord64# x#))
495 "fromIntegral/Word64->Int64" fromIntegral = \(W64# x#) -> I64# (word64ToInt64# x#)
496 "fromIntegral/Int64->Int"    fromIntegral = \(I64# x#) -> I#   (int64ToInt# x#)
497 "fromIntegral/Int64->Word"   fromIntegral = \(I64# x#) -> W#   (int2Word# (int64ToInt# x#))
498 "fromIntegral/Int64->Word64" fromIntegral = \(I64# x#) -> W64# (int64ToWord64# x#)
499 "fromIntegral/Int64->Int64"  fromIntegral = id :: Int64 -> Int64
500   #-}
501
502 #else
503
504 data Int64 = I64# Int# deriving (Eq, Ord)
505
506 instance Show Int64 where
507     showsPrec p x = showsPrec p (fromIntegral x :: Int)
508
509 instance Num Int64 where
510     (I64# x#) + (I64# y#)  = I64# (x# +# y#)
511     (I64# x#) - (I64# y#)  = I64# (x# -# y#)
512     (I64# x#) * (I64# y#)  = I64# (x# *# y#)
513     negate (I64# x#)       = I64# (negateInt# x#)
514     abs x | x >= 0         = x
515           | otherwise      = negate x
516     signum x | x > 0       = 1
517     signum 0               = 0
518     signum _               = -1
519     fromInteger (S# i#)    = I64# i#
520     fromInteger (J# s# d#) = I64# (integer2Int# s# d#)
521
522 instance Enum Int64 where
523     succ x
524         | x /= maxBound = x + 1
525         | otherwise     = succError "Int64"
526     pred x
527         | x /= minBound = x - 1
528         | otherwise     = predError "Int64"
529     toEnum (I# i#)      = I64# i#
530     fromEnum (I64# x#)  = I# x#
531     enumFrom            = boundedEnumFrom
532     enumFromThen        = boundedEnumFromThen
533
534 instance Integral Int64 where
535     quot    x@(I64# x#) y@(I64# y#)
536         | y /= 0                  = I64# (x# `quotInt#` y#)
537         | otherwise               = divZeroError "quot{Int64}" x
538     rem     x@(I64# x#) y@(I64# y#)
539         | y /= 0                  = I64# (x# `remInt#` y#)
540         | otherwise               = divZeroError "rem{Int64}" x
541     div     x@(I64# x#) y@(I64# y#)
542         | y /= 0                  = I64# (x# `divInt#` y#)
543         | otherwise               = divZeroError "div{Int64}" x
544     mod     x@(I64# x#) y@(I64# y#)
545         | y /= 0                  = I64# (x# `modInt#` y#)
546         | otherwise               = divZeroError "mod{Int64}" x
547     quotRem x@(I64# x#) y@(I64# y#)
548         | y /= 0                  = (I64# (x# `quotInt#` y#), I64# (x# `remInt#` y#))
549         | otherwise               = divZeroError "quotRem{Int64}" x
550     divMod  x@(I64# x#) y@(I64# y#)
551         | y /= 0                  = (I64# (x# `divInt#` y#), I64# (x# `modInt#` y#))
552         | otherwise               = divZeroError "divMod{Int64}" x
553     toInteger (I64# x#)           = S# x#
554
555 instance Read Int64 where
556     readsPrec p s = [(fromIntegral (x::Int), r) | (x, r) <- readsPrec p s]
557
558 instance Bits Int64 where
559     (I64# x#) .&.   (I64# y#)  = I64# (word2Int# (int2Word# x# `and#` int2Word# y#))
560     (I64# x#) .|.   (I64# y#)  = I64# (word2Int# (int2Word# x# `or#`  int2Word# y#))
561     (I64# x#) `xor` (I64# y#)  = I64# (word2Int# (int2Word# x# `xor#` int2Word# y#))
562     complement (I64# x#)       = I64# (word2Int# (int2Word# x# `xor#` int2Word# (-1#)))
563     (I64# x#) `shift` (I# i#)
564         | i# >=# 0#            = I64# (x# `iShiftL#` i#)
565         | otherwise            = I64# (x# `iShiftRA#` negateInt# i#)
566     (I64# x#) `rotate` (I# i#) =
567         I64# (word2Int# ((x'# `shiftL#` i'#) `or#`
568                          (x'# `shiftRL#` (64# -# i'#))))
569         where
570         x'# = int2Word# x#
571         i'# = word2Int# (int2Word# i# `and#` int2Word# 63#)
572     bitSize  _                 = 64
573     isSigned _                 = True
574
575 {-# RULES
576 "fromIntegral/a->Int64" fromIntegral = \x -> case fromIntegral x of I# x# -> I64# x#
577 "fromIntegral/Int64->a" fromIntegral = \(I64# x#) -> fromIntegral (I# x#)
578   #-}
579
580 #endif
581
582 instance CCallable Int64
583 instance CReturnable Int64
584
585 instance Real Int64 where
586     toRational x = toInteger x % 1
587
588 instance Bounded Int64 where
589     minBound = -0x8000000000000000
590     maxBound =  0x7FFFFFFFFFFFFFFF
591
592 instance Ix Int64 where
593     range (m,n)       = [m..n]
594     index b@(m,_) i
595         | inRange b i = fromIntegral (i - m)
596         | otherwise   = indexError b i "Int64"
597     inRange (m,n) i   = m <= i && i <= n
598 \end{code}