[project @ 2005-01-28 23:33:57 by krasimir]
[haskell-directory.git] / cbits / longlong.c
1 /* -----------------------------------------------------------------------------
2  * $Id: longlong.c,v 1.4 2002/12/13 14:23:42 simonmar Exp $
3  *
4  * (c) The GHC Team, 1998-1999
5  *
6  * Primitive operations over (64-bit) long longs
7  * (only used on 32-bit platforms.)
8  *
9  * ---------------------------------------------------------------------------*/
10
11
12 /*
13 Miscellaneous primitive operations on StgInt64 and StgWord64s.
14 N.B. These are not primops!
15
16 Instead of going the normal (boring) route of making the list
17 of primitive operations even longer to cope with operations
18 over 64-bit entities, we implement them instead 'out-of-line'.
19
20 The primitive ops get their own routine (in C) that implements
21 the operation, requiring the caller to _ccall_ out. This has
22 performance implications of course, but we currently don't
23 expect intensive use of either Int64 or Word64 types.
24
25 The exceptions to the rule are primops that cast to and from
26 64-bit entities (these are defined in PrimOps.h)
27 */
28
29 #include "Rts.h"
30
31 #ifdef SUPPORT_LONG_LONGS
32
33 /* Relational operators */
34
35 StgBool stg_gtWord64 (StgWord64 a, StgWord64 b) {return a >  b;}
36 StgBool stg_geWord64 (StgWord64 a, StgWord64 b) {return a >= b;}
37 StgBool stg_eqWord64 (StgWord64 a, StgWord64 b) {return a == b;}
38 StgBool stg_neWord64 (StgWord64 a, StgWord64 b) {return a != b;}
39 StgBool stg_ltWord64 (StgWord64 a, StgWord64 b) {return a <  b;}
40 StgBool stg_leWord64 (StgWord64 a, StgWord64 b) {return a <= b;}
41
42 StgBool stg_gtInt64 (StgInt64 a, StgInt64 b) {return a >  b;}
43 StgBool stg_geInt64 (StgInt64 a, StgInt64 b) {return a >= b;}
44 StgBool stg_eqInt64 (StgInt64 a, StgInt64 b) {return a == b;}
45 StgBool stg_neInt64 (StgInt64 a, StgInt64 b) {return a != b;}
46 StgBool stg_ltInt64 (StgInt64 a, StgInt64 b) {return a <  b;}
47 StgBool stg_leInt64 (StgInt64 a, StgInt64 b) {return a <= b;}
48
49 /* Arithmetic operators */
50
51 StgWord64 stg_remWord64  (StgWord64 a, StgWord64 b) {return a % b;}
52 StgWord64 stg_quotWord64 (StgWord64 a, StgWord64 b) {return a / b;}
53 StgInt64 stg_remInt64    (StgInt64 a, StgInt64 b)   {return a % b;}
54 StgInt64 stg_quotInt64   (StgInt64 a, StgInt64 b)   {return a / b;}
55 StgInt64 stg_negateInt64 (StgInt64 a)               {return -a;}
56 StgInt64 stg_plusInt64   (StgInt64 a, StgInt64 b)   {return a + b;}
57 StgInt64 stg_minusInt64  (StgInt64 a, StgInt64 b)   {return a - b;}
58 StgInt64 stg_timesInt64  (StgInt64 a, StgInt64 b)   {return a * b;}
59
60 /* Logical operators: */
61
62 StgWord64 stg_and64      (StgWord64 a, StgWord64 b) {return a & b;}
63 StgWord64 stg_or64       (StgWord64 a, StgWord64 b) {return a | b;}
64 StgWord64 stg_xor64      (StgWord64 a, StgWord64 b) {return a ^ b;}
65 StgWord64 stg_not64      (StgWord64 a)              {return ~a;}
66 StgWord64 stg_uncheckedShiftL64   (StgWord64 a, StgInt b)    {return a << b;}
67 StgWord64 stg_uncheckedShiftRL64  (StgWord64 a, StgInt b)    {return a >> b;}
68 /* Right shifting of signed quantities is not portable in C, so
69    the behaviour you'll get from using these primops depends
70    on the whatever your C compiler is doing. ToDo: fix. -- sof 8/98
71 */
72 StgInt64  stg_uncheckedIShiftL64  (StgInt64 a,  StgInt b)    {return a << b;}
73 StgInt64  stg_uncheckedIShiftRA64 (StgInt64 a,  StgInt b)    {return a >> b;}
74 StgInt64  stg_uncheckedIShiftRL64 (StgInt64 a,  StgInt b)
75 {return (StgInt64) ((StgWord64) a >> b);}
76
77 /* Casting between longs and longer longs.
78    (the primops that cast from long longs to Integers
79    expressed as macros, since these may cause some heap allocation).
80 */
81
82 StgInt64  stg_intToInt64    (StgInt    i) {return (StgInt64)  i;}
83 StgInt    stg_int64ToInt    (StgInt64  i) {return (StgInt)    i;}
84 StgWord64 stg_int64ToWord64 (StgInt64  i) {return (StgWord64) i;}
85 StgWord64 stg_wordToWord64  (StgWord   w) {return (StgWord64) w;}
86 StgWord   stg_word64ToWord  (StgWord64 w) {return (StgWord)   w;}
87 StgInt64  stg_word64ToInt64 (StgWord64 w) {return (StgInt64)  w;}
88
89 StgWord64 stg_integerToWord64 (I_ sa, StgByteArray /* Really: mp_limb_t* */ da)
90
91   mp_limb_t* d;
92   I_ s;
93   StgWord64 res;
94   d = (mp_limb_t *)da;
95   s = sa;
96   switch (s) {
97     case  0: res = 0;     break;
98     case  1: res = d[0];  break;
99     case -1: res = -(StgWord64)d[0]; break;
100     default:
101       res = (StgWord64)d[0] + ((StgWord64)d[1] << (BITS_IN (mp_limb_t)));
102       if (s < 0) res = -res;
103   }
104   return res;
105 }
106
107 StgInt64 stg_integerToInt64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ da)
108
109   mp_limb_t* d;
110   I_ s;
111   StgInt64 res;
112   d = (mp_limb_t *)da;
113   s = (sa);
114   switch (s) {
115     case  0: res = 0;     break;
116     case  1: res = d[0];  break;
117     case -1: res = -(StgInt64)d[0]; break;
118     default:
119       res = (StgInt64)d[0] + ((StgWord64)d[1] << (BITS_IN (mp_limb_t)));
120       if (s < 0) res = -res;
121   }
122   return res;
123 }
124
125 #endif /* SUPPORT_LONG_LONGS */