Annotation of qemu/fpu/softfloat.c, revision 1.1.1.1

1.1       root        1: 
                      2: /*============================================================================
                      3: 
                      4: This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
                      5: Package, Release 2b.
                      6: 
                      7: Written by John R. Hauser.  This work was made possible in part by the
                      8: International Computer Science Institute, located at Suite 600, 1947 Center
                      9: Street, Berkeley, California 94704.  Funding was partially provided by the
                     10: National Science Foundation under grant MIP-9311980.  The original version
                     11: of this code was written as part of a project to build a fixed-point vector
                     12: processor in collaboration with the University of California at Berkeley,
                     13: overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
                     14: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
                     15: arithmetic/SoftFloat.html'.
                     16: 
                     17: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
                     18: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
                     19: RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
                     20: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
                     21: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
                     22: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
                     23: INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
                     24: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
                     25: 
                     26: Derivative works are acceptable, even for commercial purposes, so long as
                     27: (1) the source code for the derivative work includes prominent notice that
                     28: the work is derivative, and (2) the source code includes prominent notice with
                     29: these four paragraphs for those parts of this code that are retained.
                     30: 
                     31: =============================================================================*/
                     32: 
                     33: #include "softfloat.h"
                     34: 
                     35: /*----------------------------------------------------------------------------
                     36: | Primitive arithmetic functions, including multi-word arithmetic, and
                     37: | division and square root approximations.  (Can be specialized to target if
                     38: | desired.)
                     39: *----------------------------------------------------------------------------*/
                     40: #include "softfloat-macros.h"
                     41: 
                     42: /*----------------------------------------------------------------------------
                     43: | Functions and definitions to determine:  (1) whether tininess for underflow
                     44: | is detected before or after rounding by default, (2) what (if anything)
                     45: | happens when exceptions are raised, (3) how signaling NaNs are distinguished
                     46: | from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
                     47: | are propagated from function inputs to output.  These details are target-
                     48: | specific.
                     49: *----------------------------------------------------------------------------*/
                     50: #include "softfloat-specialize.h"
                     51: 
                     52: void set_float_rounding_mode(int val STATUS_PARAM)
                     53: {
                     54:     STATUS(float_rounding_mode) = val;
                     55: }
                     56: 
                     57: void set_float_exception_flags(int val STATUS_PARAM)
                     58: {
                     59:     STATUS(float_exception_flags) = val;
                     60: }
                     61: 
                     62: #ifdef FLOATX80
                     63: void set_floatx80_rounding_precision(int val STATUS_PARAM)
                     64: {
                     65:     STATUS(floatx80_rounding_precision) = val;
                     66: }
                     67: #endif
                     68: 
                     69: /*----------------------------------------------------------------------------
                     70: | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
                     71: | and 7, and returns the properly rounded 32-bit integer corresponding to the
                     72: | input.  If `zSign' is 1, the input is negated before being converted to an
                     73: | integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point input
                     74: | is simply rounded to an integer, with the inexact exception raised if the
                     75: | input cannot be represented exactly as an integer.  However, if the fixed-
                     76: | point input is too large, the invalid exception is raised and the largest
                     77: | positive or negative integer is returned.
                     78: *----------------------------------------------------------------------------*/
                     79: 
                     80: static int32 roundAndPackInt32( flag zSign, bits64 absZ STATUS_PARAM)
                     81: {
                     82:     int8 roundingMode;
                     83:     flag roundNearestEven;
                     84:     int8 roundIncrement, roundBits;
                     85:     int32 z;
                     86: 
                     87:     roundingMode = STATUS(float_rounding_mode);
                     88:     roundNearestEven = ( roundingMode == float_round_nearest_even );
                     89:     roundIncrement = 0x40;
                     90:     if ( ! roundNearestEven ) {
                     91:         if ( roundingMode == float_round_to_zero ) {
                     92:             roundIncrement = 0;
                     93:         }
                     94:         else {
                     95:             roundIncrement = 0x7F;
                     96:             if ( zSign ) {
                     97:                 if ( roundingMode == float_round_up ) roundIncrement = 0;
                     98:             }
                     99:             else {
                    100:                 if ( roundingMode == float_round_down ) roundIncrement = 0;
                    101:             }
                    102:         }
                    103:     }
                    104:     roundBits = absZ & 0x7F;
                    105:     absZ = ( absZ + roundIncrement )>>7;
                    106:     absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
                    107:     z = absZ;
                    108:     if ( zSign ) z = - z;
                    109:     if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
                    110:         float_raise( float_flag_invalid STATUS_VAR);
                    111:         return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                    112:     }
                    113:     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
                    114:     return z;
                    115: 
                    116: }
                    117: 
                    118: /*----------------------------------------------------------------------------
                    119: | Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
                    120: | `absZ1', with binary point between bits 63 and 64 (between the input words),
                    121: | and returns the properly rounded 64-bit integer corresponding to the input.
                    122: | If `zSign' is 1, the input is negated before being converted to an integer.
                    123: | Ordinarily, the fixed-point input is simply rounded to an integer, with
                    124: | the inexact exception raised if the input cannot be represented exactly as
                    125: | an integer.  However, if the fixed-point input is too large, the invalid
                    126: | exception is raised and the largest positive or negative integer is
                    127: | returned.
                    128: *----------------------------------------------------------------------------*/
                    129: 
                    130: static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1 STATUS_PARAM)
                    131: {
                    132:     int8 roundingMode;
                    133:     flag roundNearestEven, increment;
                    134:     int64 z;
                    135: 
                    136:     roundingMode = STATUS(float_rounding_mode);
                    137:     roundNearestEven = ( roundingMode == float_round_nearest_even );
                    138:     increment = ( (sbits64) absZ1 < 0 );
                    139:     if ( ! roundNearestEven ) {
                    140:         if ( roundingMode == float_round_to_zero ) {
                    141:             increment = 0;
                    142:         }
                    143:         else {
                    144:             if ( zSign ) {
                    145:                 increment = ( roundingMode == float_round_down ) && absZ1;
                    146:             }
                    147:             else {
                    148:                 increment = ( roundingMode == float_round_up ) && absZ1;
                    149:             }
                    150:         }
                    151:     }
                    152:     if ( increment ) {
                    153:         ++absZ0;
                    154:         if ( absZ0 == 0 ) goto overflow;
                    155:         absZ0 &= ~ ( ( (bits64) ( absZ1<<1 ) == 0 ) & roundNearestEven );
                    156:     }
                    157:     z = absZ0;
                    158:     if ( zSign ) z = - z;
                    159:     if ( z && ( ( z < 0 ) ^ zSign ) ) {
                    160:  overflow:
                    161:         float_raise( float_flag_invalid STATUS_VAR);
                    162:         return
                    163:               zSign ? (sbits64) LIT64( 0x8000000000000000 )
                    164:             : LIT64( 0x7FFFFFFFFFFFFFFF );
                    165:     }
                    166:     if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact;
                    167:     return z;
                    168: 
                    169: }
                    170: 
                    171: /*----------------------------------------------------------------------------
                    172: | Returns the fraction bits of the single-precision floating-point value `a'.
                    173: *----------------------------------------------------------------------------*/
                    174: 
                    175: INLINE bits32 extractFloat32Frac( float32 a )
                    176: {
                    177: 
                    178:     return a & 0x007FFFFF;
                    179: 
                    180: }
                    181: 
                    182: /*----------------------------------------------------------------------------
                    183: | Returns the exponent bits of the single-precision floating-point value `a'.
                    184: *----------------------------------------------------------------------------*/
                    185: 
                    186: INLINE int16 extractFloat32Exp( float32 a )
                    187: {
                    188: 
                    189:     return ( a>>23 ) & 0xFF;
                    190: 
                    191: }
                    192: 
                    193: /*----------------------------------------------------------------------------
                    194: | Returns the sign bit of the single-precision floating-point value `a'.
                    195: *----------------------------------------------------------------------------*/
                    196: 
                    197: INLINE flag extractFloat32Sign( float32 a )
                    198: {
                    199: 
                    200:     return a>>31;
                    201: 
                    202: }
                    203: 
                    204: /*----------------------------------------------------------------------------
                    205: | Normalizes the subnormal single-precision floating-point value represented
                    206: | by the denormalized significand `aSig'.  The normalized exponent and
                    207: | significand are stored at the locations pointed to by `zExpPtr' and
                    208: | `zSigPtr', respectively.
                    209: *----------------------------------------------------------------------------*/
                    210: 
                    211: static void
                    212:  normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
                    213: {
                    214:     int8 shiftCount;
                    215: 
                    216:     shiftCount = countLeadingZeros32( aSig ) - 8;
                    217:     *zSigPtr = aSig<<shiftCount;
                    218:     *zExpPtr = 1 - shiftCount;
                    219: 
                    220: }
                    221: 
                    222: /*----------------------------------------------------------------------------
                    223: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
                    224: | single-precision floating-point value, returning the result.  After being
                    225: | shifted into the proper positions, the three fields are simply added
                    226: | together to form the result.  This means that any integer portion of `zSig'
                    227: | will be added into the exponent.  Since a properly normalized significand
                    228: | will have an integer portion equal to 1, the `zExp' input should be 1 less
                    229: | than the desired result exponent whenever `zSig' is a complete, normalized
                    230: | significand.
                    231: *----------------------------------------------------------------------------*/
                    232: 
                    233: INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
                    234: {
                    235: 
                    236:     return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
                    237: 
                    238: }
                    239: 
                    240: /*----------------------------------------------------------------------------
                    241: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                    242: | and significand `zSig', and returns the proper single-precision floating-
                    243: | point value corresponding to the abstract input.  Ordinarily, the abstract
                    244: | value is simply rounded and packed into the single-precision format, with
                    245: | the inexact exception raised if the abstract input cannot be represented
                    246: | exactly.  However, if the abstract value is too large, the overflow and
                    247: | inexact exceptions are raised and an infinity or maximal finite value is
                    248: | returned.  If the abstract value is too small, the input value is rounded to
                    249: | a subnormal number, and the underflow and inexact exceptions are raised if
                    250: | the abstract input cannot be represented exactly as a subnormal single-
                    251: | precision floating-point number.
                    252: |     The input significand `zSig' has its binary point between bits 30
                    253: | and 29, which is 7 bits to the left of the usual location.  This shifted
                    254: | significand must be normalized or smaller.  If `zSig' is not normalized,
                    255: | `zExp' must be 0; in that case, the result returned is a subnormal number,
                    256: | and it must not require rounding.  In the usual case that `zSig' is
                    257: | normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
                    258: | The handling of underflow and overflow follows the IEC/IEEE Standard for
                    259: | Binary Floating-Point Arithmetic.
                    260: *----------------------------------------------------------------------------*/
                    261: 
                    262: static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM)
                    263: {
                    264:     int8 roundingMode;
                    265:     flag roundNearestEven;
                    266:     int8 roundIncrement, roundBits;
                    267:     flag isTiny;
                    268: 
                    269:     roundingMode = STATUS(float_rounding_mode);
                    270:     roundNearestEven = ( roundingMode == float_round_nearest_even );
                    271:     roundIncrement = 0x40;
                    272:     if ( ! roundNearestEven ) {
                    273:         if ( roundingMode == float_round_to_zero ) {
                    274:             roundIncrement = 0;
                    275:         }
                    276:         else {
                    277:             roundIncrement = 0x7F;
                    278:             if ( zSign ) {
                    279:                 if ( roundingMode == float_round_up ) roundIncrement = 0;
                    280:             }
                    281:             else {
                    282:                 if ( roundingMode == float_round_down ) roundIncrement = 0;
                    283:             }
                    284:         }
                    285:     }
                    286:     roundBits = zSig & 0x7F;
                    287:     if ( 0xFD <= (bits16) zExp ) {
                    288:         if (    ( 0xFD < zExp )
                    289:              || (    ( zExp == 0xFD )
                    290:                   && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
                    291:            ) {
                    292:             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
                    293:             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
                    294:         }
                    295:         if ( zExp < 0 ) {
                    296:             isTiny =
                    297:                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    298:                 || ( zExp < -1 )
                    299:                 || ( zSig + roundIncrement < 0x80000000 );
                    300:             shift32RightJamming( zSig, - zExp, &zSig );
                    301:             zExp = 0;
                    302:             roundBits = zSig & 0x7F;
                    303:             if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
                    304:         }
                    305:     }
                    306:     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
                    307:     zSig = ( zSig + roundIncrement )>>7;
                    308:     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
                    309:     if ( zSig == 0 ) zExp = 0;
                    310:     return packFloat32( zSign, zExp, zSig );
                    311: 
                    312: }
                    313: 
                    314: /*----------------------------------------------------------------------------
                    315: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                    316: | and significand `zSig', and returns the proper single-precision floating-
                    317: | point value corresponding to the abstract input.  This routine is just like
                    318: | `roundAndPackFloat32' except that `zSig' does not have to be normalized.
                    319: | Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
                    320: | floating-point exponent.
                    321: *----------------------------------------------------------------------------*/
                    322: 
                    323: static float32
                    324:  normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig STATUS_PARAM)
                    325: {
                    326:     int8 shiftCount;
                    327: 
                    328:     shiftCount = countLeadingZeros32( zSig ) - 1;
                    329:     return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
                    330: 
                    331: }
                    332: 
                    333: /*----------------------------------------------------------------------------
                    334: | Returns the fraction bits of the double-precision floating-point value `a'.
                    335: *----------------------------------------------------------------------------*/
                    336: 
                    337: INLINE bits64 extractFloat64Frac( float64 a )
                    338: {
                    339: 
                    340:     return a & LIT64( 0x000FFFFFFFFFFFFF );
                    341: 
                    342: }
                    343: 
                    344: /*----------------------------------------------------------------------------
                    345: | Returns the exponent bits of the double-precision floating-point value `a'.
                    346: *----------------------------------------------------------------------------*/
                    347: 
                    348: INLINE int16 extractFloat64Exp( float64 a )
                    349: {
                    350: 
                    351:     return ( a>>52 ) & 0x7FF;
                    352: 
                    353: }
                    354: 
                    355: /*----------------------------------------------------------------------------
                    356: | Returns the sign bit of the double-precision floating-point value `a'.
                    357: *----------------------------------------------------------------------------*/
                    358: 
                    359: INLINE flag extractFloat64Sign( float64 a )
                    360: {
                    361: 
                    362:     return a>>63;
                    363: 
                    364: }
                    365: 
                    366: /*----------------------------------------------------------------------------
                    367: | Normalizes the subnormal double-precision floating-point value represented
                    368: | by the denormalized significand `aSig'.  The normalized exponent and
                    369: | significand are stored at the locations pointed to by `zExpPtr' and
                    370: | `zSigPtr', respectively.
                    371: *----------------------------------------------------------------------------*/
                    372: 
                    373: static void
                    374:  normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
                    375: {
                    376:     int8 shiftCount;
                    377: 
                    378:     shiftCount = countLeadingZeros64( aSig ) - 11;
                    379:     *zSigPtr = aSig<<shiftCount;
                    380:     *zExpPtr = 1 - shiftCount;
                    381: 
                    382: }
                    383: 
                    384: /*----------------------------------------------------------------------------
                    385: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
                    386: | double-precision floating-point value, returning the result.  After being
                    387: | shifted into the proper positions, the three fields are simply added
                    388: | together to form the result.  This means that any integer portion of `zSig'
                    389: | will be added into the exponent.  Since a properly normalized significand
                    390: | will have an integer portion equal to 1, the `zExp' input should be 1 less
                    391: | than the desired result exponent whenever `zSig' is a complete, normalized
                    392: | significand.
                    393: *----------------------------------------------------------------------------*/
                    394: 
                    395: INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
                    396: {
                    397: 
                    398:     return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
                    399: 
                    400: }
                    401: 
                    402: /*----------------------------------------------------------------------------
                    403: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                    404: | and significand `zSig', and returns the proper double-precision floating-
                    405: | point value corresponding to the abstract input.  Ordinarily, the abstract
                    406: | value is simply rounded and packed into the double-precision format, with
                    407: | the inexact exception raised if the abstract input cannot be represented
                    408: | exactly.  However, if the abstract value is too large, the overflow and
                    409: | inexact exceptions are raised and an infinity or maximal finite value is
                    410: | returned.  If the abstract value is too small, the input value is rounded
                    411: | to a subnormal number, and the underflow and inexact exceptions are raised
                    412: | if the abstract input cannot be represented exactly as a subnormal double-
                    413: | precision floating-point number.
                    414: |     The input significand `zSig' has its binary point between bits 62
                    415: | and 61, which is 10 bits to the left of the usual location.  This shifted
                    416: | significand must be normalized or smaller.  If `zSig' is not normalized,
                    417: | `zExp' must be 0; in that case, the result returned is a subnormal number,
                    418: | and it must not require rounding.  In the usual case that `zSig' is
                    419: | normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
                    420: | The handling of underflow and overflow follows the IEC/IEEE Standard for
                    421: | Binary Floating-Point Arithmetic.
                    422: *----------------------------------------------------------------------------*/
                    423: 
                    424: static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM)
                    425: {
                    426:     int8 roundingMode;
                    427:     flag roundNearestEven;
                    428:     int16 roundIncrement, roundBits;
                    429:     flag isTiny;
                    430: 
                    431:     roundingMode = STATUS(float_rounding_mode);
                    432:     roundNearestEven = ( roundingMode == float_round_nearest_even );
                    433:     roundIncrement = 0x200;
                    434:     if ( ! roundNearestEven ) {
                    435:         if ( roundingMode == float_round_to_zero ) {
                    436:             roundIncrement = 0;
                    437:         }
                    438:         else {
                    439:             roundIncrement = 0x3FF;
                    440:             if ( zSign ) {
                    441:                 if ( roundingMode == float_round_up ) roundIncrement = 0;
                    442:             }
                    443:             else {
                    444:                 if ( roundingMode == float_round_down ) roundIncrement = 0;
                    445:             }
                    446:         }
                    447:     }
                    448:     roundBits = zSig & 0x3FF;
                    449:     if ( 0x7FD <= (bits16) zExp ) {
                    450:         if (    ( 0x7FD < zExp )
                    451:              || (    ( zExp == 0x7FD )
                    452:                   && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
                    453:            ) {
                    454:             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
                    455:             return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
                    456:         }
                    457:         if ( zExp < 0 ) {
                    458:             isTiny =
                    459:                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    460:                 || ( zExp < -1 )
                    461:                 || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
                    462:             shift64RightJamming( zSig, - zExp, &zSig );
                    463:             zExp = 0;
                    464:             roundBits = zSig & 0x3FF;
                    465:             if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
                    466:         }
                    467:     }
                    468:     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
                    469:     zSig = ( zSig + roundIncrement )>>10;
                    470:     zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
                    471:     if ( zSig == 0 ) zExp = 0;
                    472:     return packFloat64( zSign, zExp, zSig );
                    473: 
                    474: }
                    475: 
                    476: /*----------------------------------------------------------------------------
                    477: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                    478: | and significand `zSig', and returns the proper double-precision floating-
                    479: | point value corresponding to the abstract input.  This routine is just like
                    480: | `roundAndPackFloat64' except that `zSig' does not have to be normalized.
                    481: | Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
                    482: | floating-point exponent.
                    483: *----------------------------------------------------------------------------*/
                    484: 
                    485: static float64
                    486:  normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig STATUS_PARAM)
                    487: {
                    488:     int8 shiftCount;
                    489: 
                    490:     shiftCount = countLeadingZeros64( zSig ) - 1;
                    491:     return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
                    492: 
                    493: }
                    494: 
                    495: #ifdef FLOATX80
                    496: 
                    497: /*----------------------------------------------------------------------------
                    498: | Returns the fraction bits of the extended double-precision floating-point
                    499: | value `a'.
                    500: *----------------------------------------------------------------------------*/
                    501: 
                    502: INLINE bits64 extractFloatx80Frac( floatx80 a )
                    503: {
                    504: 
                    505:     return a.low;
                    506: 
                    507: }
                    508: 
                    509: /*----------------------------------------------------------------------------
                    510: | Returns the exponent bits of the extended double-precision floating-point
                    511: | value `a'.
                    512: *----------------------------------------------------------------------------*/
                    513: 
                    514: INLINE int32 extractFloatx80Exp( floatx80 a )
                    515: {
                    516: 
                    517:     return a.high & 0x7FFF;
                    518: 
                    519: }
                    520: 
                    521: /*----------------------------------------------------------------------------
                    522: | Returns the sign bit of the extended double-precision floating-point value
                    523: | `a'.
                    524: *----------------------------------------------------------------------------*/
                    525: 
                    526: INLINE flag extractFloatx80Sign( floatx80 a )
                    527: {
                    528: 
                    529:     return a.high>>15;
                    530: 
                    531: }
                    532: 
                    533: /*----------------------------------------------------------------------------
                    534: | Normalizes the subnormal extended double-precision floating-point value
                    535: | represented by the denormalized significand `aSig'.  The normalized exponent
                    536: | and significand are stored at the locations pointed to by `zExpPtr' and
                    537: | `zSigPtr', respectively.
                    538: *----------------------------------------------------------------------------*/
                    539: 
                    540: static void
                    541:  normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
                    542: {
                    543:     int8 shiftCount;
                    544: 
                    545:     shiftCount = countLeadingZeros64( aSig );
                    546:     *zSigPtr = aSig<<shiftCount;
                    547:     *zExpPtr = 1 - shiftCount;
                    548: 
                    549: }
                    550: 
                    551: /*----------------------------------------------------------------------------
                    552: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
                    553: | extended double-precision floating-point value, returning the result.
                    554: *----------------------------------------------------------------------------*/
                    555: 
                    556: INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
                    557: {
                    558:     floatx80 z;
                    559: 
                    560:     z.low = zSig;
                    561:     z.high = ( ( (bits16) zSign )<<15 ) + zExp;
                    562:     return z;
                    563: 
                    564: }
                    565: 
                    566: /*----------------------------------------------------------------------------
                    567: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                    568: | and extended significand formed by the concatenation of `zSig0' and `zSig1',
                    569: | and returns the proper extended double-precision floating-point value
                    570: | corresponding to the abstract input.  Ordinarily, the abstract value is
                    571: | rounded and packed into the extended double-precision format, with the
                    572: | inexact exception raised if the abstract input cannot be represented
                    573: | exactly.  However, if the abstract value is too large, the overflow and
                    574: | inexact exceptions are raised and an infinity or maximal finite value is
                    575: | returned.  If the abstract value is too small, the input value is rounded to
                    576: | a subnormal number, and the underflow and inexact exceptions are raised if
                    577: | the abstract input cannot be represented exactly as a subnormal extended
                    578: | double-precision floating-point number.
                    579: |     If `roundingPrecision' is 32 or 64, the result is rounded to the same
                    580: | number of bits as single or double precision, respectively.  Otherwise, the
                    581: | result is rounded to the full precision of the extended double-precision
                    582: | format.
                    583: |     The input significand must be normalized or smaller.  If the input
                    584: | significand is not normalized, `zExp' must be 0; in that case, the result
                    585: | returned is a subnormal number, and it must not require rounding.  The
                    586: | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
                    587: | Floating-Point Arithmetic.
                    588: *----------------------------------------------------------------------------*/
                    589: 
                    590: static floatx80
                    591:  roundAndPackFloatx80(
                    592:      int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
                    593:  STATUS_PARAM)
                    594: {
                    595:     int8 roundingMode;
                    596:     flag roundNearestEven, increment, isTiny;
                    597:     int64 roundIncrement, roundMask, roundBits;
                    598: 
                    599:     roundingMode = STATUS(float_rounding_mode);
                    600:     roundNearestEven = ( roundingMode == float_round_nearest_even );
                    601:     if ( roundingPrecision == 80 ) goto precision80;
                    602:     if ( roundingPrecision == 64 ) {
                    603:         roundIncrement = LIT64( 0x0000000000000400 );
                    604:         roundMask = LIT64( 0x00000000000007FF );
                    605:     }
                    606:     else if ( roundingPrecision == 32 ) {
                    607:         roundIncrement = LIT64( 0x0000008000000000 );
                    608:         roundMask = LIT64( 0x000000FFFFFFFFFF );
                    609:     }
                    610:     else {
                    611:         goto precision80;
                    612:     }
                    613:     zSig0 |= ( zSig1 != 0 );
                    614:     if ( ! roundNearestEven ) {
                    615:         if ( roundingMode == float_round_to_zero ) {
                    616:             roundIncrement = 0;
                    617:         }
                    618:         else {
                    619:             roundIncrement = roundMask;
                    620:             if ( zSign ) {
                    621:                 if ( roundingMode == float_round_up ) roundIncrement = 0;
                    622:             }
                    623:             else {
                    624:                 if ( roundingMode == float_round_down ) roundIncrement = 0;
                    625:             }
                    626:         }
                    627:     }
                    628:     roundBits = zSig0 & roundMask;
                    629:     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
                    630:         if (    ( 0x7FFE < zExp )
                    631:              || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
                    632:            ) {
                    633:             goto overflow;
                    634:         }
                    635:         if ( zExp <= 0 ) {
                    636:             isTiny =
                    637:                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    638:                 || ( zExp < 0 )
                    639:                 || ( zSig0 <= zSig0 + roundIncrement );
                    640:             shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
                    641:             zExp = 0;
                    642:             roundBits = zSig0 & roundMask;
                    643:             if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
                    644:             if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
                    645:             zSig0 += roundIncrement;
                    646:             if ( (sbits64) zSig0 < 0 ) zExp = 1;
                    647:             roundIncrement = roundMask + 1;
                    648:             if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
                    649:                 roundMask |= roundIncrement;
                    650:             }
                    651:             zSig0 &= ~ roundMask;
                    652:             return packFloatx80( zSign, zExp, zSig0 );
                    653:         }
                    654:     }
                    655:     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
                    656:     zSig0 += roundIncrement;
                    657:     if ( zSig0 < roundIncrement ) {
                    658:         ++zExp;
                    659:         zSig0 = LIT64( 0x8000000000000000 );
                    660:     }
                    661:     roundIncrement = roundMask + 1;
                    662:     if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
                    663:         roundMask |= roundIncrement;
                    664:     }
                    665:     zSig0 &= ~ roundMask;
                    666:     if ( zSig0 == 0 ) zExp = 0;
                    667:     return packFloatx80( zSign, zExp, zSig0 );
                    668:  precision80:
                    669:     increment = ( (sbits64) zSig1 < 0 );
                    670:     if ( ! roundNearestEven ) {
                    671:         if ( roundingMode == float_round_to_zero ) {
                    672:             increment = 0;
                    673:         }
                    674:         else {
                    675:             if ( zSign ) {
                    676:                 increment = ( roundingMode == float_round_down ) && zSig1;
                    677:             }
                    678:             else {
                    679:                 increment = ( roundingMode == float_round_up ) && zSig1;
                    680:             }
                    681:         }
                    682:     }
                    683:     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
                    684:         if (    ( 0x7FFE < zExp )
                    685:              || (    ( zExp == 0x7FFE )
                    686:                   && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
                    687:                   && increment
                    688:                 )
                    689:            ) {
                    690:             roundMask = 0;
                    691:  overflow:
                    692:             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
                    693:             if (    ( roundingMode == float_round_to_zero )
                    694:                  || ( zSign && ( roundingMode == float_round_up ) )
                    695:                  || ( ! zSign && ( roundingMode == float_round_down ) )
                    696:                ) {
                    697:                 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
                    698:             }
                    699:             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                    700:         }
                    701:         if ( zExp <= 0 ) {
                    702:             isTiny =
                    703:                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    704:                 || ( zExp < 0 )
                    705:                 || ! increment
                    706:                 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
                    707:             shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
                    708:             zExp = 0;
                    709:             if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR);
                    710:             if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
                    711:             if ( roundNearestEven ) {
                    712:                 increment = ( (sbits64) zSig1 < 0 );
                    713:             }
                    714:             else {
                    715:                 if ( zSign ) {
                    716:                     increment = ( roundingMode == float_round_down ) && zSig1;
                    717:                 }
                    718:                 else {
                    719:                     increment = ( roundingMode == float_round_up ) && zSig1;
                    720:                 }
                    721:             }
                    722:             if ( increment ) {
                    723:                 ++zSig0;
                    724:                 zSig0 &=
                    725:                     ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
                    726:                 if ( (sbits64) zSig0 < 0 ) zExp = 1;
                    727:             }
                    728:             return packFloatx80( zSign, zExp, zSig0 );
                    729:         }
                    730:     }
                    731:     if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
                    732:     if ( increment ) {
                    733:         ++zSig0;
                    734:         if ( zSig0 == 0 ) {
                    735:             ++zExp;
                    736:             zSig0 = LIT64( 0x8000000000000000 );
                    737:         }
                    738:         else {
                    739:             zSig0 &= ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & roundNearestEven );
                    740:         }
                    741:     }
                    742:     else {
                    743:         if ( zSig0 == 0 ) zExp = 0;
                    744:     }
                    745:     return packFloatx80( zSign, zExp, zSig0 );
                    746: 
                    747: }
                    748: 
                    749: /*----------------------------------------------------------------------------
                    750: | Takes an abstract floating-point value having sign `zSign', exponent
                    751: | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
                    752: | and returns the proper extended double-precision floating-point value
                    753: | corresponding to the abstract input.  This routine is just like
                    754: | `roundAndPackFloatx80' except that the input significand does not have to be
                    755: | normalized.
                    756: *----------------------------------------------------------------------------*/
                    757: 
                    758: static floatx80
                    759:  normalizeRoundAndPackFloatx80(
                    760:      int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
                    761:  STATUS_PARAM)
                    762: {
                    763:     int8 shiftCount;
                    764: 
                    765:     if ( zSig0 == 0 ) {
                    766:         zSig0 = zSig1;
                    767:         zSig1 = 0;
                    768:         zExp -= 64;
                    769:     }
                    770:     shiftCount = countLeadingZeros64( zSig0 );
                    771:     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
                    772:     zExp -= shiftCount;
                    773:     return
                    774:         roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 STATUS_VAR);
                    775: 
                    776: }
                    777: 
                    778: #endif
                    779: 
                    780: #ifdef FLOAT128
                    781: 
                    782: /*----------------------------------------------------------------------------
                    783: | Returns the least-significant 64 fraction bits of the quadruple-precision
                    784: | floating-point value `a'.
                    785: *----------------------------------------------------------------------------*/
                    786: 
                    787: INLINE bits64 extractFloat128Frac1( float128 a )
                    788: {
                    789: 
                    790:     return a.low;
                    791: 
                    792: }
                    793: 
                    794: /*----------------------------------------------------------------------------
                    795: | Returns the most-significant 48 fraction bits of the quadruple-precision
                    796: | floating-point value `a'.
                    797: *----------------------------------------------------------------------------*/
                    798: 
                    799: INLINE bits64 extractFloat128Frac0( float128 a )
                    800: {
                    801: 
                    802:     return a.high & LIT64( 0x0000FFFFFFFFFFFF );
                    803: 
                    804: }
                    805: 
                    806: /*----------------------------------------------------------------------------
                    807: | Returns the exponent bits of the quadruple-precision floating-point value
                    808: | `a'.
                    809: *----------------------------------------------------------------------------*/
                    810: 
                    811: INLINE int32 extractFloat128Exp( float128 a )
                    812: {
                    813: 
                    814:     return ( a.high>>48 ) & 0x7FFF;
                    815: 
                    816: }
                    817: 
                    818: /*----------------------------------------------------------------------------
                    819: | Returns the sign bit of the quadruple-precision floating-point value `a'.
                    820: *----------------------------------------------------------------------------*/
                    821: 
                    822: INLINE flag extractFloat128Sign( float128 a )
                    823: {
                    824: 
                    825:     return a.high>>63;
                    826: 
                    827: }
                    828: 
                    829: /*----------------------------------------------------------------------------
                    830: | Normalizes the subnormal quadruple-precision floating-point value
                    831: | represented by the denormalized significand formed by the concatenation of
                    832: | `aSig0' and `aSig1'.  The normalized exponent is stored at the location
                    833: | pointed to by `zExpPtr'.  The most significant 49 bits of the normalized
                    834: | significand are stored at the location pointed to by `zSig0Ptr', and the
                    835: | least significant 64 bits of the normalized significand are stored at the
                    836: | location pointed to by `zSig1Ptr'.
                    837: *----------------------------------------------------------------------------*/
                    838: 
                    839: static void
                    840:  normalizeFloat128Subnormal(
                    841:      bits64 aSig0,
                    842:      bits64 aSig1,
                    843:      int32 *zExpPtr,
                    844:      bits64 *zSig0Ptr,
                    845:      bits64 *zSig1Ptr
                    846:  )
                    847: {
                    848:     int8 shiftCount;
                    849: 
                    850:     if ( aSig0 == 0 ) {
                    851:         shiftCount = countLeadingZeros64( aSig1 ) - 15;
                    852:         if ( shiftCount < 0 ) {
                    853:             *zSig0Ptr = aSig1>>( - shiftCount );
                    854:             *zSig1Ptr = aSig1<<( shiftCount & 63 );
                    855:         }
                    856:         else {
                    857:             *zSig0Ptr = aSig1<<shiftCount;
                    858:             *zSig1Ptr = 0;
                    859:         }
                    860:         *zExpPtr = - shiftCount - 63;
                    861:     }
                    862:     else {
                    863:         shiftCount = countLeadingZeros64( aSig0 ) - 15;
                    864:         shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
                    865:         *zExpPtr = 1 - shiftCount;
                    866:     }
                    867: 
                    868: }
                    869: 
                    870: /*----------------------------------------------------------------------------
                    871: | Packs the sign `zSign', the exponent `zExp', and the significand formed
                    872: | by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
                    873: | floating-point value, returning the result.  After being shifted into the
                    874: | proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
                    875: | added together to form the most significant 32 bits of the result.  This
                    876: | means that any integer portion of `zSig0' will be added into the exponent.
                    877: | Since a properly normalized significand will have an integer portion equal
                    878: | to 1, the `zExp' input should be 1 less than the desired result exponent
                    879: | whenever `zSig0' and `zSig1' concatenated form a complete, normalized
                    880: | significand.
                    881: *----------------------------------------------------------------------------*/
                    882: 
                    883: INLINE float128
                    884:  packFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 )
                    885: {
                    886:     float128 z;
                    887: 
                    888:     z.low = zSig1;
                    889:     z.high = ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<48 ) + zSig0;
                    890:     return z;
                    891: 
                    892: }
                    893: 
                    894: /*----------------------------------------------------------------------------
                    895: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                    896: | and extended significand formed by the concatenation of `zSig0', `zSig1',
                    897: | and `zSig2', and returns the proper quadruple-precision floating-point value
                    898: | corresponding to the abstract input.  Ordinarily, the abstract value is
                    899: | simply rounded and packed into the quadruple-precision format, with the
                    900: | inexact exception raised if the abstract input cannot be represented
                    901: | exactly.  However, if the abstract value is too large, the overflow and
                    902: | inexact exceptions are raised and an infinity or maximal finite value is
                    903: | returned.  If the abstract value is too small, the input value is rounded to
                    904: | a subnormal number, and the underflow and inexact exceptions are raised if
                    905: | the abstract input cannot be represented exactly as a subnormal quadruple-
                    906: | precision floating-point number.
                    907: |     The input significand must be normalized or smaller.  If the input
                    908: | significand is not normalized, `zExp' must be 0; in that case, the result
                    909: | returned is a subnormal number, and it must not require rounding.  In the
                    910: | usual case that the input significand is normalized, `zExp' must be 1 less
                    911: | than the ``true'' floating-point exponent.  The handling of underflow and
                    912: | overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                    913: *----------------------------------------------------------------------------*/
                    914: 
                    915: static float128
                    916:  roundAndPackFloat128(
                    917:      flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2 STATUS_PARAM)
                    918: {
                    919:     int8 roundingMode;
                    920:     flag roundNearestEven, increment, isTiny;
                    921: 
                    922:     roundingMode = STATUS(float_rounding_mode);
                    923:     roundNearestEven = ( roundingMode == float_round_nearest_even );
                    924:     increment = ( (sbits64) zSig2 < 0 );
                    925:     if ( ! roundNearestEven ) {
                    926:         if ( roundingMode == float_round_to_zero ) {
                    927:             increment = 0;
                    928:         }
                    929:         else {
                    930:             if ( zSign ) {
                    931:                 increment = ( roundingMode == float_round_down ) && zSig2;
                    932:             }
                    933:             else {
                    934:                 increment = ( roundingMode == float_round_up ) && zSig2;
                    935:             }
                    936:         }
                    937:     }
                    938:     if ( 0x7FFD <= (bits32) zExp ) {
                    939:         if (    ( 0x7FFD < zExp )
                    940:              || (    ( zExp == 0x7FFD )
                    941:                   && eq128(
                    942:                          LIT64( 0x0001FFFFFFFFFFFF ),
                    943:                          LIT64( 0xFFFFFFFFFFFFFFFF ),
                    944:                          zSig0,
                    945:                          zSig1
                    946:                      )
                    947:                   && increment
                    948:                 )
                    949:            ) {
                    950:             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
                    951:             if (    ( roundingMode == float_round_to_zero )
                    952:                  || ( zSign && ( roundingMode == float_round_up ) )
                    953:                  || ( ! zSign && ( roundingMode == float_round_down ) )
                    954:                ) {
                    955:                 return
                    956:                     packFloat128(
                    957:                         zSign,
                    958:                         0x7FFE,
                    959:                         LIT64( 0x0000FFFFFFFFFFFF ),
                    960:                         LIT64( 0xFFFFFFFFFFFFFFFF )
                    961:                     );
                    962:             }
                    963:             return packFloat128( zSign, 0x7FFF, 0, 0 );
                    964:         }
                    965:         if ( zExp < 0 ) {
                    966:             isTiny =
                    967:                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
                    968:                 || ( zExp < -1 )
                    969:                 || ! increment
                    970:                 || lt128(
                    971:                        zSig0,
                    972:                        zSig1,
                    973:                        LIT64( 0x0001FFFFFFFFFFFF ),
                    974:                        LIT64( 0xFFFFFFFFFFFFFFFF )
                    975:                    );
                    976:             shift128ExtraRightJamming(
                    977:                 zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
                    978:             zExp = 0;
                    979:             if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
                    980:             if ( roundNearestEven ) {
                    981:                 increment = ( (sbits64) zSig2 < 0 );
                    982:             }
                    983:             else {
                    984:                 if ( zSign ) {
                    985:                     increment = ( roundingMode == float_round_down ) && zSig2;
                    986:                 }
                    987:                 else {
                    988:                     increment = ( roundingMode == float_round_up ) && zSig2;
                    989:                 }
                    990:             }
                    991:         }
                    992:     }
                    993:     if ( zSig2 ) STATUS(float_exception_flags) |= float_flag_inexact;
                    994:     if ( increment ) {
                    995:         add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
                    996:         zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
                    997:     }
                    998:     else {
                    999:         if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
                   1000:     }
                   1001:     return packFloat128( zSign, zExp, zSig0, zSig1 );
                   1002: 
                   1003: }
                   1004: 
                   1005: /*----------------------------------------------------------------------------
                   1006: | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
                   1007: | and significand formed by the concatenation of `zSig0' and `zSig1', and
                   1008: | returns the proper quadruple-precision floating-point value corresponding
                   1009: | to the abstract input.  This routine is just like `roundAndPackFloat128'
                   1010: | except that the input significand has fewer bits and does not have to be
                   1011: | normalized.  In all cases, `zExp' must be 1 less than the ``true'' floating-
                   1012: | point exponent.
                   1013: *----------------------------------------------------------------------------*/
                   1014: 
                   1015: static float128
                   1016:  normalizeRoundAndPackFloat128(
                   1017:      flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1 STATUS_PARAM)
                   1018: {
                   1019:     int8 shiftCount;
                   1020:     bits64 zSig2;
                   1021: 
                   1022:     if ( zSig0 == 0 ) {
                   1023:         zSig0 = zSig1;
                   1024:         zSig1 = 0;
                   1025:         zExp -= 64;
                   1026:     }
                   1027:     shiftCount = countLeadingZeros64( zSig0 ) - 15;
                   1028:     if ( 0 <= shiftCount ) {
                   1029:         zSig2 = 0;
                   1030:         shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
                   1031:     }
                   1032:     else {
                   1033:         shift128ExtraRightJamming(
                   1034:             zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
                   1035:     }
                   1036:     zExp -= shiftCount;
                   1037:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR);
                   1038: 
                   1039: }
                   1040: 
                   1041: #endif
                   1042: 
                   1043: /*----------------------------------------------------------------------------
                   1044: | Returns the result of converting the 32-bit two's complement integer `a'
                   1045: | to the single-precision floating-point format.  The conversion is performed
                   1046: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1047: *----------------------------------------------------------------------------*/
                   1048: 
                   1049: float32 int32_to_float32( int32 a STATUS_PARAM )
                   1050: {
                   1051:     flag zSign;
                   1052: 
                   1053:     if ( a == 0 ) return 0;
                   1054:     if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
                   1055:     zSign = ( a < 0 );
                   1056:     return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR );
                   1057: 
                   1058: }
                   1059: 
                   1060: /*----------------------------------------------------------------------------
                   1061: | Returns the result of converting the 32-bit two's complement integer `a'
                   1062: | to the double-precision floating-point format.  The conversion is performed
                   1063: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1064: *----------------------------------------------------------------------------*/
                   1065: 
                   1066: float64 int32_to_float64( int32 a STATUS_PARAM )
                   1067: {
                   1068:     flag zSign;
                   1069:     uint32 absA;
                   1070:     int8 shiftCount;
                   1071:     bits64 zSig;
                   1072: 
                   1073:     if ( a == 0 ) return 0;
                   1074:     zSign = ( a < 0 );
                   1075:     absA = zSign ? - a : a;
                   1076:     shiftCount = countLeadingZeros32( absA ) + 21;
                   1077:     zSig = absA;
                   1078:     return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
                   1079: 
                   1080: }
                   1081: 
                   1082: #ifdef FLOATX80
                   1083: 
                   1084: /*----------------------------------------------------------------------------
                   1085: | Returns the result of converting the 32-bit two's complement integer `a'
                   1086: | to the extended double-precision floating-point format.  The conversion
                   1087: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1088: | Arithmetic.
                   1089: *----------------------------------------------------------------------------*/
                   1090: 
                   1091: floatx80 int32_to_floatx80( int32 a STATUS_PARAM )
                   1092: {
                   1093:     flag zSign;
                   1094:     uint32 absA;
                   1095:     int8 shiftCount;
                   1096:     bits64 zSig;
                   1097: 
                   1098:     if ( a == 0 ) return packFloatx80( 0, 0, 0 );
                   1099:     zSign = ( a < 0 );
                   1100:     absA = zSign ? - a : a;
                   1101:     shiftCount = countLeadingZeros32( absA ) + 32;
                   1102:     zSig = absA;
                   1103:     return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
                   1104: 
                   1105: }
                   1106: 
                   1107: #endif
                   1108: 
                   1109: #ifdef FLOAT128
                   1110: 
                   1111: /*----------------------------------------------------------------------------
                   1112: | Returns the result of converting the 32-bit two's complement integer `a' to
                   1113: | the quadruple-precision floating-point format.  The conversion is performed
                   1114: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1115: *----------------------------------------------------------------------------*/
                   1116: 
                   1117: float128 int32_to_float128( int32 a STATUS_PARAM )
                   1118: {
                   1119:     flag zSign;
                   1120:     uint32 absA;
                   1121:     int8 shiftCount;
                   1122:     bits64 zSig0;
                   1123: 
                   1124:     if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
                   1125:     zSign = ( a < 0 );
                   1126:     absA = zSign ? - a : a;
                   1127:     shiftCount = countLeadingZeros32( absA ) + 17;
                   1128:     zSig0 = absA;
                   1129:     return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
                   1130: 
                   1131: }
                   1132: 
                   1133: #endif
                   1134: 
                   1135: /*----------------------------------------------------------------------------
                   1136: | Returns the result of converting the 64-bit two's complement integer `a'
                   1137: | to the single-precision floating-point format.  The conversion is performed
                   1138: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1139: *----------------------------------------------------------------------------*/
                   1140: 
                   1141: float32 int64_to_float32( int64 a STATUS_PARAM )
                   1142: {
                   1143:     flag zSign;
                   1144:     uint64 absA;
                   1145:     int8 shiftCount;
                   1146: 
                   1147:     if ( a == 0 ) return 0;
                   1148:     zSign = ( a < 0 );
                   1149:     absA = zSign ? - a : a;
                   1150:     shiftCount = countLeadingZeros64( absA ) - 40;
                   1151:     if ( 0 <= shiftCount ) {
                   1152:         return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
                   1153:     }
                   1154:     else {
                   1155:         shiftCount += 7;
                   1156:         if ( shiftCount < 0 ) {
                   1157:             shift64RightJamming( absA, - shiftCount, &absA );
                   1158:         }
                   1159:         else {
                   1160:             absA <<= shiftCount;
                   1161:         }
                   1162:         return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
                   1163:     }
                   1164: 
                   1165: }
                   1166: 
                   1167: /*----------------------------------------------------------------------------
                   1168: | Returns the result of converting the 64-bit two's complement integer `a'
                   1169: | to the double-precision floating-point format.  The conversion is performed
                   1170: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1171: *----------------------------------------------------------------------------*/
                   1172: 
                   1173: float64 int64_to_float64( int64 a STATUS_PARAM )
                   1174: {
                   1175:     flag zSign;
                   1176: 
                   1177:     if ( a == 0 ) return 0;
                   1178:     if ( a == (sbits64) LIT64( 0x8000000000000000 ) ) {
                   1179:         return packFloat64( 1, 0x43E, 0 );
                   1180:     }
                   1181:     zSign = ( a < 0 );
                   1182:     return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
                   1183: 
                   1184: }
                   1185: 
                   1186: #ifdef FLOATX80
                   1187: 
                   1188: /*----------------------------------------------------------------------------
                   1189: | Returns the result of converting the 64-bit two's complement integer `a'
                   1190: | to the extended double-precision floating-point format.  The conversion
                   1191: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1192: | Arithmetic.
                   1193: *----------------------------------------------------------------------------*/
                   1194: 
                   1195: floatx80 int64_to_floatx80( int64 a STATUS_PARAM )
                   1196: {
                   1197:     flag zSign;
                   1198:     uint64 absA;
                   1199:     int8 shiftCount;
                   1200: 
                   1201:     if ( a == 0 ) return packFloatx80( 0, 0, 0 );
                   1202:     zSign = ( a < 0 );
                   1203:     absA = zSign ? - a : a;
                   1204:     shiftCount = countLeadingZeros64( absA );
                   1205:     return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
                   1206: 
                   1207: }
                   1208: 
                   1209: #endif
                   1210: 
                   1211: #ifdef FLOAT128
                   1212: 
                   1213: /*----------------------------------------------------------------------------
                   1214: | Returns the result of converting the 64-bit two's complement integer `a' to
                   1215: | the quadruple-precision floating-point format.  The conversion is performed
                   1216: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1217: *----------------------------------------------------------------------------*/
                   1218: 
                   1219: float128 int64_to_float128( int64 a STATUS_PARAM )
                   1220: {
                   1221:     flag zSign;
                   1222:     uint64 absA;
                   1223:     int8 shiftCount;
                   1224:     int32 zExp;
                   1225:     bits64 zSig0, zSig1;
                   1226: 
                   1227:     if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
                   1228:     zSign = ( a < 0 );
                   1229:     absA = zSign ? - a : a;
                   1230:     shiftCount = countLeadingZeros64( absA ) + 49;
                   1231:     zExp = 0x406E - shiftCount;
                   1232:     if ( 64 <= shiftCount ) {
                   1233:         zSig1 = 0;
                   1234:         zSig0 = absA;
                   1235:         shiftCount -= 64;
                   1236:     }
                   1237:     else {
                   1238:         zSig1 = absA;
                   1239:         zSig0 = 0;
                   1240:     }
                   1241:     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
                   1242:     return packFloat128( zSign, zExp, zSig0, zSig1 );
                   1243: 
                   1244: }
                   1245: 
                   1246: #endif
                   1247: 
                   1248: /*----------------------------------------------------------------------------
                   1249: | Returns the result of converting the single-precision floating-point value
                   1250: | `a' to the 32-bit two's complement integer format.  The conversion is
                   1251: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1252: | Arithmetic---which means in particular that the conversion is rounded
                   1253: | according to the current rounding mode.  If `a' is a NaN, the largest
                   1254: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   1255: | largest integer with the same sign as `a' is returned.
                   1256: *----------------------------------------------------------------------------*/
                   1257: 
                   1258: int32 float32_to_int32( float32 a STATUS_PARAM )
                   1259: {
                   1260:     flag aSign;
                   1261:     int16 aExp, shiftCount;
                   1262:     bits32 aSig;
                   1263:     bits64 aSig64;
                   1264: 
                   1265:     aSig = extractFloat32Frac( a );
                   1266:     aExp = extractFloat32Exp( a );
                   1267:     aSign = extractFloat32Sign( a );
                   1268:     if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
                   1269:     if ( aExp ) aSig |= 0x00800000;
                   1270:     shiftCount = 0xAF - aExp;
                   1271:     aSig64 = aSig;
                   1272:     aSig64 <<= 32;
                   1273:     if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
                   1274:     return roundAndPackInt32( aSign, aSig64 STATUS_VAR );
                   1275: 
                   1276: }
                   1277: 
                   1278: /*----------------------------------------------------------------------------
                   1279: | Returns the result of converting the single-precision floating-point value
                   1280: | `a' to the 32-bit two's complement integer format.  The conversion is
                   1281: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1282: | Arithmetic, except that the conversion is always rounded toward zero.
                   1283: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   1284: | the conversion overflows, the largest integer with the same sign as `a' is
                   1285: | returned.
                   1286: *----------------------------------------------------------------------------*/
                   1287: 
                   1288: int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
                   1289: {
                   1290:     flag aSign;
                   1291:     int16 aExp, shiftCount;
                   1292:     bits32 aSig;
                   1293:     int32 z;
                   1294: 
                   1295:     aSig = extractFloat32Frac( a );
                   1296:     aExp = extractFloat32Exp( a );
                   1297:     aSign = extractFloat32Sign( a );
                   1298:     shiftCount = aExp - 0x9E;
                   1299:     if ( 0 <= shiftCount ) {
                   1300:         if ( a != 0xCF000000 ) {
                   1301:             float_raise( float_flag_invalid STATUS_VAR);
                   1302:             if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
                   1303:         }
                   1304:         return (sbits32) 0x80000000;
                   1305:     }
                   1306:     else if ( aExp <= 0x7E ) {
                   1307:         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   1308:         return 0;
                   1309:     }
                   1310:     aSig = ( aSig | 0x00800000 )<<8;
                   1311:     z = aSig>>( - shiftCount );
                   1312:     if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
                   1313:         STATUS(float_exception_flags) |= float_flag_inexact;
                   1314:     }
                   1315:     if ( aSign ) z = - z;
                   1316:     return z;
                   1317: 
                   1318: }
                   1319: 
                   1320: /*----------------------------------------------------------------------------
                   1321: | Returns the result of converting the single-precision floating-point value
                   1322: | `a' to the 64-bit two's complement integer format.  The conversion is
                   1323: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1324: | Arithmetic---which means in particular that the conversion is rounded
                   1325: | according to the current rounding mode.  If `a' is a NaN, the largest
                   1326: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   1327: | largest integer with the same sign as `a' is returned.
                   1328: *----------------------------------------------------------------------------*/
                   1329: 
                   1330: int64 float32_to_int64( float32 a STATUS_PARAM )
                   1331: {
                   1332:     flag aSign;
                   1333:     int16 aExp, shiftCount;
                   1334:     bits32 aSig;
                   1335:     bits64 aSig64, aSigExtra;
                   1336: 
                   1337:     aSig = extractFloat32Frac( a );
                   1338:     aExp = extractFloat32Exp( a );
                   1339:     aSign = extractFloat32Sign( a );
                   1340:     shiftCount = 0xBE - aExp;
                   1341:     if ( shiftCount < 0 ) {
                   1342:         float_raise( float_flag_invalid STATUS_VAR);
                   1343:         if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
                   1344:             return LIT64( 0x7FFFFFFFFFFFFFFF );
                   1345:         }
                   1346:         return (sbits64) LIT64( 0x8000000000000000 );
                   1347:     }
                   1348:     if ( aExp ) aSig |= 0x00800000;
                   1349:     aSig64 = aSig;
                   1350:     aSig64 <<= 40;
                   1351:     shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
                   1352:     return roundAndPackInt64( aSign, aSig64, aSigExtra STATUS_VAR );
                   1353: 
                   1354: }
                   1355: 
                   1356: /*----------------------------------------------------------------------------
                   1357: | Returns the result of converting the single-precision floating-point value
                   1358: | `a' to the 64-bit two's complement integer format.  The conversion is
                   1359: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1360: | Arithmetic, except that the conversion is always rounded toward zero.  If
                   1361: | `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
                   1362: | conversion overflows, the largest integer with the same sign as `a' is
                   1363: | returned.
                   1364: *----------------------------------------------------------------------------*/
                   1365: 
                   1366: int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
                   1367: {
                   1368:     flag aSign;
                   1369:     int16 aExp, shiftCount;
                   1370:     bits32 aSig;
                   1371:     bits64 aSig64;
                   1372:     int64 z;
                   1373: 
                   1374:     aSig = extractFloat32Frac( a );
                   1375:     aExp = extractFloat32Exp( a );
                   1376:     aSign = extractFloat32Sign( a );
                   1377:     shiftCount = aExp - 0xBE;
                   1378:     if ( 0 <= shiftCount ) {
                   1379:         if ( a != 0xDF000000 ) {
                   1380:             float_raise( float_flag_invalid STATUS_VAR);
                   1381:             if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
                   1382:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   1383:             }
                   1384:         }
                   1385:         return (sbits64) LIT64( 0x8000000000000000 );
                   1386:     }
                   1387:     else if ( aExp <= 0x7E ) {
                   1388:         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   1389:         return 0;
                   1390:     }
                   1391:     aSig64 = aSig | 0x00800000;
                   1392:     aSig64 <<= 40;
                   1393:     z = aSig64>>( - shiftCount );
                   1394:     if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) {
                   1395:         STATUS(float_exception_flags) |= float_flag_inexact;
                   1396:     }
                   1397:     if ( aSign ) z = - z;
                   1398:     return z;
                   1399: 
                   1400: }
                   1401: 
                   1402: /*----------------------------------------------------------------------------
                   1403: | Returns the result of converting the single-precision floating-point value
                   1404: | `a' to the double-precision floating-point format.  The conversion is
                   1405: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1406: | Arithmetic.
                   1407: *----------------------------------------------------------------------------*/
                   1408: 
                   1409: float64 float32_to_float64( float32 a STATUS_PARAM )
                   1410: {
                   1411:     flag aSign;
                   1412:     int16 aExp;
                   1413:     bits32 aSig;
                   1414: 
                   1415:     aSig = extractFloat32Frac( a );
                   1416:     aExp = extractFloat32Exp( a );
                   1417:     aSign = extractFloat32Sign( a );
                   1418:     if ( aExp == 0xFF ) {
                   1419:         if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ));
                   1420:         return packFloat64( aSign, 0x7FF, 0 );
                   1421:     }
                   1422:     if ( aExp == 0 ) {
                   1423:         if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
                   1424:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1425:         --aExp;
                   1426:     }
                   1427:     return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
                   1428: 
                   1429: }
                   1430: 
                   1431: #ifdef FLOATX80
                   1432: 
                   1433: /*----------------------------------------------------------------------------
                   1434: | Returns the result of converting the single-precision floating-point value
                   1435: | `a' to the extended double-precision floating-point format.  The conversion
                   1436: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1437: | Arithmetic.
                   1438: *----------------------------------------------------------------------------*/
                   1439: 
                   1440: floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
                   1441: {
                   1442:     flag aSign;
                   1443:     int16 aExp;
                   1444:     bits32 aSig;
                   1445: 
                   1446:     aSig = extractFloat32Frac( a );
                   1447:     aExp = extractFloat32Exp( a );
                   1448:     aSign = extractFloat32Sign( a );
                   1449:     if ( aExp == 0xFF ) {
                   1450:         if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) );
                   1451:         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   1452:     }
                   1453:     if ( aExp == 0 ) {
                   1454:         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
                   1455:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1456:     }
                   1457:     aSig |= 0x00800000;
                   1458:     return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
                   1459: 
                   1460: }
                   1461: 
                   1462: #endif
                   1463: 
                   1464: #ifdef FLOAT128
                   1465: 
                   1466: /*----------------------------------------------------------------------------
                   1467: | Returns the result of converting the single-precision floating-point value
                   1468: | `a' to the double-precision floating-point format.  The conversion is
                   1469: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   1470: | Arithmetic.
                   1471: *----------------------------------------------------------------------------*/
                   1472: 
                   1473: float128 float32_to_float128( float32 a STATUS_PARAM )
                   1474: {
                   1475:     flag aSign;
                   1476:     int16 aExp;
                   1477:     bits32 aSig;
                   1478: 
                   1479:     aSig = extractFloat32Frac( a );
                   1480:     aExp = extractFloat32Exp( a );
                   1481:     aSign = extractFloat32Sign( a );
                   1482:     if ( aExp == 0xFF ) {
                   1483:         if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) );
                   1484:         return packFloat128( aSign, 0x7FFF, 0, 0 );
                   1485:     }
                   1486:     if ( aExp == 0 ) {
                   1487:         if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
                   1488:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1489:         --aExp;
                   1490:     }
                   1491:     return packFloat128( aSign, aExp + 0x3F80, ( (bits64) aSig )<<25, 0 );
                   1492: 
                   1493: }
                   1494: 
                   1495: #endif
                   1496: 
                   1497: /*----------------------------------------------------------------------------
                   1498: | Rounds the single-precision floating-point value `a' to an integer, and
                   1499: | returns the result as a single-precision floating-point value.  The
                   1500: | operation is performed according to the IEC/IEEE Standard for Binary
                   1501: | Floating-Point Arithmetic.
                   1502: *----------------------------------------------------------------------------*/
                   1503: 
                   1504: float32 float32_round_to_int( float32 a STATUS_PARAM)
                   1505: {
                   1506:     flag aSign;
                   1507:     int16 aExp;
                   1508:     bits32 lastBitMask, roundBitsMask;
                   1509:     int8 roundingMode;
                   1510:     float32 z;
                   1511: 
                   1512:     aExp = extractFloat32Exp( a );
                   1513:     if ( 0x96 <= aExp ) {
                   1514:         if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
                   1515:             return propagateFloat32NaN( a, a STATUS_VAR );
                   1516:         }
                   1517:         return a;
                   1518:     }
                   1519:     if ( aExp <= 0x7E ) {
                   1520:         if ( (bits32) ( a<<1 ) == 0 ) return a;
                   1521:         STATUS(float_exception_flags) |= float_flag_inexact;
                   1522:         aSign = extractFloat32Sign( a );
                   1523:         switch ( STATUS(float_rounding_mode) ) {
                   1524:          case float_round_nearest_even:
                   1525:             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
                   1526:                 return packFloat32( aSign, 0x7F, 0 );
                   1527:             }
                   1528:             break;
                   1529:          case float_round_down:
                   1530:             return aSign ? 0xBF800000 : 0;
                   1531:          case float_round_up:
                   1532:             return aSign ? 0x80000000 : 0x3F800000;
                   1533:         }
                   1534:         return packFloat32( aSign, 0, 0 );
                   1535:     }
                   1536:     lastBitMask = 1;
                   1537:     lastBitMask <<= 0x96 - aExp;
                   1538:     roundBitsMask = lastBitMask - 1;
                   1539:     z = a;
                   1540:     roundingMode = STATUS(float_rounding_mode);
                   1541:     if ( roundingMode == float_round_nearest_even ) {
                   1542:         z += lastBitMask>>1;
                   1543:         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
                   1544:     }
                   1545:     else if ( roundingMode != float_round_to_zero ) {
                   1546:         if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
                   1547:             z += roundBitsMask;
                   1548:         }
                   1549:     }
                   1550:     z &= ~ roundBitsMask;
                   1551:     if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact;
                   1552:     return z;
                   1553: 
                   1554: }
                   1555: 
                   1556: /*----------------------------------------------------------------------------
                   1557: | Returns the result of adding the absolute values of the single-precision
                   1558: | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
                   1559: | before being returned.  `zSign' is ignored if the result is a NaN.
                   1560: | The addition is performed according to the IEC/IEEE Standard for Binary
                   1561: | Floating-Point Arithmetic.
                   1562: *----------------------------------------------------------------------------*/
                   1563: 
                   1564: static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
                   1565: {
                   1566:     int16 aExp, bExp, zExp;
                   1567:     bits32 aSig, bSig, zSig;
                   1568:     int16 expDiff;
                   1569: 
                   1570:     aSig = extractFloat32Frac( a );
                   1571:     aExp = extractFloat32Exp( a );
                   1572:     bSig = extractFloat32Frac( b );
                   1573:     bExp = extractFloat32Exp( b );
                   1574:     expDiff = aExp - bExp;
                   1575:     aSig <<= 6;
                   1576:     bSig <<= 6;
                   1577:     if ( 0 < expDiff ) {
                   1578:         if ( aExp == 0xFF ) {
                   1579:             if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1580:             return a;
                   1581:         }
                   1582:         if ( bExp == 0 ) {
                   1583:             --expDiff;
                   1584:         }
                   1585:         else {
                   1586:             bSig |= 0x20000000;
                   1587:         }
                   1588:         shift32RightJamming( bSig, expDiff, &bSig );
                   1589:         zExp = aExp;
                   1590:     }
                   1591:     else if ( expDiff < 0 ) {
                   1592:         if ( bExp == 0xFF ) {
                   1593:             if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1594:             return packFloat32( zSign, 0xFF, 0 );
                   1595:         }
                   1596:         if ( aExp == 0 ) {
                   1597:             ++expDiff;
                   1598:         }
                   1599:         else {
                   1600:             aSig |= 0x20000000;
                   1601:         }
                   1602:         shift32RightJamming( aSig, - expDiff, &aSig );
                   1603:         zExp = bExp;
                   1604:     }
                   1605:     else {
                   1606:         if ( aExp == 0xFF ) {
                   1607:             if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1608:             return a;
                   1609:         }
                   1610:         if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
                   1611:         zSig = 0x40000000 + aSig + bSig;
                   1612:         zExp = aExp;
                   1613:         goto roundAndPack;
                   1614:     }
                   1615:     aSig |= 0x20000000;
                   1616:     zSig = ( aSig + bSig )<<1;
                   1617:     --zExp;
                   1618:     if ( (sbits32) zSig < 0 ) {
                   1619:         zSig = aSig + bSig;
                   1620:         ++zExp;
                   1621:     }
                   1622:  roundAndPack:
                   1623:     return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
                   1624: 
                   1625: }
                   1626: 
                   1627: /*----------------------------------------------------------------------------
                   1628: | Returns the result of subtracting the absolute values of the single-
                   1629: | precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   1630: | difference is negated before being returned.  `zSign' is ignored if the
                   1631: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   1632: | Standard for Binary Floating-Point Arithmetic.
                   1633: *----------------------------------------------------------------------------*/
                   1634: 
                   1635: static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
                   1636: {
                   1637:     int16 aExp, bExp, zExp;
                   1638:     bits32 aSig, bSig, zSig;
                   1639:     int16 expDiff;
                   1640: 
                   1641:     aSig = extractFloat32Frac( a );
                   1642:     aExp = extractFloat32Exp( a );
                   1643:     bSig = extractFloat32Frac( b );
                   1644:     bExp = extractFloat32Exp( b );
                   1645:     expDiff = aExp - bExp;
                   1646:     aSig <<= 7;
                   1647:     bSig <<= 7;
                   1648:     if ( 0 < expDiff ) goto aExpBigger;
                   1649:     if ( expDiff < 0 ) goto bExpBigger;
                   1650:     if ( aExp == 0xFF ) {
                   1651:         if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1652:         float_raise( float_flag_invalid STATUS_VAR);
                   1653:         return float32_default_nan;
                   1654:     }
                   1655:     if ( aExp == 0 ) {
                   1656:         aExp = 1;
                   1657:         bExp = 1;
                   1658:     }
                   1659:     if ( bSig < aSig ) goto aBigger;
                   1660:     if ( aSig < bSig ) goto bBigger;
                   1661:     return packFloat32( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
                   1662:  bExpBigger:
                   1663:     if ( bExp == 0xFF ) {
                   1664:         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1665:         return packFloat32( zSign ^ 1, 0xFF, 0 );
                   1666:     }
                   1667:     if ( aExp == 0 ) {
                   1668:         ++expDiff;
                   1669:     }
                   1670:     else {
                   1671:         aSig |= 0x40000000;
                   1672:     }
                   1673:     shift32RightJamming( aSig, - expDiff, &aSig );
                   1674:     bSig |= 0x40000000;
                   1675:  bBigger:
                   1676:     zSig = bSig - aSig;
                   1677:     zExp = bExp;
                   1678:     zSign ^= 1;
                   1679:     goto normalizeRoundAndPack;
                   1680:  aExpBigger:
                   1681:     if ( aExp == 0xFF ) {
                   1682:         if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1683:         return a;
                   1684:     }
                   1685:     if ( bExp == 0 ) {
                   1686:         --expDiff;
                   1687:     }
                   1688:     else {
                   1689:         bSig |= 0x40000000;
                   1690:     }
                   1691:     shift32RightJamming( bSig, expDiff, &bSig );
                   1692:     aSig |= 0x40000000;
                   1693:  aBigger:
                   1694:     zSig = aSig - bSig;
                   1695:     zExp = aExp;
                   1696:  normalizeRoundAndPack:
                   1697:     --zExp;
                   1698:     return normalizeRoundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
                   1699: 
                   1700: }
                   1701: 
                   1702: /*----------------------------------------------------------------------------
                   1703: | Returns the result of adding the single-precision floating-point values `a'
                   1704: | and `b'.  The operation is performed according to the IEC/IEEE Standard for
                   1705: | Binary Floating-Point Arithmetic.
                   1706: *----------------------------------------------------------------------------*/
                   1707: 
                   1708: float32 float32_add( float32 a, float32 b STATUS_PARAM )
                   1709: {
                   1710:     flag aSign, bSign;
                   1711: 
                   1712:     aSign = extractFloat32Sign( a );
                   1713:     bSign = extractFloat32Sign( b );
                   1714:     if ( aSign == bSign ) {
                   1715:         return addFloat32Sigs( a, b, aSign STATUS_VAR);
                   1716:     }
                   1717:     else {
                   1718:         return subFloat32Sigs( a, b, aSign STATUS_VAR );
                   1719:     }
                   1720: 
                   1721: }
                   1722: 
                   1723: /*----------------------------------------------------------------------------
                   1724: | Returns the result of subtracting the single-precision floating-point values
                   1725: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   1726: | for Binary Floating-Point Arithmetic.
                   1727: *----------------------------------------------------------------------------*/
                   1728: 
                   1729: float32 float32_sub( float32 a, float32 b STATUS_PARAM )
                   1730: {
                   1731:     flag aSign, bSign;
                   1732: 
                   1733:     aSign = extractFloat32Sign( a );
                   1734:     bSign = extractFloat32Sign( b );
                   1735:     if ( aSign == bSign ) {
                   1736:         return subFloat32Sigs( a, b, aSign STATUS_VAR );
                   1737:     }
                   1738:     else {
                   1739:         return addFloat32Sigs( a, b, aSign STATUS_VAR );
                   1740:     }
                   1741: 
                   1742: }
                   1743: 
                   1744: /*----------------------------------------------------------------------------
                   1745: | Returns the result of multiplying the single-precision floating-point values
                   1746: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   1747: | for Binary Floating-Point Arithmetic.
                   1748: *----------------------------------------------------------------------------*/
                   1749: 
                   1750: float32 float32_mul( float32 a, float32 b STATUS_PARAM )
                   1751: {
                   1752:     flag aSign, bSign, zSign;
                   1753:     int16 aExp, bExp, zExp;
                   1754:     bits32 aSig, bSig;
                   1755:     bits64 zSig64;
                   1756:     bits32 zSig;
                   1757: 
                   1758:     aSig = extractFloat32Frac( a );
                   1759:     aExp = extractFloat32Exp( a );
                   1760:     aSign = extractFloat32Sign( a );
                   1761:     bSig = extractFloat32Frac( b );
                   1762:     bExp = extractFloat32Exp( b );
                   1763:     bSign = extractFloat32Sign( b );
                   1764:     zSign = aSign ^ bSign;
                   1765:     if ( aExp == 0xFF ) {
                   1766:         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
                   1767:             return propagateFloat32NaN( a, b STATUS_VAR );
                   1768:         }
                   1769:         if ( ( bExp | bSig ) == 0 ) {
                   1770:             float_raise( float_flag_invalid STATUS_VAR);
                   1771:             return float32_default_nan;
                   1772:         }
                   1773:         return packFloat32( zSign, 0xFF, 0 );
                   1774:     }
                   1775:     if ( bExp == 0xFF ) {
                   1776:         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1777:         if ( ( aExp | aSig ) == 0 ) {
                   1778:             float_raise( float_flag_invalid STATUS_VAR);
                   1779:             return float32_default_nan;
                   1780:         }
                   1781:         return packFloat32( zSign, 0xFF, 0 );
                   1782:     }
                   1783:     if ( aExp == 0 ) {
                   1784:         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
                   1785:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1786:     }
                   1787:     if ( bExp == 0 ) {
                   1788:         if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
                   1789:         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
                   1790:     }
                   1791:     zExp = aExp + bExp - 0x7F;
                   1792:     aSig = ( aSig | 0x00800000 )<<7;
                   1793:     bSig = ( bSig | 0x00800000 )<<8;
                   1794:     shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
                   1795:     zSig = zSig64;
                   1796:     if ( 0 <= (sbits32) ( zSig<<1 ) ) {
                   1797:         zSig <<= 1;
                   1798:         --zExp;
                   1799:     }
                   1800:     return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
                   1801: 
                   1802: }
                   1803: 
                   1804: /*----------------------------------------------------------------------------
                   1805: | Returns the result of dividing the single-precision floating-point value `a'
                   1806: | by the corresponding value `b'.  The operation is performed according to the
                   1807: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1808: *----------------------------------------------------------------------------*/
                   1809: 
                   1810: float32 float32_div( float32 a, float32 b STATUS_PARAM )
                   1811: {
                   1812:     flag aSign, bSign, zSign;
                   1813:     int16 aExp, bExp, zExp;
                   1814:     bits32 aSig, bSig, zSig;
                   1815: 
                   1816:     aSig = extractFloat32Frac( a );
                   1817:     aExp = extractFloat32Exp( a );
                   1818:     aSign = extractFloat32Sign( a );
                   1819:     bSig = extractFloat32Frac( b );
                   1820:     bExp = extractFloat32Exp( b );
                   1821:     bSign = extractFloat32Sign( b );
                   1822:     zSign = aSign ^ bSign;
                   1823:     if ( aExp == 0xFF ) {
                   1824:         if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1825:         if ( bExp == 0xFF ) {
                   1826:             if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1827:             float_raise( float_flag_invalid STATUS_VAR);
                   1828:             return float32_default_nan;
                   1829:         }
                   1830:         return packFloat32( zSign, 0xFF, 0 );
                   1831:     }
                   1832:     if ( bExp == 0xFF ) {
                   1833:         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1834:         return packFloat32( zSign, 0, 0 );
                   1835:     }
                   1836:     if ( bExp == 0 ) {
                   1837:         if ( bSig == 0 ) {
                   1838:             if ( ( aExp | aSig ) == 0 ) {
                   1839:                 float_raise( float_flag_invalid STATUS_VAR);
                   1840:                 return float32_default_nan;
                   1841:             }
                   1842:             float_raise( float_flag_divbyzero STATUS_VAR);
                   1843:             return packFloat32( zSign, 0xFF, 0 );
                   1844:         }
                   1845:         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
                   1846:     }
                   1847:     if ( aExp == 0 ) {
                   1848:         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
                   1849:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1850:     }
                   1851:     zExp = aExp - bExp + 0x7D;
                   1852:     aSig = ( aSig | 0x00800000 )<<7;
                   1853:     bSig = ( bSig | 0x00800000 )<<8;
                   1854:     if ( bSig <= ( aSig + aSig ) ) {
                   1855:         aSig >>= 1;
                   1856:         ++zExp;
                   1857:     }
                   1858:     zSig = ( ( (bits64) aSig )<<32 ) / bSig;
                   1859:     if ( ( zSig & 0x3F ) == 0 ) {
                   1860:         zSig |= ( (bits64) bSig * zSig != ( (bits64) aSig )<<32 );
                   1861:     }
                   1862:     return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
                   1863: 
                   1864: }
                   1865: 
                   1866: /*----------------------------------------------------------------------------
                   1867: | Returns the remainder of the single-precision floating-point value `a'
                   1868: | with respect to the corresponding value `b'.  The operation is performed
                   1869: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   1870: *----------------------------------------------------------------------------*/
                   1871: 
                   1872: float32 float32_rem( float32 a, float32 b STATUS_PARAM )
                   1873: {
                   1874:     flag aSign, bSign, zSign;
                   1875:     int16 aExp, bExp, expDiff;
                   1876:     bits32 aSig, bSig;
                   1877:     bits32 q;
                   1878:     bits64 aSig64, bSig64, q64;
                   1879:     bits32 alternateASig;
                   1880:     sbits32 sigMean;
                   1881: 
                   1882:     aSig = extractFloat32Frac( a );
                   1883:     aExp = extractFloat32Exp( a );
                   1884:     aSign = extractFloat32Sign( a );
                   1885:     bSig = extractFloat32Frac( b );
                   1886:     bExp = extractFloat32Exp( b );
                   1887:     bSign = extractFloat32Sign( b );
                   1888:     if ( aExp == 0xFF ) {
                   1889:         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
                   1890:             return propagateFloat32NaN( a, b STATUS_VAR );
                   1891:         }
                   1892:         float_raise( float_flag_invalid STATUS_VAR);
                   1893:         return float32_default_nan;
                   1894:     }
                   1895:     if ( bExp == 0xFF ) {
                   1896:         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1897:         return a;
                   1898:     }
                   1899:     if ( bExp == 0 ) {
                   1900:         if ( bSig == 0 ) {
                   1901:             float_raise( float_flag_invalid STATUS_VAR);
                   1902:             return float32_default_nan;
                   1903:         }
                   1904:         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
                   1905:     }
                   1906:     if ( aExp == 0 ) {
                   1907:         if ( aSig == 0 ) return a;
                   1908:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1909:     }
                   1910:     expDiff = aExp - bExp;
                   1911:     aSig |= 0x00800000;
                   1912:     bSig |= 0x00800000;
                   1913:     if ( expDiff < 32 ) {
                   1914:         aSig <<= 8;
                   1915:         bSig <<= 8;
                   1916:         if ( expDiff < 0 ) {
                   1917:             if ( expDiff < -1 ) return a;
                   1918:             aSig >>= 1;
                   1919:         }
                   1920:         q = ( bSig <= aSig );
                   1921:         if ( q ) aSig -= bSig;
                   1922:         if ( 0 < expDiff ) {
                   1923:             q = ( ( (bits64) aSig )<<32 ) / bSig;
                   1924:             q >>= 32 - expDiff;
                   1925:             bSig >>= 2;
                   1926:             aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
                   1927:         }
                   1928:         else {
                   1929:             aSig >>= 2;
                   1930:             bSig >>= 2;
                   1931:         }
                   1932:     }
                   1933:     else {
                   1934:         if ( bSig <= aSig ) aSig -= bSig;
                   1935:         aSig64 = ( (bits64) aSig )<<40;
                   1936:         bSig64 = ( (bits64) bSig )<<40;
                   1937:         expDiff -= 64;
                   1938:         while ( 0 < expDiff ) {
                   1939:             q64 = estimateDiv128To64( aSig64, 0, bSig64 );
                   1940:             q64 = ( 2 < q64 ) ? q64 - 2 : 0;
                   1941:             aSig64 = - ( ( bSig * q64 )<<38 );
                   1942:             expDiff -= 62;
                   1943:         }
                   1944:         expDiff += 64;
                   1945:         q64 = estimateDiv128To64( aSig64, 0, bSig64 );
                   1946:         q64 = ( 2 < q64 ) ? q64 - 2 : 0;
                   1947:         q = q64>>( 64 - expDiff );
                   1948:         bSig <<= 6;
                   1949:         aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
                   1950:     }
                   1951:     do {
                   1952:         alternateASig = aSig;
                   1953:         ++q;
                   1954:         aSig -= bSig;
                   1955:     } while ( 0 <= (sbits32) aSig );
                   1956:     sigMean = aSig + alternateASig;
                   1957:     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
                   1958:         aSig = alternateASig;
                   1959:     }
                   1960:     zSign = ( (sbits32) aSig < 0 );
                   1961:     if ( zSign ) aSig = - aSig;
                   1962:     return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
                   1963: 
                   1964: }
                   1965: 
                   1966: /*----------------------------------------------------------------------------
                   1967: | Returns the square root of the single-precision floating-point value `a'.
                   1968: | The operation is performed according to the IEC/IEEE Standard for Binary
                   1969: | Floating-Point Arithmetic.
                   1970: *----------------------------------------------------------------------------*/
                   1971: 
                   1972: float32 float32_sqrt( float32 a STATUS_PARAM )
                   1973: {
                   1974:     flag aSign;
                   1975:     int16 aExp, zExp;
                   1976:     bits32 aSig, zSig;
                   1977:     bits64 rem, term;
                   1978: 
                   1979:     aSig = extractFloat32Frac( a );
                   1980:     aExp = extractFloat32Exp( a );
                   1981:     aSign = extractFloat32Sign( a );
                   1982:     if ( aExp == 0xFF ) {
                   1983:         if ( aSig ) return propagateFloat32NaN( a, 0 STATUS_VAR );
                   1984:         if ( ! aSign ) return a;
                   1985:         float_raise( float_flag_invalid STATUS_VAR);
                   1986:         return float32_default_nan;
                   1987:     }
                   1988:     if ( aSign ) {
                   1989:         if ( ( aExp | aSig ) == 0 ) return a;
                   1990:         float_raise( float_flag_invalid STATUS_VAR);
                   1991:         return float32_default_nan;
                   1992:     }
                   1993:     if ( aExp == 0 ) {
                   1994:         if ( aSig == 0 ) return 0;
                   1995:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1996:     }
                   1997:     zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
                   1998:     aSig = ( aSig | 0x00800000 )<<8;
                   1999:     zSig = estimateSqrt32( aExp, aSig ) + 2;
                   2000:     if ( ( zSig & 0x7F ) <= 5 ) {
                   2001:         if ( zSig < 2 ) {
                   2002:             zSig = 0x7FFFFFFF;
                   2003:             goto roundAndPack;
                   2004:         }
                   2005:         aSig >>= aExp & 1;
                   2006:         term = ( (bits64) zSig ) * zSig;
                   2007:         rem = ( ( (bits64) aSig )<<32 ) - term;
                   2008:         while ( (sbits64) rem < 0 ) {
                   2009:             --zSig;
                   2010:             rem += ( ( (bits64) zSig )<<1 ) | 1;
                   2011:         }
                   2012:         zSig |= ( rem != 0 );
                   2013:     }
                   2014:     shift32RightJamming( zSig, 1, &zSig );
                   2015:  roundAndPack:
                   2016:     return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
                   2017: 
                   2018: }
                   2019: 
                   2020: /*----------------------------------------------------------------------------
                   2021: | Returns 1 if the single-precision floating-point value `a' is equal to
                   2022: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   2023: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2024: *----------------------------------------------------------------------------*/
                   2025: 
                   2026: flag float32_eq( float32 a, float32 b STATUS_PARAM )
                   2027: {
                   2028: 
                   2029:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2030:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2031:        ) {
                   2032:         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
                   2033:             float_raise( float_flag_invalid STATUS_VAR);
                   2034:         }
                   2035:         return 0;
                   2036:     }
                   2037:     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
                   2038: 
                   2039: }
                   2040: 
                   2041: /*----------------------------------------------------------------------------
                   2042: | Returns 1 if the single-precision floating-point value `a' is less than
                   2043: | or equal to the corresponding value `b', and 0 otherwise.  The comparison
                   2044: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2045: | Arithmetic.
                   2046: *----------------------------------------------------------------------------*/
                   2047: 
                   2048: flag float32_le( float32 a, float32 b STATUS_PARAM )
                   2049: {
                   2050:     flag aSign, bSign;
                   2051: 
                   2052:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2053:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2054:        ) {
                   2055:         float_raise( float_flag_invalid STATUS_VAR);
                   2056:         return 0;
                   2057:     }
                   2058:     aSign = extractFloat32Sign( a );
                   2059:     bSign = extractFloat32Sign( b );
                   2060:     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
                   2061:     return ( a == b ) || ( aSign ^ ( a < b ) );
                   2062: 
                   2063: }
                   2064: 
                   2065: /*----------------------------------------------------------------------------
                   2066: | Returns 1 if the single-precision floating-point value `a' is less than
                   2067: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   2068: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2069: *----------------------------------------------------------------------------*/
                   2070: 
                   2071: flag float32_lt( float32 a, float32 b STATUS_PARAM )
                   2072: {
                   2073:     flag aSign, bSign;
                   2074: 
                   2075:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2076:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2077:        ) {
                   2078:         float_raise( float_flag_invalid STATUS_VAR);
                   2079:         return 0;
                   2080:     }
                   2081:     aSign = extractFloat32Sign( a );
                   2082:     bSign = extractFloat32Sign( b );
                   2083:     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
                   2084:     return ( a != b ) && ( aSign ^ ( a < b ) );
                   2085: 
                   2086: }
                   2087: 
                   2088: /*----------------------------------------------------------------------------
                   2089: | Returns 1 if the single-precision floating-point value `a' is equal to
                   2090: | the corresponding value `b', and 0 otherwise.  The invalid exception is
                   2091: | raised if either operand is a NaN.  Otherwise, the comparison is performed
                   2092: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2093: *----------------------------------------------------------------------------*/
                   2094: 
                   2095: flag float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
                   2096: {
                   2097: 
                   2098:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2099:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2100:        ) {
                   2101:         float_raise( float_flag_invalid STATUS_VAR);
                   2102:         return 0;
                   2103:     }
                   2104:     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
                   2105: 
                   2106: }
                   2107: 
                   2108: /*----------------------------------------------------------------------------
                   2109: | Returns 1 if the single-precision floating-point value `a' is less than or
                   2110: | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
                   2111: | cause an exception.  Otherwise, the comparison is performed according to the
                   2112: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2113: *----------------------------------------------------------------------------*/
                   2114: 
                   2115: flag float32_le_quiet( float32 a, float32 b STATUS_PARAM )
                   2116: {
                   2117:     flag aSign, bSign;
                   2118: 
                   2119:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2120:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2121:        ) {
                   2122:         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
                   2123:             float_raise( float_flag_invalid STATUS_VAR);
                   2124:         }
                   2125:         return 0;
                   2126:     }
                   2127:     aSign = extractFloat32Sign( a );
                   2128:     bSign = extractFloat32Sign( b );
                   2129:     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
                   2130:     return ( a == b ) || ( aSign ^ ( a < b ) );
                   2131: 
                   2132: }
                   2133: 
                   2134: /*----------------------------------------------------------------------------
                   2135: | Returns 1 if the single-precision floating-point value `a' is less than
                   2136: | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
                   2137: | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
                   2138: | Standard for Binary Floating-Point Arithmetic.
                   2139: *----------------------------------------------------------------------------*/
                   2140: 
                   2141: flag float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
                   2142: {
                   2143:     flag aSign, bSign;
                   2144: 
                   2145:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2146:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2147:        ) {
                   2148:         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
                   2149:             float_raise( float_flag_invalid STATUS_VAR);
                   2150:         }
                   2151:         return 0;
                   2152:     }
                   2153:     aSign = extractFloat32Sign( a );
                   2154:     bSign = extractFloat32Sign( b );
                   2155:     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
                   2156:     return ( a != b ) && ( aSign ^ ( a < b ) );
                   2157: 
                   2158: }
                   2159: 
                   2160: /*----------------------------------------------------------------------------
                   2161: | Returns the result of converting the double-precision floating-point value
                   2162: | `a' to the 32-bit two's complement integer format.  The conversion is
                   2163: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2164: | Arithmetic---which means in particular that the conversion is rounded
                   2165: | according to the current rounding mode.  If `a' is a NaN, the largest
                   2166: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   2167: | largest integer with the same sign as `a' is returned.
                   2168: *----------------------------------------------------------------------------*/
                   2169: 
                   2170: int32 float64_to_int32( float64 a STATUS_PARAM )
                   2171: {
                   2172:     flag aSign;
                   2173:     int16 aExp, shiftCount;
                   2174:     bits64 aSig;
                   2175: 
                   2176:     aSig = extractFloat64Frac( a );
                   2177:     aExp = extractFloat64Exp( a );
                   2178:     aSign = extractFloat64Sign( a );
                   2179:     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
                   2180:     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
                   2181:     shiftCount = 0x42C - aExp;
                   2182:     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
                   2183:     return roundAndPackInt32( aSign, aSig STATUS_VAR );
                   2184: 
                   2185: }
                   2186: 
                   2187: /*----------------------------------------------------------------------------
                   2188: | Returns the result of converting the double-precision floating-point value
                   2189: | `a' to the 32-bit two's complement integer format.  The conversion is
                   2190: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2191: | Arithmetic, except that the conversion is always rounded toward zero.
                   2192: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   2193: | the conversion overflows, the largest integer with the same sign as `a' is
                   2194: | returned.
                   2195: *----------------------------------------------------------------------------*/
                   2196: 
                   2197: int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
                   2198: {
                   2199:     flag aSign;
                   2200:     int16 aExp, shiftCount;
                   2201:     bits64 aSig, savedASig;
                   2202:     int32 z;
                   2203: 
                   2204:     aSig = extractFloat64Frac( a );
                   2205:     aExp = extractFloat64Exp( a );
                   2206:     aSign = extractFloat64Sign( a );
                   2207:     if ( 0x41E < aExp ) {
                   2208:         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
                   2209:         goto invalid;
                   2210:     }
                   2211:     else if ( aExp < 0x3FF ) {
                   2212:         if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   2213:         return 0;
                   2214:     }
                   2215:     aSig |= LIT64( 0x0010000000000000 );
                   2216:     shiftCount = 0x433 - aExp;
                   2217:     savedASig = aSig;
                   2218:     aSig >>= shiftCount;
                   2219:     z = aSig;
                   2220:     if ( aSign ) z = - z;
                   2221:     if ( ( z < 0 ) ^ aSign ) {
                   2222:  invalid:
                   2223:         float_raise( float_flag_invalid STATUS_VAR);
                   2224:         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                   2225:     }
                   2226:     if ( ( aSig<<shiftCount ) != savedASig ) {
                   2227:         STATUS(float_exception_flags) |= float_flag_inexact;
                   2228:     }
                   2229:     return z;
                   2230: 
                   2231: }
                   2232: 
                   2233: /*----------------------------------------------------------------------------
                   2234: | Returns the result of converting the double-precision floating-point value
                   2235: | `a' to the 64-bit two's complement integer format.  The conversion is
                   2236: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2237: | Arithmetic---which means in particular that the conversion is rounded
                   2238: | according to the current rounding mode.  If `a' is a NaN, the largest
                   2239: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   2240: | largest integer with the same sign as `a' is returned.
                   2241: *----------------------------------------------------------------------------*/
                   2242: 
                   2243: int64 float64_to_int64( float64 a STATUS_PARAM )
                   2244: {
                   2245:     flag aSign;
                   2246:     int16 aExp, shiftCount;
                   2247:     bits64 aSig, aSigExtra;
                   2248: 
                   2249:     aSig = extractFloat64Frac( a );
                   2250:     aExp = extractFloat64Exp( a );
                   2251:     aSign = extractFloat64Sign( a );
                   2252:     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
                   2253:     shiftCount = 0x433 - aExp;
                   2254:     if ( shiftCount <= 0 ) {
                   2255:         if ( 0x43E < aExp ) {
                   2256:             float_raise( float_flag_invalid STATUS_VAR);
                   2257:             if (    ! aSign
                   2258:                  || (    ( aExp == 0x7FF )
                   2259:                       && ( aSig != LIT64( 0x0010000000000000 ) ) )
                   2260:                ) {
                   2261:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   2262:             }
                   2263:             return (sbits64) LIT64( 0x8000000000000000 );
                   2264:         }
                   2265:         aSigExtra = 0;
                   2266:         aSig <<= - shiftCount;
                   2267:     }
                   2268:     else {
                   2269:         shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
                   2270:     }
                   2271:     return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
                   2272: 
                   2273: }
                   2274: 
                   2275: /*----------------------------------------------------------------------------
                   2276: | Returns the result of converting the double-precision floating-point value
                   2277: | `a' to the 64-bit two's complement integer format.  The conversion is
                   2278: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2279: | Arithmetic, except that the conversion is always rounded toward zero.
                   2280: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   2281: | the conversion overflows, the largest integer with the same sign as `a' is
                   2282: | returned.
                   2283: *----------------------------------------------------------------------------*/
                   2284: 
                   2285: int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
                   2286: {
                   2287:     flag aSign;
                   2288:     int16 aExp, shiftCount;
                   2289:     bits64 aSig;
                   2290:     int64 z;
                   2291: 
                   2292:     aSig = extractFloat64Frac( a );
                   2293:     aExp = extractFloat64Exp( a );
                   2294:     aSign = extractFloat64Sign( a );
                   2295:     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
                   2296:     shiftCount = aExp - 0x433;
                   2297:     if ( 0 <= shiftCount ) {
                   2298:         if ( 0x43E <= aExp ) {
                   2299:             if ( a != LIT64( 0xC3E0000000000000 ) ) {
                   2300:                 float_raise( float_flag_invalid STATUS_VAR);
                   2301:                 if (    ! aSign
                   2302:                      || (    ( aExp == 0x7FF )
                   2303:                           && ( aSig != LIT64( 0x0010000000000000 ) ) )
                   2304:                    ) {
                   2305:                     return LIT64( 0x7FFFFFFFFFFFFFFF );
                   2306:                 }
                   2307:             }
                   2308:             return (sbits64) LIT64( 0x8000000000000000 );
                   2309:         }
                   2310:         z = aSig<<shiftCount;
                   2311:     }
                   2312:     else {
                   2313:         if ( aExp < 0x3FE ) {
                   2314:             if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   2315:             return 0;
                   2316:         }
                   2317:         z = aSig>>( - shiftCount );
                   2318:         if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
                   2319:             STATUS(float_exception_flags) |= float_flag_inexact;
                   2320:         }
                   2321:     }
                   2322:     if ( aSign ) z = - z;
                   2323:     return z;
                   2324: 
                   2325: }
                   2326: 
                   2327: /*----------------------------------------------------------------------------
                   2328: | Returns the result of converting the double-precision floating-point value
                   2329: | `a' to the single-precision floating-point format.  The conversion is
                   2330: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2331: | Arithmetic.
                   2332: *----------------------------------------------------------------------------*/
                   2333: 
                   2334: float32 float64_to_float32( float64 a STATUS_PARAM )
                   2335: {
                   2336:     flag aSign;
                   2337:     int16 aExp;
                   2338:     bits64 aSig;
                   2339:     bits32 zSig;
                   2340: 
                   2341:     aSig = extractFloat64Frac( a );
                   2342:     aExp = extractFloat64Exp( a );
                   2343:     aSign = extractFloat64Sign( a );
                   2344:     if ( aExp == 0x7FF ) {
                   2345:         if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) );
                   2346:         return packFloat32( aSign, 0xFF, 0 );
                   2347:     }
                   2348:     shift64RightJamming( aSig, 22, &aSig );
                   2349:     zSig = aSig;
                   2350:     if ( aExp || zSig ) {
                   2351:         zSig |= 0x40000000;
                   2352:         aExp -= 0x381;
                   2353:     }
                   2354:     return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
                   2355: 
                   2356: }
                   2357: 
                   2358: #ifdef FLOATX80
                   2359: 
                   2360: /*----------------------------------------------------------------------------
                   2361: | Returns the result of converting the double-precision floating-point value
                   2362: | `a' to the extended double-precision floating-point format.  The conversion
                   2363: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2364: | Arithmetic.
                   2365: *----------------------------------------------------------------------------*/
                   2366: 
                   2367: floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
                   2368: {
                   2369:     flag aSign;
                   2370:     int16 aExp;
                   2371:     bits64 aSig;
                   2372: 
                   2373:     aSig = extractFloat64Frac( a );
                   2374:     aExp = extractFloat64Exp( a );
                   2375:     aSign = extractFloat64Sign( a );
                   2376:     if ( aExp == 0x7FF ) {
                   2377:         if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) );
                   2378:         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   2379:     }
                   2380:     if ( aExp == 0 ) {
                   2381:         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
                   2382:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2383:     }
                   2384:     return
                   2385:         packFloatx80(
                   2386:             aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
                   2387: 
                   2388: }
                   2389: 
                   2390: #endif
                   2391: 
                   2392: #ifdef FLOAT128
                   2393: 
                   2394: /*----------------------------------------------------------------------------
                   2395: | Returns the result of converting the double-precision floating-point value
                   2396: | `a' to the quadruple-precision floating-point format.  The conversion is
                   2397: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2398: | Arithmetic.
                   2399: *----------------------------------------------------------------------------*/
                   2400: 
                   2401: float128 float64_to_float128( float64 a STATUS_PARAM )
                   2402: {
                   2403:     flag aSign;
                   2404:     int16 aExp;
                   2405:     bits64 aSig, zSig0, zSig1;
                   2406: 
                   2407:     aSig = extractFloat64Frac( a );
                   2408:     aExp = extractFloat64Exp( a );
                   2409:     aSign = extractFloat64Sign( a );
                   2410:     if ( aExp == 0x7FF ) {
                   2411:         if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) );
                   2412:         return packFloat128( aSign, 0x7FFF, 0, 0 );
                   2413:     }
                   2414:     if ( aExp == 0 ) {
                   2415:         if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
                   2416:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2417:         --aExp;
                   2418:     }
                   2419:     shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
                   2420:     return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
                   2421: 
                   2422: }
                   2423: 
                   2424: #endif
                   2425: 
                   2426: /*----------------------------------------------------------------------------
                   2427: | Rounds the double-precision floating-point value `a' to an integer, and
                   2428: | returns the result as a double-precision floating-point value.  The
                   2429: | operation is performed according to the IEC/IEEE Standard for Binary
                   2430: | Floating-Point Arithmetic.
                   2431: *----------------------------------------------------------------------------*/
                   2432: 
                   2433: float64 float64_round_to_int( float64 a STATUS_PARAM )
                   2434: {
                   2435:     flag aSign;
                   2436:     int16 aExp;
                   2437:     bits64 lastBitMask, roundBitsMask;
                   2438:     int8 roundingMode;
                   2439:     float64 z;
                   2440: 
                   2441:     aExp = extractFloat64Exp( a );
                   2442:     if ( 0x433 <= aExp ) {
                   2443:         if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
                   2444:             return propagateFloat64NaN( a, a STATUS_VAR );
                   2445:         }
                   2446:         return a;
                   2447:     }
                   2448:     if ( aExp < 0x3FF ) {
                   2449:         if ( (bits64) ( a<<1 ) == 0 ) return a;
                   2450:         STATUS(float_exception_flags) |= float_flag_inexact;
                   2451:         aSign = extractFloat64Sign( a );
                   2452:         switch ( STATUS(float_rounding_mode) ) {
                   2453:          case float_round_nearest_even:
                   2454:             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
                   2455:                 return packFloat64( aSign, 0x3FF, 0 );
                   2456:             }
                   2457:             break;
                   2458:          case float_round_down:
                   2459:             return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
                   2460:          case float_round_up:
                   2461:             return
                   2462:             aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
                   2463:         }
                   2464:         return packFloat64( aSign, 0, 0 );
                   2465:     }
                   2466:     lastBitMask = 1;
                   2467:     lastBitMask <<= 0x433 - aExp;
                   2468:     roundBitsMask = lastBitMask - 1;
                   2469:     z = a;
                   2470:     roundingMode = STATUS(float_rounding_mode);
                   2471:     if ( roundingMode == float_round_nearest_even ) {
                   2472:         z += lastBitMask>>1;
                   2473:         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
                   2474:     }
                   2475:     else if ( roundingMode != float_round_to_zero ) {
                   2476:         if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
                   2477:             z += roundBitsMask;
                   2478:         }
                   2479:     }
                   2480:     z &= ~ roundBitsMask;
                   2481:     if ( z != a ) STATUS(float_exception_flags) |= float_flag_inexact;
                   2482:     return z;
                   2483: 
                   2484: }
                   2485: 
                   2486: /*----------------------------------------------------------------------------
                   2487: | Returns the result of adding the absolute values of the double-precision
                   2488: | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
                   2489: | before being returned.  `zSign' is ignored if the result is a NaN.
                   2490: | The addition is performed according to the IEC/IEEE Standard for Binary
                   2491: | Floating-Point Arithmetic.
                   2492: *----------------------------------------------------------------------------*/
                   2493: 
                   2494: static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
                   2495: {
                   2496:     int16 aExp, bExp, zExp;
                   2497:     bits64 aSig, bSig, zSig;
                   2498:     int16 expDiff;
                   2499: 
                   2500:     aSig = extractFloat64Frac( a );
                   2501:     aExp = extractFloat64Exp( a );
                   2502:     bSig = extractFloat64Frac( b );
                   2503:     bExp = extractFloat64Exp( b );
                   2504:     expDiff = aExp - bExp;
                   2505:     aSig <<= 9;
                   2506:     bSig <<= 9;
                   2507:     if ( 0 < expDiff ) {
                   2508:         if ( aExp == 0x7FF ) {
                   2509:             if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2510:             return a;
                   2511:         }
                   2512:         if ( bExp == 0 ) {
                   2513:             --expDiff;
                   2514:         }
                   2515:         else {
                   2516:             bSig |= LIT64( 0x2000000000000000 );
                   2517:         }
                   2518:         shift64RightJamming( bSig, expDiff, &bSig );
                   2519:         zExp = aExp;
                   2520:     }
                   2521:     else if ( expDiff < 0 ) {
                   2522:         if ( bExp == 0x7FF ) {
                   2523:             if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2524:             return packFloat64( zSign, 0x7FF, 0 );
                   2525:         }
                   2526:         if ( aExp == 0 ) {
                   2527:             ++expDiff;
                   2528:         }
                   2529:         else {
                   2530:             aSig |= LIT64( 0x2000000000000000 );
                   2531:         }
                   2532:         shift64RightJamming( aSig, - expDiff, &aSig );
                   2533:         zExp = bExp;
                   2534:     }
                   2535:     else {
                   2536:         if ( aExp == 0x7FF ) {
                   2537:             if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2538:             return a;
                   2539:         }
                   2540:         if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
                   2541:         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
                   2542:         zExp = aExp;
                   2543:         goto roundAndPack;
                   2544:     }
                   2545:     aSig |= LIT64( 0x2000000000000000 );
                   2546:     zSig = ( aSig + bSig )<<1;
                   2547:     --zExp;
                   2548:     if ( (sbits64) zSig < 0 ) {
                   2549:         zSig = aSig + bSig;
                   2550:         ++zExp;
                   2551:     }
                   2552:  roundAndPack:
                   2553:     return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
                   2554: 
                   2555: }
                   2556: 
                   2557: /*----------------------------------------------------------------------------
                   2558: | Returns the result of subtracting the absolute values of the double-
                   2559: | precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   2560: | difference is negated before being returned.  `zSign' is ignored if the
                   2561: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   2562: | Standard for Binary Floating-Point Arithmetic.
                   2563: *----------------------------------------------------------------------------*/
                   2564: 
                   2565: static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
                   2566: {
                   2567:     int16 aExp, bExp, zExp;
                   2568:     bits64 aSig, bSig, zSig;
                   2569:     int16 expDiff;
                   2570: 
                   2571:     aSig = extractFloat64Frac( a );
                   2572:     aExp = extractFloat64Exp( a );
                   2573:     bSig = extractFloat64Frac( b );
                   2574:     bExp = extractFloat64Exp( b );
                   2575:     expDiff = aExp - bExp;
                   2576:     aSig <<= 10;
                   2577:     bSig <<= 10;
                   2578:     if ( 0 < expDiff ) goto aExpBigger;
                   2579:     if ( expDiff < 0 ) goto bExpBigger;
                   2580:     if ( aExp == 0x7FF ) {
                   2581:         if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2582:         float_raise( float_flag_invalid STATUS_VAR);
                   2583:         return float64_default_nan;
                   2584:     }
                   2585:     if ( aExp == 0 ) {
                   2586:         aExp = 1;
                   2587:         bExp = 1;
                   2588:     }
                   2589:     if ( bSig < aSig ) goto aBigger;
                   2590:     if ( aSig < bSig ) goto bBigger;
                   2591:     return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
                   2592:  bExpBigger:
                   2593:     if ( bExp == 0x7FF ) {
                   2594:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2595:         return packFloat64( zSign ^ 1, 0x7FF, 0 );
                   2596:     }
                   2597:     if ( aExp == 0 ) {
                   2598:         ++expDiff;
                   2599:     }
                   2600:     else {
                   2601:         aSig |= LIT64( 0x4000000000000000 );
                   2602:     }
                   2603:     shift64RightJamming( aSig, - expDiff, &aSig );
                   2604:     bSig |= LIT64( 0x4000000000000000 );
                   2605:  bBigger:
                   2606:     zSig = bSig - aSig;
                   2607:     zExp = bExp;
                   2608:     zSign ^= 1;
                   2609:     goto normalizeRoundAndPack;
                   2610:  aExpBigger:
                   2611:     if ( aExp == 0x7FF ) {
                   2612:         if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2613:         return a;
                   2614:     }
                   2615:     if ( bExp == 0 ) {
                   2616:         --expDiff;
                   2617:     }
                   2618:     else {
                   2619:         bSig |= LIT64( 0x4000000000000000 );
                   2620:     }
                   2621:     shift64RightJamming( bSig, expDiff, &bSig );
                   2622:     aSig |= LIT64( 0x4000000000000000 );
                   2623:  aBigger:
                   2624:     zSig = aSig - bSig;
                   2625:     zExp = aExp;
                   2626:  normalizeRoundAndPack:
                   2627:     --zExp;
                   2628:     return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
                   2629: 
                   2630: }
                   2631: 
                   2632: /*----------------------------------------------------------------------------
                   2633: | Returns the result of adding the double-precision floating-point values `a'
                   2634: | and `b'.  The operation is performed according to the IEC/IEEE Standard for
                   2635: | Binary Floating-Point Arithmetic.
                   2636: *----------------------------------------------------------------------------*/
                   2637: 
                   2638: float64 float64_add( float64 a, float64 b STATUS_PARAM )
                   2639: {
                   2640:     flag aSign, bSign;
                   2641: 
                   2642:     aSign = extractFloat64Sign( a );
                   2643:     bSign = extractFloat64Sign( b );
                   2644:     if ( aSign == bSign ) {
                   2645:         return addFloat64Sigs( a, b, aSign STATUS_VAR );
                   2646:     }
                   2647:     else {
                   2648:         return subFloat64Sigs( a, b, aSign STATUS_VAR );
                   2649:     }
                   2650: 
                   2651: }
                   2652: 
                   2653: /*----------------------------------------------------------------------------
                   2654: | Returns the result of subtracting the double-precision floating-point values
                   2655: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   2656: | for Binary Floating-Point Arithmetic.
                   2657: *----------------------------------------------------------------------------*/
                   2658: 
                   2659: float64 float64_sub( float64 a, float64 b STATUS_PARAM )
                   2660: {
                   2661:     flag aSign, bSign;
                   2662: 
                   2663:     aSign = extractFloat64Sign( a );
                   2664:     bSign = extractFloat64Sign( b );
                   2665:     if ( aSign == bSign ) {
                   2666:         return subFloat64Sigs( a, b, aSign STATUS_VAR );
                   2667:     }
                   2668:     else {
                   2669:         return addFloat64Sigs( a, b, aSign STATUS_VAR );
                   2670:     }
                   2671: 
                   2672: }
                   2673: 
                   2674: /*----------------------------------------------------------------------------
                   2675: | Returns the result of multiplying the double-precision floating-point values
                   2676: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   2677: | for Binary Floating-Point Arithmetic.
                   2678: *----------------------------------------------------------------------------*/
                   2679: 
                   2680: float64 float64_mul( float64 a, float64 b STATUS_PARAM )
                   2681: {
                   2682:     flag aSign, bSign, zSign;
                   2683:     int16 aExp, bExp, zExp;
                   2684:     bits64 aSig, bSig, zSig0, zSig1;
                   2685: 
                   2686:     aSig = extractFloat64Frac( a );
                   2687:     aExp = extractFloat64Exp( a );
                   2688:     aSign = extractFloat64Sign( a );
                   2689:     bSig = extractFloat64Frac( b );
                   2690:     bExp = extractFloat64Exp( b );
                   2691:     bSign = extractFloat64Sign( b );
                   2692:     zSign = aSign ^ bSign;
                   2693:     if ( aExp == 0x7FF ) {
                   2694:         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
                   2695:             return propagateFloat64NaN( a, b STATUS_VAR );
                   2696:         }
                   2697:         if ( ( bExp | bSig ) == 0 ) {
                   2698:             float_raise( float_flag_invalid STATUS_VAR);
                   2699:             return float64_default_nan;
                   2700:         }
                   2701:         return packFloat64( zSign, 0x7FF, 0 );
                   2702:     }
                   2703:     if ( bExp == 0x7FF ) {
                   2704:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2705:         if ( ( aExp | aSig ) == 0 ) {
                   2706:             float_raise( float_flag_invalid STATUS_VAR);
                   2707:             return float64_default_nan;
                   2708:         }
                   2709:         return packFloat64( zSign, 0x7FF, 0 );
                   2710:     }
                   2711:     if ( aExp == 0 ) {
                   2712:         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
                   2713:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2714:     }
                   2715:     if ( bExp == 0 ) {
                   2716:         if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
                   2717:         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
                   2718:     }
                   2719:     zExp = aExp + bExp - 0x3FF;
                   2720:     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
                   2721:     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
                   2722:     mul64To128( aSig, bSig, &zSig0, &zSig1 );
                   2723:     zSig0 |= ( zSig1 != 0 );
                   2724:     if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
                   2725:         zSig0 <<= 1;
                   2726:         --zExp;
                   2727:     }
                   2728:     return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
                   2729: 
                   2730: }
                   2731: 
                   2732: /*----------------------------------------------------------------------------
                   2733: | Returns the result of dividing the double-precision floating-point value `a'
                   2734: | by the corresponding value `b'.  The operation is performed according to
                   2735: | the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2736: *----------------------------------------------------------------------------*/
                   2737: 
                   2738: float64 float64_div( float64 a, float64 b STATUS_PARAM )
                   2739: {
                   2740:     flag aSign, bSign, zSign;
                   2741:     int16 aExp, bExp, zExp;
                   2742:     bits64 aSig, bSig, zSig;
                   2743:     bits64 rem0, rem1;
                   2744:     bits64 term0, term1;
                   2745: 
                   2746:     aSig = extractFloat64Frac( a );
                   2747:     aExp = extractFloat64Exp( a );
                   2748:     aSign = extractFloat64Sign( a );
                   2749:     bSig = extractFloat64Frac( b );
                   2750:     bExp = extractFloat64Exp( b );
                   2751:     bSign = extractFloat64Sign( b );
                   2752:     zSign = aSign ^ bSign;
                   2753:     if ( aExp == 0x7FF ) {
                   2754:         if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2755:         if ( bExp == 0x7FF ) {
                   2756:             if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2757:             float_raise( float_flag_invalid STATUS_VAR);
                   2758:             return float64_default_nan;
                   2759:         }
                   2760:         return packFloat64( zSign, 0x7FF, 0 );
                   2761:     }
                   2762:     if ( bExp == 0x7FF ) {
                   2763:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2764:         return packFloat64( zSign, 0, 0 );
                   2765:     }
                   2766:     if ( bExp == 0 ) {
                   2767:         if ( bSig == 0 ) {
                   2768:             if ( ( aExp | aSig ) == 0 ) {
                   2769:                 float_raise( float_flag_invalid STATUS_VAR);
                   2770:                 return float64_default_nan;
                   2771:             }
                   2772:             float_raise( float_flag_divbyzero STATUS_VAR);
                   2773:             return packFloat64( zSign, 0x7FF, 0 );
                   2774:         }
                   2775:         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
                   2776:     }
                   2777:     if ( aExp == 0 ) {
                   2778:         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
                   2779:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2780:     }
                   2781:     zExp = aExp - bExp + 0x3FD;
                   2782:     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
                   2783:     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
                   2784:     if ( bSig <= ( aSig + aSig ) ) {
                   2785:         aSig >>= 1;
                   2786:         ++zExp;
                   2787:     }
                   2788:     zSig = estimateDiv128To64( aSig, 0, bSig );
                   2789:     if ( ( zSig & 0x1FF ) <= 2 ) {
                   2790:         mul64To128( bSig, zSig, &term0, &term1 );
                   2791:         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
                   2792:         while ( (sbits64) rem0 < 0 ) {
                   2793:             --zSig;
                   2794:             add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
                   2795:         }
                   2796:         zSig |= ( rem1 != 0 );
                   2797:     }
                   2798:     return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
                   2799: 
                   2800: }
                   2801: 
                   2802: /*----------------------------------------------------------------------------
                   2803: | Returns the remainder of the double-precision floating-point value `a'
                   2804: | with respect to the corresponding value `b'.  The operation is performed
                   2805: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2806: *----------------------------------------------------------------------------*/
                   2807: 
                   2808: float64 float64_rem( float64 a, float64 b STATUS_PARAM )
                   2809: {
                   2810:     flag aSign, bSign, zSign;
                   2811:     int16 aExp, bExp, expDiff;
                   2812:     bits64 aSig, bSig;
                   2813:     bits64 q, alternateASig;
                   2814:     sbits64 sigMean;
                   2815: 
                   2816:     aSig = extractFloat64Frac( a );
                   2817:     aExp = extractFloat64Exp( a );
                   2818:     aSign = extractFloat64Sign( a );
                   2819:     bSig = extractFloat64Frac( b );
                   2820:     bExp = extractFloat64Exp( b );
                   2821:     bSign = extractFloat64Sign( b );
                   2822:     if ( aExp == 0x7FF ) {
                   2823:         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
                   2824:             return propagateFloat64NaN( a, b STATUS_VAR );
                   2825:         }
                   2826:         float_raise( float_flag_invalid STATUS_VAR);
                   2827:         return float64_default_nan;
                   2828:     }
                   2829:     if ( bExp == 0x7FF ) {
                   2830:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2831:         return a;
                   2832:     }
                   2833:     if ( bExp == 0 ) {
                   2834:         if ( bSig == 0 ) {
                   2835:             float_raise( float_flag_invalid STATUS_VAR);
                   2836:             return float64_default_nan;
                   2837:         }
                   2838:         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
                   2839:     }
                   2840:     if ( aExp == 0 ) {
                   2841:         if ( aSig == 0 ) return a;
                   2842:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2843:     }
                   2844:     expDiff = aExp - bExp;
                   2845:     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
                   2846:     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
                   2847:     if ( expDiff < 0 ) {
                   2848:         if ( expDiff < -1 ) return a;
                   2849:         aSig >>= 1;
                   2850:     }
                   2851:     q = ( bSig <= aSig );
                   2852:     if ( q ) aSig -= bSig;
                   2853:     expDiff -= 64;
                   2854:     while ( 0 < expDiff ) {
                   2855:         q = estimateDiv128To64( aSig, 0, bSig );
                   2856:         q = ( 2 < q ) ? q - 2 : 0;
                   2857:         aSig = - ( ( bSig>>2 ) * q );
                   2858:         expDiff -= 62;
                   2859:     }
                   2860:     expDiff += 64;
                   2861:     if ( 0 < expDiff ) {
                   2862:         q = estimateDiv128To64( aSig, 0, bSig );
                   2863:         q = ( 2 < q ) ? q - 2 : 0;
                   2864:         q >>= 64 - expDiff;
                   2865:         bSig >>= 2;
                   2866:         aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
                   2867:     }
                   2868:     else {
                   2869:         aSig >>= 2;
                   2870:         bSig >>= 2;
                   2871:     }
                   2872:     do {
                   2873:         alternateASig = aSig;
                   2874:         ++q;
                   2875:         aSig -= bSig;
                   2876:     } while ( 0 <= (sbits64) aSig );
                   2877:     sigMean = aSig + alternateASig;
                   2878:     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
                   2879:         aSig = alternateASig;
                   2880:     }
                   2881:     zSign = ( (sbits64) aSig < 0 );
                   2882:     if ( zSign ) aSig = - aSig;
                   2883:     return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
                   2884: 
                   2885: }
                   2886: 
                   2887: /*----------------------------------------------------------------------------
                   2888: | Returns the square root of the double-precision floating-point value `a'.
                   2889: | The operation is performed according to the IEC/IEEE Standard for Binary
                   2890: | Floating-Point Arithmetic.
                   2891: *----------------------------------------------------------------------------*/
                   2892: 
                   2893: float64 float64_sqrt( float64 a STATUS_PARAM )
                   2894: {
                   2895:     flag aSign;
                   2896:     int16 aExp, zExp;
                   2897:     bits64 aSig, zSig, doubleZSig;
                   2898:     bits64 rem0, rem1, term0, term1;
                   2899: 
                   2900:     aSig = extractFloat64Frac( a );
                   2901:     aExp = extractFloat64Exp( a );
                   2902:     aSign = extractFloat64Sign( a );
                   2903:     if ( aExp == 0x7FF ) {
                   2904:         if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
                   2905:         if ( ! aSign ) return a;
                   2906:         float_raise( float_flag_invalid STATUS_VAR);
                   2907:         return float64_default_nan;
                   2908:     }
                   2909:     if ( aSign ) {
                   2910:         if ( ( aExp | aSig ) == 0 ) return a;
                   2911:         float_raise( float_flag_invalid STATUS_VAR);
                   2912:         return float64_default_nan;
                   2913:     }
                   2914:     if ( aExp == 0 ) {
                   2915:         if ( aSig == 0 ) return 0;
                   2916:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2917:     }
                   2918:     zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
                   2919:     aSig |= LIT64( 0x0010000000000000 );
                   2920:     zSig = estimateSqrt32( aExp, aSig>>21 );
                   2921:     aSig <<= 9 - ( aExp & 1 );
                   2922:     zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
                   2923:     if ( ( zSig & 0x1FF ) <= 5 ) {
                   2924:         doubleZSig = zSig<<1;
                   2925:         mul64To128( zSig, zSig, &term0, &term1 );
                   2926:         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
                   2927:         while ( (sbits64) rem0 < 0 ) {
                   2928:             --zSig;
                   2929:             doubleZSig -= 2;
                   2930:             add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
                   2931:         }
                   2932:         zSig |= ( ( rem0 | rem1 ) != 0 );
                   2933:     }
                   2934:     return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
                   2935: 
                   2936: }
                   2937: 
                   2938: /*----------------------------------------------------------------------------
                   2939: | Returns 1 if the double-precision floating-point value `a' is equal to the
                   2940: | corresponding value `b', and 0 otherwise.  The comparison is performed
                   2941: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2942: *----------------------------------------------------------------------------*/
                   2943: 
                   2944: flag float64_eq( float64 a, float64 b STATUS_PARAM )
                   2945: {
                   2946: 
                   2947:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   2948:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   2949:        ) {
                   2950:         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
                   2951:             float_raise( float_flag_invalid STATUS_VAR);
                   2952:         }
                   2953:         return 0;
                   2954:     }
                   2955:     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
                   2956: 
                   2957: }
                   2958: 
                   2959: /*----------------------------------------------------------------------------
                   2960: | Returns 1 if the double-precision floating-point value `a' is less than or
                   2961: | equal to the corresponding value `b', and 0 otherwise.  The comparison is
                   2962: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2963: | Arithmetic.
                   2964: *----------------------------------------------------------------------------*/
                   2965: 
                   2966: flag float64_le( float64 a, float64 b STATUS_PARAM )
                   2967: {
                   2968:     flag aSign, bSign;
                   2969: 
                   2970:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   2971:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   2972:        ) {
                   2973:         float_raise( float_flag_invalid STATUS_VAR);
                   2974:         return 0;
                   2975:     }
                   2976:     aSign = extractFloat64Sign( a );
                   2977:     bSign = extractFloat64Sign( b );
                   2978:     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
                   2979:     return ( a == b ) || ( aSign ^ ( a < b ) );
                   2980: 
                   2981: }
                   2982: 
                   2983: /*----------------------------------------------------------------------------
                   2984: | Returns 1 if the double-precision floating-point value `a' is less than
                   2985: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   2986: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2987: *----------------------------------------------------------------------------*/
                   2988: 
                   2989: flag float64_lt( float64 a, float64 b STATUS_PARAM )
                   2990: {
                   2991:     flag aSign, bSign;
                   2992: 
                   2993:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   2994:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   2995:        ) {
                   2996:         float_raise( float_flag_invalid STATUS_VAR);
                   2997:         return 0;
                   2998:     }
                   2999:     aSign = extractFloat64Sign( a );
                   3000:     bSign = extractFloat64Sign( b );
                   3001:     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
                   3002:     return ( a != b ) && ( aSign ^ ( a < b ) );
                   3003: 
                   3004: }
                   3005: 
                   3006: /*----------------------------------------------------------------------------
                   3007: | Returns 1 if the double-precision floating-point value `a' is equal to the
                   3008: | corresponding value `b', and 0 otherwise.  The invalid exception is raised
                   3009: | if either operand is a NaN.  Otherwise, the comparison is performed
                   3010: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3011: *----------------------------------------------------------------------------*/
                   3012: 
                   3013: flag float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
                   3014: {
                   3015: 
                   3016:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3017:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3018:        ) {
                   3019:         float_raise( float_flag_invalid STATUS_VAR);
                   3020:         return 0;
                   3021:     }
                   3022:     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
                   3023: 
                   3024: }
                   3025: 
                   3026: /*----------------------------------------------------------------------------
                   3027: | Returns 1 if the double-precision floating-point value `a' is less than or
                   3028: | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
                   3029: | cause an exception.  Otherwise, the comparison is performed according to the
                   3030: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3031: *----------------------------------------------------------------------------*/
                   3032: 
                   3033: flag float64_le_quiet( float64 a, float64 b STATUS_PARAM )
                   3034: {
                   3035:     flag aSign, bSign;
                   3036: 
                   3037:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3038:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3039:        ) {
                   3040:         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
                   3041:             float_raise( float_flag_invalid STATUS_VAR);
                   3042:         }
                   3043:         return 0;
                   3044:     }
                   3045:     aSign = extractFloat64Sign( a );
                   3046:     bSign = extractFloat64Sign( b );
                   3047:     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
                   3048:     return ( a == b ) || ( aSign ^ ( a < b ) );
                   3049: 
                   3050: }
                   3051: 
                   3052: /*----------------------------------------------------------------------------
                   3053: | Returns 1 if the double-precision floating-point value `a' is less than
                   3054: | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
                   3055: | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
                   3056: | Standard for Binary Floating-Point Arithmetic.
                   3057: *----------------------------------------------------------------------------*/
                   3058: 
                   3059: flag float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
                   3060: {
                   3061:     flag aSign, bSign;
                   3062: 
                   3063:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3064:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3065:        ) {
                   3066:         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
                   3067:             float_raise( float_flag_invalid STATUS_VAR);
                   3068:         }
                   3069:         return 0;
                   3070:     }
                   3071:     aSign = extractFloat64Sign( a );
                   3072:     bSign = extractFloat64Sign( b );
                   3073:     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
                   3074:     return ( a != b ) && ( aSign ^ ( a < b ) );
                   3075: 
                   3076: }
                   3077: 
                   3078: #ifdef FLOATX80
                   3079: 
                   3080: /*----------------------------------------------------------------------------
                   3081: | Returns the result of converting the extended double-precision floating-
                   3082: | point value `a' to the 32-bit two's complement integer format.  The
                   3083: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3084: | Floating-Point Arithmetic---which means in particular that the conversion
                   3085: | is rounded according to the current rounding mode.  If `a' is a NaN, the
                   3086: | largest positive integer is returned.  Otherwise, if the conversion
                   3087: | overflows, the largest integer with the same sign as `a' is returned.
                   3088: *----------------------------------------------------------------------------*/
                   3089: 
                   3090: int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
                   3091: {
                   3092:     flag aSign;
                   3093:     int32 aExp, shiftCount;
                   3094:     bits64 aSig;
                   3095: 
                   3096:     aSig = extractFloatx80Frac( a );
                   3097:     aExp = extractFloatx80Exp( a );
                   3098:     aSign = extractFloatx80Sign( a );
                   3099:     if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
                   3100:     shiftCount = 0x4037 - aExp;
                   3101:     if ( shiftCount <= 0 ) shiftCount = 1;
                   3102:     shift64RightJamming( aSig, shiftCount, &aSig );
                   3103:     return roundAndPackInt32( aSign, aSig STATUS_VAR );
                   3104: 
                   3105: }
                   3106: 
                   3107: /*----------------------------------------------------------------------------
                   3108: | Returns the result of converting the extended double-precision floating-
                   3109: | point value `a' to the 32-bit two's complement integer format.  The
                   3110: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3111: | Floating-Point Arithmetic, except that the conversion is always rounded
                   3112: | toward zero.  If `a' is a NaN, the largest positive integer is returned.
                   3113: | Otherwise, if the conversion overflows, the largest integer with the same
                   3114: | sign as `a' is returned.
                   3115: *----------------------------------------------------------------------------*/
                   3116: 
                   3117: int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
                   3118: {
                   3119:     flag aSign;
                   3120:     int32 aExp, shiftCount;
                   3121:     bits64 aSig, savedASig;
                   3122:     int32 z;
                   3123: 
                   3124:     aSig = extractFloatx80Frac( a );
                   3125:     aExp = extractFloatx80Exp( a );
                   3126:     aSign = extractFloatx80Sign( a );
                   3127:     if ( 0x401E < aExp ) {
                   3128:         if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
                   3129:         goto invalid;
                   3130:     }
                   3131:     else if ( aExp < 0x3FFF ) {
                   3132:         if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   3133:         return 0;
                   3134:     }
                   3135:     shiftCount = 0x403E - aExp;
                   3136:     savedASig = aSig;
                   3137:     aSig >>= shiftCount;
                   3138:     z = aSig;
                   3139:     if ( aSign ) z = - z;
                   3140:     if ( ( z < 0 ) ^ aSign ) {
                   3141:  invalid:
                   3142:         float_raise( float_flag_invalid STATUS_VAR);
                   3143:         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                   3144:     }
                   3145:     if ( ( aSig<<shiftCount ) != savedASig ) {
                   3146:         STATUS(float_exception_flags) |= float_flag_inexact;
                   3147:     }
                   3148:     return z;
                   3149: 
                   3150: }
                   3151: 
                   3152: /*----------------------------------------------------------------------------
                   3153: | Returns the result of converting the extended double-precision floating-
                   3154: | point value `a' to the 64-bit two's complement integer format.  The
                   3155: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3156: | Floating-Point Arithmetic---which means in particular that the conversion
                   3157: | is rounded according to the current rounding mode.  If `a' is a NaN,
                   3158: | the largest positive integer is returned.  Otherwise, if the conversion
                   3159: | overflows, the largest integer with the same sign as `a' is returned.
                   3160: *----------------------------------------------------------------------------*/
                   3161: 
                   3162: int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
                   3163: {
                   3164:     flag aSign;
                   3165:     int32 aExp, shiftCount;
                   3166:     bits64 aSig, aSigExtra;
                   3167: 
                   3168:     aSig = extractFloatx80Frac( a );
                   3169:     aExp = extractFloatx80Exp( a );
                   3170:     aSign = extractFloatx80Sign( a );
                   3171:     shiftCount = 0x403E - aExp;
                   3172:     if ( shiftCount <= 0 ) {
                   3173:         if ( shiftCount ) {
                   3174:             float_raise( float_flag_invalid STATUS_VAR);
                   3175:             if (    ! aSign
                   3176:                  || (    ( aExp == 0x7FFF )
                   3177:                       && ( aSig != LIT64( 0x8000000000000000 ) ) )
                   3178:                ) {
                   3179:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   3180:             }
                   3181:             return (sbits64) LIT64( 0x8000000000000000 );
                   3182:         }
                   3183:         aSigExtra = 0;
                   3184:     }
                   3185:     else {
                   3186:         shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
                   3187:     }
                   3188:     return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
                   3189: 
                   3190: }
                   3191: 
                   3192: /*----------------------------------------------------------------------------
                   3193: | Returns the result of converting the extended double-precision floating-
                   3194: | point value `a' to the 64-bit two's complement integer format.  The
                   3195: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3196: | Floating-Point Arithmetic, except that the conversion is always rounded
                   3197: | toward zero.  If `a' is a NaN, the largest positive integer is returned.
                   3198: | Otherwise, if the conversion overflows, the largest integer with the same
                   3199: | sign as `a' is returned.
                   3200: *----------------------------------------------------------------------------*/
                   3201: 
                   3202: int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
                   3203: {
                   3204:     flag aSign;
                   3205:     int32 aExp, shiftCount;
                   3206:     bits64 aSig;
                   3207:     int64 z;
                   3208: 
                   3209:     aSig = extractFloatx80Frac( a );
                   3210:     aExp = extractFloatx80Exp( a );
                   3211:     aSign = extractFloatx80Sign( a );
                   3212:     shiftCount = aExp - 0x403E;
                   3213:     if ( 0 <= shiftCount ) {
                   3214:         aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
                   3215:         if ( ( a.high != 0xC03E ) || aSig ) {
                   3216:             float_raise( float_flag_invalid STATUS_VAR);
                   3217:             if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
                   3218:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   3219:             }
                   3220:         }
                   3221:         return (sbits64) LIT64( 0x8000000000000000 );
                   3222:     }
                   3223:     else if ( aExp < 0x3FFF ) {
                   3224:         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   3225:         return 0;
                   3226:     }
                   3227:     z = aSig>>( - shiftCount );
                   3228:     if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
                   3229:         STATUS(float_exception_flags) |= float_flag_inexact;
                   3230:     }
                   3231:     if ( aSign ) z = - z;
                   3232:     return z;
                   3233: 
                   3234: }
                   3235: 
                   3236: /*----------------------------------------------------------------------------
                   3237: | Returns the result of converting the extended double-precision floating-
                   3238: | point value `a' to the single-precision floating-point format.  The
                   3239: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3240: | Floating-Point Arithmetic.
                   3241: *----------------------------------------------------------------------------*/
                   3242: 
                   3243: float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
                   3244: {
                   3245:     flag aSign;
                   3246:     int32 aExp;
                   3247:     bits64 aSig;
                   3248: 
                   3249:     aSig = extractFloatx80Frac( a );
                   3250:     aExp = extractFloatx80Exp( a );
                   3251:     aSign = extractFloatx80Sign( a );
                   3252:     if ( aExp == 0x7FFF ) {
                   3253:         if ( (bits64) ( aSig<<1 ) ) {
                   3254:             return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) );
                   3255:         }
                   3256:         return packFloat32( aSign, 0xFF, 0 );
                   3257:     }
                   3258:     shift64RightJamming( aSig, 33, &aSig );
                   3259:     if ( aExp || aSig ) aExp -= 0x3F81;
                   3260:     return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
                   3261: 
                   3262: }
                   3263: 
                   3264: /*----------------------------------------------------------------------------
                   3265: | Returns the result of converting the extended double-precision floating-
                   3266: | point value `a' to the double-precision floating-point format.  The
                   3267: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3268: | Floating-Point Arithmetic.
                   3269: *----------------------------------------------------------------------------*/
                   3270: 
                   3271: float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
                   3272: {
                   3273:     flag aSign;
                   3274:     int32 aExp;
                   3275:     bits64 aSig, zSig;
                   3276: 
                   3277:     aSig = extractFloatx80Frac( a );
                   3278:     aExp = extractFloatx80Exp( a );
                   3279:     aSign = extractFloatx80Sign( a );
                   3280:     if ( aExp == 0x7FFF ) {
                   3281:         if ( (bits64) ( aSig<<1 ) ) {
                   3282:             return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) );
                   3283:         }
                   3284:         return packFloat64( aSign, 0x7FF, 0 );
                   3285:     }
                   3286:     shift64RightJamming( aSig, 1, &zSig );
                   3287:     if ( aExp || aSig ) aExp -= 0x3C01;
                   3288:     return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
                   3289: 
                   3290: }
                   3291: 
                   3292: #ifdef FLOAT128
                   3293: 
                   3294: /*----------------------------------------------------------------------------
                   3295: | Returns the result of converting the extended double-precision floating-
                   3296: | point value `a' to the quadruple-precision floating-point format.  The
                   3297: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3298: | Floating-Point Arithmetic.
                   3299: *----------------------------------------------------------------------------*/
                   3300: 
                   3301: float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
                   3302: {
                   3303:     flag aSign;
                   3304:     int16 aExp;
                   3305:     bits64 aSig, zSig0, zSig1;
                   3306: 
                   3307:     aSig = extractFloatx80Frac( a );
                   3308:     aExp = extractFloatx80Exp( a );
                   3309:     aSign = extractFloatx80Sign( a );
                   3310:     if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
                   3311:         return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) );
                   3312:     }
                   3313:     shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
                   3314:     return packFloat128( aSign, aExp, zSig0, zSig1 );
                   3315: 
                   3316: }
                   3317: 
                   3318: #endif
                   3319: 
                   3320: /*----------------------------------------------------------------------------
                   3321: | Rounds the extended double-precision floating-point value `a' to an integer,
                   3322: | and returns the result as an extended quadruple-precision floating-point
                   3323: | value.  The operation is performed according to the IEC/IEEE Standard for
                   3324: | Binary Floating-Point Arithmetic.
                   3325: *----------------------------------------------------------------------------*/
                   3326: 
                   3327: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
                   3328: {
                   3329:     flag aSign;
                   3330:     int32 aExp;
                   3331:     bits64 lastBitMask, roundBitsMask;
                   3332:     int8 roundingMode;
                   3333:     floatx80 z;
                   3334: 
                   3335:     aExp = extractFloatx80Exp( a );
                   3336:     if ( 0x403E <= aExp ) {
                   3337:         if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
                   3338:             return propagateFloatx80NaN( a, a STATUS_VAR );
                   3339:         }
                   3340:         return a;
                   3341:     }
                   3342:     if ( aExp < 0x3FFF ) {
                   3343:         if (    ( aExp == 0 )
                   3344:              && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
                   3345:             return a;
                   3346:         }
                   3347:         STATUS(float_exception_flags) |= float_flag_inexact;
                   3348:         aSign = extractFloatx80Sign( a );
                   3349:         switch ( STATUS(float_rounding_mode) ) {
                   3350:          case float_round_nearest_even:
                   3351:             if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
                   3352:                ) {
                   3353:                 return
                   3354:                     packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
                   3355:             }
                   3356:             break;
                   3357:          case float_round_down:
                   3358:             return
                   3359:                   aSign ?
                   3360:                       packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
                   3361:                 : packFloatx80( 0, 0, 0 );
                   3362:          case float_round_up:
                   3363:             return
                   3364:                   aSign ? packFloatx80( 1, 0, 0 )
                   3365:                 : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
                   3366:         }
                   3367:         return packFloatx80( aSign, 0, 0 );
                   3368:     }
                   3369:     lastBitMask = 1;
                   3370:     lastBitMask <<= 0x403E - aExp;
                   3371:     roundBitsMask = lastBitMask - 1;
                   3372:     z = a;
                   3373:     roundingMode = STATUS(float_rounding_mode);
                   3374:     if ( roundingMode == float_round_nearest_even ) {
                   3375:         z.low += lastBitMask>>1;
                   3376:         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
                   3377:     }
                   3378:     else if ( roundingMode != float_round_to_zero ) {
                   3379:         if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
                   3380:             z.low += roundBitsMask;
                   3381:         }
                   3382:     }
                   3383:     z.low &= ~ roundBitsMask;
                   3384:     if ( z.low == 0 ) {
                   3385:         ++z.high;
                   3386:         z.low = LIT64( 0x8000000000000000 );
                   3387:     }
                   3388:     if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
                   3389:     return z;
                   3390: 
                   3391: }
                   3392: 
                   3393: /*----------------------------------------------------------------------------
                   3394: | Returns the result of adding the absolute values of the extended double-
                   3395: | precision floating-point values `a' and `b'.  If `zSign' is 1, the sum is
                   3396: | negated before being returned.  `zSign' is ignored if the result is a NaN.
                   3397: | The addition is performed according to the IEC/IEEE Standard for Binary
                   3398: | Floating-Point Arithmetic.
                   3399: *----------------------------------------------------------------------------*/
                   3400: 
                   3401: static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
                   3402: {
                   3403:     int32 aExp, bExp, zExp;
                   3404:     bits64 aSig, bSig, zSig0, zSig1;
                   3405:     int32 expDiff;
                   3406: 
                   3407:     aSig = extractFloatx80Frac( a );
                   3408:     aExp = extractFloatx80Exp( a );
                   3409:     bSig = extractFloatx80Frac( b );
                   3410:     bExp = extractFloatx80Exp( b );
                   3411:     expDiff = aExp - bExp;
                   3412:     if ( 0 < expDiff ) {
                   3413:         if ( aExp == 0x7FFF ) {
                   3414:             if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3415:             return a;
                   3416:         }
                   3417:         if ( bExp == 0 ) --expDiff;
                   3418:         shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
                   3419:         zExp = aExp;
                   3420:     }
                   3421:     else if ( expDiff < 0 ) {
                   3422:         if ( bExp == 0x7FFF ) {
                   3423:             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3424:             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3425:         }
                   3426:         if ( aExp == 0 ) ++expDiff;
                   3427:         shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
                   3428:         zExp = bExp;
                   3429:     }
                   3430:     else {
                   3431:         if ( aExp == 0x7FFF ) {
                   3432:             if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
                   3433:                 return propagateFloatx80NaN( a, b STATUS_VAR );
                   3434:             }
                   3435:             return a;
                   3436:         }
                   3437:         zSig1 = 0;
                   3438:         zSig0 = aSig + bSig;
                   3439:         if ( aExp == 0 ) {
                   3440:             normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
                   3441:             goto roundAndPack;
                   3442:         }
                   3443:         zExp = aExp;
                   3444:         goto shiftRight1;
                   3445:     }
                   3446:     zSig0 = aSig + bSig;
                   3447:     if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
                   3448:  shiftRight1:
                   3449:     shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
                   3450:     zSig0 |= LIT64( 0x8000000000000000 );
                   3451:     ++zExp;
                   3452:  roundAndPack:
                   3453:     return
                   3454:         roundAndPackFloatx80(
                   3455:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   3456: 
                   3457: }
                   3458: 
                   3459: /*----------------------------------------------------------------------------
                   3460: | Returns the result of subtracting the absolute values of the extended
                   3461: | double-precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   3462: | difference is negated before being returned.  `zSign' is ignored if the
                   3463: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   3464: | Standard for Binary Floating-Point Arithmetic.
                   3465: *----------------------------------------------------------------------------*/
                   3466: 
                   3467: static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
                   3468: {
                   3469:     int32 aExp, bExp, zExp;
                   3470:     bits64 aSig, bSig, zSig0, zSig1;
                   3471:     int32 expDiff;
                   3472:     floatx80 z;
                   3473: 
                   3474:     aSig = extractFloatx80Frac( a );
                   3475:     aExp = extractFloatx80Exp( a );
                   3476:     bSig = extractFloatx80Frac( b );
                   3477:     bExp = extractFloatx80Exp( b );
                   3478:     expDiff = aExp - bExp;
                   3479:     if ( 0 < expDiff ) goto aExpBigger;
                   3480:     if ( expDiff < 0 ) goto bExpBigger;
                   3481:     if ( aExp == 0x7FFF ) {
                   3482:         if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
                   3483:             return propagateFloatx80NaN( a, b STATUS_VAR );
                   3484:         }
                   3485:         float_raise( float_flag_invalid STATUS_VAR);
                   3486:         z.low = floatx80_default_nan_low;
                   3487:         z.high = floatx80_default_nan_high;
                   3488:         return z;
                   3489:     }
                   3490:     if ( aExp == 0 ) {
                   3491:         aExp = 1;
                   3492:         bExp = 1;
                   3493:     }
                   3494:     zSig1 = 0;
                   3495:     if ( bSig < aSig ) goto aBigger;
                   3496:     if ( aSig < bSig ) goto bBigger;
                   3497:     return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
                   3498:  bExpBigger:
                   3499:     if ( bExp == 0x7FFF ) {
                   3500:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3501:         return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3502:     }
                   3503:     if ( aExp == 0 ) ++expDiff;
                   3504:     shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
                   3505:  bBigger:
                   3506:     sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
                   3507:     zExp = bExp;
                   3508:     zSign ^= 1;
                   3509:     goto normalizeRoundAndPack;
                   3510:  aExpBigger:
                   3511:     if ( aExp == 0x7FFF ) {
                   3512:         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3513:         return a;
                   3514:     }
                   3515:     if ( bExp == 0 ) --expDiff;
                   3516:     shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
                   3517:  aBigger:
                   3518:     sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
                   3519:     zExp = aExp;
                   3520:  normalizeRoundAndPack:
                   3521:     return
                   3522:         normalizeRoundAndPackFloatx80(
                   3523:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   3524: 
                   3525: }
                   3526: 
                   3527: /*----------------------------------------------------------------------------
                   3528: | Returns the result of adding the extended double-precision floating-point
                   3529: | values `a' and `b'.  The operation is performed according to the IEC/IEEE
                   3530: | Standard for Binary Floating-Point Arithmetic.
                   3531: *----------------------------------------------------------------------------*/
                   3532: 
                   3533: floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
                   3534: {
                   3535:     flag aSign, bSign;
                   3536: 
                   3537:     aSign = extractFloatx80Sign( a );
                   3538:     bSign = extractFloatx80Sign( b );
                   3539:     if ( aSign == bSign ) {
                   3540:         return addFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3541:     }
                   3542:     else {
                   3543:         return subFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3544:     }
                   3545: 
                   3546: }
                   3547: 
                   3548: /*----------------------------------------------------------------------------
                   3549: | Returns the result of subtracting the extended double-precision floating-
                   3550: | point values `a' and `b'.  The operation is performed according to the
                   3551: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3552: *----------------------------------------------------------------------------*/
                   3553: 
                   3554: floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
                   3555: {
                   3556:     flag aSign, bSign;
                   3557: 
                   3558:     aSign = extractFloatx80Sign( a );
                   3559:     bSign = extractFloatx80Sign( b );
                   3560:     if ( aSign == bSign ) {
                   3561:         return subFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3562:     }
                   3563:     else {
                   3564:         return addFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3565:     }
                   3566: 
                   3567: }
                   3568: 
                   3569: /*----------------------------------------------------------------------------
                   3570: | Returns the result of multiplying the extended double-precision floating-
                   3571: | point values `a' and `b'.  The operation is performed according to the
                   3572: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3573: *----------------------------------------------------------------------------*/
                   3574: 
                   3575: floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
                   3576: {
                   3577:     flag aSign, bSign, zSign;
                   3578:     int32 aExp, bExp, zExp;
                   3579:     bits64 aSig, bSig, zSig0, zSig1;
                   3580:     floatx80 z;
                   3581: 
                   3582:     aSig = extractFloatx80Frac( a );
                   3583:     aExp = extractFloatx80Exp( a );
                   3584:     aSign = extractFloatx80Sign( a );
                   3585:     bSig = extractFloatx80Frac( b );
                   3586:     bExp = extractFloatx80Exp( b );
                   3587:     bSign = extractFloatx80Sign( b );
                   3588:     zSign = aSign ^ bSign;
                   3589:     if ( aExp == 0x7FFF ) {
                   3590:         if (    (bits64) ( aSig<<1 )
                   3591:              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
                   3592:             return propagateFloatx80NaN( a, b STATUS_VAR );
                   3593:         }
                   3594:         if ( ( bExp | bSig ) == 0 ) goto invalid;
                   3595:         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3596:     }
                   3597:     if ( bExp == 0x7FFF ) {
                   3598:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3599:         if ( ( aExp | aSig ) == 0 ) {
                   3600:  invalid:
                   3601:             float_raise( float_flag_invalid STATUS_VAR);
                   3602:             z.low = floatx80_default_nan_low;
                   3603:             z.high = floatx80_default_nan_high;
                   3604:             return z;
                   3605:         }
                   3606:         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3607:     }
                   3608:     if ( aExp == 0 ) {
                   3609:         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
                   3610:         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
                   3611:     }
                   3612:     if ( bExp == 0 ) {
                   3613:         if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
                   3614:         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
                   3615:     }
                   3616:     zExp = aExp + bExp - 0x3FFE;
                   3617:     mul64To128( aSig, bSig, &zSig0, &zSig1 );
                   3618:     if ( 0 < (sbits64) zSig0 ) {
                   3619:         shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
                   3620:         --zExp;
                   3621:     }
                   3622:     return
                   3623:         roundAndPackFloatx80(
                   3624:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   3625: 
                   3626: }
                   3627: 
                   3628: /*----------------------------------------------------------------------------
                   3629: | Returns the result of dividing the extended double-precision floating-point
                   3630: | value `a' by the corresponding value `b'.  The operation is performed
                   3631: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3632: *----------------------------------------------------------------------------*/
                   3633: 
                   3634: floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
                   3635: {
                   3636:     flag aSign, bSign, zSign;
                   3637:     int32 aExp, bExp, zExp;
                   3638:     bits64 aSig, bSig, zSig0, zSig1;
                   3639:     bits64 rem0, rem1, rem2, term0, term1, term2;
                   3640:     floatx80 z;
                   3641: 
                   3642:     aSig = extractFloatx80Frac( a );
                   3643:     aExp = extractFloatx80Exp( a );
                   3644:     aSign = extractFloatx80Sign( a );
                   3645:     bSig = extractFloatx80Frac( b );
                   3646:     bExp = extractFloatx80Exp( b );
                   3647:     bSign = extractFloatx80Sign( b );
                   3648:     zSign = aSign ^ bSign;
                   3649:     if ( aExp == 0x7FFF ) {
                   3650:         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3651:         if ( bExp == 0x7FFF ) {
                   3652:             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3653:             goto invalid;
                   3654:         }
                   3655:         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3656:     }
                   3657:     if ( bExp == 0x7FFF ) {
                   3658:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3659:         return packFloatx80( zSign, 0, 0 );
                   3660:     }
                   3661:     if ( bExp == 0 ) {
                   3662:         if ( bSig == 0 ) {
                   3663:             if ( ( aExp | aSig ) == 0 ) {
                   3664:  invalid:
                   3665:                 float_raise( float_flag_invalid STATUS_VAR);
                   3666:                 z.low = floatx80_default_nan_low;
                   3667:                 z.high = floatx80_default_nan_high;
                   3668:                 return z;
                   3669:             }
                   3670:             float_raise( float_flag_divbyzero STATUS_VAR);
                   3671:             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3672:         }
                   3673:         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
                   3674:     }
                   3675:     if ( aExp == 0 ) {
                   3676:         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
                   3677:         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
                   3678:     }
                   3679:     zExp = aExp - bExp + 0x3FFE;
                   3680:     rem1 = 0;
                   3681:     if ( bSig <= aSig ) {
                   3682:         shift128Right( aSig, 0, 1, &aSig, &rem1 );
                   3683:         ++zExp;
                   3684:     }
                   3685:     zSig0 = estimateDiv128To64( aSig, rem1, bSig );
                   3686:     mul64To128( bSig, zSig0, &term0, &term1 );
                   3687:     sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
                   3688:     while ( (sbits64) rem0 < 0 ) {
                   3689:         --zSig0;
                   3690:         add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
                   3691:     }
                   3692:     zSig1 = estimateDiv128To64( rem1, 0, bSig );
                   3693:     if ( (bits64) ( zSig1<<1 ) <= 8 ) {
                   3694:         mul64To128( bSig, zSig1, &term1, &term2 );
                   3695:         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
                   3696:         while ( (sbits64) rem1 < 0 ) {
                   3697:             --zSig1;
                   3698:             add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
                   3699:         }
                   3700:         zSig1 |= ( ( rem1 | rem2 ) != 0 );
                   3701:     }
                   3702:     return
                   3703:         roundAndPackFloatx80(
                   3704:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   3705: 
                   3706: }
                   3707: 
                   3708: /*----------------------------------------------------------------------------
                   3709: | Returns the remainder of the extended double-precision floating-point value
                   3710: | `a' with respect to the corresponding value `b'.  The operation is performed
                   3711: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3712: *----------------------------------------------------------------------------*/
                   3713: 
                   3714: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
                   3715: {
                   3716:     flag aSign, bSign, zSign;
                   3717:     int32 aExp, bExp, expDiff;
                   3718:     bits64 aSig0, aSig1, bSig;
                   3719:     bits64 q, term0, term1, alternateASig0, alternateASig1;
                   3720:     floatx80 z;
                   3721: 
                   3722:     aSig0 = extractFloatx80Frac( a );
                   3723:     aExp = extractFloatx80Exp( a );
                   3724:     aSign = extractFloatx80Sign( a );
                   3725:     bSig = extractFloatx80Frac( b );
                   3726:     bExp = extractFloatx80Exp( b );
                   3727:     bSign = extractFloatx80Sign( b );
                   3728:     if ( aExp == 0x7FFF ) {
                   3729:         if (    (bits64) ( aSig0<<1 )
                   3730:              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
                   3731:             return propagateFloatx80NaN( a, b STATUS_VAR );
                   3732:         }
                   3733:         goto invalid;
                   3734:     }
                   3735:     if ( bExp == 0x7FFF ) {
                   3736:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3737:         return a;
                   3738:     }
                   3739:     if ( bExp == 0 ) {
                   3740:         if ( bSig == 0 ) {
                   3741:  invalid:
                   3742:             float_raise( float_flag_invalid STATUS_VAR);
                   3743:             z.low = floatx80_default_nan_low;
                   3744:             z.high = floatx80_default_nan_high;
                   3745:             return z;
                   3746:         }
                   3747:         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
                   3748:     }
                   3749:     if ( aExp == 0 ) {
                   3750:         if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
                   3751:         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
                   3752:     }
                   3753:     bSig |= LIT64( 0x8000000000000000 );
                   3754:     zSign = aSign;
                   3755:     expDiff = aExp - bExp;
                   3756:     aSig1 = 0;
                   3757:     if ( expDiff < 0 ) {
                   3758:         if ( expDiff < -1 ) return a;
                   3759:         shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
                   3760:         expDiff = 0;
                   3761:     }
                   3762:     q = ( bSig <= aSig0 );
                   3763:     if ( q ) aSig0 -= bSig;
                   3764:     expDiff -= 64;
                   3765:     while ( 0 < expDiff ) {
                   3766:         q = estimateDiv128To64( aSig0, aSig1, bSig );
                   3767:         q = ( 2 < q ) ? q - 2 : 0;
                   3768:         mul64To128( bSig, q, &term0, &term1 );
                   3769:         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
                   3770:         shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
                   3771:         expDiff -= 62;
                   3772:     }
                   3773:     expDiff += 64;
                   3774:     if ( 0 < expDiff ) {
                   3775:         q = estimateDiv128To64( aSig0, aSig1, bSig );
                   3776:         q = ( 2 < q ) ? q - 2 : 0;
                   3777:         q >>= 64 - expDiff;
                   3778:         mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
                   3779:         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
                   3780:         shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
                   3781:         while ( le128( term0, term1, aSig0, aSig1 ) ) {
                   3782:             ++q;
                   3783:             sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
                   3784:         }
                   3785:     }
                   3786:     else {
                   3787:         term1 = 0;
                   3788:         term0 = bSig;
                   3789:     }
                   3790:     sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
                   3791:     if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
                   3792:          || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
                   3793:               && ( q & 1 ) )
                   3794:        ) {
                   3795:         aSig0 = alternateASig0;
                   3796:         aSig1 = alternateASig1;
                   3797:         zSign = ! zSign;
                   3798:     }
                   3799:     return
                   3800:         normalizeRoundAndPackFloatx80(
                   3801:             80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
                   3802: 
                   3803: }
                   3804: 
                   3805: /*----------------------------------------------------------------------------
                   3806: | Returns the square root of the extended double-precision floating-point
                   3807: | value `a'.  The operation is performed according to the IEC/IEEE Standard
                   3808: | for Binary Floating-Point Arithmetic.
                   3809: *----------------------------------------------------------------------------*/
                   3810: 
                   3811: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
                   3812: {
                   3813:     flag aSign;
                   3814:     int32 aExp, zExp;
                   3815:     bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0;
                   3816:     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
                   3817:     floatx80 z;
                   3818: 
                   3819:     aSig0 = extractFloatx80Frac( a );
                   3820:     aExp = extractFloatx80Exp( a );
                   3821:     aSign = extractFloatx80Sign( a );
                   3822:     if ( aExp == 0x7FFF ) {
                   3823:         if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
                   3824:         if ( ! aSign ) return a;
                   3825:         goto invalid;
                   3826:     }
                   3827:     if ( aSign ) {
                   3828:         if ( ( aExp | aSig0 ) == 0 ) return a;
                   3829:  invalid:
                   3830:         float_raise( float_flag_invalid STATUS_VAR);
                   3831:         z.low = floatx80_default_nan_low;
                   3832:         z.high = floatx80_default_nan_high;
                   3833:         return z;
                   3834:     }
                   3835:     if ( aExp == 0 ) {
                   3836:         if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
                   3837:         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
                   3838:     }
                   3839:     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
                   3840:     zSig0 = estimateSqrt32( aExp, aSig0>>32 );
                   3841:     shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
                   3842:     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
                   3843:     doubleZSig0 = zSig0<<1;
                   3844:     mul64To128( zSig0, zSig0, &term0, &term1 );
                   3845:     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
                   3846:     while ( (sbits64) rem0 < 0 ) {
                   3847:         --zSig0;
                   3848:         doubleZSig0 -= 2;
                   3849:         add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
                   3850:     }
                   3851:     zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
                   3852:     if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
                   3853:         if ( zSig1 == 0 ) zSig1 = 1;
                   3854:         mul64To128( doubleZSig0, zSig1, &term1, &term2 );
                   3855:         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
                   3856:         mul64To128( zSig1, zSig1, &term2, &term3 );
                   3857:         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
                   3858:         while ( (sbits64) rem1 < 0 ) {
                   3859:             --zSig1;
                   3860:             shortShift128Left( 0, zSig1, 1, &term2, &term3 );
                   3861:             term3 |= 1;
                   3862:             term2 |= doubleZSig0;
                   3863:             add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
                   3864:         }
                   3865:         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
                   3866:     }
                   3867:     shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
                   3868:     zSig0 |= doubleZSig0;
                   3869:     return
                   3870:         roundAndPackFloatx80(
                   3871:             STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
                   3872: 
                   3873: }
                   3874: 
                   3875: /*----------------------------------------------------------------------------
                   3876: | Returns 1 if the extended double-precision floating-point value `a' is
                   3877: | equal to the corresponding value `b', and 0 otherwise.  The comparison is
                   3878: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   3879: | Arithmetic.
                   3880: *----------------------------------------------------------------------------*/
                   3881: 
                   3882: flag floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
                   3883: {
                   3884: 
                   3885:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   3886:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   3887:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   3888:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   3889:        ) {
                   3890:         if (    floatx80_is_signaling_nan( a )
                   3891:              || floatx80_is_signaling_nan( b ) ) {
                   3892:             float_raise( float_flag_invalid STATUS_VAR);
                   3893:         }
                   3894:         return 0;
                   3895:     }
                   3896:     return
                   3897:            ( a.low == b.low )
                   3898:         && (    ( a.high == b.high )
                   3899:              || (    ( a.low == 0 )
                   3900:                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
                   3901:            );
                   3902: 
                   3903: }
                   3904: 
                   3905: /*----------------------------------------------------------------------------
                   3906: | Returns 1 if the extended double-precision floating-point value `a' is
                   3907: | less than or equal to the corresponding value `b', and 0 otherwise.  The
                   3908: | comparison is performed according to the IEC/IEEE Standard for Binary
                   3909: | Floating-Point Arithmetic.
                   3910: *----------------------------------------------------------------------------*/
                   3911: 
                   3912: flag floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
                   3913: {
                   3914:     flag aSign, bSign;
                   3915: 
                   3916:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   3917:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   3918:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   3919:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   3920:        ) {
                   3921:         float_raise( float_flag_invalid STATUS_VAR);
                   3922:         return 0;
                   3923:     }
                   3924:     aSign = extractFloatx80Sign( a );
                   3925:     bSign = extractFloatx80Sign( b );
                   3926:     if ( aSign != bSign ) {
                   3927:         return
                   3928:                aSign
                   3929:             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   3930:                  == 0 );
                   3931:     }
                   3932:     return
                   3933:           aSign ? le128( b.high, b.low, a.high, a.low )
                   3934:         : le128( a.high, a.low, b.high, b.low );
                   3935: 
                   3936: }
                   3937: 
                   3938: /*----------------------------------------------------------------------------
                   3939: | Returns 1 if the extended double-precision floating-point value `a' is
                   3940: | less than the corresponding value `b', and 0 otherwise.  The comparison
                   3941: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   3942: | Arithmetic.
                   3943: *----------------------------------------------------------------------------*/
                   3944: 
                   3945: flag floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
                   3946: {
                   3947:     flag aSign, bSign;
                   3948: 
                   3949:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   3950:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   3951:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   3952:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   3953:        ) {
                   3954:         float_raise( float_flag_invalid STATUS_VAR);
                   3955:         return 0;
                   3956:     }
                   3957:     aSign = extractFloatx80Sign( a );
                   3958:     bSign = extractFloatx80Sign( b );
                   3959:     if ( aSign != bSign ) {
                   3960:         return
                   3961:                aSign
                   3962:             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   3963:                  != 0 );
                   3964:     }
                   3965:     return
                   3966:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   3967:         : lt128( a.high, a.low, b.high, b.low );
                   3968: 
                   3969: }
                   3970: 
                   3971: /*----------------------------------------------------------------------------
                   3972: | Returns 1 if the extended double-precision floating-point value `a' is equal
                   3973: | to the corresponding value `b', and 0 otherwise.  The invalid exception is
                   3974: | raised if either operand is a NaN.  Otherwise, the comparison is performed
                   3975: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3976: *----------------------------------------------------------------------------*/
                   3977: 
                   3978: flag floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
                   3979: {
                   3980: 
                   3981:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   3982:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   3983:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   3984:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   3985:        ) {
                   3986:         float_raise( float_flag_invalid STATUS_VAR);
                   3987:         return 0;
                   3988:     }
                   3989:     return
                   3990:            ( a.low == b.low )
                   3991:         && (    ( a.high == b.high )
                   3992:              || (    ( a.low == 0 )
                   3993:                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
                   3994:            );
                   3995: 
                   3996: }
                   3997: 
                   3998: /*----------------------------------------------------------------------------
                   3999: | Returns 1 if the extended double-precision floating-point value `a' is less
                   4000: | than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
                   4001: | do not cause an exception.  Otherwise, the comparison is performed according
                   4002: | to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4003: *----------------------------------------------------------------------------*/
                   4004: 
                   4005: flag floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
                   4006: {
                   4007:     flag aSign, bSign;
                   4008: 
                   4009:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4010:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4011:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4012:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4013:        ) {
                   4014:         if (    floatx80_is_signaling_nan( a )
                   4015:              || floatx80_is_signaling_nan( b ) ) {
                   4016:             float_raise( float_flag_invalid STATUS_VAR);
                   4017:         }
                   4018:         return 0;
                   4019:     }
                   4020:     aSign = extractFloatx80Sign( a );
                   4021:     bSign = extractFloatx80Sign( b );
                   4022:     if ( aSign != bSign ) {
                   4023:         return
                   4024:                aSign
                   4025:             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   4026:                  == 0 );
                   4027:     }
                   4028:     return
                   4029:           aSign ? le128( b.high, b.low, a.high, a.low )
                   4030:         : le128( a.high, a.low, b.high, b.low );
                   4031: 
                   4032: }
                   4033: 
                   4034: /*----------------------------------------------------------------------------
                   4035: | Returns 1 if the extended double-precision floating-point value `a' is less
                   4036: | than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
                   4037: | an exception.  Otherwise, the comparison is performed according to the
                   4038: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4039: *----------------------------------------------------------------------------*/
                   4040: 
                   4041: flag floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
                   4042: {
                   4043:     flag aSign, bSign;
                   4044: 
                   4045:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4046:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4047:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4048:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4049:        ) {
                   4050:         if (    floatx80_is_signaling_nan( a )
                   4051:              || floatx80_is_signaling_nan( b ) ) {
                   4052:             float_raise( float_flag_invalid STATUS_VAR);
                   4053:         }
                   4054:         return 0;
                   4055:     }
                   4056:     aSign = extractFloatx80Sign( a );
                   4057:     bSign = extractFloatx80Sign( b );
                   4058:     if ( aSign != bSign ) {
                   4059:         return
                   4060:                aSign
                   4061:             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   4062:                  != 0 );
                   4063:     }
                   4064:     return
                   4065:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   4066:         : lt128( a.high, a.low, b.high, b.low );
                   4067: 
                   4068: }
                   4069: 
                   4070: #endif
                   4071: 
                   4072: #ifdef FLOAT128
                   4073: 
                   4074: /*----------------------------------------------------------------------------
                   4075: | Returns the result of converting the quadruple-precision floating-point
                   4076: | value `a' to the 32-bit two's complement integer format.  The conversion
                   4077: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4078: | Arithmetic---which means in particular that the conversion is rounded
                   4079: | according to the current rounding mode.  If `a' is a NaN, the largest
                   4080: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   4081: | largest integer with the same sign as `a' is returned.
                   4082: *----------------------------------------------------------------------------*/
                   4083: 
                   4084: int32 float128_to_int32( float128 a STATUS_PARAM )
                   4085: {
                   4086:     flag aSign;
                   4087:     int32 aExp, shiftCount;
                   4088:     bits64 aSig0, aSig1;
                   4089: 
                   4090:     aSig1 = extractFloat128Frac1( a );
                   4091:     aSig0 = extractFloat128Frac0( a );
                   4092:     aExp = extractFloat128Exp( a );
                   4093:     aSign = extractFloat128Sign( a );
                   4094:     if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
                   4095:     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
                   4096:     aSig0 |= ( aSig1 != 0 );
                   4097:     shiftCount = 0x4028 - aExp;
                   4098:     if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
                   4099:     return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
                   4100: 
                   4101: }
                   4102: 
                   4103: /*----------------------------------------------------------------------------
                   4104: | Returns the result of converting the quadruple-precision floating-point
                   4105: | value `a' to the 32-bit two's complement integer format.  The conversion
                   4106: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4107: | Arithmetic, except that the conversion is always rounded toward zero.  If
                   4108: | `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
                   4109: | conversion overflows, the largest integer with the same sign as `a' is
                   4110: | returned.
                   4111: *----------------------------------------------------------------------------*/
                   4112: 
                   4113: int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
                   4114: {
                   4115:     flag aSign;
                   4116:     int32 aExp, shiftCount;
                   4117:     bits64 aSig0, aSig1, savedASig;
                   4118:     int32 z;
                   4119: 
                   4120:     aSig1 = extractFloat128Frac1( a );
                   4121:     aSig0 = extractFloat128Frac0( a );
                   4122:     aExp = extractFloat128Exp( a );
                   4123:     aSign = extractFloat128Sign( a );
                   4124:     aSig0 |= ( aSig1 != 0 );
                   4125:     if ( 0x401E < aExp ) {
                   4126:         if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
                   4127:         goto invalid;
                   4128:     }
                   4129:     else if ( aExp < 0x3FFF ) {
                   4130:         if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
                   4131:         return 0;
                   4132:     }
                   4133:     aSig0 |= LIT64( 0x0001000000000000 );
                   4134:     shiftCount = 0x402F - aExp;
                   4135:     savedASig = aSig0;
                   4136:     aSig0 >>= shiftCount;
                   4137:     z = aSig0;
                   4138:     if ( aSign ) z = - z;
                   4139:     if ( ( z < 0 ) ^ aSign ) {
                   4140:  invalid:
                   4141:         float_raise( float_flag_invalid STATUS_VAR);
                   4142:         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                   4143:     }
                   4144:     if ( ( aSig0<<shiftCount ) != savedASig ) {
                   4145:         STATUS(float_exception_flags) |= float_flag_inexact;
                   4146:     }
                   4147:     return z;
                   4148: 
                   4149: }
                   4150: 
                   4151: /*----------------------------------------------------------------------------
                   4152: | Returns the result of converting the quadruple-precision floating-point
                   4153: | value `a' to the 64-bit two's complement integer format.  The conversion
                   4154: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4155: | Arithmetic---which means in particular that the conversion is rounded
                   4156: | according to the current rounding mode.  If `a' is a NaN, the largest
                   4157: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   4158: | largest integer with the same sign as `a' is returned.
                   4159: *----------------------------------------------------------------------------*/
                   4160: 
                   4161: int64 float128_to_int64( float128 a STATUS_PARAM )
                   4162: {
                   4163:     flag aSign;
                   4164:     int32 aExp, shiftCount;
                   4165:     bits64 aSig0, aSig1;
                   4166: 
                   4167:     aSig1 = extractFloat128Frac1( a );
                   4168:     aSig0 = extractFloat128Frac0( a );
                   4169:     aExp = extractFloat128Exp( a );
                   4170:     aSign = extractFloat128Sign( a );
                   4171:     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
                   4172:     shiftCount = 0x402F - aExp;
                   4173:     if ( shiftCount <= 0 ) {
                   4174:         if ( 0x403E < aExp ) {
                   4175:             float_raise( float_flag_invalid STATUS_VAR);
                   4176:             if (    ! aSign
                   4177:                  || (    ( aExp == 0x7FFF )
                   4178:                       && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
                   4179:                     )
                   4180:                ) {
                   4181:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   4182:             }
                   4183:             return (sbits64) LIT64( 0x8000000000000000 );
                   4184:         }
                   4185:         shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
                   4186:     }
                   4187:     else {
                   4188:         shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
                   4189:     }
                   4190:     return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
                   4191: 
                   4192: }
                   4193: 
                   4194: /*----------------------------------------------------------------------------
                   4195: | Returns the result of converting the quadruple-precision floating-point
                   4196: | value `a' to the 64-bit two's complement integer format.  The conversion
                   4197: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4198: | Arithmetic, except that the conversion is always rounded toward zero.
                   4199: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   4200: | the conversion overflows, the largest integer with the same sign as `a' is
                   4201: | returned.
                   4202: *----------------------------------------------------------------------------*/
                   4203: 
                   4204: int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
                   4205: {
                   4206:     flag aSign;
                   4207:     int32 aExp, shiftCount;
                   4208:     bits64 aSig0, aSig1;
                   4209:     int64 z;
                   4210: 
                   4211:     aSig1 = extractFloat128Frac1( a );
                   4212:     aSig0 = extractFloat128Frac0( a );
                   4213:     aExp = extractFloat128Exp( a );
                   4214:     aSign = extractFloat128Sign( a );
                   4215:     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
                   4216:     shiftCount = aExp - 0x402F;
                   4217:     if ( 0 < shiftCount ) {
                   4218:         if ( 0x403E <= aExp ) {
                   4219:             aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
                   4220:             if (    ( a.high == LIT64( 0xC03E000000000000 ) )
                   4221:                  && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
                   4222:                 if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
                   4223:             }
                   4224:             else {
                   4225:                 float_raise( float_flag_invalid STATUS_VAR);
                   4226:                 if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
                   4227:                     return LIT64( 0x7FFFFFFFFFFFFFFF );
                   4228:                 }
                   4229:             }
                   4230:             return (sbits64) LIT64( 0x8000000000000000 );
                   4231:         }
                   4232:         z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
                   4233:         if ( (bits64) ( aSig1<<shiftCount ) ) {
                   4234:             STATUS(float_exception_flags) |= float_flag_inexact;
                   4235:         }
                   4236:     }
                   4237:     else {
                   4238:         if ( aExp < 0x3FFF ) {
                   4239:             if ( aExp | aSig0 | aSig1 ) {
                   4240:                 STATUS(float_exception_flags) |= float_flag_inexact;
                   4241:             }
                   4242:             return 0;
                   4243:         }
                   4244:         z = aSig0>>( - shiftCount );
                   4245:         if (    aSig1
                   4246:              || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) {
                   4247:             STATUS(float_exception_flags) |= float_flag_inexact;
                   4248:         }
                   4249:     }
                   4250:     if ( aSign ) z = - z;
                   4251:     return z;
                   4252: 
                   4253: }
                   4254: 
                   4255: /*----------------------------------------------------------------------------
                   4256: | Returns the result of converting the quadruple-precision floating-point
                   4257: | value `a' to the single-precision floating-point format.  The conversion
                   4258: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4259: | Arithmetic.
                   4260: *----------------------------------------------------------------------------*/
                   4261: 
                   4262: float32 float128_to_float32( float128 a STATUS_PARAM )
                   4263: {
                   4264:     flag aSign;
                   4265:     int32 aExp;
                   4266:     bits64 aSig0, aSig1;
                   4267:     bits32 zSig;
                   4268: 
                   4269:     aSig1 = extractFloat128Frac1( a );
                   4270:     aSig0 = extractFloat128Frac0( a );
                   4271:     aExp = extractFloat128Exp( a );
                   4272:     aSign = extractFloat128Sign( a );
                   4273:     if ( aExp == 0x7FFF ) {
                   4274:         if ( aSig0 | aSig1 ) {
                   4275:             return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) );
                   4276:         }
                   4277:         return packFloat32( aSign, 0xFF, 0 );
                   4278:     }
                   4279:     aSig0 |= ( aSig1 != 0 );
                   4280:     shift64RightJamming( aSig0, 18, &aSig0 );
                   4281:     zSig = aSig0;
                   4282:     if ( aExp || zSig ) {
                   4283:         zSig |= 0x40000000;
                   4284:         aExp -= 0x3F81;
                   4285:     }
                   4286:     return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
                   4287: 
                   4288: }
                   4289: 
                   4290: /*----------------------------------------------------------------------------
                   4291: | Returns the result of converting the quadruple-precision floating-point
                   4292: | value `a' to the double-precision floating-point format.  The conversion
                   4293: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4294: | Arithmetic.
                   4295: *----------------------------------------------------------------------------*/
                   4296: 
                   4297: float64 float128_to_float64( float128 a STATUS_PARAM )
                   4298: {
                   4299:     flag aSign;
                   4300:     int32 aExp;
                   4301:     bits64 aSig0, aSig1;
                   4302: 
                   4303:     aSig1 = extractFloat128Frac1( a );
                   4304:     aSig0 = extractFloat128Frac0( a );
                   4305:     aExp = extractFloat128Exp( a );
                   4306:     aSign = extractFloat128Sign( a );
                   4307:     if ( aExp == 0x7FFF ) {
                   4308:         if ( aSig0 | aSig1 ) {
                   4309:             return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) );
                   4310:         }
                   4311:         return packFloat64( aSign, 0x7FF, 0 );
                   4312:     }
                   4313:     shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
                   4314:     aSig0 |= ( aSig1 != 0 );
                   4315:     if ( aExp || aSig0 ) {
                   4316:         aSig0 |= LIT64( 0x4000000000000000 );
                   4317:         aExp -= 0x3C01;
                   4318:     }
                   4319:     return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
                   4320: 
                   4321: }
                   4322: 
                   4323: #ifdef FLOATX80
                   4324: 
                   4325: /*----------------------------------------------------------------------------
                   4326: | Returns the result of converting the quadruple-precision floating-point
                   4327: | value `a' to the extended double-precision floating-point format.  The
                   4328: | conversion is performed according to the IEC/IEEE Standard for Binary
                   4329: | Floating-Point Arithmetic.
                   4330: *----------------------------------------------------------------------------*/
                   4331: 
                   4332: floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
                   4333: {
                   4334:     flag aSign;
                   4335:     int32 aExp;
                   4336:     bits64 aSig0, aSig1;
                   4337: 
                   4338:     aSig1 = extractFloat128Frac1( a );
                   4339:     aSig0 = extractFloat128Frac0( a );
                   4340:     aExp = extractFloat128Exp( a );
                   4341:     aSign = extractFloat128Sign( a );
                   4342:     if ( aExp == 0x7FFF ) {
                   4343:         if ( aSig0 | aSig1 ) {
                   4344:             return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) );
                   4345:         }
                   4346:         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   4347:     }
                   4348:     if ( aExp == 0 ) {
                   4349:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
                   4350:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   4351:     }
                   4352:     else {
                   4353:         aSig0 |= LIT64( 0x0001000000000000 );
                   4354:     }
                   4355:     shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
                   4356:     return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
                   4357: 
                   4358: }
                   4359: 
                   4360: #endif
                   4361: 
                   4362: /*----------------------------------------------------------------------------
                   4363: | Rounds the quadruple-precision floating-point value `a' to an integer, and
                   4364: | returns the result as a quadruple-precision floating-point value.  The
                   4365: | operation is performed according to the IEC/IEEE Standard for Binary
                   4366: | Floating-Point Arithmetic.
                   4367: *----------------------------------------------------------------------------*/
                   4368: 
                   4369: float128 float128_round_to_int( float128 a STATUS_PARAM )
                   4370: {
                   4371:     flag aSign;
                   4372:     int32 aExp;
                   4373:     bits64 lastBitMask, roundBitsMask;
                   4374:     int8 roundingMode;
                   4375:     float128 z;
                   4376: 
                   4377:     aExp = extractFloat128Exp( a );
                   4378:     if ( 0x402F <= aExp ) {
                   4379:         if ( 0x406F <= aExp ) {
                   4380:             if (    ( aExp == 0x7FFF )
                   4381:                  && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
                   4382:                ) {
                   4383:                 return propagateFloat128NaN( a, a STATUS_VAR );
                   4384:             }
                   4385:             return a;
                   4386:         }
                   4387:         lastBitMask = 1;
                   4388:         lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
                   4389:         roundBitsMask = lastBitMask - 1;
                   4390:         z = a;
                   4391:         roundingMode = STATUS(float_rounding_mode);
                   4392:         if ( roundingMode == float_round_nearest_even ) {
                   4393:             if ( lastBitMask ) {
                   4394:                 add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
                   4395:                 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
                   4396:             }
                   4397:             else {
                   4398:                 if ( (sbits64) z.low < 0 ) {
                   4399:                     ++z.high;
                   4400:                     if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
                   4401:                 }
                   4402:             }
                   4403:         }
                   4404:         else if ( roundingMode != float_round_to_zero ) {
                   4405:             if (   extractFloat128Sign( z )
                   4406:                  ^ ( roundingMode == float_round_up ) ) {
                   4407:                 add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
                   4408:             }
                   4409:         }
                   4410:         z.low &= ~ roundBitsMask;
                   4411:     }
                   4412:     else {
                   4413:         if ( aExp < 0x3FFF ) {
                   4414:             if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
                   4415:             STATUS(float_exception_flags) |= float_flag_inexact;
                   4416:             aSign = extractFloat128Sign( a );
                   4417:             switch ( STATUS(float_rounding_mode) ) {
                   4418:              case float_round_nearest_even:
                   4419:                 if (    ( aExp == 0x3FFE )
                   4420:                      && (   extractFloat128Frac0( a )
                   4421:                           | extractFloat128Frac1( a ) )
                   4422:                    ) {
                   4423:                     return packFloat128( aSign, 0x3FFF, 0, 0 );
                   4424:                 }
                   4425:                 break;
                   4426:              case float_round_down:
                   4427:                 return
                   4428:                       aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
                   4429:                     : packFloat128( 0, 0, 0, 0 );
                   4430:              case float_round_up:
                   4431:                 return
                   4432:                       aSign ? packFloat128( 1, 0, 0, 0 )
                   4433:                     : packFloat128( 0, 0x3FFF, 0, 0 );
                   4434:             }
                   4435:             return packFloat128( aSign, 0, 0, 0 );
                   4436:         }
                   4437:         lastBitMask = 1;
                   4438:         lastBitMask <<= 0x402F - aExp;
                   4439:         roundBitsMask = lastBitMask - 1;
                   4440:         z.low = 0;
                   4441:         z.high = a.high;
                   4442:         roundingMode = STATUS(float_rounding_mode);
                   4443:         if ( roundingMode == float_round_nearest_even ) {
                   4444:             z.high += lastBitMask>>1;
                   4445:             if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
                   4446:                 z.high &= ~ lastBitMask;
                   4447:             }
                   4448:         }
                   4449:         else if ( roundingMode != float_round_to_zero ) {
                   4450:             if (   extractFloat128Sign( z )
                   4451:                  ^ ( roundingMode == float_round_up ) ) {
                   4452:                 z.high |= ( a.low != 0 );
                   4453:                 z.high += roundBitsMask;
                   4454:             }
                   4455:         }
                   4456:         z.high &= ~ roundBitsMask;
                   4457:     }
                   4458:     if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
                   4459:         STATUS(float_exception_flags) |= float_flag_inexact;
                   4460:     }
                   4461:     return z;
                   4462: 
                   4463: }
                   4464: 
                   4465: /*----------------------------------------------------------------------------
                   4466: | Returns the result of adding the absolute values of the quadruple-precision
                   4467: | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
                   4468: | before being returned.  `zSign' is ignored if the result is a NaN.
                   4469: | The addition is performed according to the IEC/IEEE Standard for Binary
                   4470: | Floating-Point Arithmetic.
                   4471: *----------------------------------------------------------------------------*/
                   4472: 
                   4473: static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
                   4474: {
                   4475:     int32 aExp, bExp, zExp;
                   4476:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
                   4477:     int32 expDiff;
                   4478: 
                   4479:     aSig1 = extractFloat128Frac1( a );
                   4480:     aSig0 = extractFloat128Frac0( a );
                   4481:     aExp = extractFloat128Exp( a );
                   4482:     bSig1 = extractFloat128Frac1( b );
                   4483:     bSig0 = extractFloat128Frac0( b );
                   4484:     bExp = extractFloat128Exp( b );
                   4485:     expDiff = aExp - bExp;
                   4486:     if ( 0 < expDiff ) {
                   4487:         if ( aExp == 0x7FFF ) {
                   4488:             if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4489:             return a;
                   4490:         }
                   4491:         if ( bExp == 0 ) {
                   4492:             --expDiff;
                   4493:         }
                   4494:         else {
                   4495:             bSig0 |= LIT64( 0x0001000000000000 );
                   4496:         }
                   4497:         shift128ExtraRightJamming(
                   4498:             bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
                   4499:         zExp = aExp;
                   4500:     }
                   4501:     else if ( expDiff < 0 ) {
                   4502:         if ( bExp == 0x7FFF ) {
                   4503:             if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4504:             return packFloat128( zSign, 0x7FFF, 0, 0 );
                   4505:         }
                   4506:         if ( aExp == 0 ) {
                   4507:             ++expDiff;
                   4508:         }
                   4509:         else {
                   4510:             aSig0 |= LIT64( 0x0001000000000000 );
                   4511:         }
                   4512:         shift128ExtraRightJamming(
                   4513:             aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
                   4514:         zExp = bExp;
                   4515:     }
                   4516:     else {
                   4517:         if ( aExp == 0x7FFF ) {
                   4518:             if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
                   4519:                 return propagateFloat128NaN( a, b STATUS_VAR );
                   4520:             }
                   4521:             return a;
                   4522:         }
                   4523:         add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
                   4524:         if ( aExp == 0 ) return packFloat128( zSign, 0, zSig0, zSig1 );
                   4525:         zSig2 = 0;
                   4526:         zSig0 |= LIT64( 0x0002000000000000 );
                   4527:         zExp = aExp;
                   4528:         goto shiftRight1;
                   4529:     }
                   4530:     aSig0 |= LIT64( 0x0001000000000000 );
                   4531:     add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
                   4532:     --zExp;
                   4533:     if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
                   4534:     ++zExp;
                   4535:  shiftRight1:
                   4536:     shift128ExtraRightJamming(
                   4537:         zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
                   4538:  roundAndPack:
                   4539:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   4540: 
                   4541: }
                   4542: 
                   4543: /*----------------------------------------------------------------------------
                   4544: | Returns the result of subtracting the absolute values of the quadruple-
                   4545: | precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   4546: | difference is negated before being returned.  `zSign' is ignored if the
                   4547: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   4548: | Standard for Binary Floating-Point Arithmetic.
                   4549: *----------------------------------------------------------------------------*/
                   4550: 
                   4551: static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
                   4552: {
                   4553:     int32 aExp, bExp, zExp;
                   4554:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
                   4555:     int32 expDiff;
                   4556:     float128 z;
                   4557: 
                   4558:     aSig1 = extractFloat128Frac1( a );
                   4559:     aSig0 = extractFloat128Frac0( a );
                   4560:     aExp = extractFloat128Exp( a );
                   4561:     bSig1 = extractFloat128Frac1( b );
                   4562:     bSig0 = extractFloat128Frac0( b );
                   4563:     bExp = extractFloat128Exp( b );
                   4564:     expDiff = aExp - bExp;
                   4565:     shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
                   4566:     shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
                   4567:     if ( 0 < expDiff ) goto aExpBigger;
                   4568:     if ( expDiff < 0 ) goto bExpBigger;
                   4569:     if ( aExp == 0x7FFF ) {
                   4570:         if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
                   4571:             return propagateFloat128NaN( a, b STATUS_VAR );
                   4572:         }
                   4573:         float_raise( float_flag_invalid STATUS_VAR);
                   4574:         z.low = float128_default_nan_low;
                   4575:         z.high = float128_default_nan_high;
                   4576:         return z;
                   4577:     }
                   4578:     if ( aExp == 0 ) {
                   4579:         aExp = 1;
                   4580:         bExp = 1;
                   4581:     }
                   4582:     if ( bSig0 < aSig0 ) goto aBigger;
                   4583:     if ( aSig0 < bSig0 ) goto bBigger;
                   4584:     if ( bSig1 < aSig1 ) goto aBigger;
                   4585:     if ( aSig1 < bSig1 ) goto bBigger;
                   4586:     return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
                   4587:  bExpBigger:
                   4588:     if ( bExp == 0x7FFF ) {
                   4589:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4590:         return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
                   4591:     }
                   4592:     if ( aExp == 0 ) {
                   4593:         ++expDiff;
                   4594:     }
                   4595:     else {
                   4596:         aSig0 |= LIT64( 0x4000000000000000 );
                   4597:     }
                   4598:     shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
                   4599:     bSig0 |= LIT64( 0x4000000000000000 );
                   4600:  bBigger:
                   4601:     sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
                   4602:     zExp = bExp;
                   4603:     zSign ^= 1;
                   4604:     goto normalizeRoundAndPack;
                   4605:  aExpBigger:
                   4606:     if ( aExp == 0x7FFF ) {
                   4607:         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4608:         return a;
                   4609:     }
                   4610:     if ( bExp == 0 ) {
                   4611:         --expDiff;
                   4612:     }
                   4613:     else {
                   4614:         bSig0 |= LIT64( 0x4000000000000000 );
                   4615:     }
                   4616:     shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
                   4617:     aSig0 |= LIT64( 0x4000000000000000 );
                   4618:  aBigger:
                   4619:     sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
                   4620:     zExp = aExp;
                   4621:  normalizeRoundAndPack:
                   4622:     --zExp;
                   4623:     return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
                   4624: 
                   4625: }
                   4626: 
                   4627: /*----------------------------------------------------------------------------
                   4628: | Returns the result of adding the quadruple-precision floating-point values
                   4629: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   4630: | for Binary Floating-Point Arithmetic.
                   4631: *----------------------------------------------------------------------------*/
                   4632: 
                   4633: float128 float128_add( float128 a, float128 b STATUS_PARAM )
                   4634: {
                   4635:     flag aSign, bSign;
                   4636: 
                   4637:     aSign = extractFloat128Sign( a );
                   4638:     bSign = extractFloat128Sign( b );
                   4639:     if ( aSign == bSign ) {
                   4640:         return addFloat128Sigs( a, b, aSign STATUS_VAR );
                   4641:     }
                   4642:     else {
                   4643:         return subFloat128Sigs( a, b, aSign STATUS_VAR );
                   4644:     }
                   4645: 
                   4646: }
                   4647: 
                   4648: /*----------------------------------------------------------------------------
                   4649: | Returns the result of subtracting the quadruple-precision floating-point
                   4650: | values `a' and `b'.  The operation is performed according to the IEC/IEEE
                   4651: | Standard for Binary Floating-Point Arithmetic.
                   4652: *----------------------------------------------------------------------------*/
                   4653: 
                   4654: float128 float128_sub( float128 a, float128 b STATUS_PARAM )
                   4655: {
                   4656:     flag aSign, bSign;
                   4657: 
                   4658:     aSign = extractFloat128Sign( a );
                   4659:     bSign = extractFloat128Sign( b );
                   4660:     if ( aSign == bSign ) {
                   4661:         return subFloat128Sigs( a, b, aSign STATUS_VAR );
                   4662:     }
                   4663:     else {
                   4664:         return addFloat128Sigs( a, b, aSign STATUS_VAR );
                   4665:     }
                   4666: 
                   4667: }
                   4668: 
                   4669: /*----------------------------------------------------------------------------
                   4670: | Returns the result of multiplying the quadruple-precision floating-point
                   4671: | values `a' and `b'.  The operation is performed according to the IEC/IEEE
                   4672: | Standard for Binary Floating-Point Arithmetic.
                   4673: *----------------------------------------------------------------------------*/
                   4674: 
                   4675: float128 float128_mul( float128 a, float128 b STATUS_PARAM )
                   4676: {
                   4677:     flag aSign, bSign, zSign;
                   4678:     int32 aExp, bExp, zExp;
                   4679:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
                   4680:     float128 z;
                   4681: 
                   4682:     aSig1 = extractFloat128Frac1( a );
                   4683:     aSig0 = extractFloat128Frac0( a );
                   4684:     aExp = extractFloat128Exp( a );
                   4685:     aSign = extractFloat128Sign( a );
                   4686:     bSig1 = extractFloat128Frac1( b );
                   4687:     bSig0 = extractFloat128Frac0( b );
                   4688:     bExp = extractFloat128Exp( b );
                   4689:     bSign = extractFloat128Sign( b );
                   4690:     zSign = aSign ^ bSign;
                   4691:     if ( aExp == 0x7FFF ) {
                   4692:         if (    ( aSig0 | aSig1 )
                   4693:              || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
                   4694:             return propagateFloat128NaN( a, b STATUS_VAR );
                   4695:         }
                   4696:         if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
                   4697:         return packFloat128( zSign, 0x7FFF, 0, 0 );
                   4698:     }
                   4699:     if ( bExp == 0x7FFF ) {
                   4700:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4701:         if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
                   4702:  invalid:
                   4703:             float_raise( float_flag_invalid STATUS_VAR);
                   4704:             z.low = float128_default_nan_low;
                   4705:             z.high = float128_default_nan_high;
                   4706:             return z;
                   4707:         }
                   4708:         return packFloat128( zSign, 0x7FFF, 0, 0 );
                   4709:     }
                   4710:     if ( aExp == 0 ) {
                   4711:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
                   4712:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   4713:     }
                   4714:     if ( bExp == 0 ) {
                   4715:         if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
                   4716:         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
                   4717:     }
                   4718:     zExp = aExp + bExp - 0x4000;
                   4719:     aSig0 |= LIT64( 0x0001000000000000 );
                   4720:     shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
                   4721:     mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
                   4722:     add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
                   4723:     zSig2 |= ( zSig3 != 0 );
                   4724:     if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
                   4725:         shift128ExtraRightJamming(
                   4726:             zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
                   4727:         ++zExp;
                   4728:     }
                   4729:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   4730: 
                   4731: }
                   4732: 
                   4733: /*----------------------------------------------------------------------------
                   4734: | Returns the result of dividing the quadruple-precision floating-point value
                   4735: | `a' by the corresponding value `b'.  The operation is performed according to
                   4736: | the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4737: *----------------------------------------------------------------------------*/
                   4738: 
                   4739: float128 float128_div( float128 a, float128 b STATUS_PARAM )
                   4740: {
                   4741:     flag aSign, bSign, zSign;
                   4742:     int32 aExp, bExp, zExp;
                   4743:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
                   4744:     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
                   4745:     float128 z;
                   4746: 
                   4747:     aSig1 = extractFloat128Frac1( a );
                   4748:     aSig0 = extractFloat128Frac0( a );
                   4749:     aExp = extractFloat128Exp( a );
                   4750:     aSign = extractFloat128Sign( a );
                   4751:     bSig1 = extractFloat128Frac1( b );
                   4752:     bSig0 = extractFloat128Frac0( b );
                   4753:     bExp = extractFloat128Exp( b );
                   4754:     bSign = extractFloat128Sign( b );
                   4755:     zSign = aSign ^ bSign;
                   4756:     if ( aExp == 0x7FFF ) {
                   4757:         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4758:         if ( bExp == 0x7FFF ) {
                   4759:             if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4760:             goto invalid;
                   4761:         }
                   4762:         return packFloat128( zSign, 0x7FFF, 0, 0 );
                   4763:     }
                   4764:     if ( bExp == 0x7FFF ) {
                   4765:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4766:         return packFloat128( zSign, 0, 0, 0 );
                   4767:     }
                   4768:     if ( bExp == 0 ) {
                   4769:         if ( ( bSig0 | bSig1 ) == 0 ) {
                   4770:             if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
                   4771:  invalid:
                   4772:                 float_raise( float_flag_invalid STATUS_VAR);
                   4773:                 z.low = float128_default_nan_low;
                   4774:                 z.high = float128_default_nan_high;
                   4775:                 return z;
                   4776:             }
                   4777:             float_raise( float_flag_divbyzero STATUS_VAR);
                   4778:             return packFloat128( zSign, 0x7FFF, 0, 0 );
                   4779:         }
                   4780:         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
                   4781:     }
                   4782:     if ( aExp == 0 ) {
                   4783:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
                   4784:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   4785:     }
                   4786:     zExp = aExp - bExp + 0x3FFD;
                   4787:     shortShift128Left(
                   4788:         aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
                   4789:     shortShift128Left(
                   4790:         bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
                   4791:     if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
                   4792:         shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
                   4793:         ++zExp;
                   4794:     }
                   4795:     zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
                   4796:     mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
                   4797:     sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
                   4798:     while ( (sbits64) rem0 < 0 ) {
                   4799:         --zSig0;
                   4800:         add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
                   4801:     }
                   4802:     zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
                   4803:     if ( ( zSig1 & 0x3FFF ) <= 4 ) {
                   4804:         mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
                   4805:         sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
                   4806:         while ( (sbits64) rem1 < 0 ) {
                   4807:             --zSig1;
                   4808:             add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
                   4809:         }
                   4810:         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
                   4811:     }
                   4812:     shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
                   4813:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   4814: 
                   4815: }
                   4816: 
                   4817: /*----------------------------------------------------------------------------
                   4818: | Returns the remainder of the quadruple-precision floating-point value `a'
                   4819: | with respect to the corresponding value `b'.  The operation is performed
                   4820: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4821: *----------------------------------------------------------------------------*/
                   4822: 
                   4823: float128 float128_rem( float128 a, float128 b STATUS_PARAM )
                   4824: {
                   4825:     flag aSign, bSign, zSign;
                   4826:     int32 aExp, bExp, expDiff;
                   4827:     bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
                   4828:     bits64 allZero, alternateASig0, alternateASig1, sigMean1;
                   4829:     sbits64 sigMean0;
                   4830:     float128 z;
                   4831: 
                   4832:     aSig1 = extractFloat128Frac1( a );
                   4833:     aSig0 = extractFloat128Frac0( a );
                   4834:     aExp = extractFloat128Exp( a );
                   4835:     aSign = extractFloat128Sign( a );
                   4836:     bSig1 = extractFloat128Frac1( b );
                   4837:     bSig0 = extractFloat128Frac0( b );
                   4838:     bExp = extractFloat128Exp( b );
                   4839:     bSign = extractFloat128Sign( b );
                   4840:     if ( aExp == 0x7FFF ) {
                   4841:         if (    ( aSig0 | aSig1 )
                   4842:              || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
                   4843:             return propagateFloat128NaN( a, b STATUS_VAR );
                   4844:         }
                   4845:         goto invalid;
                   4846:     }
                   4847:     if ( bExp == 0x7FFF ) {
                   4848:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4849:         return a;
                   4850:     }
                   4851:     if ( bExp == 0 ) {
                   4852:         if ( ( bSig0 | bSig1 ) == 0 ) {
                   4853:  invalid:
                   4854:             float_raise( float_flag_invalid STATUS_VAR);
                   4855:             z.low = float128_default_nan_low;
                   4856:             z.high = float128_default_nan_high;
                   4857:             return z;
                   4858:         }
                   4859:         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
                   4860:     }
                   4861:     if ( aExp == 0 ) {
                   4862:         if ( ( aSig0 | aSig1 ) == 0 ) return a;
                   4863:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   4864:     }
                   4865:     expDiff = aExp - bExp;
                   4866:     if ( expDiff < -1 ) return a;
                   4867:     shortShift128Left(
                   4868:         aSig0 | LIT64( 0x0001000000000000 ),
                   4869:         aSig1,
                   4870:         15 - ( expDiff < 0 ),
                   4871:         &aSig0,
                   4872:         &aSig1
                   4873:     );
                   4874:     shortShift128Left(
                   4875:         bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
                   4876:     q = le128( bSig0, bSig1, aSig0, aSig1 );
                   4877:     if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
                   4878:     expDiff -= 64;
                   4879:     while ( 0 < expDiff ) {
                   4880:         q = estimateDiv128To64( aSig0, aSig1, bSig0 );
                   4881:         q = ( 4 < q ) ? q - 4 : 0;
                   4882:         mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
                   4883:         shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
                   4884:         shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
                   4885:         sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
                   4886:         expDiff -= 61;
                   4887:     }
                   4888:     if ( -64 < expDiff ) {
                   4889:         q = estimateDiv128To64( aSig0, aSig1, bSig0 );
                   4890:         q = ( 4 < q ) ? q - 4 : 0;
                   4891:         q >>= - expDiff;
                   4892:         shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
                   4893:         expDiff += 52;
                   4894:         if ( expDiff < 0 ) {
                   4895:             shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
                   4896:         }
                   4897:         else {
                   4898:             shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
                   4899:         }
                   4900:         mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
                   4901:         sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
                   4902:     }
                   4903:     else {
                   4904:         shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
                   4905:         shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
                   4906:     }
                   4907:     do {
                   4908:         alternateASig0 = aSig0;
                   4909:         alternateASig1 = aSig1;
                   4910:         ++q;
                   4911:         sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
                   4912:     } while ( 0 <= (sbits64) aSig0 );
                   4913:     add128(
                   4914:         aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
                   4915:     if (    ( sigMean0 < 0 )
                   4916:          || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
                   4917:         aSig0 = alternateASig0;
                   4918:         aSig1 = alternateASig1;
                   4919:     }
                   4920:     zSign = ( (sbits64) aSig0 < 0 );
                   4921:     if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
                   4922:     return
                   4923:         normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
                   4924: 
                   4925: }
                   4926: 
                   4927: /*----------------------------------------------------------------------------
                   4928: | Returns the square root of the quadruple-precision floating-point value `a'.
                   4929: | The operation is performed according to the IEC/IEEE Standard for Binary
                   4930: | Floating-Point Arithmetic.
                   4931: *----------------------------------------------------------------------------*/
                   4932: 
                   4933: float128 float128_sqrt( float128 a STATUS_PARAM )
                   4934: {
                   4935:     flag aSign;
                   4936:     int32 aExp, zExp;
                   4937:     bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
                   4938:     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
                   4939:     float128 z;
                   4940: 
                   4941:     aSig1 = extractFloat128Frac1( a );
                   4942:     aSig0 = extractFloat128Frac0( a );
                   4943:     aExp = extractFloat128Exp( a );
                   4944:     aSign = extractFloat128Sign( a );
                   4945:     if ( aExp == 0x7FFF ) {
                   4946:         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
                   4947:         if ( ! aSign ) return a;
                   4948:         goto invalid;
                   4949:     }
                   4950:     if ( aSign ) {
                   4951:         if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
                   4952:  invalid:
                   4953:         float_raise( float_flag_invalid STATUS_VAR);
                   4954:         z.low = float128_default_nan_low;
                   4955:         z.high = float128_default_nan_high;
                   4956:         return z;
                   4957:     }
                   4958:     if ( aExp == 0 ) {
                   4959:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
                   4960:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   4961:     }
                   4962:     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
                   4963:     aSig0 |= LIT64( 0x0001000000000000 );
                   4964:     zSig0 = estimateSqrt32( aExp, aSig0>>17 );
                   4965:     shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
                   4966:     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
                   4967:     doubleZSig0 = zSig0<<1;
                   4968:     mul64To128( zSig0, zSig0, &term0, &term1 );
                   4969:     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
                   4970:     while ( (sbits64) rem0 < 0 ) {
                   4971:         --zSig0;
                   4972:         doubleZSig0 -= 2;
                   4973:         add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
                   4974:     }
                   4975:     zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
                   4976:     if ( ( zSig1 & 0x1FFF ) <= 5 ) {
                   4977:         if ( zSig1 == 0 ) zSig1 = 1;
                   4978:         mul64To128( doubleZSig0, zSig1, &term1, &term2 );
                   4979:         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
                   4980:         mul64To128( zSig1, zSig1, &term2, &term3 );
                   4981:         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
                   4982:         while ( (sbits64) rem1 < 0 ) {
                   4983:             --zSig1;
                   4984:             shortShift128Left( 0, zSig1, 1, &term2, &term3 );
                   4985:             term3 |= 1;
                   4986:             term2 |= doubleZSig0;
                   4987:             add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
                   4988:         }
                   4989:         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
                   4990:     }
                   4991:     shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
                   4992:     return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   4993: 
                   4994: }
                   4995: 
                   4996: /*----------------------------------------------------------------------------
                   4997: | Returns 1 if the quadruple-precision floating-point value `a' is equal to
                   4998: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   4999: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5000: *----------------------------------------------------------------------------*/
                   5001: 
                   5002: flag float128_eq( float128 a, float128 b STATUS_PARAM )
                   5003: {
                   5004: 
                   5005:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5006:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5007:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5008:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5009:        ) {
                   5010:         if (    float128_is_signaling_nan( a )
                   5011:              || float128_is_signaling_nan( b ) ) {
                   5012:             float_raise( float_flag_invalid STATUS_VAR);
                   5013:         }
                   5014:         return 0;
                   5015:     }
                   5016:     return
                   5017:            ( a.low == b.low )
                   5018:         && (    ( a.high == b.high )
                   5019:              || (    ( a.low == 0 )
                   5020:                   && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
                   5021:            );
                   5022: 
                   5023: }
                   5024: 
                   5025: /*----------------------------------------------------------------------------
                   5026: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5027: | or equal to the corresponding value `b', and 0 otherwise.  The comparison
                   5028: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   5029: | Arithmetic.
                   5030: *----------------------------------------------------------------------------*/
                   5031: 
                   5032: flag float128_le( float128 a, float128 b STATUS_PARAM )
                   5033: {
                   5034:     flag aSign, bSign;
                   5035: 
                   5036:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5037:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5038:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5039:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5040:        ) {
                   5041:         float_raise( float_flag_invalid STATUS_VAR);
                   5042:         return 0;
                   5043:     }
                   5044:     aSign = extractFloat128Sign( a );
                   5045:     bSign = extractFloat128Sign( b );
                   5046:     if ( aSign != bSign ) {
                   5047:         return
                   5048:                aSign
                   5049:             || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5050:                  == 0 );
                   5051:     }
                   5052:     return
                   5053:           aSign ? le128( b.high, b.low, a.high, a.low )
                   5054:         : le128( a.high, a.low, b.high, b.low );
                   5055: 
                   5056: }
                   5057: 
                   5058: /*----------------------------------------------------------------------------
                   5059: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5060: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   5061: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5062: *----------------------------------------------------------------------------*/
                   5063: 
                   5064: flag float128_lt( float128 a, float128 b STATUS_PARAM )
                   5065: {
                   5066:     flag aSign, bSign;
                   5067: 
                   5068:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5069:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5070:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5071:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5072:        ) {
                   5073:         float_raise( float_flag_invalid STATUS_VAR);
                   5074:         return 0;
                   5075:     }
                   5076:     aSign = extractFloat128Sign( a );
                   5077:     bSign = extractFloat128Sign( b );
                   5078:     if ( aSign != bSign ) {
                   5079:         return
                   5080:                aSign
                   5081:             && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5082:                  != 0 );
                   5083:     }
                   5084:     return
                   5085:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   5086:         : lt128( a.high, a.low, b.high, b.low );
                   5087: 
                   5088: }
                   5089: 
                   5090: /*----------------------------------------------------------------------------
                   5091: | Returns 1 if the quadruple-precision floating-point value `a' is equal to
                   5092: | the corresponding value `b', and 0 otherwise.  The invalid exception is
                   5093: | raised if either operand is a NaN.  Otherwise, the comparison is performed
                   5094: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5095: *----------------------------------------------------------------------------*/
                   5096: 
                   5097: flag float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
                   5098: {
                   5099: 
                   5100:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5101:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5102:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5103:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5104:        ) {
                   5105:         float_raise( float_flag_invalid STATUS_VAR);
                   5106:         return 0;
                   5107:     }
                   5108:     return
                   5109:            ( a.low == b.low )
                   5110:         && (    ( a.high == b.high )
                   5111:              || (    ( a.low == 0 )
                   5112:                   && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
                   5113:            );
                   5114: 
                   5115: }
                   5116: 
                   5117: /*----------------------------------------------------------------------------
                   5118: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5119: | or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
                   5120: | cause an exception.  Otherwise, the comparison is performed according to the
                   5121: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5122: *----------------------------------------------------------------------------*/
                   5123: 
                   5124: flag float128_le_quiet( float128 a, float128 b STATUS_PARAM )
                   5125: {
                   5126:     flag aSign, bSign;
                   5127: 
                   5128:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5129:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5130:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5131:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5132:        ) {
                   5133:         if (    float128_is_signaling_nan( a )
                   5134:              || float128_is_signaling_nan( b ) ) {
                   5135:             float_raise( float_flag_invalid STATUS_VAR);
                   5136:         }
                   5137:         return 0;
                   5138:     }
                   5139:     aSign = extractFloat128Sign( a );
                   5140:     bSign = extractFloat128Sign( b );
                   5141:     if ( aSign != bSign ) {
                   5142:         return
                   5143:                aSign
                   5144:             || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5145:                  == 0 );
                   5146:     }
                   5147:     return
                   5148:           aSign ? le128( b.high, b.low, a.high, a.low )
                   5149:         : le128( a.high, a.low, b.high, b.low );
                   5150: 
                   5151: }
                   5152: 
                   5153: /*----------------------------------------------------------------------------
                   5154: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5155: | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
                   5156: | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
                   5157: | Standard for Binary Floating-Point Arithmetic.
                   5158: *----------------------------------------------------------------------------*/
                   5159: 
                   5160: flag float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
                   5161: {
                   5162:     flag aSign, bSign;
                   5163: 
                   5164:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5165:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5166:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5167:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5168:        ) {
                   5169:         if (    float128_is_signaling_nan( a )
                   5170:              || float128_is_signaling_nan( b ) ) {
                   5171:             float_raise( float_flag_invalid STATUS_VAR);
                   5172:         }
                   5173:         return 0;
                   5174:     }
                   5175:     aSign = extractFloat128Sign( a );
                   5176:     bSign = extractFloat128Sign( b );
                   5177:     if ( aSign != bSign ) {
                   5178:         return
                   5179:                aSign
                   5180:             && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5181:                  != 0 );
                   5182:     }
                   5183:     return
                   5184:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   5185:         : lt128( a.high, a.low, b.high, b.low );
                   5186: 
                   5187: }
                   5188: 
                   5189: #endif
                   5190: 
                   5191: /* misc functions */
                   5192: float32 uint32_to_float32( unsigned int a STATUS_PARAM )
                   5193: {
                   5194:     return int64_to_float32(a STATUS_VAR);
                   5195: }
                   5196: 
                   5197: float64 uint32_to_float64( unsigned int a STATUS_PARAM )
                   5198: {
                   5199:     return int64_to_float64(a STATUS_VAR);
                   5200: }
                   5201: 
                   5202: unsigned int float32_to_uint32( float32 a STATUS_PARAM )
                   5203: {
                   5204:     int64_t v;
                   5205:     unsigned int res;
                   5206: 
                   5207:     v = float32_to_int64(a STATUS_VAR);
                   5208:     if (v < 0) {
                   5209:         res = 0;
                   5210:         float_raise( float_flag_invalid STATUS_VAR);
                   5211:     } else if (v > 0xffffffff) {
                   5212:         res = 0xffffffff;
                   5213:         float_raise( float_flag_invalid STATUS_VAR);
                   5214:     } else {
                   5215:         res = v;
                   5216:     }
                   5217:     return res;
                   5218: }
                   5219: 
                   5220: unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
                   5221: {
                   5222:     int64_t v;
                   5223:     unsigned int res;
                   5224: 
                   5225:     v = float32_to_int64_round_to_zero(a STATUS_VAR);
                   5226:     if (v < 0) {
                   5227:         res = 0;
                   5228:         float_raise( float_flag_invalid STATUS_VAR);
                   5229:     } else if (v > 0xffffffff) {
                   5230:         res = 0xffffffff;
                   5231:         float_raise( float_flag_invalid STATUS_VAR);
                   5232:     } else {
                   5233:         res = v;
                   5234:     }
                   5235:     return res;
                   5236: }
                   5237: 
                   5238: unsigned int float64_to_uint32( float64 a STATUS_PARAM )
                   5239: {
                   5240:     int64_t v;
                   5241:     unsigned int res;
                   5242: 
                   5243:     v = float64_to_int64(a STATUS_VAR);
                   5244:     if (v < 0) {
                   5245:         res = 0;
                   5246:         float_raise( float_flag_invalid STATUS_VAR);
                   5247:     } else if (v > 0xffffffff) {
                   5248:         res = 0xffffffff;
                   5249:         float_raise( float_flag_invalid STATUS_VAR);
                   5250:     } else {
                   5251:         res = v;
                   5252:     }
                   5253:     return res;
                   5254: }
                   5255: 
                   5256: unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
                   5257: {
                   5258:     int64_t v;
                   5259:     unsigned int res;
                   5260: 
                   5261:     v = float64_to_int64_round_to_zero(a STATUS_VAR);
                   5262:     if (v < 0) {
                   5263:         res = 0;
                   5264:         float_raise( float_flag_invalid STATUS_VAR);
                   5265:     } else if (v > 0xffffffff) {
                   5266:         res = 0xffffffff;
                   5267:         float_raise( float_flag_invalid STATUS_VAR);
                   5268:     } else {
                   5269:         res = v;
                   5270:     }
                   5271:     return res;
                   5272: }
                   5273: 
                   5274: #define COMPARE(s, nan_exp)                                                  \
                   5275: INLINE char float ## s ## _compare_internal( float ## s a, float ## s b,     \
                   5276:                                       int is_quiet STATUS_PARAM )            \
                   5277: {                                                                            \
                   5278:     flag aSign, bSign;                                                       \
                   5279:                                                                              \
                   5280:     if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&                    \
                   5281:          extractFloat ## s ## Frac( a ) ) ||                                 \
                   5282:         ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
                   5283:           extractFloat ## s ## Frac( b ) )) {                                \
                   5284:         if (!is_quiet ||                                                     \
                   5285:             float ## s ## _is_signaling_nan( a ) ||                          \
                   5286:             float ## s ## _is_signaling_nan( b ) ) {                         \
                   5287:             float_raise( float_flag_invalid STATUS_VAR);                     \
                   5288:         }                                                                    \
                   5289:         return float_relation_unordered;                                     \
                   5290:     }                                                                        \
                   5291:     aSign = extractFloat ## s ## Sign( a );                                  \
                   5292:     bSign = extractFloat ## s ## Sign( b );                                  \
                   5293:     if ( aSign != bSign ) {                                                  \
                   5294:         if ( (bits ## s) ( ( a | b )<<1 ) == 0 ) {                           \
                   5295:             /* zero case */                                                  \
                   5296:             return float_relation_equal;                                     \
                   5297:         } else {                                                             \
                   5298:             return 1 - (2 * aSign);                                          \
                   5299:         }                                                                    \
                   5300:     } else {                                                                 \
                   5301:         if (a == b) {                                                        \
                   5302:             return float_relation_equal;                                     \
                   5303:         } else {                                                             \
                   5304:             return 1 - 2 * (aSign ^ ( a < b ));                              \
                   5305:         }                                                                    \
                   5306:     }                                                                        \
                   5307: }                                                                            \
                   5308:                                                                              \
                   5309: char float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM )       \
                   5310: {                                                                            \
                   5311:     return float ## s ## _compare_internal(a, b, 0 STATUS_VAR);              \
                   5312: }                                                                            \
                   5313:                                                                              \
                   5314: char float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM ) \
                   5315: {                                                                            \
                   5316:     return float ## s ## _compare_internal(a, b, 1 STATUS_VAR);              \
                   5317: }
                   5318: 
                   5319: COMPARE(32, 0xff)
                   5320: COMPARE(64, 0x7ff)

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.