• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /*
3  * The contents of this file are subject to the Mozilla Public
4  * License Version 1.1 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of
6  * the License at http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS
9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10  * implied. See the License for the specific language governing
11  * rights and limitations under the License.
12  *
13  * The Original Code is the Netscape Portable Runtime (NSPR).
14  *
15  * The Initial Developer of the Original Code is Netscape
16  * Communications Corporation.  Portions created by Netscape are
17  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
18  * Rights Reserved.
19  *
20  * Contributor(s):
21  *
22  * Alternatively, the contents of this file may be used under the
23  * terms of the GNU General Public License Version 2 or later (the
24  * "GPL"), in which case the provisions of the GPL are applicable
25  * instead of those above.  If you wish to allow use of your
26  * version of this file only under the terms of the GPL and not to
27  * allow others to use your version of this file under the MPL,
28  * indicate your decision by deleting the provisions above and
29  * replace them with the notice and other provisions required by
30  * the GPL.  If you do not delete the provisions above, a recipient
31  * may use your version of this file under either the MPL or the
32  * GPL.
33  */
34 
35 /*
36 ** File:                prlong.h
37 ** Description: Portable access to 64 bit numerics
38 **
39 ** Long-long (64-bit signed integer type) support. Some C compilers
40 ** don't support 64 bit integers yet, so we use these macros to
41 ** support both machines that do and don't.
42 **/
43 #ifndef prlong_h___
44 #define prlong_h___
45 
46 #include "prtypes.h"
47 
48 PR_BEGIN_EXTERN_C
49 
50 /***********************************************************************
51 ** DEFINES:     LL_MaxInt
52 **              LL_MinInt
53 **              LL_Zero
54 **              LL_MaxUint
55 ** DESCRIPTION:
56 **      Various interesting constants and static variable
57 **      initializer
58 ***********************************************************************/
59 #if defined(HAVE_WATCOM_BUG_2)
60 PRInt64 __pascal __loadds __export
61     LL_MaxInt(void);
62 PRInt64 __pascal __loadds __export
63     LL_MinInt(void);
64 PRInt64 __pascal __loadds __export
65     LL_Zero(void);
66 PRUint64 __pascal __loadds __export
67     LL_MaxUint(void);
68 #else
69 NSPR_API(PRInt64) LL_MaxInt(void);
70 NSPR_API(PRInt64) LL_MinInt(void);
71 NSPR_API(PRInt64) LL_Zero(void);
72 NSPR_API(PRUint64) LL_MaxUint(void);
73 #endif
74 
75 #define LL_MAXINT   LL_MaxInt()
76 #define LL_MININT   LL_MinInt()
77 #define LL_ZERO     LL_Zero()
78 #define LL_MAXUINT  LL_MaxUint()
79 
80 #if defined(HAVE_LONG_LONG)
81 
82 #if PR_BYTES_PER_LONG == 8
83 #define LL_INIT(hi, lo)  ((hi ## L << 32) + lo ## L)
84 #elif (defined(WIN32) || defined(WIN16)) && !defined(__GNUC__)
85 #define LL_INIT(hi, lo)  ((hi ## i64 << 32) + lo ## i64)
86 #else
87 #define LL_INIT(hi, lo)  ((hi ## LL << 32) + lo ## LL)
88 #endif
89 
90 /***********************************************************************
91 ** MACROS:      LL_*
92 ** DESCRIPTION:
93 **      The following macros define portable access to the 64 bit
94 **      math facilities.
95 **
96 ***********************************************************************/
97 
98 /***********************************************************************
99 ** MACROS:      LL_<relational operators>
100 **
101 **  LL_IS_ZERO        Test for zero
102 **  LL_EQ             Test for equality
103 **  LL_NE             Test for inequality
104 **  LL_GE_ZERO        Test for zero or positive
105 **  LL_CMP            Compare two values
106 ***********************************************************************/
107 #define LL_IS_ZERO(a)       ((a) == 0)
108 #define LL_EQ(a, b)         ((a) == (b))
109 #define LL_NE(a, b)         ((a) != (b))
110 #define LL_GE_ZERO(a)       ((a) >= 0)
111 #define LL_CMP(a, op, b)    ((PRInt64)(a) op (PRInt64)(b))
112 #define LL_UCMP(a, op, b)   ((PRUint64)(a) op (PRUint64)(b))
113 
114 /***********************************************************************
115 ** MACROS:      LL_<logical operators>
116 **
117 **  LL_AND            Logical and
118 **  LL_OR             Logical or
119 **  LL_XOR            Logical exclusion
120 **  LL_OR2            A disgusting deviation
121 **  LL_NOT            Negation (one's complement)
122 ***********************************************************************/
123 #define LL_AND(r, a, b)        ((r) = (a) & (b))
124 #define LL_OR(r, a, b)        ((r) = (a) | (b))
125 #define LL_XOR(r, a, b)        ((r) = (a) ^ (b))
126 #define LL_OR2(r, a)        ((r) = (r) | (a))
127 #define LL_NOT(r, a)        ((r) = ~(a))
128 
129 /***********************************************************************
130 ** MACROS:      LL_<mathematical operators>
131 **
132 **  LL_NEG            Negation (two's complement)
133 **  LL_ADD            Summation (two's complement)
134 **  LL_SUB            Difference (two's complement)
135 ***********************************************************************/
136 #define LL_NEG(r, a)        ((r) = -(a))
137 #define LL_ADD(r, a, b)     ((r) = (a) + (b))
138 #define LL_SUB(r, a, b)     ((r) = (a) - (b))
139 
140 /***********************************************************************
141 ** MACROS:      LL_<mathematical operators>
142 **
143 **  LL_MUL            Product (two's complement)
144 **  LL_DIV            Quotient (two's complement)
145 **  LL_MOD            Modulus (two's complement)
146 ***********************************************************************/
147 #define LL_MUL(r, a, b)        ((r) = (a) * (b))
148 #define LL_DIV(r, a, b)        ((r) = (a) / (b))
149 #define LL_MOD(r, a, b)        ((r) = (a) % (b))
150 
151 /***********************************************************************
152 ** MACROS:      LL_<shifting operators>
153 **
154 **  LL_SHL            Shift left [0..64] bits
155 **  LL_SHR            Shift right [0..64] bits with sign extension
156 **  LL_USHR           Unsigned shift right [0..64] bits
157 **  LL_ISHL           Signed shift left [0..64] bits
158 ***********************************************************************/
159 #define LL_SHL(r, a, b)     ((r) = (PRInt64)(a) << (b))
160 #define LL_SHR(r, a, b)     ((r) = (PRInt64)(a) >> (b))
161 #define LL_USHR(r, a, b)    ((r) = (PRUint64)(a) >> (b))
162 #define LL_ISHL(r, a, b)    ((r) = (PRInt64)(a) << (b))
163 
164 /***********************************************************************
165 ** MACROS:      LL_<conversion operators>
166 **
167 **  LL_L2I            Convert to signed 32 bit
168 **  LL_L2UI           Convert to unsigned 32 bit
169 **  LL_L2F            Convert to floating point
170 **  LL_L2D            Convert to floating point
171 **  LL_I2L            Convert signed to 64 bit
172 **  LL_UI2L           Convert unsigned to 64 bit
173 **  LL_F2L            Convert float to 64 bit
174 **  LL_D2L            Convert float to 64 bit
175 ***********************************************************************/
176 #define LL_L2I(i, l)        ((i) = (PRInt32)(l))
177 #define LL_L2UI(ui, l)        ((ui) = (PRUint32)(l))
178 #define LL_L2F(f, l)        ((f) = (PRFloat64)(l))
179 #define LL_L2D(d, l)        ((d) = (PRFloat64)(l))
180 
181 #define LL_I2L(l, i)        ((l) = (PRInt64)(i))
182 #define LL_UI2L(l, ui)        ((l) = (PRInt64)(ui))
183 #define LL_F2L(l, f)        ((l) = (PRInt64)(f))
184 #define LL_D2L(l, d)        ((l) = (PRInt64)(d))
185 
186 /***********************************************************************
187 ** MACROS:      LL_UDIVMOD
188 ** DESCRIPTION:
189 **  Produce both a quotient and a remainder given an unsigned
190 ** INPUTS:      PRUint64 a: The dividend of the operation
191 **              PRUint64 b: The quotient of the operation
192 ** OUTPUTS:     PRUint64 *qp: pointer to quotient
193 **              PRUint64 *rp: pointer to remainder
194 ***********************************************************************/
195 #define LL_UDIVMOD(qp, rp, a, b) \
196     (*(qp) = ((PRUint64)(a) / (b)), \
197      *(rp) = ((PRUint64)(a) % (b)))
198 
199 #else  /* !HAVE_LONG_LONG */
200 
201 #ifdef IS_LITTLE_ENDIAN
202 #define LL_INIT(hi, lo) {PR_INT32(lo), PR_INT32(hi)}
203 #else
204 #define LL_INIT(hi, lo) {PR_INT32(hi), PR_INT32(lo)}
205 #endif
206 
207 #define LL_IS_ZERO(a)        (((a).hi == 0) && ((a).lo == 0))
208 #define LL_EQ(a, b)        (((a).hi == (b).hi) && ((a).lo == (b).lo))
209 #define LL_NE(a, b)        (((a).hi != (b).hi) || ((a).lo != (b).lo))
210 #define LL_GE_ZERO(a)        (((a).hi >> 31) == 0)
211 
212 #define LL_CMP(a, op, b)    (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
213                  ((PRInt32)(a).hi op (PRInt32)(b).hi))
214 #define LL_UCMP(a, op, b)    (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
215                  ((a).hi op (b).hi))
216 
217 #define LL_AND(r, a, b)        ((r).lo = (a).lo & (b).lo, \
218                  (r).hi = (a).hi & (b).hi)
219 #define LL_OR(r, a, b)        ((r).lo = (a).lo | (b).lo, \
220                  (r).hi = (a).hi | (b).hi)
221 #define LL_XOR(r, a, b)        ((r).lo = (a).lo ^ (b).lo, \
222                  (r).hi = (a).hi ^ (b).hi)
223 #define LL_OR2(r, a)        ((r).lo = (r).lo | (a).lo, \
224                  (r).hi = (r).hi | (a).hi)
225 #define LL_NOT(r, a)        ((r).lo = ~(a).lo, \
226                  (r).hi = ~(a).hi)
227 
228 #define LL_NEG(r, a)        ((r).lo = -(PRInt32)(a).lo, \
229                  (r).hi = -(PRInt32)(a).hi - ((r).lo != 0))
230 #define LL_ADD(r, a, b) { \
231     PRInt64 _a, _b; \
232     _a = a; _b = b; \
233     (r).lo = _a.lo + _b.lo; \
234     (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \
235 }
236 
237 #define LL_SUB(r, a, b) { \
238     PRInt64 _a, _b; \
239     _a = a; _b = b; \
240     (r).lo = _a.lo - _b.lo; \
241     (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \
242 }
243 
244 #define LL_MUL(r, a, b) { \
245     PRInt64 _a, _b; \
246     _a = a; _b = b; \
247     LL_MUL32(r, _a.lo, _b.lo); \
248     (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \
249 }
250 
251 #define _lo16(a)        ((a) & PR_BITMASK(16))
252 #define _hi16(a)        ((a) >> 16)
253 
254 #define LL_MUL32(r, a, b) { \
255      PRUint32 _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \
256      _a1 = _hi16(a), _a0 = _lo16(a); \
257      _b1 = _hi16(b), _b0 = _lo16(b); \
258      _y0 = _a0 * _b0; \
259      _y1 = _a0 * _b1; \
260      _y2 = _a1 * _b0; \
261      _y3 = _a1 * _b1; \
262      _y1 += _hi16(_y0);                         /* can't carry */ \
263      _y1 += _y2;                                /* might carry */ \
264      if (_y1 < _y2)    \
265         _y3 += (PRUint32)(PR_BIT(16));  /* propagate */ \
266      (r).lo = (_lo16(_y1) << 16) + _lo16(_y0); \
267      (r).hi = _y3 + _hi16(_y1); \
268 }
269 
270 #define LL_UDIVMOD(qp, rp, a, b)    ll_udivmod(qp, rp, a, b)
271 
272 NSPR_API(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b);
273 
274 #define LL_DIV(r, a, b) { \
275     PRInt64 _a, _b; \
276     PRUint32 _negative = (PRInt32)(a).hi < 0; \
277     if (_negative) { \
278     LL_NEG(_a, a); \
279     } else { \
280     _a = a; \
281     } \
282     if ((PRInt32)(b).hi < 0) { \
283     _negative ^= 1; \
284     LL_NEG(_b, b); \
285     } else { \
286     _b = b; \
287     } \
288     LL_UDIVMOD(&(r), 0, _a, _b); \
289     if (_negative) \
290     LL_NEG(r, r); \
291 }
292 
293 #define LL_MOD(r, a, b) { \
294     PRInt64 _a, _b; \
295     PRUint32 _negative = (PRInt32)(a).hi < 0; \
296     if (_negative) { \
297     LL_NEG(_a, a); \
298     } else { \
299     _a = a; \
300     } \
301     if ((PRInt32)(b).hi < 0) { \
302     LL_NEG(_b, b); \
303     } else { \
304     _b = b; \
305     } \
306     LL_UDIVMOD(0, &(r), _a, _b); \
307     if (_negative) \
308     LL_NEG(r, r); \
309 }
310 
311 #define LL_SHL(r, a, b) { \
312     if (b) { \
313     PRInt64 _a; \
314         _a = a; \
315         if ((b) < 32) { \
316         (r).lo = _a.lo << ((b) & 31); \
317         (r).hi = (_a.hi << ((b) & 31)) | (_a.lo >> (32 - (b))); \
318     } else { \
319         (r).lo = 0; \
320         (r).hi = _a.lo << ((b) & 31); \
321     } \
322     } else { \
323     (r) = (a); \
324     } \
325 }
326 
327 /* a is an PRInt32, b is PRInt32, r is PRInt64 */
328 #define LL_ISHL(r, a, b) { \
329     if (b) { \
330     PRInt64 _a; \
331     _a.lo = (a); \
332     _a.hi = 0; \
333         if ((b) < 32) { \
334         (r).lo = (a) << ((b) & 31); \
335         (r).hi = ((a) >> (32 - (b))); \
336     } else { \
337         (r).lo = 0; \
338         (r).hi = (a) << ((b) & 31); \
339     } \
340     } else { \
341     (r).lo = (a); \
342     (r).hi = 0; \
343     } \
344 }
345 
346 #define LL_SHR(r, a, b) { \
347     if (b) { \
348     PRInt64 _a; \
349         _a = a; \
350     if ((b) < 32) { \
351         (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
352         (r).hi = (PRInt32)_a.hi >> ((b) & 31); \
353     } else { \
354         (r).lo = (PRInt32)_a.hi >> ((b) & 31); \
355         (r).hi = (PRInt32)_a.hi >> 31; \
356     } \
357     } else { \
358     (r) = (a); \
359     } \
360 }
361 
362 #define LL_USHR(r, a, b) { \
363     if (b) { \
364     PRInt64 _a; \
365         _a = a; \
366     if ((b) < 32) { \
367         (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> ((b) & 31)); \
368         (r).hi = _a.hi >> ((b) & 31); \
369     } else { \
370         (r).lo = _a.hi >> ((b) & 31); \
371         (r).hi = 0; \
372     } \
373     } else { \
374     (r) = (a); \
375     } \
376 }
377 
378 #define LL_L2I(i, l)        ((i) = (l).lo)
379 #define LL_L2UI(ui, l)        ((ui) = (l).lo)
380 #define LL_L2F(f, l)        { double _d; LL_L2D(_d, l); (f) = (PRFloat64)_d; }
381 
382 #define LL_L2D(d, l) { \
383     int _negative; \
384     PRInt64 _absval; \
385  \
386     _negative = (l).hi >> 31; \
387     if (_negative) { \
388     LL_NEG(_absval, l); \
389     } else { \
390     _absval = l; \
391     } \
392     (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
393     if (_negative) \
394     (d) = -(d); \
395 }
396 
397 #define LL_I2L(l, i)        { PRInt32 _i = ((PRInt32)(i)) >> 31; (l).lo = (i); (l).hi = _i; }
398 #define LL_UI2L(l, ui)      ((l).lo = (ui), (l).hi = 0)
399 #define LL_F2L(l, f)        { double _d = (double)f; LL_D2L(l, _d); }
400 
401 #define LL_D2L(l, d) { \
402     int _negative; \
403     double _absval, _d_hi; \
404     PRInt64 _lo_d; \
405  \
406     _negative = ((d) < 0); \
407     _absval = _negative ? -(d) : (d); \
408  \
409     (l).hi = _absval / 4.294967296e9; \
410     (l).lo = 0; \
411     LL_L2D(_d_hi, l); \
412     _absval -= _d_hi; \
413     _lo_d.hi = 0; \
414     if (_absval < 0) { \
415     _lo_d.lo = -_absval; \
416     LL_SUB(l, l, _lo_d); \
417     } else { \
418     _lo_d.lo = _absval; \
419     LL_ADD(l, l, _lo_d); \
420     } \
421  \
422     if (_negative) \
423     LL_NEG(l, l); \
424 }
425 
426 #endif /* !HAVE_LONG_LONG */
427 
428 PR_END_EXTERN_C
429 
430 #endif /* prlong_h___ */
431