[project @ 2000-12-20 15:18:47 by rrt]
[ghc-hetmet.git] / ghc / lib / std / PrelInt.lhs
1 %
2 % (c) The University of Glasgow, 2000
3 %
4 \section[Int]{Module @PrelInt@}
5
6 \begin{code}
7 {-# OPTIONS -monly-3-regs #-}
8
9 module PrelInt 
10    ( 
11         Int8(..), Int16(..), Int32(..), Int64(..)
12
13         , intToInt8      -- :: Int     -> Int8
14         , intToInt16     -- :: Int     -> Int16
15         , intToInt32     -- :: Int     -> Int32
16         , intToInt64     -- :: Int     -> Int64
17
18         , integerToInt8  -- :: Integer -> Int8
19         , integerToInt16 -- :: Integer -> Int16
20         , integerToInt32 -- :: Integer -> Int32
21         , integerToInt64 -- :: Integer -> Int64
22
23         , int8ToInt      -- :: Int8    -> Int
24         , int8ToInteger  -- :: Int8    -> Integer
25         , int8ToInt16    -- :: Int8    -> Int16
26         , int8ToInt32    -- :: Int8    -> Int32
27         , int8ToInt64    -- :: Int8    -> Int64
28
29         , int16ToInt     -- :: Int16   -> Int
30         , int16ToInteger -- :: Int16   -> Integer
31         , int16ToInt8    -- :: Int16   -> Int8
32         , int16ToInt32   -- :: Int16   -> Int32
33         , int16ToInt64   -- :: Int16   -> Int64
34
35         , int32ToInt     -- :: Int32   -> Int
36         , int32ToInteger -- :: Int32   -> Integer
37         , int32ToInt8    -- :: Int32   -> Int8
38         , int32ToInt16   -- :: Int32   -> Int16
39         , int32ToInt64   -- :: Int32   -> Int64
40
41         , int64ToInt     -- :: Int64   -> Int
42         , int64ToInteger -- :: Int64   -> Integer
43         , int64ToInt8    -- :: Int64   -> Int8
44         , int64ToInt16   -- :: Int64   -> Int16
45         , int64ToInt32   -- :: Int64   -> Int32
46
47         -- The "official" place to get these from is Addr, importing
48         -- them from Int is a non-standard thing to do.
49         -- SUP: deprecated in the new FFI, subsumed by the Storable class
50         , indexInt8OffAddr
51         , indexInt16OffAddr
52         , indexInt32OffAddr
53         , indexInt64OffAddr
54         
55         , readInt8OffAddr
56         , readInt16OffAddr
57         , readInt32OffAddr
58         , readInt64OffAddr
59         
60         , writeInt8OffAddr
61         , writeInt16OffAddr
62         , writeInt32OffAddr
63         , writeInt64OffAddr
64         
65         -- internal stuff
66         , intToInt8#, i8ToInt#, intToInt16#, i16ToInt#, intToInt32#, i32ToInt#,
67         , intToInt64#, plusInt64#, minusInt64#, negateInt64#
68  ) where
69
70 import PrelWord
71 import PrelArr
72 import PrelRead
73 import PrelIOBase
74 import PrelAddr
75 import PrelReal
76 import PrelNum
77 import PrelBase
78
79 -- ---------------------------------------------------------------------------
80 -- Coercion functions (DEPRECATED)
81 -- ---------------------------------------------------------------------------
82
83 intToInt8      :: Int     -> Int8
84 intToInt16     :: Int     -> Int16
85 intToInt32     :: Int     -> Int32
86 intToInt64     :: Int     -> Int64
87
88 integerToInt8  :: Integer -> Int8
89 integerToInt16 :: Integer -> Int16
90 integerToInt32 :: Integer -> Int32
91 integerToInt64 :: Integer -> Int64
92
93 int8ToInt      :: Int8    -> Int
94 int8ToInteger  :: Int8    -> Integer
95 int8ToInt16    :: Int8    -> Int16
96 int8ToInt32    :: Int8    -> Int32
97 int8ToInt64    :: Int8    -> Int64
98
99 int16ToInt     :: Int16   -> Int
100 int16ToInteger :: Int16   -> Integer
101 int16ToInt8    :: Int16   -> Int8
102 int16ToInt32   :: Int16   -> Int32
103 int16ToInt64   :: Int16   -> Int64
104
105 int32ToInt     :: Int32   -> Int
106 int32ToInteger :: Int32   -> Integer
107 int32ToInt8    :: Int32   -> Int8
108 int32ToInt16   :: Int32   -> Int16
109 int32ToInt64   :: Int32   -> Int64
110
111 int64ToInt     :: Int64   -> Int
112 int64ToInteger :: Int64   -> Integer
113 int64ToInt8    :: Int64   -> Int8
114 int64ToInt16   :: Int64   -> Int16
115 int64ToInt32   :: Int64   -> Int32
116
117 integerToInt8  = fromInteger
118 integerToInt16 = fromInteger
119 integerToInt32 = fromInteger
120
121 int8ToInt16  (I8#  x) = I16# x
122 int8ToInt32  (I8#  x) = I32# x
123
124 int16ToInt8  (I16# x) = I8#  x
125 int16ToInt32 (I16# x) = I32# x
126
127 int32ToInt8  (I32# x) = I8#  x
128 int32ToInt16 (I32# x) = I16# x
129
130 int8ToInteger  = toInteger
131 int8ToInt64    = int32ToInt64 . int8ToInt32
132
133 int16ToInteger = toInteger
134 int16ToInt64   = int32ToInt64 . int16ToInt32
135
136 int32ToInteger = toInteger
137
138 int64ToInt8    = int32ToInt8  . int64ToInt32
139 int64ToInt16   = int32ToInt16 . int64ToInt32
140
141 -----------------------------------------------------------------------------
142 -- The following rules for fromIntegral remove the need to export specialized
143 -- conversion functions.
144 -----------------------------------------------------------------------------
145
146 {-# RULES
147    "fromIntegral/Int->Int8"         fromIntegral = intToInt8;
148    "fromIntegral/Int->Int16"        fromIntegral = intToInt16;
149    "fromIntegral/Int->Int32"        fromIntegral = intToInt32;
150    "fromIntegral/Int->Int64"        fromIntegral = intToInt64;
151
152    "fromIntegral/Integer->Int8"     fromIntegral = integerToInt8;
153    "fromIntegral/Integer->Int16"    fromIntegral = integerToInt16;
154    "fromIntegral/Integer->Int32"    fromIntegral = integerToInt32;
155    "fromIntegral/Integer->Int64"    fromIntegral = integerToInt64;
156
157    "fromIntegral/Int8->Int"         fromIntegral = int8ToInt;
158    "fromIntegral/Int8->Integer"     fromIntegral = int8ToInteger;
159    "fromIntegral/Int8->Int16"       fromIntegral = int8ToInt16;
160    "fromIntegral/Int8->Int32"       fromIntegral = int8ToInt32;
161    "fromIntegral/Int8->Int64"       fromIntegral = int8ToInt64;
162
163    "fromIntegral/Int16->Int"        fromIntegral = int16ToInt;
164    "fromIntegral/Int16->Integer"    fromIntegral = int16ToInteger;
165    "fromIntegral/Int16->Int8"       fromIntegral = int16ToInt8;
166    "fromIntegral/Int16->Int32"      fromIntegral = int16ToInt32;
167    "fromIntegral/Int16->Int64"      fromIntegral = int16ToInt64;
168
169    "fromIntegral/Int32->Int"        fromIntegral = int32ToInt;
170    "fromIntegral/Int32->Integer"    fromIntegral = int32ToInteger;
171    "fromIntegral/Int32->Int8"       fromIntegral = int32ToInt8;
172    "fromIntegral/Int32->Int16"      fromIntegral = int32ToInt16;
173    "fromIntegral/Int32->Int64"      fromIntegral = int32ToInt64;
174
175    "fromIntegral/Int64->Int"        fromIntegral = int64ToInt;
176    "fromIntegral/Int64->Integer"    fromIntegral = int64ToInteger;
177    "fromIntegral/Int64->Int8"       fromIntegral = int64ToInt8;
178    "fromIntegral/Int64->Int16"      fromIntegral = int64ToInt16;
179    "fromIntegral/Int64->Int32"      fromIntegral = int64ToInt32
180  #-}
181
182 -- -----------------------------------------------------------------------------
183 -- Int8
184 -- -----------------------------------------------------------------------------
185
186 data Int8 = I8# Int#
187
188 instance CCallable Int8
189 instance CReturnable Int8
190
191 int8ToInt (I8# x)  = I# (i8ToInt# x)
192
193 i8ToInt# :: Int# -> Int#
194 i8ToInt# x = if x' <=# 0x7f# then x' else x' -# 0x100#
195    where x' = word2Int# (int2Word# x `and#` int2Word# 0xff#)
196
197 -- This doesn't perform any bounds checking on the value it is passed,
198 -- nor its sign, i.e., show (intToInt8 511) => "-1"
199 intToInt8 (I# x) = I8# (intToInt8# x)
200
201 intToInt8# :: Int# -> Int#
202 intToInt8# i# = word2Int# ((int2Word# i#) `and#` int2Word# 0xff#)
203
204 instance Eq  Int8     where 
205   (I8# x#) == (I8# y#) = x# ==# y#
206   (I8# x#) /= (I8# y#) = x# /=# y#
207
208 instance Ord Int8 where 
209   compare (I8# x#) (I8# y#) = compareInt# (i8ToInt# x#) (i8ToInt# y#)
210
211 compareInt# :: Int# -> Int# -> Ordering
212 compareInt# x# y#
213  | x# <#  y# = LT
214  | x# ==# y# = EQ
215  | otherwise = GT
216
217 instance Num Int8 where
218   (I8# x#) + (I8# y#) = I8# (intToInt8# (x# +# y#))
219   (I8# x#) - (I8# y#) = I8# (intToInt8# (x# -# y#))
220   (I8# x#) * (I8# y#) = I8# (intToInt8# (x# *# y#))
221   negate i@(I8# x#) = 
222      if x# ==# 0#
223       then i
224       else I8# (0x100# -# x#)
225
226   abs           = absReal
227   signum        = signumReal
228   fromInteger (S# i#)    = I8# (intToInt8# i#)
229   fromInteger (J# s# d#) = I8# (intToInt8# (integer2Int# s# d#))
230   fromInt       = intToInt8
231
232 instance Bounded Int8 where
233     minBound = 0x80
234     maxBound = 0x7f 
235
236 instance Real Int8 where
237     toRational x = toInteger x % 1
238
239 instance Integral Int8 where
240     div x y
241        | x > 0 && y < 0 = quotInt8 (x-y-1) y
242        | x < 0 && y > 0 = quotInt8 (x-y+1) y
243        | otherwise      = quotInt8 x y
244     quot x@(I8# _) y@(I8# y#)
245        | y# /=# 0# = x `quotInt8` y
246        | otherwise = divZeroError "quot{Int8}" x
247     rem x@(I8# _) y@(I8# y#)
248        | y# /=# 0#  = x `remInt8` y
249        | otherwise  = divZeroError "rem{Int8}" x
250     mod x y
251        | x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
252        | otherwise = r
253         where r = remInt8 x y
254
255     a@(I8# _) `quotRem` b@(I8# _) = (a `quotInt8` b, a `remInt8` b)
256     toInteger i8  = toInteger (int8ToInt i8)
257     toInt     i8  = int8ToInt i8
258
259
260 remInt8, quotInt8 :: Int8 -> Int8 -> Int8
261 remInt8  (I8# x) (I8# y) = I8# (intToInt8# ((i8ToInt# x) `remInt#`  (i8ToInt# y)))
262 quotInt8 (I8# x) (I8# y) = I8# (intToInt8# ((i8ToInt# x) `quotInt#` (i8ToInt# y)))
263
264 instance Ix Int8 where
265     range (m,n)          = [m..n]
266     index b@(m,_) i
267               | inRange b i = int8ToInt (i - m)
268               | otherwise   = indexError b i "Int8"
269     inRange (m,n) i      = m <= i && i <= n
270
271 instance Enum Int8 where
272     succ i
273       | i == maxBound = succError "Int8"
274       | otherwise     = i+1
275     pred i
276       | i == minBound = predError "Int8"
277       | otherwise     = i-1
278
279     toEnum x
280       | x >= toInt (minBound::Int8) && x <= toInt (maxBound::Int8) 
281       = intToInt8 x
282       | otherwise
283       = toEnumError "Int8" x (minBound::Int8,maxBound::Int8)
284
285     fromEnum           = int8ToInt
286     enumFrom e1        = map toEnum [fromEnum e1 .. fromEnum (maxBound::Int8)]
287     enumFromThen e1 e2 = 
288              map toEnum [fromEnum e1, fromEnum e2 .. fromEnum (last::Int8)]
289                 where 
290                    last 
291                      | e2 < e1   = minBound
292                      | otherwise = maxBound
293
294 instance Read Int8 where
295     readsPrec p s = [ (intToInt8 x,r) | (x,r) <- readsPrec p s ]
296
297 instance Show Int8 where
298     showsPrec p i8 = showsPrec p (int8ToInt i8)
299
300 -- -----------------------------------------------------------------------------
301 -- Int16
302 -- -----------------------------------------------------------------------------
303
304 data Int16  = I16# Int#
305
306 instance CCallable Int16
307 instance CReturnable Int16
308
309 int16ToInt  (I16# x) = I# (i16ToInt# x)
310
311 i16ToInt# :: Int# -> Int#
312 i16ToInt# x = if x' <=# 0x7fff# then x' else x' -# 0x10000#
313    where x' = word2Int# (int2Word# x `and#` int2Word# 0xffff#)
314
315 -- This doesn't perform any bounds checking on the value it is passed,
316 -- nor its sign, i.e., show (intToInt8 131071) => "-1"
317 intToInt16 (I# x) = I16# (intToInt16# x)
318
319 intToInt16# :: Int# -> Int#
320 intToInt16# i# = word2Int# ((int2Word# i#) `and#` int2Word# 0xffff#)
321
322 instance Eq  Int16     where
323   (I16# x#) == (I16# y#) = x# ==# y#
324   (I16# x#) /= (I16# y#) = x# /=# y#
325
326 instance Ord Int16 where
327   compare (I16# x#) (I16# y#) = compareInt# (i16ToInt# x#) (i16ToInt# y#)
328
329 instance Num Int16 where
330   (I16# x#) + (I16# y#) = I16# (intToInt16# (x# +# y#))
331   (I16# x#) - (I16# y#) = I16# (intToInt16# (x# -# y#))
332   (I16# x#) * (I16# y#) = I16# (intToInt16# (x# *# y#))
333   negate i@(I16# x#) = 
334      if x# ==# 0#
335       then i
336       else I16# (0x10000# -# x#)
337   abs           = absReal
338   signum        = signumReal
339   fromInteger (S# i#)    = I16# (intToInt16# i#)
340   fromInteger (J# s# d#) = I16# (intToInt16# (integer2Int# s# d#))
341   fromInt       = intToInt16
342
343 instance Bounded Int16 where
344     minBound = 0x8000
345     maxBound = 0x7fff 
346
347 instance Real Int16 where
348     toRational x = toInteger x % 1
349
350 instance Integral Int16 where
351     div x y
352        | x > 0 && y < 0 = quotInt16 (x-y-1) y
353        | x < 0 && y > 0 = quotInt16 (x-y+1) y
354        | otherwise      = quotInt16 x y
355     quot x@(I16# _) y@(I16# y#)
356        | y# /=# 0#      = x `quotInt16` y
357        | otherwise      = divZeroError "quot{Int16}" x
358     rem x@(I16# _) y@(I16# y#)
359        | y# /=# 0#      = x `remInt16` y
360        | otherwise      = divZeroError "rem{Int16}" x
361     mod x y
362        | x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
363        | otherwise                        = r
364         where r = remInt16 x y
365
366     a@(I16# _) `quotRem` b@(I16# _) = (a `quotInt16` b, a `remInt16` b)
367     toInteger i16  = toInteger (int16ToInt i16)
368     toInt     i16  = int16ToInt i16
369
370 remInt16, quotInt16 :: Int16 -> Int16 -> Int16
371 remInt16  (I16# x) (I16# y) = I16# (intToInt16# ((i16ToInt# x) `remInt#` (i16ToInt# y)))
372 quotInt16 (I16# x) (I16# y) = I16# (intToInt16# ((i16ToInt# x) `quotInt#` (i16ToInt# y)))
373
374 instance Ix Int16 where
375     range (m,n)          = [m..n]
376     index b@(m,_) i
377               | inRange b i = int16ToInt (i - m)
378               | otherwise   = indexError b i "Int16"
379     inRange (m,n) i      = m <= i && i <= n
380
381 instance Enum Int16 where
382     succ i
383       | i == maxBound = succError "Int16"
384       | otherwise     = i+1
385
386     pred i
387       | i == minBound = predError "Int16"
388       | otherwise     = i-1
389
390     toEnum x
391       | x >= toInt (minBound::Int16) && x <= toInt (maxBound::Int16) 
392       = intToInt16 x
393       | otherwise
394       = toEnumError "Int16" x (minBound::Int16, maxBound::Int16)
395
396     fromEnum         = int16ToInt
397
398     enumFrom e1        = map toEnum [fromEnum e1 .. fromEnum (maxBound::Int16)]
399     enumFromThen e1 e2 = map toEnum [fromEnum e1, fromEnum e2 .. fromEnum (last::Int16)]
400                           where last 
401                                   | e2 < e1   = minBound
402                                   | otherwise = maxBound
403
404 instance Read Int16 where
405     readsPrec p s = [ (intToInt16 x,r) | (x,r) <- readsPrec p s ]
406
407 instance Show Int16 where
408     showsPrec p i16 = showsPrec p (int16ToInt i16)
409
410 -- -----------------------------------------------------------------------------
411 -- Int32
412 -- -----------------------------------------------------------------------------
413
414 data Int32  = I32# Int#
415
416 instance CCallable Int32
417 instance CReturnable Int32
418
419 int32ToInt  (I32# x) = I# (i32ToInt# x)
420
421 i32ToInt# :: Int# -> Int#
422 #if WORD_SIZE_IN_BYTES > 4
423 i32ToInt# x = if x' <=# 0x7fffffff# then x' else x' -# 0x100000000#
424    where x' = word2Int# (int2Word# x `and#` int2Word# 0xffffffff#)
425 #else
426 i32ToInt# x = x
427 #endif
428
429 intToInt32 (I# x) = I32# (intToInt32# x)
430
431 intToInt32# :: Int# -> Int#
432 #if WORD_SIZE_IN_BYTES > 4
433 intToInt32# i# = word2Int# ((int2Word# i#) `and#` int2Word# 0xffffffff#)
434 #else
435 intToInt32# i# = i#
436 #endif
437
438 instance Eq  Int32     where
439   (I32# x#) == (I32# y#) = x# ==# y#
440   (I32# x#) /= (I32# y#) = x# /=# y#
441
442 instance Ord Int32    where
443   compare (I32# x#) (I32# y#) = compareInt# (i32ToInt# x#) (i32ToInt# y#)
444
445 instance Num Int32 where
446   (I32# x#) + (I32# y#) = I32# (intToInt32# (x# +# y#))
447   (I32# x#) - (I32# y#) = I32# (intToInt32# (x# -# y#))
448   (I32# x#) * (I32# y#) = I32# (intToInt32# (x# *# y#))
449 #if WORD_SIZE_IN_BYTES > 4
450   negate i@(I32# x)  = 
451       if x ==# 0#
452        then i
453        else I32# (intToInt32# (0x100000000# -# x'))
454 #else
455   negate (I32# x)  = I32# (negateInt# x)
456 #endif
457   abs           = absReal
458   signum        = signumReal
459   fromInteger (S# i#)    = I32# (intToInt32# i#)
460   fromInteger (J# s# d#) = I32# (intToInt32# (integer2Int# s# d#))
461   fromInt       = intToInt32
462
463
464 instance Bounded Int32 where 
465     minBound = fromInt minBound
466     maxBound = fromInt maxBound
467
468 instance Real Int32 where
469     toRational x = toInteger x % 1
470
471 instance Integral Int32 where
472     div x y
473        | x > 0 && y < 0 = quotInt32 (x-y-1) y
474        | x < 0 && y > 0 = quotInt32 (x-y+1) y
475        | otherwise      = quotInt32 x y
476     quot x@(I32# _) y@(I32# y#)
477        | y# /=# 0#  = x `quotInt32` y
478        | otherwise  = divZeroError "quot{Int32}" x
479     rem x@(I32# _) y@(I32# y#)
480        | y# /=# 0#  = x `remInt32` y
481        | otherwise  = divZeroError "rem{Int32}" x
482     mod x y
483        | x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
484        | otherwise                        = r
485         where r = remInt32 x y
486
487     a@(I32# _) `quotRem` b@(I32# _) = (a `quotInt32` b, a `remInt32` b)
488     toInteger i32  = toInteger (int32ToInt i32)
489     toInt     i32  = int32ToInt i32
490
491 remInt32, quotInt32 :: Int32 -> Int32 -> Int32
492 remInt32  (I32# x) (I32# y) = I32# (intToInt32# ((i32ToInt# x) `remInt#`  (i32ToInt# y)))
493 quotInt32 (I32# x) (I32# y) = I32# (intToInt32# ((i32ToInt# x) `quotInt#` (i32ToInt# y)))
494
495 instance Ix Int32 where
496     range (m,n)          = [m..n]
497     index b@(m,_) i
498               | inRange b i = int32ToInt (i - m)
499               | otherwise   = indexError b i "Int32"
500     inRange (m,n) i      = m <= i && i <= n
501
502 instance Enum Int32 where
503     succ i
504       | i == maxBound = succError "Int32"
505       | otherwise     = i+1
506
507     pred i
508       | i == minBound = predError "Int32"
509       | otherwise     = i-1
510
511     toEnum x
512         -- with Int having the same range as Int32, the following test
513         -- shouldn't fail. However, having it here 
514       | x >= toInt (minBound::Int32) && x <= toInt (maxBound::Int32) 
515       = intToInt32 x
516       | otherwise
517       = toEnumError "Int32" x (minBound::Int32, maxBound::Int32)
518
519     fromEnum           = int32ToInt
520
521     enumFrom e1        = map toEnum [fromEnum e1 .. fromEnum (maxBound::Int32)]
522     enumFromThen e1 e2 = map toEnum [fromEnum e1, fromEnum e2 .. fromEnum (last::Int32)]
523                           where 
524                             last
525                              | e2 < e1   = minBound
526                              | otherwise = maxBound
527
528
529 instance Read Int32 where
530     readsPrec p s = [ (intToInt32 x,r) | (x,r) <- readsPrec p s ]
531
532 instance Show Int32 where
533     showsPrec p i32 = showsPrec p (int32ToInt i32)
534
535 -- -----------------------------------------------------------------------------
536 -- Int64
537 -- -----------------------------------------------------------------------------
538
539 #if WORD_SIZE_IN_BYTES == 8
540
541 --data Int64 = I64# Int#
542
543 int32ToInt64 (I32# i#) = I64# i#
544
545 intToInt32# :: Int# -> Int#
546 intToInt32# i# = word2Int# ((int2Word# i#) `and#` (case (maxBound::Word32) of W# x# -> x#))
547
548 int64ToInt32 (I64# i#) = I32# (intToInt32# w#)
549
550 instance Eq  Int64     where 
551   (I64# x) == (I64# y) = x `eqInt#` y
552   (I64# x) /= (I64# y) = x `neInt#` y
553
554 instance Ord Int32    where
555   compare (I64# x#) (I64# y#) = compareInt# x# y#
556
557 instance Num Int64 where
558   (I64# x) + (I64# y) = I64# (x +# y)
559   (I64# x) - (I64# y) = I64# (x -# y)
560   (I64# x) * (I64# y) = I64# (x *# y)
561   negate w@(I64# x)   = I64# (negateInt# x)
562   abs x               = absReal
563   signum              = signumReal
564   fromInteger (S# i#)    = I64# i#
565   fromInteger (J# s# d#) = I64# (integer2Int# s# d#)
566   fromInt       = intToInt64
567
568 instance Bounded Int64 where
569   minBound = integerToInt64 (-0x8000000000000000)
570   maxBound = integerToInt64 0x7fffffffffffffff
571
572 instance Integral Int64 where
573     div x y
574       | x > 0 && y < 0  = quotInt64 (x-y-1) y
575       | x < 0 && y > 0  = quotInt64 (x-y+1) y
576       | otherwise       = quotInt64 x y
577
578     quot x@(I64# _) y@(I64# y#)
579        | y# /=# 0# = x `quotInt64` y
580        | otherwise = divZeroError "quot{Int64}" x
581
582     rem x@(I64# _) y@(I64# y#)
583        | y# /=# 0# = x `remInt64` y
584        | otherwise = divZeroError "rem{Int64}" x
585
586     mod x y
587        | x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
588        | otherwise = r
589         where r = remInt64 x y
590
591     a@(I64# _) `quotRem` b@(I64# _) = (a `quotInt64` b, a `remInt64` b)
592     toInteger (I64# i#) = toInteger (I# i#)
593     toInt     (I64# i#) = I# i#
594
595 remInt64  (I64# x) (I64# y) = I64# (x `remInt#` y)
596 quotInt64 (I64# x) (I64# y) = I64# (x `quotInt#` y)
597
598 int64ToInteger (I64# i#) = toInteger (I# i#)
599 integerToInt64 i = case fromInteger i of { I# i# -> I64# i# }
600
601 intToInt64 (I# i#) = I64# i#
602 int64ToInt (I64# i#) = I# i#
603
604 #else
605 --assume: support for long-longs
606 --data Int64 = I64 Int64# deriving (Eq, Ord, Bounded)
607
608 int32ToInt64 (I32# i#) = I64# (intToInt64# i#)
609 int64ToInt32 (I64# i#) = I32# (int64ToInt# i#)
610
611 int64ToInteger (I64# x#) = 
612    case int64ToInteger# x# of
613      (# s#, p# #) -> J# s# p#
614
615 integerToInt64 (S# i#) = I64# (intToInt64# i#)
616 integerToInt64 (J# s# d#) = I64# (integerToInt64# s# d#)
617
618 instance Eq  Int64     where 
619   (I64# x) == (I64# y) = x `eqInt64#` y
620   (I64# x) /= (I64# y) = x `neInt64#` y
621
622 instance Ord Int64     where 
623   compare (I64# x) (I64# y)   = compareInt64# x y
624   (<)  (I64# x) (I64# y)      = x `ltInt64#` y
625   (<=) (I64# x) (I64# y)      = x `leInt64#` y
626   (>=) (I64# x) (I64# y)      = x `geInt64#` y
627   (>)  (I64# x) (I64# y)      = x `gtInt64#` y
628   max x@(I64# x#) y@(I64# y#) = 
629      case (compareInt64# x# y#) of { LT -> y ; EQ -> x ; GT -> x }
630   min x@(I64# x#) y@(I64# y#) =
631      case (compareInt64# x# y#) of { LT -> x ; EQ -> x ; GT -> y }
632
633 instance Num Int64 where
634   (I64# x) + (I64# y) = I64# (x `plusInt64#`  y)
635   (I64# x) - (I64# y) = I64# (x `minusInt64#` y)
636   (I64# x) * (I64# y) = I64# (x `timesInt64#` y)
637   negate (I64# x)     = I64# (negateInt64# x)
638   abs x               = absReal x
639   signum              = signumReal
640   fromInteger i       = integerToInt64 i
641   fromInt     i       = intToInt64 i
642
643 compareInt64# :: Int64# -> Int64# -> Ordering
644 compareInt64# i# j# 
645  | i# `ltInt64#` j# = LT
646  | i# `eqInt64#` j# = EQ
647  | otherwise        = GT
648
649 instance Bounded Int64 where
650   minBound = integerToInt64 (-0x8000000000000000)
651   maxBound = integerToInt64 0x7fffffffffffffff
652
653 instance Integral Int64 where
654     div x y
655       | x > 0 && y < 0  = quotInt64 (x-y-1) y
656       | x < 0 && y > 0  = quotInt64 (x-y+1) y
657       | otherwise       = quotInt64 x y
658
659     quot x@(I64# _) y@(I64# y#)
660        | y# `neInt64#` (intToInt64# 0#) = x `quotInt64` y
661        | otherwise = divZeroError "quot{Int64}" x
662
663     rem x@(I64# _) y@(I64# y#)
664        | y# `neInt64#` (intToInt64# 0#) = x `remInt64` y
665        | otherwise = divZeroError "rem{Int64}" x
666
667     mod x y
668        | x > 0 && y < 0 || x < 0 && y > 0 = if r/=0 then r+y else 0
669        | otherwise = r
670         where r = remInt64 x y
671
672     a@(I64# _) `quotRem` b@(I64# _) = (a `quotInt64` b, a `remInt64` b)
673     toInteger i         = int64ToInteger i
674     toInt     i         = int64ToInt i
675
676 remInt64, quotInt64 :: Int64 -> Int64 -> Int64
677 remInt64  (I64# x) (I64# y) = I64# (x `remInt64#` y)
678 quotInt64 (I64# x) (I64# y) = I64# (x `quotInt64#` y)
679
680 intToInt64 (I# i#) = I64# (intToInt64# i#)
681 int64ToInt (I64# i#) = I# (int64ToInt# i#)
682
683 -- Word64# primop wrappers:
684
685 ltInt64# :: Int64# -> Int64# -> Bool
686 ltInt64# x# y# = stg_ltInt64 x# y# /= 0
687       
688 leInt64# :: Int64# -> Int64# -> Bool
689 leInt64# x# y# = stg_leInt64 x# y# /= 0
690
691 eqInt64# :: Int64# -> Int64# -> Bool
692 eqInt64# x# y# = stg_eqInt64 x# y# /= 0
693
694 neInt64# :: Int64# -> Int64# -> Bool
695 neInt64# x# y# = stg_neInt64 x# y# /= 0
696
697 geInt64# :: Int64# -> Int64# -> Bool
698 geInt64# x# y# = stg_geInt64 x# y# /= 0
699
700 gtInt64# :: Int64# -> Int64# -> Bool
701 gtInt64# x# y# = stg_gtInt64 x# y# /= 0
702
703 plusInt64# :: Int64# -> Int64# -> Int64#
704 plusInt64# a# b# = case stg_plusInt64 a# b# of { I64# i# -> i# }
705
706 minusInt64# :: Int64# -> Int64# -> Int64#
707 minusInt64# a# b# = case stg_minusInt64 a# b# of { I64# i# -> i# }
708
709 timesInt64# :: Int64# -> Int64# -> Int64#
710 timesInt64# a# b# = case stg_timesInt64 a# b# of { I64# i# -> i# }
711
712 quotInt64# :: Int64# -> Int64# -> Int64#
713 quotInt64# a# b# = case stg_quotInt64 a# b# of { I64# i# -> i# }
714
715 remInt64# :: Int64# -> Int64# -> Int64#
716 remInt64# a# b# = case stg_remInt64 a# b# of { I64# i# -> i# }
717
718 negateInt64# :: Int64# -> Int64#
719 negateInt64# a# = case stg_negateInt64 a# of { I64# i# -> i# }
720
721 int64ToInt# :: Int64# -> Int#
722 int64ToInt# i64# = case stg_int64ToInt i64# of { I# i# -> i# }
723
724 intToInt64# :: Int# -> Int64#
725 intToInt64# i# = case stg_intToInt64 i# of { I64# i64# -> i64# }
726
727 foreign import "stg_intToInt64" unsafe stg_intToInt64 :: Int# -> Int64
728 foreign import "stg_int64ToInt" unsafe stg_int64ToInt :: Int64# -> Int
729 foreign import "stg_negateInt64" unsafe stg_negateInt64 :: Int64# -> Int64
730 foreign import "stg_remInt64" unsafe stg_remInt64 :: Int64# -> Int64# -> Int64
731 foreign import "stg_quotInt64" unsafe stg_quotInt64 :: Int64# -> Int64# -> Int64
732 foreign import "stg_timesInt64" unsafe stg_timesInt64 :: Int64# -> Int64# -> Int64
733 foreign import "stg_minusInt64" unsafe stg_minusInt64 :: Int64# -> Int64# -> Int64
734 foreign import "stg_plusInt64" unsafe stg_plusInt64 :: Int64# -> Int64# -> Int64
735 foreign import "stg_gtInt64" unsafe stg_gtInt64 :: Int64# -> Int64# -> Int
736 foreign import "stg_geInt64" unsafe stg_geInt64 :: Int64# -> Int64# -> Int
737 foreign import "stg_neInt64" unsafe stg_neInt64 :: Int64# -> Int64# -> Int
738 foreign import "stg_eqInt64" unsafe stg_eqInt64 :: Int64# -> Int64# -> Int
739 foreign import "stg_leInt64" unsafe stg_leInt64 :: Int64# -> Int64# -> Int
740 foreign import "stg_ltInt64" unsafe stg_ltInt64 :: Int64# -> Int64# -> Int
741
742 #endif
743
744 --
745 -- Code that's independent of Int64 rep.
746 -- 
747 instance Enum Int64 where
748     succ i
749       | i == maxBound = succError "Int64"
750       | otherwise     = i+1
751
752     pred i
753       | i == minBound = predError "Int64"
754       | otherwise     = i-1
755
756     toEnum    i = intToInt64 i
757     fromEnum  x
758       | x >= intToInt64 (minBound::Int) && x <= intToInt64 (maxBound::Int)
759       = int64ToInt x
760       | otherwise
761       = fromEnumError "Int64" x
762
763     enumFrom e1        = map integerToInt64 [int64ToInteger e1 .. int64ToInteger (maxBound::Int64)]
764     enumFromTo e1 e2   = map integerToInt64 [int64ToInteger e1 .. int64ToInteger e2]
765     enumFromThen e1 e2 = map integerToInt64 [int64ToInteger e1, int64ToInteger e2 .. int64ToInteger last]
766                        where 
767                           last :: Int64
768                           last 
769                            | e2 < e1   = minBound
770                            | otherwise = maxBound
771
772     enumFromThenTo e1 e2 e3 = map integerToInt64 [int64ToInteger e1, int64ToInteger e2 .. int64ToInteger e3]
773
774 instance Show Int64 where
775     showsPrec p i64 = showsPrec p (int64ToInteger i64)
776
777 instance Read Int64 where
778   readsPrec _ s = [ (integerToInt64 x,r) | (x,r) <- readDec s ]
779
780 instance Ix Int64 where
781     range (m,n)          = [m..n]
782     index b@(m,_) i
783            | inRange b i = int64ToInt (i-m)
784            | otherwise   = indexError b i "Int64"
785     inRange (m,n) i      = m <= i && i <= n
786
787 instance Real Int64 where
788   toRational x = toInteger x % 1
789
790 -- ---------------------------------------------------------------------------
791 -- Reading/writing Ints from memory
792 -- ---------------------------------------------------------------------------
793
794 indexInt8OffAddr  :: Addr -> Int -> Int8
795 indexInt8OffAddr (A# a#) (I# i#) = I8# (indexInt8OffAddr# a# i#)
796
797 indexInt16OffAddr  :: Addr -> Int -> Int16
798 indexInt16OffAddr (A# a#) (I# i#) = I16# (indexInt16OffAddr# a# i#)
799
800 indexInt32OffAddr  :: Addr -> Int -> Int32
801 indexInt32OffAddr (A# a#) (I# i#) = I32# (indexInt32OffAddr# a# i#)
802
803 indexInt64OffAddr  :: Addr -> Int -> Int64
804 #if WORD_SIZE_IN_BYTES==8
805 indexInt64OffAddr (A# a#) (I# i#) = I64# (indexIntOffAddr# a# i#)
806 #else
807 indexInt64OffAddr (A# a#) (I# i#) = I64# (indexInt64OffAddr# a# i#)
808 #endif
809
810
811 readInt8OffAddr :: Addr -> Int -> IO Int8
812 readInt8OffAddr (A# a) (I# i)
813   = IO $ \s -> case readInt8OffAddr# a i s of (# s, w #) -> (# s, I8# w #)
814
815 readInt16OffAddr :: Addr -> Int -> IO Int16
816 readInt16OffAddr (A# a) (I# i)
817   = IO $ \s -> case readInt16OffAddr# a i s of (# s, w #) -> (# s, I16# w #)
818
819 readInt32OffAddr :: Addr -> Int -> IO Int32
820 readInt32OffAddr (A# a) (I# i)
821   = IO $ \s -> case readInt32OffAddr# a i s of (# s, w #) -> (# s, I32# w #)
822
823 readInt64OffAddr  :: Addr -> Int -> IO Int64
824 #if WORD_SIZE_IN_BYTES == 8
825 readInt64OffAddr (A# a) (I# i)
826   = IO $ \s -> case readIntOffAddr# a i s of (# s, w #) -> (# s, I64# w #)
827 #else
828 readInt64OffAddr (A# a) (I# i)
829   = IO $ \s -> case readInt64OffAddr# a i s of (# s, w #) -> (# s, I64# w #)
830 #endif
831
832
833 writeInt8OffAddr  :: Addr -> Int -> Int8  -> IO ()
834 writeInt8OffAddr (A# a#) (I# i#) (I8# w#) = IO $ \ s# ->
835       case (writeInt8OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
836
837 writeInt16OffAddr  :: Addr -> Int -> Int16  -> IO ()
838 writeInt16OffAddr (A# a#) (I# i#) (I16# w#) = IO $ \ s# ->
839       case (writeInt16OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
840
841 writeInt32OffAddr  :: Addr -> Int -> Int32  -> IO ()
842 writeInt32OffAddr (A# a#) (I# i#) (I32# w#) = IO $ \ s# ->
843       case (writeInt32OffAddr# a# i# w# s#) of s2# -> (# s2#, () #)
844
845 writeInt64OffAddr :: Addr -> Int -> Int64 -> IO ()
846 #if WORD_SIZE_IN_BYTES == 8
847 writeInt64OffAddr (A# a#) (I# i#) (I64# w#) = IO $ \ s# ->
848       case (writeIntOffAddr#  a# i# w# s#) of s2# -> (# s2#, () #)
849 #else
850 writeInt64OffAddr (A# a#) (I# i#) (I64# w#) = IO $ \ s# ->
851       case (writeInt64OffAddr#  a# i# w# s#) of s2# -> (# s2#, () #)
852 #endif
853 \end{code}
854
855 Miscellaneous Utilities
856
857 \begin{code}
858 absReal :: (Ord a, Num a) => a -> a
859 absReal x    | x >= 0    = x
860              | otherwise = -x
861
862 signumReal :: (Ord a, Num a) => a -> a
863 signumReal x | x == 0    =  0
864              | x > 0     =  1
865              | otherwise = -1
866 \end{code}