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

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

unix.superglobalmegacorp.com

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