|
|
1.1 ! root 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___ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.