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

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

unix.superglobalmegacorp.com

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