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