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

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

unix.superglobalmegacorp.com

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