|
|
1.1 ! root 1: /* ! 2: * QEMU float support macros ! 3: * ! 4: * The code in this source file is derived from release 2a of the SoftFloat ! 5: * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and ! 6: * some later contributions) are provided under that license, as detailed below. ! 7: * It has subsequently been modified by contributors to the QEMU Project, ! 8: * so some portions are provided under: ! 9: * the SoftFloat-2a license ! 10: * the BSD license ! 11: * GPL-v2-or-later ! 12: * ! 13: * Any future contributions to this file after December 1st 2014 will be ! 14: * taken to be licensed under the Softfloat-2a license unless specifically ! 15: * indicated otherwise. ! 16: */ ! 17: ! 18: /* ! 19: =============================================================================== ! 20: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point ! 21: Arithmetic Package, Release 2a. ! 22: ! 23: Written by John R. Hauser. This work was made possible in part by the ! 24: International Computer Science Institute, located at Suite 600, 1947 Center ! 25: Street, Berkeley, California 94704. Funding was partially provided by the ! 26: National Science Foundation under grant MIP-9311980. The original version ! 27: of this code was written as part of a project to build a fixed-point vector ! 28: processor in collaboration with the University of California at Berkeley, ! 29: overseen by Profs. Nelson Morgan and John Wawrzynek. More information ! 30: is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ ! 31: arithmetic/SoftFloat.html'. ! 32: ! 33: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort ! 34: has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT ! 35: TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO ! 36: PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY ! 37: AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. ! 38: ! 39: Derivative works are acceptable, even for commercial purposes, so long as ! 40: (1) they include prominent notice that the work is derivative, and (2) they ! 41: include prominent notice akin to these four paragraphs for those parts of ! 42: this code that are retained. ! 43: ! 44: =============================================================================== ! 45: */ ! 46: ! 47: /* BSD licensing: ! 48: * Copyright (c) 2006, Fabrice Bellard ! 49: * All rights reserved. ! 50: * ! 51: * Redistribution and use in source and binary forms, with or without ! 52: * modification, are permitted provided that the following conditions are met: ! 53: * ! 54: * 1. Redistributions of source code must retain the above copyright notice, ! 55: * this list of conditions and the following disclaimer. ! 56: * ! 57: * 2. Redistributions in binary form must reproduce the above copyright notice, ! 58: * this list of conditions and the following disclaimer in the documentation ! 59: * and/or other materials provided with the distribution. ! 60: * ! 61: * 3. Neither the name of the copyright holder nor the names of its contributors ! 62: * may be used to endorse or promote products derived from this software without ! 63: * specific prior written permission. ! 64: * ! 65: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ! 66: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 67: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 68: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ! 69: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ! 70: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ! 71: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ! 72: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ! 73: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ! 74: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF ! 75: * THE POSSIBILITY OF SUCH DAMAGE. ! 76: */ ! 77: ! 78: /* Portions of this work are licensed under the terms of the GNU GPL, ! 79: * version 2 or later. See the COPYING file in the top-level directory. ! 80: */ ! 81: ! 82: /*---------------------------------------------------------------------------- ! 83: | This macro tests for minimum version of the GNU C compiler. ! 84: *----------------------------------------------------------------------------*/ ! 85: #if defined(__GNUC__) && defined(__GNUC_MINOR__) ! 86: # define SOFTFLOAT_GNUC_PREREQ(maj, min) \ ! 87: ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) ! 88: #else ! 89: # define SOFTFLOAT_GNUC_PREREQ(maj, min) 0 ! 90: #endif ! 91: ! 92: ! 93: /*---------------------------------------------------------------------------- ! 94: | Shifts `a' right by the number of bits given in `count'. If any nonzero ! 95: | bits are shifted off, they are ``jammed'' into the least significant bit of ! 96: | the result by setting the least significant bit to 1. The value of `count' ! 97: | can be arbitrarily large; in particular, if `count' is greater than 32, the ! 98: | result will be either 0 or 1, depending on whether `a' is zero or nonzero. ! 99: | The result is stored in the location pointed to by `zPtr'. ! 100: *----------------------------------------------------------------------------*/ ! 101: ! 102: static inline void shift32RightJamming(uint32_t a, int count, uint32_t *zPtr) ! 103: { ! 104: uint32_t z; ! 105: ! 106: if ( count == 0 ) { ! 107: z = a; ! 108: } ! 109: else if ( count < 32 ) { ! 110: z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 ); ! 111: } ! 112: else { ! 113: z = ( a != 0 ); ! 114: } ! 115: *zPtr = z; ! 116: ! 117: } ! 118: ! 119: /*---------------------------------------------------------------------------- ! 120: | Shifts `a' right by the number of bits given in `count'. If any nonzero ! 121: | bits are shifted off, they are ``jammed'' into the least significant bit of ! 122: | the result by setting the least significant bit to 1. The value of `count' ! 123: | can be arbitrarily large; in particular, if `count' is greater than 64, the ! 124: | result will be either 0 or 1, depending on whether `a' is zero or nonzero. ! 125: | The result is stored in the location pointed to by `zPtr'. ! 126: *----------------------------------------------------------------------------*/ ! 127: ! 128: static inline void shift64RightJamming(uint64_t a, int count, uint64_t *zPtr) ! 129: { ! 130: uint64_t z; ! 131: ! 132: if ( count == 0 ) { ! 133: z = a; ! 134: } ! 135: else if ( count < 64 ) { ! 136: z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 ); ! 137: } ! 138: else { ! 139: z = ( a != 0 ); ! 140: } ! 141: *zPtr = z; ! 142: ! 143: } ! 144: ! 145: /*---------------------------------------------------------------------------- ! 146: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64 ! 147: | _plus_ the number of bits given in `count'. The shifted result is at most ! 148: | 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The ! 149: | bits shifted off form a second 64-bit result as follows: The _last_ bit ! 150: | shifted off is the most-significant bit of the extra result, and the other ! 151: | 63 bits of the extra result are all zero if and only if _all_but_the_last_ ! 152: | bits shifted off were all zero. This extra result is stored in the location ! 153: | pointed to by `z1Ptr'. The value of `count' can be arbitrarily large. ! 154: | (This routine makes more sense if `a0' and `a1' are considered to form a ! 155: | fixed-point value with binary point between `a0' and `a1'. This fixed-point ! 156: | value is shifted right by the number of bits given in `count', and the ! 157: | integer part of the result is returned at the location pointed to by ! 158: | `z0Ptr'. The fractional part of the result may be slightly corrupted as ! 159: | described above, and is returned at the location pointed to by `z1Ptr'.) ! 160: *----------------------------------------------------------------------------*/ ! 161: ! 162: static inline void ! 163: shift64ExtraRightJamming( ! 164: uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) ! 165: { ! 166: uint64_t z0, z1; ! 167: int8_t negCount = ( - count ) & 63; ! 168: ! 169: if ( count == 0 ) { ! 170: z1 = a1; ! 171: z0 = a0; ! 172: } ! 173: else if ( count < 64 ) { ! 174: z1 = ( a0<<negCount ) | ( a1 != 0 ); ! 175: z0 = a0>>count; ! 176: } ! 177: else { ! 178: if ( count == 64 ) { ! 179: z1 = a0 | ( a1 != 0 ); ! 180: } ! 181: else { ! 182: z1 = ( ( a0 | a1 ) != 0 ); ! 183: } ! 184: z0 = 0; ! 185: } ! 186: *z1Ptr = z1; ! 187: *z0Ptr = z0; ! 188: ! 189: } ! 190: ! 191: /*---------------------------------------------------------------------------- ! 192: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the ! 193: | number of bits given in `count'. Any bits shifted off are lost. The value ! 194: | of `count' can be arbitrarily large; in particular, if `count' is greater ! 195: | than 128, the result will be 0. The result is broken into two 64-bit pieces ! 196: | which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. ! 197: *----------------------------------------------------------------------------*/ ! 198: ! 199: static inline void ! 200: shift128Right( ! 201: uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) ! 202: { ! 203: uint64_t z0, z1; ! 204: int8_t negCount = ( - count ) & 63; ! 205: ! 206: if ( count == 0 ) { ! 207: z1 = a1; ! 208: z0 = a0; ! 209: } ! 210: else if ( count < 64 ) { ! 211: z1 = ( a0<<negCount ) | ( a1>>count ); ! 212: z0 = a0>>count; ! 213: } ! 214: else { ! 215: z1 = (count < 128) ? (a0 >> (count & 63)) : 0; ! 216: z0 = 0; ! 217: } ! 218: *z1Ptr = z1; ! 219: *z0Ptr = z0; ! 220: ! 221: } ! 222: ! 223: /*---------------------------------------------------------------------------- ! 224: | Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the ! 225: | number of bits given in `count'. If any nonzero bits are shifted off, they ! 226: | are ``jammed'' into the least significant bit of the result by setting the ! 227: | least significant bit to 1. The value of `count' can be arbitrarily large; ! 228: | in particular, if `count' is greater than 128, the result will be either ! 229: | 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or ! 230: | nonzero. The result is broken into two 64-bit pieces which are stored at ! 231: | the locations pointed to by `z0Ptr' and `z1Ptr'. ! 232: *----------------------------------------------------------------------------*/ ! 233: ! 234: static inline void ! 235: shift128RightJamming( ! 236: uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) ! 237: { ! 238: uint64_t z0, z1; ! 239: int8_t negCount = ( - count ) & 63; ! 240: ! 241: if ( count == 0 ) { ! 242: z1 = a1; ! 243: z0 = a0; ! 244: } ! 245: else if ( count < 64 ) { ! 246: z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 ); ! 247: z0 = a0>>count; ! 248: } ! 249: else { ! 250: if ( count == 64 ) { ! 251: z1 = a0 | ( a1 != 0 ); ! 252: } ! 253: else if ( count < 128 ) { ! 254: z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 ); ! 255: } ! 256: else { ! 257: z1 = ( ( a0 | a1 ) != 0 ); ! 258: } ! 259: z0 = 0; ! 260: } ! 261: *z1Ptr = z1; ! 262: *z0Ptr = z0; ! 263: ! 264: } ! 265: ! 266: /*---------------------------------------------------------------------------- ! 267: | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right ! 268: | by 64 _plus_ the number of bits given in `count'. The shifted result is ! 269: | at most 128 nonzero bits; these are broken into two 64-bit pieces which are ! 270: | stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted ! 271: | off form a third 64-bit result as follows: The _last_ bit shifted off is ! 272: | the most-significant bit of the extra result, and the other 63 bits of the ! 273: | extra result are all zero if and only if _all_but_the_last_ bits shifted off ! 274: | were all zero. This extra result is stored in the location pointed to by ! 275: | `z2Ptr'. The value of `count' can be arbitrarily large. ! 276: | (This routine makes more sense if `a0', `a1', and `a2' are considered ! 277: | to form a fixed-point value with binary point between `a1' and `a2'. This ! 278: | fixed-point value is shifted right by the number of bits given in `count', ! 279: | and the integer part of the result is returned at the locations pointed to ! 280: | by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly ! 281: | corrupted as described above, and is returned at the location pointed to by ! 282: | `z2Ptr'.) ! 283: *----------------------------------------------------------------------------*/ ! 284: ! 285: static inline void ! 286: shift128ExtraRightJamming( ! 287: uint64_t a0, ! 288: uint64_t a1, ! 289: uint64_t a2, ! 290: int count, ! 291: uint64_t *z0Ptr, ! 292: uint64_t *z1Ptr, ! 293: uint64_t *z2Ptr ! 294: ) ! 295: { ! 296: uint64_t z0, z1, z2; ! 297: int8_t negCount = ( - count ) & 63; ! 298: ! 299: if ( count == 0 ) { ! 300: z2 = a2; ! 301: z1 = a1; ! 302: z0 = a0; ! 303: } ! 304: else { ! 305: if ( count < 64 ) { ! 306: z2 = a1<<negCount; ! 307: z1 = ( a0<<negCount ) | ( a1>>count ); ! 308: z0 = a0>>count; ! 309: } ! 310: else { ! 311: if ( count == 64 ) { ! 312: z2 = a1; ! 313: z1 = a0; ! 314: } ! 315: else { ! 316: a2 |= a1; ! 317: if ( count < 128 ) { ! 318: z2 = a0<<negCount; ! 319: z1 = a0>>( count & 63 ); ! 320: } ! 321: else { ! 322: z2 = ( count == 128 ) ? a0 : ( a0 != 0 ); ! 323: z1 = 0; ! 324: } ! 325: } ! 326: z0 = 0; ! 327: } ! 328: z2 |= ( a2 != 0 ); ! 329: } ! 330: *z2Ptr = z2; ! 331: *z1Ptr = z1; ! 332: *z0Ptr = z0; ! 333: ! 334: } ! 335: ! 336: /*---------------------------------------------------------------------------- ! 337: | Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the ! 338: | number of bits given in `count'. Any bits shifted off are lost. The value ! 339: | of `count' must be less than 64. The result is broken into two 64-bit ! 340: | pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. ! 341: *----------------------------------------------------------------------------*/ ! 342: ! 343: static inline void ! 344: shortShift128Left( ! 345: uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) ! 346: { ! 347: ! 348: *z1Ptr = a1<<count; ! 349: *z0Ptr = ! 350: ( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) ); ! 351: ! 352: } ! 353: ! 354: /*---------------------------------------------------------------------------- ! 355: | Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left ! 356: | by the number of bits given in `count'. Any bits shifted off are lost. ! 357: | The value of `count' must be less than 64. The result is broken into three ! 358: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr', ! 359: | `z1Ptr', and `z2Ptr'. ! 360: *----------------------------------------------------------------------------*/ ! 361: ! 362: static inline void ! 363: shortShift192Left( ! 364: uint64_t a0, ! 365: uint64_t a1, ! 366: uint64_t a2, ! 367: int count, ! 368: uint64_t *z0Ptr, ! 369: uint64_t *z1Ptr, ! 370: uint64_t *z2Ptr ! 371: ) ! 372: { ! 373: uint64_t z0, z1, z2; ! 374: int8_t negCount; ! 375: ! 376: z2 = a2<<count; ! 377: z1 = a1<<count; ! 378: z0 = a0<<count; ! 379: if ( 0 < count ) { ! 380: negCount = ( ( - count ) & 63 ); ! 381: z1 |= a2>>negCount; ! 382: z0 |= a1>>negCount; ! 383: } ! 384: *z2Ptr = z2; ! 385: *z1Ptr = z1; ! 386: *z0Ptr = z0; ! 387: ! 388: } ! 389: ! 390: /*---------------------------------------------------------------------------- ! 391: | Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit ! 392: | value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so ! 393: | any carry out is lost. The result is broken into two 64-bit pieces which ! 394: | are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. ! 395: *----------------------------------------------------------------------------*/ ! 396: ! 397: static inline void ! 398: add128( ! 399: uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr ) ! 400: { ! 401: uint64_t z1; ! 402: ! 403: z1 = a1 + b1; ! 404: *z1Ptr = z1; ! 405: *z0Ptr = a0 + b0 + ( z1 < a1 ); ! 406: ! 407: } ! 408: ! 409: /*---------------------------------------------------------------------------- ! 410: | Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the ! 411: | 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is ! 412: | modulo 2^192, so any carry out is lost. The result is broken into three ! 413: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr', ! 414: | `z1Ptr', and `z2Ptr'. ! 415: *----------------------------------------------------------------------------*/ ! 416: ! 417: static inline void ! 418: add192( ! 419: uint64_t a0, ! 420: uint64_t a1, ! 421: uint64_t a2, ! 422: uint64_t b0, ! 423: uint64_t b1, ! 424: uint64_t b2, ! 425: uint64_t *z0Ptr, ! 426: uint64_t *z1Ptr, ! 427: uint64_t *z2Ptr ! 428: ) ! 429: { ! 430: uint64_t z0, z1, z2; ! 431: uint8_t carry0, carry1; ! 432: ! 433: z2 = a2 + b2; ! 434: carry1 = ( z2 < a2 ); ! 435: z1 = a1 + b1; ! 436: carry0 = ( z1 < a1 ); ! 437: z0 = a0 + b0; ! 438: z1 += carry1; ! 439: z0 += ( z1 < carry1 ); ! 440: z0 += carry0; ! 441: *z2Ptr = z2; ! 442: *z1Ptr = z1; ! 443: *z0Ptr = z0; ! 444: ! 445: } ! 446: ! 447: /*---------------------------------------------------------------------------- ! 448: | Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the ! 449: | 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo ! 450: | 2^128, so any borrow out (carry out) is lost. The result is broken into two ! 451: | 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and ! 452: | `z1Ptr'. ! 453: *----------------------------------------------------------------------------*/ ! 454: ! 455: static inline void ! 456: sub128( ! 457: uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1, uint64_t *z0Ptr, uint64_t *z1Ptr ) ! 458: { ! 459: ! 460: *z1Ptr = a1 - b1; ! 461: *z0Ptr = a0 - b0 - ( a1 < b1 ); ! 462: ! 463: } ! 464: ! 465: /*---------------------------------------------------------------------------- ! 466: | Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2' ! 467: | from the 192-bit value formed by concatenating `a0', `a1', and `a2'. ! 468: | Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The ! 469: | result is broken into three 64-bit pieces which are stored at the locations ! 470: | pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'. ! 471: *----------------------------------------------------------------------------*/ ! 472: ! 473: static inline void ! 474: sub192( ! 475: uint64_t a0, ! 476: uint64_t a1, ! 477: uint64_t a2, ! 478: uint64_t b0, ! 479: uint64_t b1, ! 480: uint64_t b2, ! 481: uint64_t *z0Ptr, ! 482: uint64_t *z1Ptr, ! 483: uint64_t *z2Ptr ! 484: ) ! 485: { ! 486: uint64_t z0, z1, z2; ! 487: uint8_t borrow0, borrow1; ! 488: ! 489: z2 = a2 - b2; ! 490: borrow1 = ( a2 < b2 ); ! 491: z1 = a1 - b1; ! 492: borrow0 = ( a1 < b1 ); ! 493: z0 = a0 - b0; ! 494: z0 -= ( z1 < borrow1 ); ! 495: z1 -= borrow1; ! 496: z0 -= borrow0; ! 497: *z2Ptr = z2; ! 498: *z1Ptr = z1; ! 499: *z0Ptr = z0; ! 500: ! 501: } ! 502: ! 503: /*---------------------------------------------------------------------------- ! 504: | Multiplies `a' by `b' to obtain a 128-bit product. The product is broken ! 505: | into two 64-bit pieces which are stored at the locations pointed to by ! 506: | `z0Ptr' and `z1Ptr'. ! 507: *----------------------------------------------------------------------------*/ ! 508: ! 509: static inline void mul64To128( uint64_t a, uint64_t b, uint64_t *z0Ptr, uint64_t *z1Ptr ) ! 510: { ! 511: uint32_t aHigh, aLow, bHigh, bLow; ! 512: uint64_t z0, zMiddleA, zMiddleB, z1; ! 513: ! 514: aLow = a; ! 515: aHigh = a>>32; ! 516: bLow = b; ! 517: bHigh = b>>32; ! 518: z1 = ( (uint64_t) aLow ) * bLow; ! 519: zMiddleA = ( (uint64_t) aLow ) * bHigh; ! 520: zMiddleB = ( (uint64_t) aHigh ) * bLow; ! 521: z0 = ( (uint64_t) aHigh ) * bHigh; ! 522: zMiddleA += zMiddleB; ! 523: z0 += ( ( (uint64_t) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 ); ! 524: zMiddleA <<= 32; ! 525: z1 += zMiddleA; ! 526: z0 += ( z1 < zMiddleA ); ! 527: *z1Ptr = z1; ! 528: *z0Ptr = z0; ! 529: ! 530: } ! 531: ! 532: /*---------------------------------------------------------------------------- ! 533: | Multiplies the 128-bit value formed by concatenating `a0' and `a1' by ! 534: | `b' to obtain a 192-bit product. The product is broken into three 64-bit ! 535: | pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and ! 536: | `z2Ptr'. ! 537: *----------------------------------------------------------------------------*/ ! 538: ! 539: static inline void ! 540: mul128By64To192( ! 541: uint64_t a0, ! 542: uint64_t a1, ! 543: uint64_t b, ! 544: uint64_t *z0Ptr, ! 545: uint64_t *z1Ptr, ! 546: uint64_t *z2Ptr ! 547: ) ! 548: { ! 549: uint64_t z0, z1, z2, more1; ! 550: ! 551: mul64To128( a1, b, &z1, &z2 ); ! 552: mul64To128( a0, b, &z0, &more1 ); ! 553: add128( z0, more1, 0, z1, &z0, &z1 ); ! 554: *z2Ptr = z2; ! 555: *z1Ptr = z1; ! 556: *z0Ptr = z0; ! 557: ! 558: } ! 559: ! 560: /*---------------------------------------------------------------------------- ! 561: | Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the ! 562: | 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit ! 563: | product. The product is broken into four 64-bit pieces which are stored at ! 564: | the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'. ! 565: *----------------------------------------------------------------------------*/ ! 566: ! 567: static inline void ! 568: mul128To256( ! 569: uint64_t a0, ! 570: uint64_t a1, ! 571: uint64_t b0, ! 572: uint64_t b1, ! 573: uint64_t *z0Ptr, ! 574: uint64_t *z1Ptr, ! 575: uint64_t *z2Ptr, ! 576: uint64_t *z3Ptr ! 577: ) ! 578: { ! 579: uint64_t z0, z1, z2, z3; ! 580: uint64_t more1, more2; ! 581: ! 582: mul64To128( a1, b1, &z2, &z3 ); ! 583: mul64To128( a1, b0, &z1, &more2 ); ! 584: add128( z1, more2, 0, z2, &z1, &z2 ); ! 585: mul64To128( a0, b0, &z0, &more1 ); ! 586: add128( z0, more1, 0, z1, &z0, &z1 ); ! 587: mul64To128( a0, b1, &more1, &more2 ); ! 588: add128( more1, more2, 0, z2, &more1, &z2 ); ! 589: add128( z0, z1, 0, more1, &z0, &z1 ); ! 590: *z3Ptr = z3; ! 591: *z2Ptr = z2; ! 592: *z1Ptr = z1; ! 593: *z0Ptr = z0; ! 594: ! 595: } ! 596: ! 597: /*---------------------------------------------------------------------------- ! 598: | Returns an approximation to the 64-bit integer quotient obtained by dividing ! 599: | `b' into the 128-bit value formed by concatenating `a0' and `a1'. The ! 600: | divisor `b' must be at least 2^63. If q is the exact quotient truncated ! 601: | toward zero, the approximation returned lies between q and q + 2 inclusive. ! 602: | If the exact quotient q is larger than 64 bits, the maximum positive 64-bit ! 603: | unsigned integer is returned. ! 604: *----------------------------------------------------------------------------*/ ! 605: ! 606: static inline uint64_t estimateDiv128To64( uint64_t a0, uint64_t a1, uint64_t b ) ! 607: { ! 608: uint64_t b0, b1; ! 609: uint64_t rem0, rem1, term0, term1; ! 610: uint64_t z; ! 611: ! 612: if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF ); ! 613: b0 = b>>32; ! 614: z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32; ! 615: mul64To128( b, z, &term0, &term1 ); ! 616: sub128( a0, a1, term0, term1, &rem0, &rem1 ); ! 617: while ( ( (int64_t) rem0 ) < 0 ) { ! 618: z -= LIT64( 0x100000000 ); ! 619: b1 = b<<32; ! 620: add128( rem0, rem1, b0, b1, &rem0, &rem1 ); ! 621: } ! 622: rem0 = ( rem0<<32 ) | ( rem1>>32 ); ! 623: z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0; ! 624: return z; ! 625: ! 626: } ! 627: ! 628: /*---------------------------------------------------------------------------- ! 629: | Returns an approximation to the square root of the 32-bit significand given ! 630: | by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of ! 631: | `aExp' (the least significant bit) is 1, the integer returned approximates ! 632: | 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp' ! 633: | is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either ! 634: | case, the approximation returned lies strictly within +/-2 of the exact ! 635: | value. ! 636: *----------------------------------------------------------------------------*/ ! 637: ! 638: static inline uint32_t estimateSqrt32(int aExp, uint32_t a) ! 639: { ! 640: static const uint16_t sqrtOddAdjustments[] = { ! 641: 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, ! 642: 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 ! 643: }; ! 644: static const uint16_t sqrtEvenAdjustments[] = { ! 645: 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, ! 646: 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 ! 647: }; ! 648: int8_t index; ! 649: uint32_t z; ! 650: ! 651: index = ( a>>27 ) & 15; ! 652: if ( aExp & 1 ) { ! 653: z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ (int)index ]; ! 654: z = ( ( a / z )<<14 ) + ( z<<15 ); ! 655: a >>= 1; ! 656: } ! 657: else { ! 658: z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ (int)index ]; ! 659: z = a / z + z; ! 660: z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 ); ! 661: if ( z <= a ) return (uint32_t) ( ( (int32_t) a )>>1 ); ! 662: } ! 663: return ( (uint32_t) ( ( ( (uint64_t) a )<<31 ) / z ) ) + ( z>>1 ); ! 664: ! 665: } ! 666: ! 667: /*---------------------------------------------------------------------------- ! 668: | Returns the number of leading 0 bits before the most-significant 1 bit of ! 669: | `a'. If `a' is zero, 32 is returned. ! 670: *----------------------------------------------------------------------------*/ ! 671: ! 672: static inline int8_t countLeadingZeros32( uint32_t a ) ! 673: { ! 674: #if SOFTFLOAT_GNUC_PREREQ(3, 4) ! 675: if (a) { ! 676: return __builtin_clz(a); ! 677: } else { ! 678: return 32; ! 679: } ! 680: #else ! 681: static const int8_t countLeadingZerosHigh[] = { ! 682: 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, ! 683: 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, ! 684: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ! 685: 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, ! 686: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 687: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 688: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 689: 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ! 690: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 691: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 692: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 693: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 694: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 695: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 696: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! 697: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ! 698: }; ! 699: int8_t shiftCount; ! 700: ! 701: shiftCount = 0; ! 702: if ( a < 0x10000 ) { ! 703: shiftCount += 16; ! 704: a <<= 16; ! 705: } ! 706: if ( a < 0x1000000 ) { ! 707: shiftCount += 8; ! 708: a <<= 8; ! 709: } ! 710: shiftCount += countLeadingZerosHigh[ a>>24 ]; ! 711: return shiftCount; ! 712: #endif ! 713: } ! 714: ! 715: /*---------------------------------------------------------------------------- ! 716: | Returns the number of leading 0 bits before the most-significant 1 bit of ! 717: | `a'. If `a' is zero, 64 is returned. ! 718: *----------------------------------------------------------------------------*/ ! 719: ! 720: static inline int8_t countLeadingZeros64( uint64_t a ) ! 721: { ! 722: #if SOFTFLOAT_GNUC_PREREQ(3, 4) ! 723: if (a) { ! 724: return __builtin_clzll(a); ! 725: } else { ! 726: return 64; ! 727: } ! 728: #else ! 729: int8_t shiftCount; ! 730: ! 731: shiftCount = 0; ! 732: if ( a < ( (uint64_t) 1 )<<32 ) { ! 733: shiftCount += 32; ! 734: } ! 735: else { ! 736: a >>= 32; ! 737: } ! 738: shiftCount += countLeadingZeros32( a ); ! 739: return shiftCount; ! 740: #endif ! 741: } ! 742: ! 743: /*---------------------------------------------------------------------------- ! 744: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' ! 745: | is equal to the 128-bit value formed by concatenating `b0' and `b1'. ! 746: | Otherwise, returns 0. ! 747: *----------------------------------------------------------------------------*/ ! 748: ! 749: static inline flag eq128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) ! 750: { ! 751: ! 752: return ( a0 == b0 ) && ( a1 == b1 ); ! 753: ! 754: } ! 755: ! 756: /*---------------------------------------------------------------------------- ! 757: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less ! 758: | than or equal to the 128-bit value formed by concatenating `b0' and `b1'. ! 759: | Otherwise, returns 0. ! 760: *----------------------------------------------------------------------------*/ ! 761: ! 762: static inline flag le128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) ! 763: { ! 764: ! 765: return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) ); ! 766: ! 767: } ! 768: ! 769: /*---------------------------------------------------------------------------- ! 770: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less ! 771: | than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise, ! 772: | returns 0. ! 773: *----------------------------------------------------------------------------*/ ! 774: ! 775: static inline flag lt128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) ! 776: { ! 777: ! 778: return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) ); ! 779: ! 780: } ! 781: ! 782: /*---------------------------------------------------------------------------- ! 783: | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is ! 784: | not equal to the 128-bit value formed by concatenating `b0' and `b1'. ! 785: | Otherwise, returns 0. ! 786: *----------------------------------------------------------------------------*/ ! 787: ! 788: static inline flag ne128( uint64_t a0, uint64_t a1, uint64_t b0, uint64_t b1 ) ! 789: { ! 790: ! 791: return ( a0 != b0 ) || ( a1 != b1 ); ! 792: ! 793: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.