Digi XBee(R) ANSI C Host Library
jslong.h
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This is a modified version of jslong.h Rev 3.13 from mozilla.org, with as
3  few changes as possible. The original file is available here:
4  http://mxr.mozilla.org/mozilla/source/js/src/jslong.h
5 
6  Do not include it directly, as it requires glue macros and typedefs defined
7  in xbee/platform.h (which includes it automatically).
8 */
9 /* ***** BEGIN LICENSE BLOCK *****
10  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
11  *
12  * The contents of this file are subject to the Mozilla Public License Version
13  * 1.1 (the "License"); you may not use this file except in compliance with
14  * the License. You may obtain a copy of the License at
15  * http://www.mozilla.org/MPL/
16  *
17  * Software distributed under the License is distributed on an "AS IS" basis,
18  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
19  * for the specific language governing rights and limitations under the
20  * License.
21  *
22  * The Original Code is Mozilla Communicator client code, released
23  * March 31, 1998.
24  *
25  * The Initial Developer of the Original Code is
26  * Netscape Communications Corporation.
27  * Portions created by the Initial Developer are Copyright (C) 1998
28  * the Initial Developer. All Rights Reserved.
29  *
30  * Contributor(s):
31  *
32  * Alternatively, the contents of this file may be used under the terms of
33  * either of the GNU General Public License Version 2 or later (the "GPL"),
34  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
35  * in which case the provisions of the GPL or the LGPL are applicable instead
36  * of those above. If you wish to allow use of your version of this file only
37  * under the terms of either the GPL or the LGPL, and not to allow others to
38  * use your version of this file under the terms of the MPL, indicate your
39  * decision by deleting the provisions above and replace them with the notice
40  * and other provisions required by the GPL or the LGPL. If you do not delete
41  * the provisions above, a recipient may use your version of this file under
42  * the terms of any one of the MPL, the GPL or the LGPL.
43  *
44  * ***** END LICENSE BLOCK ***** */
45 
46 /*
47 ** File: jslong.h
48 ** Description: Portable access to 64 bit numerics
49 **
50 ** Long-long (64-bit signed integer type) support. Some C compilers
51 ** don't support 64 bit integers yet, so we use these macros to
52 ** support both machines that do and don't.
53 **/
54 #ifndef jslong_h___
55 #define jslong_h___
56 
57 #ifdef JS_HAVE_LONG_LONG
58 
59 #define JSLL_INIT(hi, lo) ((UINT64_C(hi) << 32) + UINT64_C(lo))
60 
61 /***********************************************************************
62 ** MACROS: JSLL_*
63 ** DESCRIPTION:
64 ** The following macros define portable access to the 64 bit
65 ** math facilities.
66 **
67 ***********************************************************************/
68 
69 /***********************************************************************
70 ** MACROS: JSLL_<relational operators>
71 **
72 ** JSLL_IS_ZERO Test for zero
73 ** JSLL_EQ Test for equality
74 ** JSLL_NE Test for inequality
75 ** JSLL_GE_ZERO Test for zero or positive
76 ** JSLL_CMP Compare two values
77 ***********************************************************************/
78 #define JSLL_IS_ZERO(a) ((a) == 0)
79 #define JSLL_EQ(a, b) ((a) == (b))
80 #define JSLL_NE(a, b) ((a) != (b))
81 #define JSLL_GE_ZERO(a) ((a) >= 0)
82 #define JSLL_CMP(a, op, b) ((JSInt64)(a) op (JSInt64)(b))
83 #define JSLL_UCMP(a, op, b) ((JSUint64)(a) op (JSUint64)(b))
84 
85 /***********************************************************************
86 ** MACROS: JSLL_<logical operators>
87 **
88 ** JSLL_AND Logical and
89 ** JSLL_OR Logical or
90 ** JSLL_XOR Logical exclusion
91 ** JSLL_OR2 A disgusting deviation
92 ** JSLL_NOT Negation (one's compliment)
93 ***********************************************************************/
94 #define JSLL_AND(r, a, b) ((r) = (a) & (b))
95 #define JSLL_OR(r, a, b) ((r) = (a) | (b))
96 #define JSLL_XOR(r, a, b) ((r) = (a) ^ (b))
97 #define JSLL_OR2(r, a) ((r) = (r) | (a))
98 #define JSLL_NOT(r, a) ((r) = ~(a))
99 
100 /***********************************************************************
101 ** MACROS: JSLL_<mathematical operators>
102 **
103 ** JSLL_NEG Negation (two's compliment)
104 ** JSLL_ADD Summation (two's compliment)
105 ** JSLL_SUB Difference (two's compliment)
106 ***********************************************************************/
107 #define JSLL_NEG(r, a) ((r) = -(a))
108 #define JSLL_ADD(r, a, b) ((r) = (a) + (b))
109 #define JSLL_SUB(r, a, b) ((r) = (a) - (b))
110 
111 /***********************************************************************
112 ** MACROS: JSLL_<mathematical operators>
113 **
114 ** JSLL_MUL Product (two's compliment)
115 ** JSLL_MUL32 64-bit product of two unsigned 32-bit integers
116 ** JSLL_DIV Quotient (two's compliment)
117 ** JSLL_MOD Modulus (two's compliment)
118 ***********************************************************************/
119 #define JSLL_MUL(r, a, b) ((r) = (a) * (b))
120 #define JSLL_MUL32(r, a, b) ((r) = (JSUint64)(a) * (JSUint32)(b))
121 #define JSLL_DIV(r, a, b) ((r) = (a) / (b))
122 #define JSLL_MOD(r, a, b) ((r) = (a) % (b))
123 
124 /***********************************************************************
125 ** MACROS: JSLL_<shifting operators>
126 **
127 ** JSLL_SHL Shift left [0..64] bits
128 ** JSLL_SHR Shift right [0..64] bits with sign extension
129 ** JSLL_USHR Unsigned shift right [0..64] bits
130 ** (consider renaming to LSR and ASR for logical and arithmetic shift right)
131 ** JSLL_ISHL Integer (32-bit) shift left [0..64] bits
132 ***********************************************************************/
133 #define JSLL_SHL(r, a, b) ((r) = (JSInt64)(a) << (b))
134 #define JSLL_SHR(r, a, b) ((r) = (JSInt64)(a) >> (b))
135 #define JSLL_USHR(r, a, b) ((r) = (JSUint64)(a) >> (b))
136 #define JSLL_ISHL(r, a, b) ((r) = (JSInt64)(a) << (b))
137 
138 /***********************************************************************
139 ** MACROS: JSLL_<conversion operators>
140 **
141 ** JSLL_L2I Convert 64-bit to signed 32-bit
142 ** JSLL_L2UI Convert 64-bit to unsigned 32-bit
143 ** JSLL_L2F Convert 64-bit to float
144 ** JSLL_L2D Convert 64-bit to double
145 ** JSLL_I2L Convert signed 32-bit to 64-bit
146 ** JSLL_UI2L Convert unsigned 32-bit to 64-bit
147 ** JSLL_F2L Convert float to 64-bit
148 ** JSLL_D2L Convert double to 64-bit
149 ***********************************************************************/
150 #define JSLL_L2I(i, l) ((i) = (JSInt32)(l))
151 #define JSLL_L2UI(ui, l) ((ui) = (JSUint32)(l))
152 #define JSLL_L2F(f, l) ((f) = (JSFloat64)(l))
153 #define JSLL_L2D(d, l) ((d) = (JSFloat64)(l))
154 
155 #define JSLL_I2L(l, i) ((l) = (JSInt64)(i))
156 #define JSLL_UI2L(l, ui) ((l) = (JSInt64)(ui))
157 #define JSLL_F2L(l, f) ((l) = (JSInt64)(f))
158 #define JSLL_D2L(l, d) ((l) = (JSInt64)(d))
159 
160 /***********************************************************************
161 ** MACROS: JSLL_UDIVMOD
162 ** DESCRIPTION:
163 ** Produce both a quotient and a remainder given an unsigned
164 ** INPUTS: JSUint64 a: The dividend of the operation
165 ** JSUint64 b: The quotient of the operation
166 ** OUTPUTS: JSUint64 *qp: pointer to quotient
167 ** JSUint64 *rp: pointer to remainder
168 ***********************************************************************/
169 #define JSLL_UDIVMOD(qp, rp, a, b) \
170  (*(qp) = ((JSUint64)(a) / (b)), \
171  *(rp) = ((JSUint64)(a) % (b)))
172 
173 /***********************************************************************
174 ** MACROS: JSLL_HEXSTR, JSLL_DECSTR
175 ** DESCRIPTION:
176 ** Convert 64-bit value to hexadecimal or decimal string.
177 ** JSLL_HEXSTR Convert to (lowercase) hexadecimal string, padded
178 ** with zeros to 16 characters
179 ** JSLL_DECSTR Convert signed value to decimal string
180 ** JSLL_UDECSTR Convert unsigned value to decimal string
181 **
182 ** Returns number of characters written to buffer.
183 ***********************************************************************/
184 #define JSLL_HEXSTR(s, a) sprintf( s, "%016" PRIx64, a)
185 #define JSLL_DECSTR(s, a) sprintf( s, "%" PRId64, a)
186 #define JSLL_UDECSTR(s, a) sprintf( s, "%" PRIu64, a)
187 
188 #else /* !JS_HAVE_LONG_LONG */
189 
190 #ifdef IS_LITTLE_ENDIAN
191 #define JSLL_INIT(hi, lo) { lo, hi }
192 #else
193 #define JSLL_INIT(hi, lo) { hi, lo }
194 #endif
195 
196 #define JSLL_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0))
197 #define JSLL_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo))
198 #define JSLL_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo))
199 #define JSLL_GE_ZERO(a) (((a).hi >> 31) == 0)
200 
201 #ifdef DEBUG
202 #define JSLL_CMP(a, op, b) (JS_ASSERT((#op)[1] != '='), JSLL_REAL_CMP(a, op, b))
203 #define JSLL_UCMP(a, op, b) (JS_ASSERT((#op)[1] != '='), JSLL_REAL_UCMP(a, op, b))
204 #else
205 #define JSLL_CMP(a, op, b) JSLL_REAL_CMP(a, op, b)
206 #define JSLL_UCMP(a, op, b) JSLL_REAL_UCMP(a, op, b)
207 #endif
208 
209 #define JSLL_REAL_CMP(a,op,b) (((JSInt32)(a).hi op (JSInt32)(b).hi) || \
210  (((a).hi == (b).hi) && ((a).lo op (b).lo)))
211 #define JSLL_REAL_UCMP(a,op,b) (((a).hi op (b).hi) || \
212  (((a).hi == (b).hi) && ((a).lo op (b).lo)))
213 
214 #define JSLL_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \
215  (r).hi = (a).hi & (b).hi)
216 #define JSLL_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \
217  (r).hi = (a).hi | (b).hi)
218 #define JSLL_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \
219  (r).hi = (a).hi ^ (b).hi)
220 #define JSLL_OR2(r, a) ((r).lo = (r).lo | (a).lo, \
221  (r).hi = (r).hi | (a).hi)
222 #define JSLL_NOT(r, a) ((r).lo = ~(a).lo, \
223  (r).hi = ~(a).hi)
224 
225 #define JSLL_NEG(r, a) ((r).lo = -(JSInt32)(a).lo, \
226  (r).hi = -(JSInt32)(a).hi - ((r).lo != 0))
227 #define JSLL_ADD(r, a, b) { \
228  JSUint32 t; \
229  t = (a).lo + (b).lo; \
230  (r).hi = (a).hi + (b).hi + (t < (b).lo); \
231  (r).lo = t; \
232 }
233 
234 #define JSLL_SUB(r, a, b) { \
235  (r).hi = (a).hi - (b).hi - ((a).lo < (b).lo); \
236  (r).lo = (a).lo - (b).lo; \
237 }
238 
239 #define JSLL_MUL(r, a, b) jsll_mul( &(r), a, b)
240 void jsll_mul(JSUint64 *rp, JSUint64 a, JSUint64 b);
241 
242 #define JSLL_MUL32(r, a, b) jsll_mul32( &(r), a, b)
243 void jsll_mul32(JSUint64 *rp, JSUint32 a, JSUint32 b);
244 
245 #define JSLL_UDIVMOD(qp, rp, a, b) jsll_udivmod(qp, rp, a, b)
246 void jsll_udivmod(JSUint64 *qp, JSUint64 *rp, JSUint64 a, JSUint64 b);
247 
248 #define JSLL_DIV(r, a, b) jsll_div( &(r), &(a), &(b))
249 void jsll_div( JSUint64 *r, const JSUint64 *a, const JSUint64 *b);
250 
251 #define JSLL_MOD(r, a, b) jsll_mod( &(r), &(a), &(b))
252 void jsll_mod( JSUint64 *r, const JSUint64 *a, const JSUint64 *b);
253 
254 /* a is an JSInt32, b is JSInt32, r is JSInt64 */
255 #define JSLL_ISHL(r, a, b) { \
256  if (b) { \
257  if ((b) < 32) { \
258  (r).lo = (a) << ((b) & 31); \
259  (r).hi = ((a) >> (32 - (b))); \
260  } else { \
261  (r).lo = 0; \
262  (r).hi = (a) << ((b) & 31); \
263  } \
264  } else { \
265  (r).lo = (a); \
266  (r).hi = 0; \
267  } \
268 }
269 
270 #define JSLL_SHL(r, a, b) jsll_shl( &(r), a, b)
271 #define JSLL_SHR(r, a, b) jsll_shr( &(r), a, b)
272 #define JSLL_USHR(r, a, b) jsll_ushr( &(r), a, b)
273 
274 void jsll_shl( JSUint64 *r, JSUint64 a, uint_fast8_t b);
275 void jsll_shr( JSInt64 *r, JSInt64 a, uint_fast8_t b);
276 void jsll_ushr( JSUint64 *r, JSUint64 a, uint_fast8_t b);
277 
278 #define JSLL_L2I(i, l) ((i) = (l).lo)
279 #define JSLL_L2UI(ui, l) ((ui) = (l).lo)
280 #define JSLL_L2F(f, l) { double _d; JSLL_L2D(_d, l); (f) = (JSFloat64)_d; }
281 
282 #define JSLL_L2D(d, l) { \
283  bool_t _negative; \
284  JSInt64 _absval; \
285  \
286  _negative = (JSInt32)(l).hi < 0; \
287  if (_negative) { \
288  JSLL_NEG(_absval, l); \
289  } else { \
290  _absval = l; \
291  } \
292  (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \
293  if (_negative) \
294  (d) = -(d); \
295 }
296 
297 #define JSLL_I2L(l, i) {(l).lo = (i); (l).hi = (JSInt32)(i) >> 31; }
298 #define JSLL_UI2L(l, ui) ((l).lo = (ui), (l).hi = 0)
299 #define JSLL_F2L(l, f) { double _d = (double)f; JSLL_D2L(l, _d); }
300 
301 #define JSLL_D2L(l, d) { \
302  int _negative; \
303  double _absval, _d_hi; \
304  JSInt64 _lo_d; \
305  \
306  _negative = ((d) < 0); \
307  _absval = _negative ? -(d) : (d); \
308  \
309  (l).hi = _absval / 4.294967296e9; \
310  (l).lo = 0; \
311  JSLL_L2D(_d_hi, l); \
312  _absval -= _d_hi; \
313  _lo_d.hi = 0; \
314  if (_absval < 0) { \
315  _lo_d.lo = -_absval; \
316  JSLL_SUB(l, l, _lo_d); \
317  } else { \
318  _lo_d.lo = _absval; \
319  JSLL_ADD(l, l, _lo_d); \
320  } \
321  \
322  if (_negative) \
323  JSLL_NEG(l, l); \
324 }
325 
326 #define JSLL_HEXSTR(s, a) \
327  sprintf( s, "%08" PRIx32 "%08" PRIx32, (a).hi, (a).lo)
328 #define JSLL_DECSTR(s, a) jsll_decstr( s, &(a))
329 #define JSLL_UDECSTR(s, a) jsll_udecstr( s, &(a))
330 
331 int jsll_decstr( char *buffer, const JSInt64 *v);
332 int jsll_udecstr( char *buffer, const JSUint64 *v);
333 
334 #endif /* !JS_HAVE_LONG_LONG */
335 
336 #endif /* jslong_h___ */
Definition: jslong_glue.h:30