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

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: {
1.1.1.6 ! root     1913:     flag aSign, zSign;
1.1       root     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:     if ( aExp == 0xFF ) {
                   1927:         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
                   1928:             return propagateFloat32NaN( a, b STATUS_VAR );
                   1929:         }
                   1930:         float_raise( float_flag_invalid STATUS_VAR);
                   1931:         return float32_default_nan;
                   1932:     }
                   1933:     if ( bExp == 0xFF ) {
                   1934:         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
                   1935:         return a;
                   1936:     }
                   1937:     if ( bExp == 0 ) {
                   1938:         if ( bSig == 0 ) {
                   1939:             float_raise( float_flag_invalid STATUS_VAR);
                   1940:             return float32_default_nan;
                   1941:         }
                   1942:         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
                   1943:     }
                   1944:     if ( aExp == 0 ) {
                   1945:         if ( aSig == 0 ) return a;
                   1946:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   1947:     }
                   1948:     expDiff = aExp - bExp;
                   1949:     aSig |= 0x00800000;
                   1950:     bSig |= 0x00800000;
                   1951:     if ( expDiff < 32 ) {
                   1952:         aSig <<= 8;
                   1953:         bSig <<= 8;
                   1954:         if ( expDiff < 0 ) {
                   1955:             if ( expDiff < -1 ) return a;
                   1956:             aSig >>= 1;
                   1957:         }
                   1958:         q = ( bSig <= aSig );
                   1959:         if ( q ) aSig -= bSig;
                   1960:         if ( 0 < expDiff ) {
                   1961:             q = ( ( (bits64) aSig )<<32 ) / bSig;
                   1962:             q >>= 32 - expDiff;
                   1963:             bSig >>= 2;
                   1964:             aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
                   1965:         }
                   1966:         else {
                   1967:             aSig >>= 2;
                   1968:             bSig >>= 2;
                   1969:         }
                   1970:     }
                   1971:     else {
                   1972:         if ( bSig <= aSig ) aSig -= bSig;
                   1973:         aSig64 = ( (bits64) aSig )<<40;
                   1974:         bSig64 = ( (bits64) bSig )<<40;
                   1975:         expDiff -= 64;
                   1976:         while ( 0 < expDiff ) {
                   1977:             q64 = estimateDiv128To64( aSig64, 0, bSig64 );
                   1978:             q64 = ( 2 < q64 ) ? q64 - 2 : 0;
                   1979:             aSig64 = - ( ( bSig * q64 )<<38 );
                   1980:             expDiff -= 62;
                   1981:         }
                   1982:         expDiff += 64;
                   1983:         q64 = estimateDiv128To64( aSig64, 0, bSig64 );
                   1984:         q64 = ( 2 < q64 ) ? q64 - 2 : 0;
                   1985:         q = q64>>( 64 - expDiff );
                   1986:         bSig <<= 6;
                   1987:         aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
                   1988:     }
                   1989:     do {
                   1990:         alternateASig = aSig;
                   1991:         ++q;
                   1992:         aSig -= bSig;
                   1993:     } while ( 0 <= (sbits32) aSig );
                   1994:     sigMean = aSig + alternateASig;
                   1995:     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
                   1996:         aSig = alternateASig;
                   1997:     }
                   1998:     zSign = ( (sbits32) aSig < 0 );
                   1999:     if ( zSign ) aSig = - aSig;
                   2000:     return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
                   2001: 
                   2002: }
                   2003: 
                   2004: /*----------------------------------------------------------------------------
                   2005: | Returns the square root of the single-precision floating-point value `a'.
                   2006: | The operation is performed according to the IEC/IEEE Standard for Binary
                   2007: | Floating-Point Arithmetic.
                   2008: *----------------------------------------------------------------------------*/
                   2009: 
                   2010: float32 float32_sqrt( float32 a STATUS_PARAM )
                   2011: {
                   2012:     flag aSign;
                   2013:     int16 aExp, zExp;
                   2014:     bits32 aSig, zSig;
                   2015:     bits64 rem, term;
                   2016: 
                   2017:     aSig = extractFloat32Frac( a );
                   2018:     aExp = extractFloat32Exp( a );
                   2019:     aSign = extractFloat32Sign( a );
                   2020:     if ( aExp == 0xFF ) {
1.1.1.3   root     2021:         if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
1.1       root     2022:         if ( ! aSign ) return a;
                   2023:         float_raise( float_flag_invalid STATUS_VAR);
                   2024:         return float32_default_nan;
                   2025:     }
                   2026:     if ( aSign ) {
                   2027:         if ( ( aExp | aSig ) == 0 ) return a;
                   2028:         float_raise( float_flag_invalid STATUS_VAR);
                   2029:         return float32_default_nan;
                   2030:     }
                   2031:     if ( aExp == 0 ) {
1.1.1.3   root     2032:         if ( aSig == 0 ) return float32_zero;
1.1       root     2033:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   2034:     }
                   2035:     zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
                   2036:     aSig = ( aSig | 0x00800000 )<<8;
                   2037:     zSig = estimateSqrt32( aExp, aSig ) + 2;
                   2038:     if ( ( zSig & 0x7F ) <= 5 ) {
                   2039:         if ( zSig < 2 ) {
                   2040:             zSig = 0x7FFFFFFF;
                   2041:             goto roundAndPack;
                   2042:         }
                   2043:         aSig >>= aExp & 1;
                   2044:         term = ( (bits64) zSig ) * zSig;
                   2045:         rem = ( ( (bits64) aSig )<<32 ) - term;
                   2046:         while ( (sbits64) rem < 0 ) {
                   2047:             --zSig;
                   2048:             rem += ( ( (bits64) zSig )<<1 ) | 1;
                   2049:         }
                   2050:         zSig |= ( rem != 0 );
                   2051:     }
                   2052:     shift32RightJamming( zSig, 1, &zSig );
                   2053:  roundAndPack:
                   2054:     return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
                   2055: 
                   2056: }
                   2057: 
                   2058: /*----------------------------------------------------------------------------
1.1.1.6 ! root     2059: | Returns the binary exponential of the single-precision floating-point value
        !          2060: | `a'. The operation is performed according to the IEC/IEEE Standard for
        !          2061: | Binary Floating-Point Arithmetic.
        !          2062: |
        !          2063: | Uses the following identities:
        !          2064: |
        !          2065: | 1. -------------------------------------------------------------------------
        !          2066: |      x    x*ln(2)
        !          2067: |     2  = e
        !          2068: |
        !          2069: | 2. -------------------------------------------------------------------------
        !          2070: |                      2     3     4     5           n
        !          2071: |      x        x     x     x     x     x           x
        !          2072: |     e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
        !          2073: |               1!    2!    3!    4!    5!          n!
        !          2074: *----------------------------------------------------------------------------*/
        !          2075: 
        !          2076: static const float64 float32_exp2_coefficients[15] =
        !          2077: {
        !          2078:     make_float64( 0x3ff0000000000000ll ), /*  1 */
        !          2079:     make_float64( 0x3fe0000000000000ll ), /*  2 */
        !          2080:     make_float64( 0x3fc5555555555555ll ), /*  3 */
        !          2081:     make_float64( 0x3fa5555555555555ll ), /*  4 */
        !          2082:     make_float64( 0x3f81111111111111ll ), /*  5 */
        !          2083:     make_float64( 0x3f56c16c16c16c17ll ), /*  6 */
        !          2084:     make_float64( 0x3f2a01a01a01a01all ), /*  7 */
        !          2085:     make_float64( 0x3efa01a01a01a01all ), /*  8 */
        !          2086:     make_float64( 0x3ec71de3a556c734ll ), /*  9 */
        !          2087:     make_float64( 0x3e927e4fb7789f5cll ), /* 10 */
        !          2088:     make_float64( 0x3e5ae64567f544e4ll ), /* 11 */
        !          2089:     make_float64( 0x3e21eed8eff8d898ll ), /* 12 */
        !          2090:     make_float64( 0x3de6124613a86d09ll ), /* 13 */
        !          2091:     make_float64( 0x3da93974a8c07c9dll ), /* 14 */
        !          2092:     make_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
        !          2093: };
        !          2094: 
        !          2095: float32 float32_exp2( float32 a STATUS_PARAM )
        !          2096: {
        !          2097:     flag aSign;
        !          2098:     int16 aExp;
        !          2099:     bits32 aSig;
        !          2100:     float64 r, x, xn;
        !          2101:     int i;
        !          2102: 
        !          2103:     aSig = extractFloat32Frac( a );
        !          2104:     aExp = extractFloat32Exp( a );
        !          2105:     aSign = extractFloat32Sign( a );
        !          2106: 
        !          2107:     if ( aExp == 0xFF) {
        !          2108:         if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
        !          2109:         return (aSign) ? float32_zero : a;
        !          2110:     }
        !          2111:     if (aExp == 0) {
        !          2112:         if (aSig == 0) return float32_one;
        !          2113:     }
        !          2114: 
        !          2115:     float_raise( float_flag_inexact STATUS_VAR);
        !          2116: 
        !          2117:     /* ******************************* */
        !          2118:     /* using float64 for approximation */
        !          2119:     /* ******************************* */
        !          2120:     x = float32_to_float64(a STATUS_VAR);
        !          2121:     x = float64_mul(x, float64_ln2 STATUS_VAR);
        !          2122: 
        !          2123:     xn = x;
        !          2124:     r = float64_one;
        !          2125:     for (i = 0 ; i < 15 ; i++) {
        !          2126:         float64 f;
        !          2127: 
        !          2128:         f = float64_mul(xn, float32_exp2_coefficients[i] STATUS_VAR);
        !          2129:         r = float64_add(r, f STATUS_VAR);
        !          2130: 
        !          2131:         xn = float64_mul(xn, x STATUS_VAR);
        !          2132:     }
        !          2133: 
        !          2134:     return float64_to_float32(r, status);
        !          2135: }
        !          2136: 
        !          2137: /*----------------------------------------------------------------------------
1.1.1.4   root     2138: | Returns the binary log of the single-precision floating-point value `a'.
                   2139: | The operation is performed according to the IEC/IEEE Standard for Binary
                   2140: | Floating-Point Arithmetic.
                   2141: *----------------------------------------------------------------------------*/
                   2142: float32 float32_log2( float32 a STATUS_PARAM )
                   2143: {
                   2144:     flag aSign, zSign;
                   2145:     int16 aExp;
                   2146:     bits32 aSig, zSig, i;
                   2147: 
                   2148:     aSig = extractFloat32Frac( a );
                   2149:     aExp = extractFloat32Exp( a );
                   2150:     aSign = extractFloat32Sign( a );
                   2151: 
                   2152:     if ( aExp == 0 ) {
                   2153:         if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
                   2154:         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
                   2155:     }
                   2156:     if ( aSign ) {
                   2157:         float_raise( float_flag_invalid STATUS_VAR);
                   2158:         return float32_default_nan;
                   2159:     }
                   2160:     if ( aExp == 0xFF ) {
                   2161:         if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
                   2162:         return a;
                   2163:     }
                   2164: 
                   2165:     aExp -= 0x7F;
                   2166:     aSig |= 0x00800000;
                   2167:     zSign = aExp < 0;
                   2168:     zSig = aExp << 23;
                   2169: 
                   2170:     for (i = 1 << 22; i > 0; i >>= 1) {
                   2171:         aSig = ( (bits64)aSig * aSig ) >> 23;
                   2172:         if ( aSig & 0x01000000 ) {
                   2173:             aSig >>= 1;
                   2174:             zSig |= i;
                   2175:         }
                   2176:     }
                   2177: 
                   2178:     if ( zSign )
                   2179:         zSig = -zSig;
                   2180: 
                   2181:     return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
                   2182: }
                   2183: 
                   2184: /*----------------------------------------------------------------------------
1.1       root     2185: | Returns 1 if the single-precision floating-point value `a' is equal to
                   2186: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   2187: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2188: *----------------------------------------------------------------------------*/
                   2189: 
1.1.1.2   root     2190: int float32_eq( float32 a, float32 b STATUS_PARAM )
1.1       root     2191: {
                   2192: 
                   2193:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2194:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2195:        ) {
                   2196:         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
                   2197:             float_raise( float_flag_invalid STATUS_VAR);
                   2198:         }
                   2199:         return 0;
                   2200:     }
1.1.1.3   root     2201:     return ( float32_val(a) == float32_val(b) ) ||
                   2202:             ( (bits32) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
1.1       root     2203: 
                   2204: }
                   2205: 
                   2206: /*----------------------------------------------------------------------------
                   2207: | Returns 1 if the single-precision floating-point value `a' is less than
                   2208: | or equal to the corresponding value `b', and 0 otherwise.  The comparison
                   2209: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2210: | Arithmetic.
                   2211: *----------------------------------------------------------------------------*/
                   2212: 
1.1.1.2   root     2213: int float32_le( float32 a, float32 b STATUS_PARAM )
1.1       root     2214: {
                   2215:     flag aSign, bSign;
1.1.1.3   root     2216:     bits32 av, bv;
1.1       root     2217: 
                   2218:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2219:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2220:        ) {
                   2221:         float_raise( float_flag_invalid STATUS_VAR);
                   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.  The comparison is performed
                   2236: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2237: *----------------------------------------------------------------------------*/
                   2238: 
1.1.1.2   root     2239: int float32_lt( float32 a, float32 b STATUS_PARAM )
1.1       root     2240: {
                   2241:     flag aSign, bSign;
1.1.1.3   root     2242:     bits32 av, bv;
1.1       root     2243: 
                   2244:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2245:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2246:        ) {
                   2247:         float_raise( float_flag_invalid STATUS_VAR);
                   2248:         return 0;
                   2249:     }
                   2250:     aSign = extractFloat32Sign( a );
                   2251:     bSign = extractFloat32Sign( b );
1.1.1.3   root     2252:     av = float32_val(a);
                   2253:     bv = float32_val(b);
                   2254:     if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
                   2255:     return ( av != bv ) && ( aSign ^ ( av < bv ) );
1.1       root     2256: 
                   2257: }
                   2258: 
                   2259: /*----------------------------------------------------------------------------
                   2260: | Returns 1 if the single-precision floating-point value `a' is equal to
                   2261: | the corresponding value `b', and 0 otherwise.  The invalid exception is
                   2262: | raised if either operand is a NaN.  Otherwise, the comparison is performed
                   2263: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2264: *----------------------------------------------------------------------------*/
                   2265: 
1.1.1.2   root     2266: int float32_eq_signaling( float32 a, float32 b STATUS_PARAM )
1.1       root     2267: {
1.1.1.3   root     2268:     bits32 av, bv;
1.1       root     2269: 
                   2270:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2271:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2272:        ) {
                   2273:         float_raise( float_flag_invalid STATUS_VAR);
                   2274:         return 0;
                   2275:     }
1.1.1.3   root     2276:     av = float32_val(a);
                   2277:     bv = float32_val(b);
                   2278:     return ( av == bv ) || ( (bits32) ( ( av | bv )<<1 ) == 0 );
1.1       root     2279: 
                   2280: }
                   2281: 
                   2282: /*----------------------------------------------------------------------------
                   2283: | Returns 1 if the single-precision floating-point value `a' is less than or
                   2284: | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
                   2285: | cause an exception.  Otherwise, the comparison is performed according to the
                   2286: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   2287: *----------------------------------------------------------------------------*/
                   2288: 
1.1.1.2   root     2289: int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
1.1       root     2290: {
                   2291:     flag aSign, bSign;
1.1.1.3   root     2292:     bits32 av, bv;
1.1       root     2293: 
                   2294:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2295:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2296:        ) {
                   2297:         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
                   2298:             float_raise( float_flag_invalid STATUS_VAR);
                   2299:         }
                   2300:         return 0;
                   2301:     }
                   2302:     aSign = extractFloat32Sign( a );
                   2303:     bSign = extractFloat32Sign( b );
1.1.1.3   root     2304:     av = float32_val(a);
                   2305:     bv = float32_val(b);
                   2306:     if ( aSign != bSign ) return aSign || ( (bits32) ( ( av | bv )<<1 ) == 0 );
                   2307:     return ( av == bv ) || ( aSign ^ ( av < bv ) );
1.1       root     2308: 
                   2309: }
                   2310: 
                   2311: /*----------------------------------------------------------------------------
                   2312: | Returns 1 if the single-precision floating-point value `a' is less than
                   2313: | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
                   2314: | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
                   2315: | Standard for Binary Floating-Point Arithmetic.
                   2316: *----------------------------------------------------------------------------*/
                   2317: 
1.1.1.2   root     2318: int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
1.1       root     2319: {
                   2320:     flag aSign, bSign;
1.1.1.3   root     2321:     bits32 av, bv;
1.1       root     2322: 
                   2323:     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
                   2324:          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
                   2325:        ) {
                   2326:         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
                   2327:             float_raise( float_flag_invalid STATUS_VAR);
                   2328:         }
                   2329:         return 0;
                   2330:     }
                   2331:     aSign = extractFloat32Sign( a );
                   2332:     bSign = extractFloat32Sign( b );
1.1.1.3   root     2333:     av = float32_val(a);
                   2334:     bv = float32_val(b);
                   2335:     if ( aSign != bSign ) return aSign && ( (bits32) ( ( av | bv )<<1 ) != 0 );
                   2336:     return ( av != bv ) && ( aSign ^ ( av < bv ) );
1.1       root     2337: 
                   2338: }
                   2339: 
                   2340: /*----------------------------------------------------------------------------
                   2341: | Returns the result of converting the double-precision floating-point value
                   2342: | `a' to the 32-bit two's complement integer format.  The conversion is
                   2343: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2344: | Arithmetic---which means in particular that the conversion is rounded
                   2345: | according to the current rounding mode.  If `a' is a NaN, the largest
                   2346: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   2347: | largest integer with the same sign as `a' is returned.
                   2348: *----------------------------------------------------------------------------*/
                   2349: 
                   2350: int32 float64_to_int32( float64 a STATUS_PARAM )
                   2351: {
                   2352:     flag aSign;
                   2353:     int16 aExp, shiftCount;
                   2354:     bits64 aSig;
                   2355: 
                   2356:     aSig = extractFloat64Frac( a );
                   2357:     aExp = extractFloat64Exp( a );
                   2358:     aSign = extractFloat64Sign( a );
                   2359:     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
                   2360:     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
                   2361:     shiftCount = 0x42C - aExp;
                   2362:     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
                   2363:     return roundAndPackInt32( aSign, aSig STATUS_VAR );
                   2364: 
                   2365: }
                   2366: 
                   2367: /*----------------------------------------------------------------------------
                   2368: | Returns the result of converting the double-precision floating-point value
                   2369: | `a' to the 32-bit two's complement integer format.  The conversion is
                   2370: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2371: | Arithmetic, except that the conversion is always rounded toward zero.
                   2372: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   2373: | the conversion overflows, the largest integer with the same sign as `a' is
                   2374: | returned.
                   2375: *----------------------------------------------------------------------------*/
                   2376: 
                   2377: int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
                   2378: {
                   2379:     flag aSign;
                   2380:     int16 aExp, shiftCount;
                   2381:     bits64 aSig, savedASig;
                   2382:     int32 z;
                   2383: 
                   2384:     aSig = extractFloat64Frac( a );
                   2385:     aExp = extractFloat64Exp( a );
                   2386:     aSign = extractFloat64Sign( a );
                   2387:     if ( 0x41E < aExp ) {
                   2388:         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
                   2389:         goto invalid;
                   2390:     }
                   2391:     else if ( aExp < 0x3FF ) {
                   2392:         if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   2393:         return 0;
                   2394:     }
                   2395:     aSig |= LIT64( 0x0010000000000000 );
                   2396:     shiftCount = 0x433 - aExp;
                   2397:     savedASig = aSig;
                   2398:     aSig >>= shiftCount;
                   2399:     z = aSig;
                   2400:     if ( aSign ) z = - z;
                   2401:     if ( ( z < 0 ) ^ aSign ) {
                   2402:  invalid:
                   2403:         float_raise( float_flag_invalid STATUS_VAR);
                   2404:         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                   2405:     }
                   2406:     if ( ( aSig<<shiftCount ) != savedASig ) {
                   2407:         STATUS(float_exception_flags) |= float_flag_inexact;
                   2408:     }
                   2409:     return z;
                   2410: 
                   2411: }
                   2412: 
                   2413: /*----------------------------------------------------------------------------
                   2414: | Returns the result of converting the double-precision floating-point value
                   2415: | `a' to the 64-bit two's complement integer format.  The conversion is
                   2416: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2417: | Arithmetic---which means in particular that the conversion is rounded
                   2418: | according to the current rounding mode.  If `a' is a NaN, the largest
                   2419: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   2420: | largest integer with the same sign as `a' is returned.
                   2421: *----------------------------------------------------------------------------*/
                   2422: 
                   2423: int64 float64_to_int64( float64 a STATUS_PARAM )
                   2424: {
                   2425:     flag aSign;
                   2426:     int16 aExp, shiftCount;
                   2427:     bits64 aSig, aSigExtra;
                   2428: 
                   2429:     aSig = extractFloat64Frac( a );
                   2430:     aExp = extractFloat64Exp( a );
                   2431:     aSign = extractFloat64Sign( a );
                   2432:     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
                   2433:     shiftCount = 0x433 - aExp;
                   2434:     if ( shiftCount <= 0 ) {
                   2435:         if ( 0x43E < aExp ) {
                   2436:             float_raise( float_flag_invalid STATUS_VAR);
                   2437:             if (    ! aSign
                   2438:                  || (    ( aExp == 0x7FF )
                   2439:                       && ( aSig != LIT64( 0x0010000000000000 ) ) )
                   2440:                ) {
                   2441:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   2442:             }
                   2443:             return (sbits64) LIT64( 0x8000000000000000 );
                   2444:         }
                   2445:         aSigExtra = 0;
                   2446:         aSig <<= - shiftCount;
                   2447:     }
                   2448:     else {
                   2449:         shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
                   2450:     }
                   2451:     return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
                   2452: 
                   2453: }
                   2454: 
                   2455: /*----------------------------------------------------------------------------
                   2456: | Returns the result of converting the double-precision floating-point value
                   2457: | `a' to the 64-bit two's complement integer format.  The conversion is
                   2458: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2459: | Arithmetic, except that the conversion is always rounded toward zero.
                   2460: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   2461: | the conversion overflows, the largest integer with the same sign as `a' is
                   2462: | returned.
                   2463: *----------------------------------------------------------------------------*/
                   2464: 
                   2465: int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
                   2466: {
                   2467:     flag aSign;
                   2468:     int16 aExp, shiftCount;
                   2469:     bits64 aSig;
                   2470:     int64 z;
                   2471: 
                   2472:     aSig = extractFloat64Frac( a );
                   2473:     aExp = extractFloat64Exp( a );
                   2474:     aSign = extractFloat64Sign( a );
                   2475:     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
                   2476:     shiftCount = aExp - 0x433;
                   2477:     if ( 0 <= shiftCount ) {
                   2478:         if ( 0x43E <= aExp ) {
1.1.1.3   root     2479:             if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) {
1.1       root     2480:                 float_raise( float_flag_invalid STATUS_VAR);
                   2481:                 if (    ! aSign
                   2482:                      || (    ( aExp == 0x7FF )
                   2483:                           && ( aSig != LIT64( 0x0010000000000000 ) ) )
                   2484:                    ) {
                   2485:                     return LIT64( 0x7FFFFFFFFFFFFFFF );
                   2486:                 }
                   2487:             }
                   2488:             return (sbits64) LIT64( 0x8000000000000000 );
                   2489:         }
                   2490:         z = aSig<<shiftCount;
                   2491:     }
                   2492:     else {
                   2493:         if ( aExp < 0x3FE ) {
                   2494:             if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   2495:             return 0;
                   2496:         }
                   2497:         z = aSig>>( - shiftCount );
                   2498:         if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
                   2499:             STATUS(float_exception_flags) |= float_flag_inexact;
                   2500:         }
                   2501:     }
                   2502:     if ( aSign ) z = - z;
                   2503:     return z;
                   2504: 
                   2505: }
                   2506: 
                   2507: /*----------------------------------------------------------------------------
                   2508: | Returns the result of converting the double-precision floating-point value
                   2509: | `a' to the single-precision floating-point format.  The conversion is
                   2510: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2511: | Arithmetic.
                   2512: *----------------------------------------------------------------------------*/
                   2513: 
                   2514: float32 float64_to_float32( float64 a STATUS_PARAM )
                   2515: {
                   2516:     flag aSign;
                   2517:     int16 aExp;
                   2518:     bits64 aSig;
                   2519:     bits32 zSig;
                   2520: 
                   2521:     aSig = extractFloat64Frac( a );
                   2522:     aExp = extractFloat64Exp( a );
                   2523:     aSign = extractFloat64Sign( a );
                   2524:     if ( aExp == 0x7FF ) {
                   2525:         if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) );
                   2526:         return packFloat32( aSign, 0xFF, 0 );
                   2527:     }
                   2528:     shift64RightJamming( aSig, 22, &aSig );
                   2529:     zSig = aSig;
                   2530:     if ( aExp || zSig ) {
                   2531:         zSig |= 0x40000000;
                   2532:         aExp -= 0x381;
                   2533:     }
                   2534:     return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
                   2535: 
                   2536: }
                   2537: 
1.1.1.5   root     2538: 
                   2539: /*----------------------------------------------------------------------------
                   2540: | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
                   2541: | half-precision floating-point value, returning the result.  After being
                   2542: | shifted into the proper positions, the three fields are simply added
                   2543: | together to form the result.  This means that any integer portion of `zSig'
                   2544: | will be added into the exponent.  Since a properly normalized significand
                   2545: | will have an integer portion equal to 1, the `zExp' input should be 1 less
                   2546: | than the desired result exponent whenever `zSig' is a complete, normalized
                   2547: | significand.
                   2548: *----------------------------------------------------------------------------*/
                   2549: static bits16 packFloat16(flag zSign, int16 zExp, bits16 zSig)
                   2550: {
                   2551:     return (((bits32)zSign) << 15) + (((bits32)zExp) << 10) + zSig;
                   2552: }
                   2553: 
                   2554: /* Half precision floats come in two formats: standard IEEE and "ARM" format.
                   2555:    The latter gains extra exponent range by omitting the NaN/Inf encodings.  */
                   2556:   
                   2557: float32 float16_to_float32( bits16 a, flag ieee STATUS_PARAM )
                   2558: {
                   2559:     flag aSign;
                   2560:     int16 aExp;
                   2561:     bits32 aSig;
                   2562: 
                   2563:     aSign = a >> 15;
                   2564:     aExp = (a >> 10) & 0x1f;
                   2565:     aSig = a & 0x3ff;
                   2566: 
                   2567:     if (aExp == 0x1f && ieee) {
                   2568:         if (aSig) {
                   2569:             /* Make sure correct exceptions are raised.  */
                   2570:             float32ToCommonNaN(a STATUS_VAR);
                   2571:             aSig |= 0x200;
                   2572:         }
                   2573:         return packFloat32(aSign, 0xff, aSig << 13);
                   2574:     }
                   2575:     if (aExp == 0) {
                   2576:         int8 shiftCount;
                   2577: 
                   2578:         if (aSig == 0) {
                   2579:             return packFloat32(aSign, 0, 0);
                   2580:         }
                   2581: 
                   2582:         shiftCount = countLeadingZeros32( aSig ) - 21;
                   2583:         aSig = aSig << shiftCount;
                   2584:         aExp = -shiftCount;
                   2585:     }
                   2586:     return packFloat32( aSign, aExp + 0x70, aSig << 13);
                   2587: }
                   2588: 
                   2589: bits16 float32_to_float16( float32 a, flag ieee STATUS_PARAM)
                   2590: {
                   2591:     flag aSign;
                   2592:     int16 aExp;
                   2593:     bits32 aSig;
                   2594:     bits32 mask;
                   2595:     bits32 increment;
                   2596:     int8 roundingMode;
                   2597: 
                   2598:     aSig = extractFloat32Frac( a );
                   2599:     aExp = extractFloat32Exp( a );
                   2600:     aSign = extractFloat32Sign( a );
                   2601:     if ( aExp == 0xFF ) {
                   2602:         if (aSig) {
                   2603:             /* Make sure correct exceptions are raised.  */
                   2604:             float32ToCommonNaN(a STATUS_VAR);
                   2605:             aSig |= 0x00400000;
                   2606:         }
                   2607:         return packFloat16(aSign, 0x1f, aSig >> 13);
                   2608:     }
                   2609:     if (aExp == 0 && aSign == 0) {
                   2610:         return packFloat16(aSign, 0, 0);
                   2611:     }
                   2612:     /* Decimal point between bits 22 and 23.  */
                   2613:     aSig |= 0x00800000;
                   2614:     aExp -= 0x7f;
                   2615:     if (aExp < -14) {
                   2616:         mask = 0x007fffff;
                   2617:         if (aExp < -24) {
                   2618:             aExp = -25;
                   2619:         } else {
                   2620:             mask >>= 24 + aExp;
                   2621:         }
                   2622:     } else {
                   2623:         mask = 0x00001fff;
                   2624:     }
                   2625:     if (aSig & mask) {
                   2626:         float_raise( float_flag_underflow STATUS_VAR );
                   2627:         roundingMode = STATUS(float_rounding_mode);
                   2628:         switch (roundingMode) {
                   2629:         case float_round_nearest_even:
                   2630:             increment = (mask + 1) >> 1;
                   2631:             if ((aSig & mask) == increment) {
                   2632:                 increment = aSig & (increment << 1);
                   2633:             }
                   2634:             break;
                   2635:         case float_round_up:
                   2636:             increment = aSign ? 0 : mask;
                   2637:             break;
                   2638:         case float_round_down:
                   2639:             increment = aSign ? mask : 0;
                   2640:             break;
                   2641:         default: /* round_to_zero */
                   2642:             increment = 0;
                   2643:             break;
                   2644:         }
                   2645:         aSig += increment;
                   2646:         if (aSig >= 0x01000000) {
                   2647:             aSig >>= 1;
                   2648:             aExp++;
                   2649:         }
                   2650:     } else if (aExp < -14
                   2651:           && STATUS(float_detect_tininess) == float_tininess_before_rounding) {
                   2652:         float_raise( float_flag_underflow STATUS_VAR);
                   2653:     }
                   2654: 
                   2655:     if (ieee) {
                   2656:         if (aExp > 15) {
                   2657:             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
                   2658:             return packFloat16(aSign, 0x1f, 0);
                   2659:         }
                   2660:     } else {
                   2661:         if (aExp > 16) {
                   2662:             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
                   2663:             return packFloat16(aSign, 0x1f, 0x3ff);
                   2664:         }
                   2665:     }
                   2666:     if (aExp < -24) {
                   2667:         return packFloat16(aSign, 0, 0);
                   2668:     }
                   2669:     if (aExp < -14) {
                   2670:         aSig >>= -14 - aExp;
                   2671:         aExp = -14;
                   2672:     }
                   2673:     return packFloat16(aSign, aExp + 14, aSig >> 13);
                   2674: }
                   2675: 
1.1       root     2676: #ifdef FLOATX80
                   2677: 
                   2678: /*----------------------------------------------------------------------------
                   2679: | Returns the result of converting the double-precision floating-point value
                   2680: | `a' to the extended double-precision floating-point format.  The conversion
                   2681: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2682: | Arithmetic.
                   2683: *----------------------------------------------------------------------------*/
                   2684: 
                   2685: floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
                   2686: {
                   2687:     flag aSign;
                   2688:     int16 aExp;
                   2689:     bits64 aSig;
                   2690: 
                   2691:     aSig = extractFloat64Frac( a );
                   2692:     aExp = extractFloat64Exp( a );
                   2693:     aSign = extractFloat64Sign( a );
                   2694:     if ( aExp == 0x7FF ) {
                   2695:         if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) );
                   2696:         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   2697:     }
                   2698:     if ( aExp == 0 ) {
                   2699:         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
                   2700:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2701:     }
                   2702:     return
                   2703:         packFloatx80(
                   2704:             aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
                   2705: 
                   2706: }
                   2707: 
                   2708: #endif
                   2709: 
                   2710: #ifdef FLOAT128
                   2711: 
                   2712: /*----------------------------------------------------------------------------
                   2713: | Returns the result of converting the double-precision floating-point value
                   2714: | `a' to the quadruple-precision floating-point format.  The conversion is
                   2715: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   2716: | Arithmetic.
                   2717: *----------------------------------------------------------------------------*/
                   2718: 
                   2719: float128 float64_to_float128( float64 a STATUS_PARAM )
                   2720: {
                   2721:     flag aSign;
                   2722:     int16 aExp;
                   2723:     bits64 aSig, zSig0, zSig1;
                   2724: 
                   2725:     aSig = extractFloat64Frac( a );
                   2726:     aExp = extractFloat64Exp( a );
                   2727:     aSign = extractFloat64Sign( a );
                   2728:     if ( aExp == 0x7FF ) {
                   2729:         if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) );
                   2730:         return packFloat128( aSign, 0x7FFF, 0, 0 );
                   2731:     }
                   2732:     if ( aExp == 0 ) {
                   2733:         if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
                   2734:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   2735:         --aExp;
                   2736:     }
                   2737:     shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
                   2738:     return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
                   2739: 
                   2740: }
                   2741: 
                   2742: #endif
                   2743: 
                   2744: /*----------------------------------------------------------------------------
                   2745: | Rounds the double-precision floating-point value `a' to an integer, and
                   2746: | returns the result as a double-precision floating-point value.  The
                   2747: | operation is performed according to the IEC/IEEE Standard for Binary
                   2748: | Floating-Point Arithmetic.
                   2749: *----------------------------------------------------------------------------*/
                   2750: 
                   2751: float64 float64_round_to_int( float64 a STATUS_PARAM )
                   2752: {
                   2753:     flag aSign;
                   2754:     int16 aExp;
                   2755:     bits64 lastBitMask, roundBitsMask;
                   2756:     int8 roundingMode;
1.1.1.3   root     2757:     bits64 z;
1.1       root     2758: 
                   2759:     aExp = extractFloat64Exp( a );
                   2760:     if ( 0x433 <= aExp ) {
                   2761:         if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
                   2762:             return propagateFloat64NaN( a, a STATUS_VAR );
                   2763:         }
                   2764:         return a;
                   2765:     }
                   2766:     if ( aExp < 0x3FF ) {
1.1.1.3   root     2767:         if ( (bits64) ( float64_val(a)<<1 ) == 0 ) return a;
1.1       root     2768:         STATUS(float_exception_flags) |= float_flag_inexact;
                   2769:         aSign = extractFloat64Sign( a );
                   2770:         switch ( STATUS(float_rounding_mode) ) {
                   2771:          case float_round_nearest_even:
                   2772:             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
                   2773:                 return packFloat64( aSign, 0x3FF, 0 );
                   2774:             }
                   2775:             break;
                   2776:          case float_round_down:
1.1.1.3   root     2777:             return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
1.1       root     2778:          case float_round_up:
1.1.1.3   root     2779:             return make_float64(
                   2780:             aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ));
1.1       root     2781:         }
                   2782:         return packFloat64( aSign, 0, 0 );
                   2783:     }
                   2784:     lastBitMask = 1;
                   2785:     lastBitMask <<= 0x433 - aExp;
                   2786:     roundBitsMask = lastBitMask - 1;
1.1.1.3   root     2787:     z = float64_val(a);
1.1       root     2788:     roundingMode = STATUS(float_rounding_mode);
                   2789:     if ( roundingMode == float_round_nearest_even ) {
                   2790:         z += lastBitMask>>1;
                   2791:         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
                   2792:     }
                   2793:     else if ( roundingMode != float_round_to_zero ) {
1.1.1.3   root     2794:         if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
1.1       root     2795:             z += roundBitsMask;
                   2796:         }
                   2797:     }
                   2798:     z &= ~ roundBitsMask;
1.1.1.3   root     2799:     if ( z != float64_val(a) )
                   2800:         STATUS(float_exception_flags) |= float_flag_inexact;
                   2801:     return make_float64(z);
1.1       root     2802: 
                   2803: }
                   2804: 
1.1.1.2   root     2805: float64 float64_trunc_to_int( float64 a STATUS_PARAM)
                   2806: {
                   2807:     int oldmode;
                   2808:     float64 res;
                   2809:     oldmode = STATUS(float_rounding_mode);
                   2810:     STATUS(float_rounding_mode) = float_round_to_zero;
                   2811:     res = float64_round_to_int(a STATUS_VAR);
                   2812:     STATUS(float_rounding_mode) = oldmode;
                   2813:     return res;
                   2814: }
                   2815: 
1.1       root     2816: /*----------------------------------------------------------------------------
                   2817: | Returns the result of adding the absolute values of the double-precision
                   2818: | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
                   2819: | before being returned.  `zSign' is ignored if the result is a NaN.
                   2820: | The addition is performed according to the IEC/IEEE Standard for Binary
                   2821: | Floating-Point Arithmetic.
                   2822: *----------------------------------------------------------------------------*/
                   2823: 
                   2824: static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
                   2825: {
                   2826:     int16 aExp, bExp, zExp;
                   2827:     bits64 aSig, bSig, zSig;
                   2828:     int16 expDiff;
                   2829: 
                   2830:     aSig = extractFloat64Frac( a );
                   2831:     aExp = extractFloat64Exp( a );
                   2832:     bSig = extractFloat64Frac( b );
                   2833:     bExp = extractFloat64Exp( b );
                   2834:     expDiff = aExp - bExp;
                   2835:     aSig <<= 9;
                   2836:     bSig <<= 9;
                   2837:     if ( 0 < expDiff ) {
                   2838:         if ( aExp == 0x7FF ) {
                   2839:             if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2840:             return a;
                   2841:         }
                   2842:         if ( bExp == 0 ) {
                   2843:             --expDiff;
                   2844:         }
                   2845:         else {
                   2846:             bSig |= LIT64( 0x2000000000000000 );
                   2847:         }
                   2848:         shift64RightJamming( bSig, expDiff, &bSig );
                   2849:         zExp = aExp;
                   2850:     }
                   2851:     else if ( expDiff < 0 ) {
                   2852:         if ( bExp == 0x7FF ) {
                   2853:             if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2854:             return packFloat64( zSign, 0x7FF, 0 );
                   2855:         }
                   2856:         if ( aExp == 0 ) {
                   2857:             ++expDiff;
                   2858:         }
                   2859:         else {
                   2860:             aSig |= LIT64( 0x2000000000000000 );
                   2861:         }
                   2862:         shift64RightJamming( aSig, - expDiff, &aSig );
                   2863:         zExp = bExp;
                   2864:     }
                   2865:     else {
                   2866:         if ( aExp == 0x7FF ) {
                   2867:             if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2868:             return a;
                   2869:         }
1.1.1.4   root     2870:         if ( aExp == 0 ) {
                   2871:             if ( STATUS(flush_to_zero) ) return packFloat64( zSign, 0, 0 );
                   2872:             return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
                   2873:         }
1.1       root     2874:         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
                   2875:         zExp = aExp;
                   2876:         goto roundAndPack;
                   2877:     }
                   2878:     aSig |= LIT64( 0x2000000000000000 );
                   2879:     zSig = ( aSig + bSig )<<1;
                   2880:     --zExp;
                   2881:     if ( (sbits64) zSig < 0 ) {
                   2882:         zSig = aSig + bSig;
                   2883:         ++zExp;
                   2884:     }
                   2885:  roundAndPack:
                   2886:     return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
                   2887: 
                   2888: }
                   2889: 
                   2890: /*----------------------------------------------------------------------------
                   2891: | Returns the result of subtracting the absolute values of the double-
                   2892: | precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   2893: | difference is negated before being returned.  `zSign' is ignored if the
                   2894: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   2895: | Standard for Binary Floating-Point Arithmetic.
                   2896: *----------------------------------------------------------------------------*/
                   2897: 
                   2898: static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
                   2899: {
                   2900:     int16 aExp, bExp, zExp;
                   2901:     bits64 aSig, bSig, zSig;
                   2902:     int16 expDiff;
                   2903: 
                   2904:     aSig = extractFloat64Frac( a );
                   2905:     aExp = extractFloat64Exp( a );
                   2906:     bSig = extractFloat64Frac( b );
                   2907:     bExp = extractFloat64Exp( b );
                   2908:     expDiff = aExp - bExp;
                   2909:     aSig <<= 10;
                   2910:     bSig <<= 10;
                   2911:     if ( 0 < expDiff ) goto aExpBigger;
                   2912:     if ( expDiff < 0 ) goto bExpBigger;
                   2913:     if ( aExp == 0x7FF ) {
                   2914:         if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2915:         float_raise( float_flag_invalid STATUS_VAR);
                   2916:         return float64_default_nan;
                   2917:     }
                   2918:     if ( aExp == 0 ) {
                   2919:         aExp = 1;
                   2920:         bExp = 1;
                   2921:     }
                   2922:     if ( bSig < aSig ) goto aBigger;
                   2923:     if ( aSig < bSig ) goto bBigger;
                   2924:     return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
                   2925:  bExpBigger:
                   2926:     if ( bExp == 0x7FF ) {
                   2927:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2928:         return packFloat64( zSign ^ 1, 0x7FF, 0 );
                   2929:     }
                   2930:     if ( aExp == 0 ) {
                   2931:         ++expDiff;
                   2932:     }
                   2933:     else {
                   2934:         aSig |= LIT64( 0x4000000000000000 );
                   2935:     }
                   2936:     shift64RightJamming( aSig, - expDiff, &aSig );
                   2937:     bSig |= LIT64( 0x4000000000000000 );
                   2938:  bBigger:
                   2939:     zSig = bSig - aSig;
                   2940:     zExp = bExp;
                   2941:     zSign ^= 1;
                   2942:     goto normalizeRoundAndPack;
                   2943:  aExpBigger:
                   2944:     if ( aExp == 0x7FF ) {
                   2945:         if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   2946:         return a;
                   2947:     }
                   2948:     if ( bExp == 0 ) {
                   2949:         --expDiff;
                   2950:     }
                   2951:     else {
                   2952:         bSig |= LIT64( 0x4000000000000000 );
                   2953:     }
                   2954:     shift64RightJamming( bSig, expDiff, &bSig );
                   2955:     aSig |= LIT64( 0x4000000000000000 );
                   2956:  aBigger:
                   2957:     zSig = aSig - bSig;
                   2958:     zExp = aExp;
                   2959:  normalizeRoundAndPack:
                   2960:     --zExp;
                   2961:     return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
                   2962: 
                   2963: }
                   2964: 
                   2965: /*----------------------------------------------------------------------------
                   2966: | Returns the result of adding the double-precision floating-point values `a'
                   2967: | and `b'.  The operation is performed according to the IEC/IEEE Standard for
                   2968: | Binary Floating-Point Arithmetic.
                   2969: *----------------------------------------------------------------------------*/
                   2970: 
                   2971: float64 float64_add( float64 a, float64 b STATUS_PARAM )
                   2972: {
                   2973:     flag aSign, bSign;
                   2974: 
                   2975:     aSign = extractFloat64Sign( a );
                   2976:     bSign = extractFloat64Sign( b );
                   2977:     if ( aSign == bSign ) {
                   2978:         return addFloat64Sigs( a, b, aSign STATUS_VAR );
                   2979:     }
                   2980:     else {
                   2981:         return subFloat64Sigs( a, b, aSign STATUS_VAR );
                   2982:     }
                   2983: 
                   2984: }
                   2985: 
                   2986: /*----------------------------------------------------------------------------
                   2987: | Returns the result of subtracting the double-precision floating-point values
                   2988: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   2989: | for Binary Floating-Point Arithmetic.
                   2990: *----------------------------------------------------------------------------*/
                   2991: 
                   2992: float64 float64_sub( float64 a, float64 b STATUS_PARAM )
                   2993: {
                   2994:     flag aSign, bSign;
                   2995: 
                   2996:     aSign = extractFloat64Sign( a );
                   2997:     bSign = extractFloat64Sign( b );
                   2998:     if ( aSign == bSign ) {
                   2999:         return subFloat64Sigs( a, b, aSign STATUS_VAR );
                   3000:     }
                   3001:     else {
                   3002:         return addFloat64Sigs( a, b, aSign STATUS_VAR );
                   3003:     }
                   3004: 
                   3005: }
                   3006: 
                   3007: /*----------------------------------------------------------------------------
                   3008: | Returns the result of multiplying the double-precision floating-point values
                   3009: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   3010: | for Binary Floating-Point Arithmetic.
                   3011: *----------------------------------------------------------------------------*/
                   3012: 
                   3013: float64 float64_mul( float64 a, float64 b STATUS_PARAM )
                   3014: {
                   3015:     flag aSign, bSign, zSign;
                   3016:     int16 aExp, bExp, zExp;
                   3017:     bits64 aSig, bSig, zSig0, zSig1;
                   3018: 
                   3019:     aSig = extractFloat64Frac( a );
                   3020:     aExp = extractFloat64Exp( a );
                   3021:     aSign = extractFloat64Sign( a );
                   3022:     bSig = extractFloat64Frac( b );
                   3023:     bExp = extractFloat64Exp( b );
                   3024:     bSign = extractFloat64Sign( b );
                   3025:     zSign = aSign ^ bSign;
                   3026:     if ( aExp == 0x7FF ) {
                   3027:         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
                   3028:             return propagateFloat64NaN( a, b STATUS_VAR );
                   3029:         }
                   3030:         if ( ( bExp | bSig ) == 0 ) {
                   3031:             float_raise( float_flag_invalid STATUS_VAR);
                   3032:             return float64_default_nan;
                   3033:         }
                   3034:         return packFloat64( zSign, 0x7FF, 0 );
                   3035:     }
                   3036:     if ( bExp == 0x7FF ) {
                   3037:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   3038:         if ( ( aExp | aSig ) == 0 ) {
                   3039:             float_raise( float_flag_invalid STATUS_VAR);
                   3040:             return float64_default_nan;
                   3041:         }
                   3042:         return packFloat64( zSign, 0x7FF, 0 );
                   3043:     }
                   3044:     if ( aExp == 0 ) {
                   3045:         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
                   3046:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   3047:     }
                   3048:     if ( bExp == 0 ) {
                   3049:         if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
                   3050:         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
                   3051:     }
                   3052:     zExp = aExp + bExp - 0x3FF;
                   3053:     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
                   3054:     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
                   3055:     mul64To128( aSig, bSig, &zSig0, &zSig1 );
                   3056:     zSig0 |= ( zSig1 != 0 );
                   3057:     if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
                   3058:         zSig0 <<= 1;
                   3059:         --zExp;
                   3060:     }
                   3061:     return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
                   3062: 
                   3063: }
                   3064: 
                   3065: /*----------------------------------------------------------------------------
                   3066: | Returns the result of dividing the double-precision floating-point value `a'
                   3067: | by the corresponding value `b'.  The operation is performed according to
                   3068: | the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3069: *----------------------------------------------------------------------------*/
                   3070: 
                   3071: float64 float64_div( float64 a, float64 b STATUS_PARAM )
                   3072: {
                   3073:     flag aSign, bSign, zSign;
                   3074:     int16 aExp, bExp, zExp;
                   3075:     bits64 aSig, bSig, zSig;
                   3076:     bits64 rem0, rem1;
                   3077:     bits64 term0, term1;
                   3078: 
                   3079:     aSig = extractFloat64Frac( a );
                   3080:     aExp = extractFloat64Exp( a );
                   3081:     aSign = extractFloat64Sign( a );
                   3082:     bSig = extractFloat64Frac( b );
                   3083:     bExp = extractFloat64Exp( b );
                   3084:     bSign = extractFloat64Sign( b );
                   3085:     zSign = aSign ^ bSign;
                   3086:     if ( aExp == 0x7FF ) {
                   3087:         if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   3088:         if ( bExp == 0x7FF ) {
                   3089:             if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   3090:             float_raise( float_flag_invalid STATUS_VAR);
                   3091:             return float64_default_nan;
                   3092:         }
                   3093:         return packFloat64( zSign, 0x7FF, 0 );
                   3094:     }
                   3095:     if ( bExp == 0x7FF ) {
                   3096:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   3097:         return packFloat64( zSign, 0, 0 );
                   3098:     }
                   3099:     if ( bExp == 0 ) {
                   3100:         if ( bSig == 0 ) {
                   3101:             if ( ( aExp | aSig ) == 0 ) {
                   3102:                 float_raise( float_flag_invalid STATUS_VAR);
                   3103:                 return float64_default_nan;
                   3104:             }
                   3105:             float_raise( float_flag_divbyzero STATUS_VAR);
                   3106:             return packFloat64( zSign, 0x7FF, 0 );
                   3107:         }
                   3108:         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
                   3109:     }
                   3110:     if ( aExp == 0 ) {
                   3111:         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
                   3112:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   3113:     }
                   3114:     zExp = aExp - bExp + 0x3FD;
                   3115:     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
                   3116:     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
                   3117:     if ( bSig <= ( aSig + aSig ) ) {
                   3118:         aSig >>= 1;
                   3119:         ++zExp;
                   3120:     }
                   3121:     zSig = estimateDiv128To64( aSig, 0, bSig );
                   3122:     if ( ( zSig & 0x1FF ) <= 2 ) {
                   3123:         mul64To128( bSig, zSig, &term0, &term1 );
                   3124:         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
                   3125:         while ( (sbits64) rem0 < 0 ) {
                   3126:             --zSig;
                   3127:             add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
                   3128:         }
                   3129:         zSig |= ( rem1 != 0 );
                   3130:     }
                   3131:     return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
                   3132: 
                   3133: }
                   3134: 
                   3135: /*----------------------------------------------------------------------------
                   3136: | Returns the remainder of the double-precision floating-point value `a'
                   3137: | with respect to the corresponding value `b'.  The operation is performed
                   3138: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3139: *----------------------------------------------------------------------------*/
                   3140: 
                   3141: float64 float64_rem( float64 a, float64 b STATUS_PARAM )
                   3142: {
1.1.1.6 ! root     3143:     flag aSign, zSign;
1.1       root     3144:     int16 aExp, bExp, expDiff;
                   3145:     bits64 aSig, bSig;
                   3146:     bits64 q, alternateASig;
                   3147:     sbits64 sigMean;
                   3148: 
                   3149:     aSig = extractFloat64Frac( a );
                   3150:     aExp = extractFloat64Exp( a );
                   3151:     aSign = extractFloat64Sign( a );
                   3152:     bSig = extractFloat64Frac( b );
                   3153:     bExp = extractFloat64Exp( b );
                   3154:     if ( aExp == 0x7FF ) {
                   3155:         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
                   3156:             return propagateFloat64NaN( a, b STATUS_VAR );
                   3157:         }
                   3158:         float_raise( float_flag_invalid STATUS_VAR);
                   3159:         return float64_default_nan;
                   3160:     }
                   3161:     if ( bExp == 0x7FF ) {
                   3162:         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
                   3163:         return a;
                   3164:     }
                   3165:     if ( bExp == 0 ) {
                   3166:         if ( bSig == 0 ) {
                   3167:             float_raise( float_flag_invalid STATUS_VAR);
                   3168:             return float64_default_nan;
                   3169:         }
                   3170:         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
                   3171:     }
                   3172:     if ( aExp == 0 ) {
                   3173:         if ( aSig == 0 ) return a;
                   3174:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   3175:     }
                   3176:     expDiff = aExp - bExp;
                   3177:     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
                   3178:     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
                   3179:     if ( expDiff < 0 ) {
                   3180:         if ( expDiff < -1 ) return a;
                   3181:         aSig >>= 1;
                   3182:     }
                   3183:     q = ( bSig <= aSig );
                   3184:     if ( q ) aSig -= bSig;
                   3185:     expDiff -= 64;
                   3186:     while ( 0 < expDiff ) {
                   3187:         q = estimateDiv128To64( aSig, 0, bSig );
                   3188:         q = ( 2 < q ) ? q - 2 : 0;
                   3189:         aSig = - ( ( bSig>>2 ) * q );
                   3190:         expDiff -= 62;
                   3191:     }
                   3192:     expDiff += 64;
                   3193:     if ( 0 < expDiff ) {
                   3194:         q = estimateDiv128To64( aSig, 0, bSig );
                   3195:         q = ( 2 < q ) ? q - 2 : 0;
                   3196:         q >>= 64 - expDiff;
                   3197:         bSig >>= 2;
                   3198:         aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
                   3199:     }
                   3200:     else {
                   3201:         aSig >>= 2;
                   3202:         bSig >>= 2;
                   3203:     }
                   3204:     do {
                   3205:         alternateASig = aSig;
                   3206:         ++q;
                   3207:         aSig -= bSig;
                   3208:     } while ( 0 <= (sbits64) aSig );
                   3209:     sigMean = aSig + alternateASig;
                   3210:     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
                   3211:         aSig = alternateASig;
                   3212:     }
                   3213:     zSign = ( (sbits64) aSig < 0 );
                   3214:     if ( zSign ) aSig = - aSig;
                   3215:     return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
                   3216: 
                   3217: }
                   3218: 
                   3219: /*----------------------------------------------------------------------------
                   3220: | Returns the square root of the double-precision floating-point value `a'.
                   3221: | The operation is performed according to the IEC/IEEE Standard for Binary
                   3222: | Floating-Point Arithmetic.
                   3223: *----------------------------------------------------------------------------*/
                   3224: 
                   3225: float64 float64_sqrt( float64 a STATUS_PARAM )
                   3226: {
                   3227:     flag aSign;
                   3228:     int16 aExp, zExp;
                   3229:     bits64 aSig, zSig, doubleZSig;
                   3230:     bits64 rem0, rem1, term0, term1;
                   3231: 
                   3232:     aSig = extractFloat64Frac( a );
                   3233:     aExp = extractFloat64Exp( a );
                   3234:     aSign = extractFloat64Sign( a );
                   3235:     if ( aExp == 0x7FF ) {
                   3236:         if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
                   3237:         if ( ! aSign ) return a;
                   3238:         float_raise( float_flag_invalid STATUS_VAR);
                   3239:         return float64_default_nan;
                   3240:     }
                   3241:     if ( aSign ) {
                   3242:         if ( ( aExp | aSig ) == 0 ) return a;
                   3243:         float_raise( float_flag_invalid STATUS_VAR);
                   3244:         return float64_default_nan;
                   3245:     }
                   3246:     if ( aExp == 0 ) {
1.1.1.3   root     3247:         if ( aSig == 0 ) return float64_zero;
1.1       root     3248:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   3249:     }
                   3250:     zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
                   3251:     aSig |= LIT64( 0x0010000000000000 );
                   3252:     zSig = estimateSqrt32( aExp, aSig>>21 );
                   3253:     aSig <<= 9 - ( aExp & 1 );
                   3254:     zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
                   3255:     if ( ( zSig & 0x1FF ) <= 5 ) {
                   3256:         doubleZSig = zSig<<1;
                   3257:         mul64To128( zSig, zSig, &term0, &term1 );
                   3258:         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
                   3259:         while ( (sbits64) rem0 < 0 ) {
                   3260:             --zSig;
                   3261:             doubleZSig -= 2;
                   3262:             add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
                   3263:         }
                   3264:         zSig |= ( ( rem0 | rem1 ) != 0 );
                   3265:     }
                   3266:     return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
                   3267: 
                   3268: }
                   3269: 
                   3270: /*----------------------------------------------------------------------------
1.1.1.4   root     3271: | Returns the binary log of the double-precision floating-point value `a'.
                   3272: | The operation is performed according to the IEC/IEEE Standard for Binary
                   3273: | Floating-Point Arithmetic.
                   3274: *----------------------------------------------------------------------------*/
                   3275: float64 float64_log2( float64 a STATUS_PARAM )
                   3276: {
                   3277:     flag aSign, zSign;
                   3278:     int16 aExp;
                   3279:     bits64 aSig, aSig0, aSig1, zSig, i;
                   3280: 
                   3281:     aSig = extractFloat64Frac( a );
                   3282:     aExp = extractFloat64Exp( a );
                   3283:     aSign = extractFloat64Sign( a );
                   3284: 
                   3285:     if ( aExp == 0 ) {
                   3286:         if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
                   3287:         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
                   3288:     }
                   3289:     if ( aSign ) {
                   3290:         float_raise( float_flag_invalid STATUS_VAR);
                   3291:         return float64_default_nan;
                   3292:     }
                   3293:     if ( aExp == 0x7FF ) {
                   3294:         if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );
                   3295:         return a;
                   3296:     }
                   3297: 
                   3298:     aExp -= 0x3FF;
                   3299:     aSig |= LIT64( 0x0010000000000000 );
                   3300:     zSign = aExp < 0;
                   3301:     zSig = (bits64)aExp << 52;
                   3302:     for (i = 1LL << 51; i > 0; i >>= 1) {
                   3303:         mul64To128( aSig, aSig, &aSig0, &aSig1 );
                   3304:         aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );
                   3305:         if ( aSig & LIT64( 0x0020000000000000 ) ) {
                   3306:             aSig >>= 1;
                   3307:             zSig |= i;
                   3308:         }
                   3309:     }
                   3310: 
                   3311:     if ( zSign )
                   3312:         zSig = -zSig;
                   3313:     return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
                   3314: }
                   3315: 
                   3316: /*----------------------------------------------------------------------------
1.1       root     3317: | Returns 1 if the double-precision floating-point value `a' is equal to the
                   3318: | corresponding value `b', and 0 otherwise.  The comparison is performed
                   3319: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3320: *----------------------------------------------------------------------------*/
                   3321: 
1.1.1.2   root     3322: int float64_eq( float64 a, float64 b STATUS_PARAM )
1.1       root     3323: {
1.1.1.3   root     3324:     bits64 av, bv;
1.1       root     3325: 
                   3326:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3327:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3328:        ) {
                   3329:         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
                   3330:             float_raise( float_flag_invalid STATUS_VAR);
                   3331:         }
                   3332:         return 0;
                   3333:     }
1.1.1.3   root     3334:     av = float64_val(a);
                   3335:     bv = float64_val(b);
                   3336:     return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 );
1.1       root     3337: 
                   3338: }
                   3339: 
                   3340: /*----------------------------------------------------------------------------
                   3341: | Returns 1 if the double-precision floating-point value `a' is less than or
                   3342: | equal to the corresponding value `b', and 0 otherwise.  The comparison is
                   3343: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   3344: | Arithmetic.
                   3345: *----------------------------------------------------------------------------*/
                   3346: 
1.1.1.2   root     3347: int float64_le( float64 a, float64 b STATUS_PARAM )
1.1       root     3348: {
                   3349:     flag aSign, bSign;
1.1.1.3   root     3350:     bits64 av, bv;
1.1       root     3351: 
                   3352:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3353:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3354:        ) {
                   3355:         float_raise( float_flag_invalid STATUS_VAR);
                   3356:         return 0;
                   3357:     }
                   3358:     aSign = extractFloat64Sign( a );
                   3359:     bSign = extractFloat64Sign( b );
1.1.1.3   root     3360:     av = float64_val(a);
                   3361:     bv = float64_val(b);
                   3362:     if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
                   3363:     return ( av == bv ) || ( aSign ^ ( av < bv ) );
1.1       root     3364: 
                   3365: }
                   3366: 
                   3367: /*----------------------------------------------------------------------------
                   3368: | Returns 1 if the double-precision floating-point value `a' is less than
                   3369: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   3370: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3371: *----------------------------------------------------------------------------*/
                   3372: 
1.1.1.2   root     3373: int float64_lt( float64 a, float64 b STATUS_PARAM )
1.1       root     3374: {
                   3375:     flag aSign, bSign;
1.1.1.3   root     3376:     bits64 av, bv;
1.1       root     3377: 
                   3378:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3379:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3380:        ) {
                   3381:         float_raise( float_flag_invalid STATUS_VAR);
                   3382:         return 0;
                   3383:     }
                   3384:     aSign = extractFloat64Sign( a );
                   3385:     bSign = extractFloat64Sign( b );
1.1.1.3   root     3386:     av = float64_val(a);
                   3387:     bv = float64_val(b);
                   3388:     if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
                   3389:     return ( av != bv ) && ( aSign ^ ( av < bv ) );
1.1       root     3390: 
                   3391: }
                   3392: 
                   3393: /*----------------------------------------------------------------------------
                   3394: | Returns 1 if the double-precision floating-point value `a' is equal to the
                   3395: | corresponding value `b', and 0 otherwise.  The invalid exception is raised
                   3396: | if either operand is a NaN.  Otherwise, the comparison is performed
                   3397: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3398: *----------------------------------------------------------------------------*/
                   3399: 
1.1.1.2   root     3400: int float64_eq_signaling( float64 a, float64 b STATUS_PARAM )
1.1       root     3401: {
1.1.1.3   root     3402:     bits64 av, bv;
1.1       root     3403: 
                   3404:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3405:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3406:        ) {
                   3407:         float_raise( float_flag_invalid STATUS_VAR);
                   3408:         return 0;
                   3409:     }
1.1.1.3   root     3410:     av = float64_val(a);
                   3411:     bv = float64_val(b);
                   3412:     return ( av == bv ) || ( (bits64) ( ( av | bv )<<1 ) == 0 );
1.1       root     3413: 
                   3414: }
                   3415: 
                   3416: /*----------------------------------------------------------------------------
                   3417: | Returns 1 if the double-precision floating-point value `a' is less than or
                   3418: | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
                   3419: | cause an exception.  Otherwise, the comparison is performed according to the
                   3420: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3421: *----------------------------------------------------------------------------*/
                   3422: 
1.1.1.2   root     3423: int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
1.1       root     3424: {
                   3425:     flag aSign, bSign;
1.1.1.3   root     3426:     bits64 av, bv;
1.1       root     3427: 
                   3428:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3429:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3430:        ) {
                   3431:         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
                   3432:             float_raise( float_flag_invalid STATUS_VAR);
                   3433:         }
                   3434:         return 0;
                   3435:     }
                   3436:     aSign = extractFloat64Sign( a );
                   3437:     bSign = extractFloat64Sign( b );
1.1.1.3   root     3438:     av = float64_val(a);
                   3439:     bv = float64_val(b);
                   3440:     if ( aSign != bSign ) return aSign || ( (bits64) ( ( av | bv )<<1 ) == 0 );
                   3441:     return ( av == bv ) || ( aSign ^ ( av < bv ) );
1.1       root     3442: 
                   3443: }
                   3444: 
                   3445: /*----------------------------------------------------------------------------
                   3446: | Returns 1 if the double-precision floating-point value `a' is less than
                   3447: | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
                   3448: | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
                   3449: | Standard for Binary Floating-Point Arithmetic.
                   3450: *----------------------------------------------------------------------------*/
                   3451: 
1.1.1.2   root     3452: int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
1.1       root     3453: {
                   3454:     flag aSign, bSign;
1.1.1.3   root     3455:     bits64 av, bv;
1.1       root     3456: 
                   3457:     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
                   3458:          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
                   3459:        ) {
                   3460:         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
                   3461:             float_raise( float_flag_invalid STATUS_VAR);
                   3462:         }
                   3463:         return 0;
                   3464:     }
                   3465:     aSign = extractFloat64Sign( a );
                   3466:     bSign = extractFloat64Sign( b );
1.1.1.3   root     3467:     av = float64_val(a);
                   3468:     bv = float64_val(b);
                   3469:     if ( aSign != bSign ) return aSign && ( (bits64) ( ( av | bv )<<1 ) != 0 );
                   3470:     return ( av != bv ) && ( aSign ^ ( av < bv ) );
1.1       root     3471: 
                   3472: }
                   3473: 
                   3474: #ifdef FLOATX80
                   3475: 
                   3476: /*----------------------------------------------------------------------------
                   3477: | Returns the result of converting the extended double-precision floating-
                   3478: | point value `a' to the 32-bit two's complement integer format.  The
                   3479: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3480: | Floating-Point Arithmetic---which means in particular that the conversion
                   3481: | is rounded according to the current rounding mode.  If `a' is a NaN, the
                   3482: | largest positive integer is returned.  Otherwise, if the conversion
                   3483: | overflows, the largest integer with the same sign as `a' is returned.
                   3484: *----------------------------------------------------------------------------*/
                   3485: 
                   3486: int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
                   3487: {
                   3488:     flag aSign;
                   3489:     int32 aExp, shiftCount;
                   3490:     bits64 aSig;
                   3491: 
                   3492:     aSig = extractFloatx80Frac( a );
                   3493:     aExp = extractFloatx80Exp( a );
                   3494:     aSign = extractFloatx80Sign( a );
                   3495:     if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
                   3496:     shiftCount = 0x4037 - aExp;
                   3497:     if ( shiftCount <= 0 ) shiftCount = 1;
                   3498:     shift64RightJamming( aSig, shiftCount, &aSig );
                   3499:     return roundAndPackInt32( aSign, aSig STATUS_VAR );
                   3500: 
                   3501: }
                   3502: 
                   3503: /*----------------------------------------------------------------------------
                   3504: | Returns the result of converting the extended double-precision floating-
                   3505: | point value `a' to the 32-bit two's complement integer format.  The
                   3506: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3507: | Floating-Point Arithmetic, except that the conversion is always rounded
                   3508: | toward zero.  If `a' is a NaN, the largest positive integer is returned.
                   3509: | Otherwise, if the conversion overflows, the largest integer with the same
                   3510: | sign as `a' is returned.
                   3511: *----------------------------------------------------------------------------*/
                   3512: 
                   3513: int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
                   3514: {
                   3515:     flag aSign;
                   3516:     int32 aExp, shiftCount;
                   3517:     bits64 aSig, savedASig;
                   3518:     int32 z;
                   3519: 
                   3520:     aSig = extractFloatx80Frac( a );
                   3521:     aExp = extractFloatx80Exp( a );
                   3522:     aSign = extractFloatx80Sign( a );
                   3523:     if ( 0x401E < aExp ) {
                   3524:         if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
                   3525:         goto invalid;
                   3526:     }
                   3527:     else if ( aExp < 0x3FFF ) {
                   3528:         if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   3529:         return 0;
                   3530:     }
                   3531:     shiftCount = 0x403E - aExp;
                   3532:     savedASig = aSig;
                   3533:     aSig >>= shiftCount;
                   3534:     z = aSig;
                   3535:     if ( aSign ) z = - z;
                   3536:     if ( ( z < 0 ) ^ aSign ) {
                   3537:  invalid:
                   3538:         float_raise( float_flag_invalid STATUS_VAR);
                   3539:         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                   3540:     }
                   3541:     if ( ( aSig<<shiftCount ) != savedASig ) {
                   3542:         STATUS(float_exception_flags) |= float_flag_inexact;
                   3543:     }
                   3544:     return z;
                   3545: 
                   3546: }
                   3547: 
                   3548: /*----------------------------------------------------------------------------
                   3549: | Returns the result of converting the extended double-precision floating-
                   3550: | point value `a' to the 64-bit two's complement integer format.  The
                   3551: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3552: | Floating-Point Arithmetic---which means in particular that the conversion
                   3553: | is rounded according to the current rounding mode.  If `a' is a NaN,
                   3554: | the largest positive integer is returned.  Otherwise, if the conversion
                   3555: | overflows, the largest integer with the same sign as `a' is returned.
                   3556: *----------------------------------------------------------------------------*/
                   3557: 
                   3558: int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
                   3559: {
                   3560:     flag aSign;
                   3561:     int32 aExp, shiftCount;
                   3562:     bits64 aSig, aSigExtra;
                   3563: 
                   3564:     aSig = extractFloatx80Frac( a );
                   3565:     aExp = extractFloatx80Exp( a );
                   3566:     aSign = extractFloatx80Sign( a );
                   3567:     shiftCount = 0x403E - aExp;
                   3568:     if ( shiftCount <= 0 ) {
                   3569:         if ( shiftCount ) {
                   3570:             float_raise( float_flag_invalid STATUS_VAR);
                   3571:             if (    ! aSign
                   3572:                  || (    ( aExp == 0x7FFF )
                   3573:                       && ( aSig != LIT64( 0x8000000000000000 ) ) )
                   3574:                ) {
                   3575:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   3576:             }
                   3577:             return (sbits64) LIT64( 0x8000000000000000 );
                   3578:         }
                   3579:         aSigExtra = 0;
                   3580:     }
                   3581:     else {
                   3582:         shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
                   3583:     }
                   3584:     return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
                   3585: 
                   3586: }
                   3587: 
                   3588: /*----------------------------------------------------------------------------
                   3589: | Returns the result of converting the extended double-precision floating-
                   3590: | point value `a' to the 64-bit two's complement integer format.  The
                   3591: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3592: | Floating-Point Arithmetic, except that the conversion is always rounded
                   3593: | toward zero.  If `a' is a NaN, the largest positive integer is returned.
                   3594: | Otherwise, if the conversion overflows, the largest integer with the same
                   3595: | sign as `a' is returned.
                   3596: *----------------------------------------------------------------------------*/
                   3597: 
                   3598: int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
                   3599: {
                   3600:     flag aSign;
                   3601:     int32 aExp, shiftCount;
                   3602:     bits64 aSig;
                   3603:     int64 z;
                   3604: 
                   3605:     aSig = extractFloatx80Frac( a );
                   3606:     aExp = extractFloatx80Exp( a );
                   3607:     aSign = extractFloatx80Sign( a );
                   3608:     shiftCount = aExp - 0x403E;
                   3609:     if ( 0 <= shiftCount ) {
                   3610:         aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
                   3611:         if ( ( a.high != 0xC03E ) || aSig ) {
                   3612:             float_raise( float_flag_invalid STATUS_VAR);
                   3613:             if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
                   3614:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   3615:             }
                   3616:         }
                   3617:         return (sbits64) LIT64( 0x8000000000000000 );
                   3618:     }
                   3619:     else if ( aExp < 0x3FFF ) {
                   3620:         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
                   3621:         return 0;
                   3622:     }
                   3623:     z = aSig>>( - shiftCount );
                   3624:     if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) {
                   3625:         STATUS(float_exception_flags) |= float_flag_inexact;
                   3626:     }
                   3627:     if ( aSign ) z = - z;
                   3628:     return z;
                   3629: 
                   3630: }
                   3631: 
                   3632: /*----------------------------------------------------------------------------
                   3633: | Returns the result of converting the extended double-precision floating-
                   3634: | point value `a' to the single-precision floating-point format.  The
                   3635: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3636: | Floating-Point Arithmetic.
                   3637: *----------------------------------------------------------------------------*/
                   3638: 
                   3639: float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
                   3640: {
                   3641:     flag aSign;
                   3642:     int32 aExp;
                   3643:     bits64 aSig;
                   3644: 
                   3645:     aSig = extractFloatx80Frac( a );
                   3646:     aExp = extractFloatx80Exp( a );
                   3647:     aSign = extractFloatx80Sign( a );
                   3648:     if ( aExp == 0x7FFF ) {
                   3649:         if ( (bits64) ( aSig<<1 ) ) {
                   3650:             return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) );
                   3651:         }
                   3652:         return packFloat32( aSign, 0xFF, 0 );
                   3653:     }
                   3654:     shift64RightJamming( aSig, 33, &aSig );
                   3655:     if ( aExp || aSig ) aExp -= 0x3F81;
                   3656:     return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
                   3657: 
                   3658: }
                   3659: 
                   3660: /*----------------------------------------------------------------------------
                   3661: | Returns the result of converting the extended double-precision floating-
                   3662: | point value `a' to the double-precision floating-point format.  The
                   3663: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3664: | Floating-Point Arithmetic.
                   3665: *----------------------------------------------------------------------------*/
                   3666: 
                   3667: float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
                   3668: {
                   3669:     flag aSign;
                   3670:     int32 aExp;
                   3671:     bits64 aSig, zSig;
                   3672: 
                   3673:     aSig = extractFloatx80Frac( a );
                   3674:     aExp = extractFloatx80Exp( a );
                   3675:     aSign = extractFloatx80Sign( a );
                   3676:     if ( aExp == 0x7FFF ) {
                   3677:         if ( (bits64) ( aSig<<1 ) ) {
                   3678:             return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) );
                   3679:         }
                   3680:         return packFloat64( aSign, 0x7FF, 0 );
                   3681:     }
                   3682:     shift64RightJamming( aSig, 1, &zSig );
                   3683:     if ( aExp || aSig ) aExp -= 0x3C01;
                   3684:     return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
                   3685: 
                   3686: }
                   3687: 
                   3688: #ifdef FLOAT128
                   3689: 
                   3690: /*----------------------------------------------------------------------------
                   3691: | Returns the result of converting the extended double-precision floating-
                   3692: | point value `a' to the quadruple-precision floating-point format.  The
                   3693: | conversion is performed according to the IEC/IEEE Standard for Binary
                   3694: | Floating-Point Arithmetic.
                   3695: *----------------------------------------------------------------------------*/
                   3696: 
                   3697: float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
                   3698: {
                   3699:     flag aSign;
                   3700:     int16 aExp;
                   3701:     bits64 aSig, zSig0, zSig1;
                   3702: 
                   3703:     aSig = extractFloatx80Frac( a );
                   3704:     aExp = extractFloatx80Exp( a );
                   3705:     aSign = extractFloatx80Sign( a );
                   3706:     if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) {
                   3707:         return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) );
                   3708:     }
                   3709:     shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
                   3710:     return packFloat128( aSign, aExp, zSig0, zSig1 );
                   3711: 
                   3712: }
                   3713: 
                   3714: #endif
                   3715: 
                   3716: /*----------------------------------------------------------------------------
                   3717: | Rounds the extended double-precision floating-point value `a' to an integer,
                   3718: | and returns the result as an extended quadruple-precision floating-point
                   3719: | value.  The operation is performed according to the IEC/IEEE Standard for
                   3720: | Binary Floating-Point Arithmetic.
                   3721: *----------------------------------------------------------------------------*/
                   3722: 
                   3723: floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
                   3724: {
                   3725:     flag aSign;
                   3726:     int32 aExp;
                   3727:     bits64 lastBitMask, roundBitsMask;
                   3728:     int8 roundingMode;
                   3729:     floatx80 z;
                   3730: 
                   3731:     aExp = extractFloatx80Exp( a );
                   3732:     if ( 0x403E <= aExp ) {
                   3733:         if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
                   3734:             return propagateFloatx80NaN( a, a STATUS_VAR );
                   3735:         }
                   3736:         return a;
                   3737:     }
                   3738:     if ( aExp < 0x3FFF ) {
                   3739:         if (    ( aExp == 0 )
                   3740:              && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
                   3741:             return a;
                   3742:         }
                   3743:         STATUS(float_exception_flags) |= float_flag_inexact;
                   3744:         aSign = extractFloatx80Sign( a );
                   3745:         switch ( STATUS(float_rounding_mode) ) {
                   3746:          case float_round_nearest_even:
                   3747:             if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
                   3748:                ) {
                   3749:                 return
                   3750:                     packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
                   3751:             }
                   3752:             break;
                   3753:          case float_round_down:
                   3754:             return
                   3755:                   aSign ?
                   3756:                       packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
                   3757:                 : packFloatx80( 0, 0, 0 );
                   3758:          case float_round_up:
                   3759:             return
                   3760:                   aSign ? packFloatx80( 1, 0, 0 )
                   3761:                 : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
                   3762:         }
                   3763:         return packFloatx80( aSign, 0, 0 );
                   3764:     }
                   3765:     lastBitMask = 1;
                   3766:     lastBitMask <<= 0x403E - aExp;
                   3767:     roundBitsMask = lastBitMask - 1;
                   3768:     z = a;
                   3769:     roundingMode = STATUS(float_rounding_mode);
                   3770:     if ( roundingMode == float_round_nearest_even ) {
                   3771:         z.low += lastBitMask>>1;
                   3772:         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
                   3773:     }
                   3774:     else if ( roundingMode != float_round_to_zero ) {
                   3775:         if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
                   3776:             z.low += roundBitsMask;
                   3777:         }
                   3778:     }
                   3779:     z.low &= ~ roundBitsMask;
                   3780:     if ( z.low == 0 ) {
                   3781:         ++z.high;
                   3782:         z.low = LIT64( 0x8000000000000000 );
                   3783:     }
                   3784:     if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
                   3785:     return z;
                   3786: 
                   3787: }
                   3788: 
                   3789: /*----------------------------------------------------------------------------
                   3790: | Returns the result of adding the absolute values of the extended double-
                   3791: | precision floating-point values `a' and `b'.  If `zSign' is 1, the sum is
                   3792: | negated before being returned.  `zSign' is ignored if the result is a NaN.
                   3793: | The addition is performed according to the IEC/IEEE Standard for Binary
                   3794: | Floating-Point Arithmetic.
                   3795: *----------------------------------------------------------------------------*/
                   3796: 
                   3797: static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
                   3798: {
                   3799:     int32 aExp, bExp, zExp;
                   3800:     bits64 aSig, bSig, zSig0, zSig1;
                   3801:     int32 expDiff;
                   3802: 
                   3803:     aSig = extractFloatx80Frac( a );
                   3804:     aExp = extractFloatx80Exp( a );
                   3805:     bSig = extractFloatx80Frac( b );
                   3806:     bExp = extractFloatx80Exp( b );
                   3807:     expDiff = aExp - bExp;
                   3808:     if ( 0 < expDiff ) {
                   3809:         if ( aExp == 0x7FFF ) {
                   3810:             if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3811:             return a;
                   3812:         }
                   3813:         if ( bExp == 0 ) --expDiff;
                   3814:         shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
                   3815:         zExp = aExp;
                   3816:     }
                   3817:     else if ( expDiff < 0 ) {
                   3818:         if ( bExp == 0x7FFF ) {
                   3819:             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3820:             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3821:         }
                   3822:         if ( aExp == 0 ) ++expDiff;
                   3823:         shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
                   3824:         zExp = bExp;
                   3825:     }
                   3826:     else {
                   3827:         if ( aExp == 0x7FFF ) {
                   3828:             if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
                   3829:                 return propagateFloatx80NaN( a, b STATUS_VAR );
                   3830:             }
                   3831:             return a;
                   3832:         }
                   3833:         zSig1 = 0;
                   3834:         zSig0 = aSig + bSig;
                   3835:         if ( aExp == 0 ) {
                   3836:             normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
                   3837:             goto roundAndPack;
                   3838:         }
                   3839:         zExp = aExp;
                   3840:         goto shiftRight1;
                   3841:     }
                   3842:     zSig0 = aSig + bSig;
                   3843:     if ( (sbits64) zSig0 < 0 ) goto roundAndPack;
                   3844:  shiftRight1:
                   3845:     shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
                   3846:     zSig0 |= LIT64( 0x8000000000000000 );
                   3847:     ++zExp;
                   3848:  roundAndPack:
                   3849:     return
                   3850:         roundAndPackFloatx80(
                   3851:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   3852: 
                   3853: }
                   3854: 
                   3855: /*----------------------------------------------------------------------------
                   3856: | Returns the result of subtracting the absolute values of the extended
                   3857: | double-precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   3858: | difference is negated before being returned.  `zSign' is ignored if the
                   3859: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   3860: | Standard for Binary Floating-Point Arithmetic.
                   3861: *----------------------------------------------------------------------------*/
                   3862: 
                   3863: static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
                   3864: {
                   3865:     int32 aExp, bExp, zExp;
                   3866:     bits64 aSig, bSig, zSig0, zSig1;
                   3867:     int32 expDiff;
                   3868:     floatx80 z;
                   3869: 
                   3870:     aSig = extractFloatx80Frac( a );
                   3871:     aExp = extractFloatx80Exp( a );
                   3872:     bSig = extractFloatx80Frac( b );
                   3873:     bExp = extractFloatx80Exp( b );
                   3874:     expDiff = aExp - bExp;
                   3875:     if ( 0 < expDiff ) goto aExpBigger;
                   3876:     if ( expDiff < 0 ) goto bExpBigger;
                   3877:     if ( aExp == 0x7FFF ) {
                   3878:         if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
                   3879:             return propagateFloatx80NaN( a, b STATUS_VAR );
                   3880:         }
                   3881:         float_raise( float_flag_invalid STATUS_VAR);
                   3882:         z.low = floatx80_default_nan_low;
                   3883:         z.high = floatx80_default_nan_high;
                   3884:         return z;
                   3885:     }
                   3886:     if ( aExp == 0 ) {
                   3887:         aExp = 1;
                   3888:         bExp = 1;
                   3889:     }
                   3890:     zSig1 = 0;
                   3891:     if ( bSig < aSig ) goto aBigger;
                   3892:     if ( aSig < bSig ) goto bBigger;
                   3893:     return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
                   3894:  bExpBigger:
                   3895:     if ( bExp == 0x7FFF ) {
                   3896:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3897:         return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3898:     }
                   3899:     if ( aExp == 0 ) ++expDiff;
                   3900:     shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
                   3901:  bBigger:
                   3902:     sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
                   3903:     zExp = bExp;
                   3904:     zSign ^= 1;
                   3905:     goto normalizeRoundAndPack;
                   3906:  aExpBigger:
                   3907:     if ( aExp == 0x7FFF ) {
                   3908:         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3909:         return a;
                   3910:     }
                   3911:     if ( bExp == 0 ) --expDiff;
                   3912:     shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
                   3913:  aBigger:
                   3914:     sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
                   3915:     zExp = aExp;
                   3916:  normalizeRoundAndPack:
                   3917:     return
                   3918:         normalizeRoundAndPackFloatx80(
                   3919:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   3920: 
                   3921: }
                   3922: 
                   3923: /*----------------------------------------------------------------------------
                   3924: | Returns the result of adding the extended double-precision floating-point
                   3925: | values `a' and `b'.  The operation is performed according to the IEC/IEEE
                   3926: | Standard for Binary Floating-Point Arithmetic.
                   3927: *----------------------------------------------------------------------------*/
                   3928: 
                   3929: floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
                   3930: {
                   3931:     flag aSign, bSign;
                   3932: 
                   3933:     aSign = extractFloatx80Sign( a );
                   3934:     bSign = extractFloatx80Sign( b );
                   3935:     if ( aSign == bSign ) {
                   3936:         return addFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3937:     }
                   3938:     else {
                   3939:         return subFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3940:     }
                   3941: 
                   3942: }
                   3943: 
                   3944: /*----------------------------------------------------------------------------
                   3945: | Returns the result of subtracting the extended double-precision floating-
                   3946: | point values `a' and `b'.  The operation is performed according to the
                   3947: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3948: *----------------------------------------------------------------------------*/
                   3949: 
                   3950: floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
                   3951: {
                   3952:     flag aSign, bSign;
                   3953: 
                   3954:     aSign = extractFloatx80Sign( a );
                   3955:     bSign = extractFloatx80Sign( b );
                   3956:     if ( aSign == bSign ) {
                   3957:         return subFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3958:     }
                   3959:     else {
                   3960:         return addFloatx80Sigs( a, b, aSign STATUS_VAR );
                   3961:     }
                   3962: 
                   3963: }
                   3964: 
                   3965: /*----------------------------------------------------------------------------
                   3966: | Returns the result of multiplying the extended double-precision floating-
                   3967: | point values `a' and `b'.  The operation is performed according to the
                   3968: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   3969: *----------------------------------------------------------------------------*/
                   3970: 
                   3971: floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
                   3972: {
                   3973:     flag aSign, bSign, zSign;
                   3974:     int32 aExp, bExp, zExp;
                   3975:     bits64 aSig, bSig, zSig0, zSig1;
                   3976:     floatx80 z;
                   3977: 
                   3978:     aSig = extractFloatx80Frac( a );
                   3979:     aExp = extractFloatx80Exp( a );
                   3980:     aSign = extractFloatx80Sign( a );
                   3981:     bSig = extractFloatx80Frac( b );
                   3982:     bExp = extractFloatx80Exp( b );
                   3983:     bSign = extractFloatx80Sign( b );
                   3984:     zSign = aSign ^ bSign;
                   3985:     if ( aExp == 0x7FFF ) {
                   3986:         if (    (bits64) ( aSig<<1 )
                   3987:              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
                   3988:             return propagateFloatx80NaN( a, b STATUS_VAR );
                   3989:         }
                   3990:         if ( ( bExp | bSig ) == 0 ) goto invalid;
                   3991:         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   3992:     }
                   3993:     if ( bExp == 0x7FFF ) {
                   3994:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   3995:         if ( ( aExp | aSig ) == 0 ) {
                   3996:  invalid:
                   3997:             float_raise( float_flag_invalid STATUS_VAR);
                   3998:             z.low = floatx80_default_nan_low;
                   3999:             z.high = floatx80_default_nan_high;
                   4000:             return z;
                   4001:         }
                   4002:         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   4003:     }
                   4004:     if ( aExp == 0 ) {
                   4005:         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
                   4006:         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
                   4007:     }
                   4008:     if ( bExp == 0 ) {
                   4009:         if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
                   4010:         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
                   4011:     }
                   4012:     zExp = aExp + bExp - 0x3FFE;
                   4013:     mul64To128( aSig, bSig, &zSig0, &zSig1 );
                   4014:     if ( 0 < (sbits64) zSig0 ) {
                   4015:         shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
                   4016:         --zExp;
                   4017:     }
                   4018:     return
                   4019:         roundAndPackFloatx80(
                   4020:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   4021: 
                   4022: }
                   4023: 
                   4024: /*----------------------------------------------------------------------------
                   4025: | Returns the result of dividing the extended double-precision floating-point
                   4026: | value `a' by the corresponding value `b'.  The operation is performed
                   4027: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4028: *----------------------------------------------------------------------------*/
                   4029: 
                   4030: floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
                   4031: {
                   4032:     flag aSign, bSign, zSign;
                   4033:     int32 aExp, bExp, zExp;
                   4034:     bits64 aSig, bSig, zSig0, zSig1;
                   4035:     bits64 rem0, rem1, rem2, term0, term1, term2;
                   4036:     floatx80 z;
                   4037: 
                   4038:     aSig = extractFloatx80Frac( a );
                   4039:     aExp = extractFloatx80Exp( a );
                   4040:     aSign = extractFloatx80Sign( a );
                   4041:     bSig = extractFloatx80Frac( b );
                   4042:     bExp = extractFloatx80Exp( b );
                   4043:     bSign = extractFloatx80Sign( b );
                   4044:     zSign = aSign ^ bSign;
                   4045:     if ( aExp == 0x7FFF ) {
                   4046:         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   4047:         if ( bExp == 0x7FFF ) {
                   4048:             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   4049:             goto invalid;
                   4050:         }
                   4051:         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   4052:     }
                   4053:     if ( bExp == 0x7FFF ) {
                   4054:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   4055:         return packFloatx80( zSign, 0, 0 );
                   4056:     }
                   4057:     if ( bExp == 0 ) {
                   4058:         if ( bSig == 0 ) {
                   4059:             if ( ( aExp | aSig ) == 0 ) {
                   4060:  invalid:
                   4061:                 float_raise( float_flag_invalid STATUS_VAR);
                   4062:                 z.low = floatx80_default_nan_low;
                   4063:                 z.high = floatx80_default_nan_high;
                   4064:                 return z;
                   4065:             }
                   4066:             float_raise( float_flag_divbyzero STATUS_VAR);
                   4067:             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   4068:         }
                   4069:         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
                   4070:     }
                   4071:     if ( aExp == 0 ) {
                   4072:         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
                   4073:         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
                   4074:     }
                   4075:     zExp = aExp - bExp + 0x3FFE;
                   4076:     rem1 = 0;
                   4077:     if ( bSig <= aSig ) {
                   4078:         shift128Right( aSig, 0, 1, &aSig, &rem1 );
                   4079:         ++zExp;
                   4080:     }
                   4081:     zSig0 = estimateDiv128To64( aSig, rem1, bSig );
                   4082:     mul64To128( bSig, zSig0, &term0, &term1 );
                   4083:     sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
                   4084:     while ( (sbits64) rem0 < 0 ) {
                   4085:         --zSig0;
                   4086:         add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
                   4087:     }
                   4088:     zSig1 = estimateDiv128To64( rem1, 0, bSig );
                   4089:     if ( (bits64) ( zSig1<<1 ) <= 8 ) {
                   4090:         mul64To128( bSig, zSig1, &term1, &term2 );
                   4091:         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
                   4092:         while ( (sbits64) rem1 < 0 ) {
                   4093:             --zSig1;
                   4094:             add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
                   4095:         }
                   4096:         zSig1 |= ( ( rem1 | rem2 ) != 0 );
                   4097:     }
                   4098:     return
                   4099:         roundAndPackFloatx80(
                   4100:             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
                   4101: 
                   4102: }
                   4103: 
                   4104: /*----------------------------------------------------------------------------
                   4105: | Returns the remainder of the extended double-precision floating-point value
                   4106: | `a' with respect to the corresponding value `b'.  The operation is performed
                   4107: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4108: *----------------------------------------------------------------------------*/
                   4109: 
                   4110: floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
                   4111: {
1.1.1.6 ! root     4112:     flag aSign, zSign;
1.1       root     4113:     int32 aExp, bExp, expDiff;
                   4114:     bits64 aSig0, aSig1, bSig;
                   4115:     bits64 q, term0, term1, alternateASig0, alternateASig1;
                   4116:     floatx80 z;
                   4117: 
                   4118:     aSig0 = extractFloatx80Frac( a );
                   4119:     aExp = extractFloatx80Exp( a );
                   4120:     aSign = extractFloatx80Sign( a );
                   4121:     bSig = extractFloatx80Frac( b );
                   4122:     bExp = extractFloatx80Exp( b );
                   4123:     if ( aExp == 0x7FFF ) {
                   4124:         if (    (bits64) ( aSig0<<1 )
                   4125:              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
                   4126:             return propagateFloatx80NaN( a, b STATUS_VAR );
                   4127:         }
                   4128:         goto invalid;
                   4129:     }
                   4130:     if ( bExp == 0x7FFF ) {
                   4131:         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
                   4132:         return a;
                   4133:     }
                   4134:     if ( bExp == 0 ) {
                   4135:         if ( bSig == 0 ) {
                   4136:  invalid:
                   4137:             float_raise( float_flag_invalid STATUS_VAR);
                   4138:             z.low = floatx80_default_nan_low;
                   4139:             z.high = floatx80_default_nan_high;
                   4140:             return z;
                   4141:         }
                   4142:         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
                   4143:     }
                   4144:     if ( aExp == 0 ) {
                   4145:         if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
                   4146:         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
                   4147:     }
                   4148:     bSig |= LIT64( 0x8000000000000000 );
                   4149:     zSign = aSign;
                   4150:     expDiff = aExp - bExp;
                   4151:     aSig1 = 0;
                   4152:     if ( expDiff < 0 ) {
                   4153:         if ( expDiff < -1 ) return a;
                   4154:         shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
                   4155:         expDiff = 0;
                   4156:     }
                   4157:     q = ( bSig <= aSig0 );
                   4158:     if ( q ) aSig0 -= bSig;
                   4159:     expDiff -= 64;
                   4160:     while ( 0 < expDiff ) {
                   4161:         q = estimateDiv128To64( aSig0, aSig1, bSig );
                   4162:         q = ( 2 < q ) ? q - 2 : 0;
                   4163:         mul64To128( bSig, q, &term0, &term1 );
                   4164:         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
                   4165:         shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
                   4166:         expDiff -= 62;
                   4167:     }
                   4168:     expDiff += 64;
                   4169:     if ( 0 < expDiff ) {
                   4170:         q = estimateDiv128To64( aSig0, aSig1, bSig );
                   4171:         q = ( 2 < q ) ? q - 2 : 0;
                   4172:         q >>= 64 - expDiff;
                   4173:         mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
                   4174:         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
                   4175:         shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
                   4176:         while ( le128( term0, term1, aSig0, aSig1 ) ) {
                   4177:             ++q;
                   4178:             sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
                   4179:         }
                   4180:     }
                   4181:     else {
                   4182:         term1 = 0;
                   4183:         term0 = bSig;
                   4184:     }
                   4185:     sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
                   4186:     if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
                   4187:          || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
                   4188:               && ( q & 1 ) )
                   4189:        ) {
                   4190:         aSig0 = alternateASig0;
                   4191:         aSig1 = alternateASig1;
                   4192:         zSign = ! zSign;
                   4193:     }
                   4194:     return
                   4195:         normalizeRoundAndPackFloatx80(
                   4196:             80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
                   4197: 
                   4198: }
                   4199: 
                   4200: /*----------------------------------------------------------------------------
                   4201: | Returns the square root of the extended double-precision floating-point
                   4202: | value `a'.  The operation is performed according to the IEC/IEEE Standard
                   4203: | for Binary Floating-Point Arithmetic.
                   4204: *----------------------------------------------------------------------------*/
                   4205: 
                   4206: floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
                   4207: {
                   4208:     flag aSign;
                   4209:     int32 aExp, zExp;
                   4210:     bits64 aSig0, aSig1, zSig0, zSig1, doubleZSig0;
                   4211:     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
                   4212:     floatx80 z;
                   4213: 
                   4214:     aSig0 = extractFloatx80Frac( a );
                   4215:     aExp = extractFloatx80Exp( a );
                   4216:     aSign = extractFloatx80Sign( a );
                   4217:     if ( aExp == 0x7FFF ) {
                   4218:         if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
                   4219:         if ( ! aSign ) return a;
                   4220:         goto invalid;
                   4221:     }
                   4222:     if ( aSign ) {
                   4223:         if ( ( aExp | aSig0 ) == 0 ) return a;
                   4224:  invalid:
                   4225:         float_raise( float_flag_invalid STATUS_VAR);
                   4226:         z.low = floatx80_default_nan_low;
                   4227:         z.high = floatx80_default_nan_high;
                   4228:         return z;
                   4229:     }
                   4230:     if ( aExp == 0 ) {
                   4231:         if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
                   4232:         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
                   4233:     }
                   4234:     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
                   4235:     zSig0 = estimateSqrt32( aExp, aSig0>>32 );
                   4236:     shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
                   4237:     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
                   4238:     doubleZSig0 = zSig0<<1;
                   4239:     mul64To128( zSig0, zSig0, &term0, &term1 );
                   4240:     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
                   4241:     while ( (sbits64) rem0 < 0 ) {
                   4242:         --zSig0;
                   4243:         doubleZSig0 -= 2;
                   4244:         add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
                   4245:     }
                   4246:     zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
                   4247:     if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
                   4248:         if ( zSig1 == 0 ) zSig1 = 1;
                   4249:         mul64To128( doubleZSig0, zSig1, &term1, &term2 );
                   4250:         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
                   4251:         mul64To128( zSig1, zSig1, &term2, &term3 );
                   4252:         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
                   4253:         while ( (sbits64) rem1 < 0 ) {
                   4254:             --zSig1;
                   4255:             shortShift128Left( 0, zSig1, 1, &term2, &term3 );
                   4256:             term3 |= 1;
                   4257:             term2 |= doubleZSig0;
                   4258:             add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
                   4259:         }
                   4260:         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
                   4261:     }
                   4262:     shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
                   4263:     zSig0 |= doubleZSig0;
                   4264:     return
                   4265:         roundAndPackFloatx80(
                   4266:             STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
                   4267: 
                   4268: }
                   4269: 
                   4270: /*----------------------------------------------------------------------------
                   4271: | Returns 1 if the extended double-precision floating-point value `a' is
                   4272: | equal to the corresponding value `b', and 0 otherwise.  The comparison is
                   4273: | performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4274: | Arithmetic.
                   4275: *----------------------------------------------------------------------------*/
                   4276: 
1.1.1.2   root     4277: int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root     4278: {
                   4279: 
                   4280:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4281:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4282:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4283:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4284:        ) {
                   4285:         if (    floatx80_is_signaling_nan( a )
                   4286:              || floatx80_is_signaling_nan( b ) ) {
                   4287:             float_raise( float_flag_invalid STATUS_VAR);
                   4288:         }
                   4289:         return 0;
                   4290:     }
                   4291:     return
                   4292:            ( a.low == b.low )
                   4293:         && (    ( a.high == b.high )
                   4294:              || (    ( a.low == 0 )
                   4295:                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
                   4296:            );
                   4297: 
                   4298: }
                   4299: 
                   4300: /*----------------------------------------------------------------------------
                   4301: | Returns 1 if the extended double-precision floating-point value `a' is
                   4302: | less than or equal to the corresponding value `b', and 0 otherwise.  The
                   4303: | comparison is performed according to the IEC/IEEE Standard for Binary
                   4304: | Floating-Point Arithmetic.
                   4305: *----------------------------------------------------------------------------*/
                   4306: 
1.1.1.2   root     4307: int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root     4308: {
                   4309:     flag aSign, bSign;
                   4310: 
                   4311:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4312:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4313:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4314:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4315:        ) {
                   4316:         float_raise( float_flag_invalid STATUS_VAR);
                   4317:         return 0;
                   4318:     }
                   4319:     aSign = extractFloatx80Sign( a );
                   4320:     bSign = extractFloatx80Sign( b );
                   4321:     if ( aSign != bSign ) {
                   4322:         return
                   4323:                aSign
                   4324:             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   4325:                  == 0 );
                   4326:     }
                   4327:     return
                   4328:           aSign ? le128( b.high, b.low, a.high, a.low )
                   4329:         : le128( a.high, a.low, b.high, b.low );
                   4330: 
                   4331: }
                   4332: 
                   4333: /*----------------------------------------------------------------------------
                   4334: | Returns 1 if the extended double-precision floating-point value `a' is
                   4335: | less than the corresponding value `b', and 0 otherwise.  The comparison
                   4336: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4337: | Arithmetic.
                   4338: *----------------------------------------------------------------------------*/
                   4339: 
1.1.1.2   root     4340: int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root     4341: {
                   4342:     flag aSign, bSign;
                   4343: 
                   4344:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4345:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4346:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4347:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4348:        ) {
                   4349:         float_raise( float_flag_invalid STATUS_VAR);
                   4350:         return 0;
                   4351:     }
                   4352:     aSign = extractFloatx80Sign( a );
                   4353:     bSign = extractFloatx80Sign( b );
                   4354:     if ( aSign != bSign ) {
                   4355:         return
                   4356:                aSign
                   4357:             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   4358:                  != 0 );
                   4359:     }
                   4360:     return
                   4361:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   4362:         : lt128( a.high, a.low, b.high, b.low );
                   4363: 
                   4364: }
                   4365: 
                   4366: /*----------------------------------------------------------------------------
                   4367: | Returns 1 if the extended double-precision floating-point value `a' is equal
                   4368: | to the corresponding value `b', and 0 otherwise.  The invalid exception is
                   4369: | raised if either operand is a NaN.  Otherwise, the comparison is performed
                   4370: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4371: *----------------------------------------------------------------------------*/
                   4372: 
1.1.1.2   root     4373: int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root     4374: {
                   4375: 
                   4376:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4377:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4378:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4379:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4380:        ) {
                   4381:         float_raise( float_flag_invalid STATUS_VAR);
                   4382:         return 0;
                   4383:     }
                   4384:     return
                   4385:            ( a.low == b.low )
                   4386:         && (    ( a.high == b.high )
                   4387:              || (    ( a.low == 0 )
                   4388:                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
                   4389:            );
                   4390: 
                   4391: }
                   4392: 
                   4393: /*----------------------------------------------------------------------------
                   4394: | Returns 1 if the extended double-precision floating-point value `a' is less
                   4395: | than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
                   4396: | do not cause an exception.  Otherwise, the comparison is performed according
                   4397: | to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4398: *----------------------------------------------------------------------------*/
                   4399: 
1.1.1.2   root     4400: int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root     4401: {
                   4402:     flag aSign, bSign;
                   4403: 
                   4404:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4405:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4406:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4407:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4408:        ) {
                   4409:         if (    floatx80_is_signaling_nan( a )
                   4410:              || floatx80_is_signaling_nan( b ) ) {
                   4411:             float_raise( float_flag_invalid STATUS_VAR);
                   4412:         }
                   4413:         return 0;
                   4414:     }
                   4415:     aSign = extractFloatx80Sign( a );
                   4416:     bSign = extractFloatx80Sign( b );
                   4417:     if ( aSign != bSign ) {
                   4418:         return
                   4419:                aSign
                   4420:             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   4421:                  == 0 );
                   4422:     }
                   4423:     return
                   4424:           aSign ? le128( b.high, b.low, a.high, a.low )
                   4425:         : le128( a.high, a.low, b.high, b.low );
                   4426: 
                   4427: }
                   4428: 
                   4429: /*----------------------------------------------------------------------------
                   4430: | Returns 1 if the extended double-precision floating-point value `a' is less
                   4431: | than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
                   4432: | an exception.  Otherwise, the comparison is performed according to the
                   4433: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   4434: *----------------------------------------------------------------------------*/
                   4435: 
1.1.1.2   root     4436: int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
1.1       root     4437: {
                   4438:     flag aSign, bSign;
                   4439: 
                   4440:     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
                   4441:               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
                   4442:          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
                   4443:               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
                   4444:        ) {
                   4445:         if (    floatx80_is_signaling_nan( a )
                   4446:              || floatx80_is_signaling_nan( b ) ) {
                   4447:             float_raise( float_flag_invalid STATUS_VAR);
                   4448:         }
                   4449:         return 0;
                   4450:     }
                   4451:     aSign = extractFloatx80Sign( a );
                   4452:     bSign = extractFloatx80Sign( b );
                   4453:     if ( aSign != bSign ) {
                   4454:         return
                   4455:                aSign
                   4456:             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   4457:                  != 0 );
                   4458:     }
                   4459:     return
                   4460:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   4461:         : lt128( a.high, a.low, b.high, b.low );
                   4462: 
                   4463: }
                   4464: 
                   4465: #endif
                   4466: 
                   4467: #ifdef FLOAT128
                   4468: 
                   4469: /*----------------------------------------------------------------------------
                   4470: | Returns the result of converting the quadruple-precision floating-point
                   4471: | value `a' to the 32-bit two's complement integer format.  The conversion
                   4472: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4473: | Arithmetic---which means in particular that the conversion is rounded
                   4474: | according to the current rounding mode.  If `a' is a NaN, the largest
                   4475: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   4476: | largest integer with the same sign as `a' is returned.
                   4477: *----------------------------------------------------------------------------*/
                   4478: 
                   4479: int32 float128_to_int32( float128 a STATUS_PARAM )
                   4480: {
                   4481:     flag aSign;
                   4482:     int32 aExp, shiftCount;
                   4483:     bits64 aSig0, aSig1;
                   4484: 
                   4485:     aSig1 = extractFloat128Frac1( a );
                   4486:     aSig0 = extractFloat128Frac0( a );
                   4487:     aExp = extractFloat128Exp( a );
                   4488:     aSign = extractFloat128Sign( a );
                   4489:     if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
                   4490:     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
                   4491:     aSig0 |= ( aSig1 != 0 );
                   4492:     shiftCount = 0x4028 - aExp;
                   4493:     if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
                   4494:     return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
                   4495: 
                   4496: }
                   4497: 
                   4498: /*----------------------------------------------------------------------------
                   4499: | Returns the result of converting the quadruple-precision floating-point
                   4500: | value `a' to the 32-bit two's complement integer format.  The conversion
                   4501: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4502: | Arithmetic, except that the conversion is always rounded toward zero.  If
                   4503: | `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
                   4504: | conversion overflows, the largest integer with the same sign as `a' is
                   4505: | returned.
                   4506: *----------------------------------------------------------------------------*/
                   4507: 
                   4508: int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
                   4509: {
                   4510:     flag aSign;
                   4511:     int32 aExp, shiftCount;
                   4512:     bits64 aSig0, aSig1, savedASig;
                   4513:     int32 z;
                   4514: 
                   4515:     aSig1 = extractFloat128Frac1( a );
                   4516:     aSig0 = extractFloat128Frac0( a );
                   4517:     aExp = extractFloat128Exp( a );
                   4518:     aSign = extractFloat128Sign( a );
                   4519:     aSig0 |= ( aSig1 != 0 );
                   4520:     if ( 0x401E < aExp ) {
                   4521:         if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
                   4522:         goto invalid;
                   4523:     }
                   4524:     else if ( aExp < 0x3FFF ) {
                   4525:         if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
                   4526:         return 0;
                   4527:     }
                   4528:     aSig0 |= LIT64( 0x0001000000000000 );
                   4529:     shiftCount = 0x402F - aExp;
                   4530:     savedASig = aSig0;
                   4531:     aSig0 >>= shiftCount;
                   4532:     z = aSig0;
                   4533:     if ( aSign ) z = - z;
                   4534:     if ( ( z < 0 ) ^ aSign ) {
                   4535:  invalid:
                   4536:         float_raise( float_flag_invalid STATUS_VAR);
                   4537:         return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
                   4538:     }
                   4539:     if ( ( aSig0<<shiftCount ) != savedASig ) {
                   4540:         STATUS(float_exception_flags) |= float_flag_inexact;
                   4541:     }
                   4542:     return z;
                   4543: 
                   4544: }
                   4545: 
                   4546: /*----------------------------------------------------------------------------
                   4547: | Returns the result of converting the quadruple-precision floating-point
                   4548: | value `a' to the 64-bit two's complement integer format.  The conversion
                   4549: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4550: | Arithmetic---which means in particular that the conversion is rounded
                   4551: | according to the current rounding mode.  If `a' is a NaN, the largest
                   4552: | positive integer is returned.  Otherwise, if the conversion overflows, the
                   4553: | largest integer with the same sign as `a' is returned.
                   4554: *----------------------------------------------------------------------------*/
                   4555: 
                   4556: int64 float128_to_int64( float128 a STATUS_PARAM )
                   4557: {
                   4558:     flag aSign;
                   4559:     int32 aExp, shiftCount;
                   4560:     bits64 aSig0, aSig1;
                   4561: 
                   4562:     aSig1 = extractFloat128Frac1( a );
                   4563:     aSig0 = extractFloat128Frac0( a );
                   4564:     aExp = extractFloat128Exp( a );
                   4565:     aSign = extractFloat128Sign( a );
                   4566:     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
                   4567:     shiftCount = 0x402F - aExp;
                   4568:     if ( shiftCount <= 0 ) {
                   4569:         if ( 0x403E < aExp ) {
                   4570:             float_raise( float_flag_invalid STATUS_VAR);
                   4571:             if (    ! aSign
                   4572:                  || (    ( aExp == 0x7FFF )
                   4573:                       && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
                   4574:                     )
                   4575:                ) {
                   4576:                 return LIT64( 0x7FFFFFFFFFFFFFFF );
                   4577:             }
                   4578:             return (sbits64) LIT64( 0x8000000000000000 );
                   4579:         }
                   4580:         shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
                   4581:     }
                   4582:     else {
                   4583:         shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
                   4584:     }
                   4585:     return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
                   4586: 
                   4587: }
                   4588: 
                   4589: /*----------------------------------------------------------------------------
                   4590: | Returns the result of converting the quadruple-precision floating-point
                   4591: | value `a' to the 64-bit two's complement integer format.  The conversion
                   4592: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4593: | Arithmetic, except that the conversion is always rounded toward zero.
                   4594: | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
                   4595: | the conversion overflows, the largest integer with the same sign as `a' is
                   4596: | returned.
                   4597: *----------------------------------------------------------------------------*/
                   4598: 
                   4599: int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
                   4600: {
                   4601:     flag aSign;
                   4602:     int32 aExp, shiftCount;
                   4603:     bits64 aSig0, aSig1;
                   4604:     int64 z;
                   4605: 
                   4606:     aSig1 = extractFloat128Frac1( a );
                   4607:     aSig0 = extractFloat128Frac0( a );
                   4608:     aExp = extractFloat128Exp( a );
                   4609:     aSign = extractFloat128Sign( a );
                   4610:     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
                   4611:     shiftCount = aExp - 0x402F;
                   4612:     if ( 0 < shiftCount ) {
                   4613:         if ( 0x403E <= aExp ) {
                   4614:             aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
                   4615:             if (    ( a.high == LIT64( 0xC03E000000000000 ) )
                   4616:                  && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
                   4617:                 if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
                   4618:             }
                   4619:             else {
                   4620:                 float_raise( float_flag_invalid STATUS_VAR);
                   4621:                 if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
                   4622:                     return LIT64( 0x7FFFFFFFFFFFFFFF );
                   4623:                 }
                   4624:             }
                   4625:             return (sbits64) LIT64( 0x8000000000000000 );
                   4626:         }
                   4627:         z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
                   4628:         if ( (bits64) ( aSig1<<shiftCount ) ) {
                   4629:             STATUS(float_exception_flags) |= float_flag_inexact;
                   4630:         }
                   4631:     }
                   4632:     else {
                   4633:         if ( aExp < 0x3FFF ) {
                   4634:             if ( aExp | aSig0 | aSig1 ) {
                   4635:                 STATUS(float_exception_flags) |= float_flag_inexact;
                   4636:             }
                   4637:             return 0;
                   4638:         }
                   4639:         z = aSig0>>( - shiftCount );
                   4640:         if (    aSig1
                   4641:              || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) {
                   4642:             STATUS(float_exception_flags) |= float_flag_inexact;
                   4643:         }
                   4644:     }
                   4645:     if ( aSign ) z = - z;
                   4646:     return z;
                   4647: 
                   4648: }
                   4649: 
                   4650: /*----------------------------------------------------------------------------
                   4651: | Returns the result of converting the quadruple-precision floating-point
                   4652: | value `a' to the single-precision floating-point format.  The conversion
                   4653: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4654: | Arithmetic.
                   4655: *----------------------------------------------------------------------------*/
                   4656: 
                   4657: float32 float128_to_float32( float128 a STATUS_PARAM )
                   4658: {
                   4659:     flag aSign;
                   4660:     int32 aExp;
                   4661:     bits64 aSig0, aSig1;
                   4662:     bits32 zSig;
                   4663: 
                   4664:     aSig1 = extractFloat128Frac1( a );
                   4665:     aSig0 = extractFloat128Frac0( a );
                   4666:     aExp = extractFloat128Exp( a );
                   4667:     aSign = extractFloat128Sign( a );
                   4668:     if ( aExp == 0x7FFF ) {
                   4669:         if ( aSig0 | aSig1 ) {
                   4670:             return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) );
                   4671:         }
                   4672:         return packFloat32( aSign, 0xFF, 0 );
                   4673:     }
                   4674:     aSig0 |= ( aSig1 != 0 );
                   4675:     shift64RightJamming( aSig0, 18, &aSig0 );
                   4676:     zSig = aSig0;
                   4677:     if ( aExp || zSig ) {
                   4678:         zSig |= 0x40000000;
                   4679:         aExp -= 0x3F81;
                   4680:     }
                   4681:     return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
                   4682: 
                   4683: }
                   4684: 
                   4685: /*----------------------------------------------------------------------------
                   4686: | Returns the result of converting the quadruple-precision floating-point
                   4687: | value `a' to the double-precision floating-point format.  The conversion
                   4688: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   4689: | Arithmetic.
                   4690: *----------------------------------------------------------------------------*/
                   4691: 
                   4692: float64 float128_to_float64( float128 a STATUS_PARAM )
                   4693: {
                   4694:     flag aSign;
                   4695:     int32 aExp;
                   4696:     bits64 aSig0, aSig1;
                   4697: 
                   4698:     aSig1 = extractFloat128Frac1( a );
                   4699:     aSig0 = extractFloat128Frac0( a );
                   4700:     aExp = extractFloat128Exp( a );
                   4701:     aSign = extractFloat128Sign( a );
                   4702:     if ( aExp == 0x7FFF ) {
                   4703:         if ( aSig0 | aSig1 ) {
                   4704:             return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) );
                   4705:         }
                   4706:         return packFloat64( aSign, 0x7FF, 0 );
                   4707:     }
                   4708:     shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
                   4709:     aSig0 |= ( aSig1 != 0 );
                   4710:     if ( aExp || aSig0 ) {
                   4711:         aSig0 |= LIT64( 0x4000000000000000 );
                   4712:         aExp -= 0x3C01;
                   4713:     }
                   4714:     return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
                   4715: 
                   4716: }
                   4717: 
                   4718: #ifdef FLOATX80
                   4719: 
                   4720: /*----------------------------------------------------------------------------
                   4721: | Returns the result of converting the quadruple-precision floating-point
                   4722: | value `a' to the extended double-precision floating-point format.  The
                   4723: | conversion is performed according to the IEC/IEEE Standard for Binary
                   4724: | Floating-Point Arithmetic.
                   4725: *----------------------------------------------------------------------------*/
                   4726: 
                   4727: floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
                   4728: {
                   4729:     flag aSign;
                   4730:     int32 aExp;
                   4731:     bits64 aSig0, aSig1;
                   4732: 
                   4733:     aSig1 = extractFloat128Frac1( a );
                   4734:     aSig0 = extractFloat128Frac0( a );
                   4735:     aExp = extractFloat128Exp( a );
                   4736:     aSign = extractFloat128Sign( a );
                   4737:     if ( aExp == 0x7FFF ) {
                   4738:         if ( aSig0 | aSig1 ) {
                   4739:             return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) );
                   4740:         }
                   4741:         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
                   4742:     }
                   4743:     if ( aExp == 0 ) {
                   4744:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
                   4745:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   4746:     }
                   4747:     else {
                   4748:         aSig0 |= LIT64( 0x0001000000000000 );
                   4749:     }
                   4750:     shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
                   4751:     return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
                   4752: 
                   4753: }
                   4754: 
                   4755: #endif
                   4756: 
                   4757: /*----------------------------------------------------------------------------
                   4758: | Rounds the quadruple-precision floating-point value `a' to an integer, and
                   4759: | returns the result as a quadruple-precision floating-point value.  The
                   4760: | operation is performed according to the IEC/IEEE Standard for Binary
                   4761: | Floating-Point Arithmetic.
                   4762: *----------------------------------------------------------------------------*/
                   4763: 
                   4764: float128 float128_round_to_int( float128 a STATUS_PARAM )
                   4765: {
                   4766:     flag aSign;
                   4767:     int32 aExp;
                   4768:     bits64 lastBitMask, roundBitsMask;
                   4769:     int8 roundingMode;
                   4770:     float128 z;
                   4771: 
                   4772:     aExp = extractFloat128Exp( a );
                   4773:     if ( 0x402F <= aExp ) {
                   4774:         if ( 0x406F <= aExp ) {
                   4775:             if (    ( aExp == 0x7FFF )
                   4776:                  && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
                   4777:                ) {
                   4778:                 return propagateFloat128NaN( a, a STATUS_VAR );
                   4779:             }
                   4780:             return a;
                   4781:         }
                   4782:         lastBitMask = 1;
                   4783:         lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
                   4784:         roundBitsMask = lastBitMask - 1;
                   4785:         z = a;
                   4786:         roundingMode = STATUS(float_rounding_mode);
                   4787:         if ( roundingMode == float_round_nearest_even ) {
                   4788:             if ( lastBitMask ) {
                   4789:                 add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
                   4790:                 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
                   4791:             }
                   4792:             else {
                   4793:                 if ( (sbits64) z.low < 0 ) {
                   4794:                     ++z.high;
                   4795:                     if ( (bits64) ( z.low<<1 ) == 0 ) z.high &= ~1;
                   4796:                 }
                   4797:             }
                   4798:         }
                   4799:         else if ( roundingMode != float_round_to_zero ) {
                   4800:             if (   extractFloat128Sign( z )
                   4801:                  ^ ( roundingMode == float_round_up ) ) {
                   4802:                 add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
                   4803:             }
                   4804:         }
                   4805:         z.low &= ~ roundBitsMask;
                   4806:     }
                   4807:     else {
                   4808:         if ( aExp < 0x3FFF ) {
                   4809:             if ( ( ( (bits64) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
                   4810:             STATUS(float_exception_flags) |= float_flag_inexact;
                   4811:             aSign = extractFloat128Sign( a );
                   4812:             switch ( STATUS(float_rounding_mode) ) {
                   4813:              case float_round_nearest_even:
                   4814:                 if (    ( aExp == 0x3FFE )
                   4815:                      && (   extractFloat128Frac0( a )
                   4816:                           | extractFloat128Frac1( a ) )
                   4817:                    ) {
                   4818:                     return packFloat128( aSign, 0x3FFF, 0, 0 );
                   4819:                 }
                   4820:                 break;
                   4821:              case float_round_down:
                   4822:                 return
                   4823:                       aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
                   4824:                     : packFloat128( 0, 0, 0, 0 );
                   4825:              case float_round_up:
                   4826:                 return
                   4827:                       aSign ? packFloat128( 1, 0, 0, 0 )
                   4828:                     : packFloat128( 0, 0x3FFF, 0, 0 );
                   4829:             }
                   4830:             return packFloat128( aSign, 0, 0, 0 );
                   4831:         }
                   4832:         lastBitMask = 1;
                   4833:         lastBitMask <<= 0x402F - aExp;
                   4834:         roundBitsMask = lastBitMask - 1;
                   4835:         z.low = 0;
                   4836:         z.high = a.high;
                   4837:         roundingMode = STATUS(float_rounding_mode);
                   4838:         if ( roundingMode == float_round_nearest_even ) {
                   4839:             z.high += lastBitMask>>1;
                   4840:             if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
                   4841:                 z.high &= ~ lastBitMask;
                   4842:             }
                   4843:         }
                   4844:         else if ( roundingMode != float_round_to_zero ) {
                   4845:             if (   extractFloat128Sign( z )
                   4846:                  ^ ( roundingMode == float_round_up ) ) {
                   4847:                 z.high |= ( a.low != 0 );
                   4848:                 z.high += roundBitsMask;
                   4849:             }
                   4850:         }
                   4851:         z.high &= ~ roundBitsMask;
                   4852:     }
                   4853:     if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
                   4854:         STATUS(float_exception_flags) |= float_flag_inexact;
                   4855:     }
                   4856:     return z;
                   4857: 
                   4858: }
                   4859: 
                   4860: /*----------------------------------------------------------------------------
                   4861: | Returns the result of adding the absolute values of the quadruple-precision
                   4862: | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
                   4863: | before being returned.  `zSign' is ignored if the result is a NaN.
                   4864: | The addition is performed according to the IEC/IEEE Standard for Binary
                   4865: | Floating-Point Arithmetic.
                   4866: *----------------------------------------------------------------------------*/
                   4867: 
                   4868: static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
                   4869: {
                   4870:     int32 aExp, bExp, zExp;
                   4871:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
                   4872:     int32 expDiff;
                   4873: 
                   4874:     aSig1 = extractFloat128Frac1( a );
                   4875:     aSig0 = extractFloat128Frac0( a );
                   4876:     aExp = extractFloat128Exp( a );
                   4877:     bSig1 = extractFloat128Frac1( b );
                   4878:     bSig0 = extractFloat128Frac0( b );
                   4879:     bExp = extractFloat128Exp( b );
                   4880:     expDiff = aExp - bExp;
                   4881:     if ( 0 < expDiff ) {
                   4882:         if ( aExp == 0x7FFF ) {
                   4883:             if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4884:             return a;
                   4885:         }
                   4886:         if ( bExp == 0 ) {
                   4887:             --expDiff;
                   4888:         }
                   4889:         else {
                   4890:             bSig0 |= LIT64( 0x0001000000000000 );
                   4891:         }
                   4892:         shift128ExtraRightJamming(
                   4893:             bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
                   4894:         zExp = aExp;
                   4895:     }
                   4896:     else if ( expDiff < 0 ) {
                   4897:         if ( bExp == 0x7FFF ) {
                   4898:             if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4899:             return packFloat128( zSign, 0x7FFF, 0, 0 );
                   4900:         }
                   4901:         if ( aExp == 0 ) {
                   4902:             ++expDiff;
                   4903:         }
                   4904:         else {
                   4905:             aSig0 |= LIT64( 0x0001000000000000 );
                   4906:         }
                   4907:         shift128ExtraRightJamming(
                   4908:             aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
                   4909:         zExp = bExp;
                   4910:     }
                   4911:     else {
                   4912:         if ( aExp == 0x7FFF ) {
                   4913:             if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
                   4914:                 return propagateFloat128NaN( a, b STATUS_VAR );
                   4915:             }
                   4916:             return a;
                   4917:         }
                   4918:         add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
1.1.1.4   root     4919:         if ( aExp == 0 ) {
                   4920:             if ( STATUS(flush_to_zero) ) return packFloat128( zSign, 0, 0, 0 );
                   4921:             return packFloat128( zSign, 0, zSig0, zSig1 );
                   4922:         }
1.1       root     4923:         zSig2 = 0;
                   4924:         zSig0 |= LIT64( 0x0002000000000000 );
                   4925:         zExp = aExp;
                   4926:         goto shiftRight1;
                   4927:     }
                   4928:     aSig0 |= LIT64( 0x0001000000000000 );
                   4929:     add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
                   4930:     --zExp;
                   4931:     if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
                   4932:     ++zExp;
                   4933:  shiftRight1:
                   4934:     shift128ExtraRightJamming(
                   4935:         zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
                   4936:  roundAndPack:
                   4937:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   4938: 
                   4939: }
                   4940: 
                   4941: /*----------------------------------------------------------------------------
                   4942: | Returns the result of subtracting the absolute values of the quadruple-
                   4943: | precision floating-point values `a' and `b'.  If `zSign' is 1, the
                   4944: | difference is negated before being returned.  `zSign' is ignored if the
                   4945: | result is a NaN.  The subtraction is performed according to the IEC/IEEE
                   4946: | Standard for Binary Floating-Point Arithmetic.
                   4947: *----------------------------------------------------------------------------*/
                   4948: 
                   4949: static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
                   4950: {
                   4951:     int32 aExp, bExp, zExp;
                   4952:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
                   4953:     int32 expDiff;
                   4954:     float128 z;
                   4955: 
                   4956:     aSig1 = extractFloat128Frac1( a );
                   4957:     aSig0 = extractFloat128Frac0( a );
                   4958:     aExp = extractFloat128Exp( a );
                   4959:     bSig1 = extractFloat128Frac1( b );
                   4960:     bSig0 = extractFloat128Frac0( b );
                   4961:     bExp = extractFloat128Exp( b );
                   4962:     expDiff = aExp - bExp;
                   4963:     shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
                   4964:     shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
                   4965:     if ( 0 < expDiff ) goto aExpBigger;
                   4966:     if ( expDiff < 0 ) goto bExpBigger;
                   4967:     if ( aExp == 0x7FFF ) {
                   4968:         if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
                   4969:             return propagateFloat128NaN( a, b STATUS_VAR );
                   4970:         }
                   4971:         float_raise( float_flag_invalid STATUS_VAR);
                   4972:         z.low = float128_default_nan_low;
                   4973:         z.high = float128_default_nan_high;
                   4974:         return z;
                   4975:     }
                   4976:     if ( aExp == 0 ) {
                   4977:         aExp = 1;
                   4978:         bExp = 1;
                   4979:     }
                   4980:     if ( bSig0 < aSig0 ) goto aBigger;
                   4981:     if ( aSig0 < bSig0 ) goto bBigger;
                   4982:     if ( bSig1 < aSig1 ) goto aBigger;
                   4983:     if ( aSig1 < bSig1 ) goto bBigger;
                   4984:     return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
                   4985:  bExpBigger:
                   4986:     if ( bExp == 0x7FFF ) {
                   4987:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   4988:         return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
                   4989:     }
                   4990:     if ( aExp == 0 ) {
                   4991:         ++expDiff;
                   4992:     }
                   4993:     else {
                   4994:         aSig0 |= LIT64( 0x4000000000000000 );
                   4995:     }
                   4996:     shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
                   4997:     bSig0 |= LIT64( 0x4000000000000000 );
                   4998:  bBigger:
                   4999:     sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
                   5000:     zExp = bExp;
                   5001:     zSign ^= 1;
                   5002:     goto normalizeRoundAndPack;
                   5003:  aExpBigger:
                   5004:     if ( aExp == 0x7FFF ) {
                   5005:         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   5006:         return a;
                   5007:     }
                   5008:     if ( bExp == 0 ) {
                   5009:         --expDiff;
                   5010:     }
                   5011:     else {
                   5012:         bSig0 |= LIT64( 0x4000000000000000 );
                   5013:     }
                   5014:     shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
                   5015:     aSig0 |= LIT64( 0x4000000000000000 );
                   5016:  aBigger:
                   5017:     sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
                   5018:     zExp = aExp;
                   5019:  normalizeRoundAndPack:
                   5020:     --zExp;
                   5021:     return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
                   5022: 
                   5023: }
                   5024: 
                   5025: /*----------------------------------------------------------------------------
                   5026: | Returns the result of adding the quadruple-precision floating-point values
                   5027: | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
                   5028: | for Binary Floating-Point Arithmetic.
                   5029: *----------------------------------------------------------------------------*/
                   5030: 
                   5031: float128 float128_add( float128 a, float128 b STATUS_PARAM )
                   5032: {
                   5033:     flag aSign, bSign;
                   5034: 
                   5035:     aSign = extractFloat128Sign( a );
                   5036:     bSign = extractFloat128Sign( b );
                   5037:     if ( aSign == bSign ) {
                   5038:         return addFloat128Sigs( a, b, aSign STATUS_VAR );
                   5039:     }
                   5040:     else {
                   5041:         return subFloat128Sigs( a, b, aSign STATUS_VAR );
                   5042:     }
                   5043: 
                   5044: }
                   5045: 
                   5046: /*----------------------------------------------------------------------------
                   5047: | Returns the result of subtracting the quadruple-precision floating-point
                   5048: | values `a' and `b'.  The operation is performed according to the IEC/IEEE
                   5049: | Standard for Binary Floating-Point Arithmetic.
                   5050: *----------------------------------------------------------------------------*/
                   5051: 
                   5052: float128 float128_sub( float128 a, float128 b STATUS_PARAM )
                   5053: {
                   5054:     flag aSign, bSign;
                   5055: 
                   5056:     aSign = extractFloat128Sign( a );
                   5057:     bSign = extractFloat128Sign( b );
                   5058:     if ( aSign == bSign ) {
                   5059:         return subFloat128Sigs( a, b, aSign STATUS_VAR );
                   5060:     }
                   5061:     else {
                   5062:         return addFloat128Sigs( a, b, aSign STATUS_VAR );
                   5063:     }
                   5064: 
                   5065: }
                   5066: 
                   5067: /*----------------------------------------------------------------------------
                   5068: | Returns the result of multiplying the quadruple-precision floating-point
                   5069: | values `a' and `b'.  The operation is performed according to the IEC/IEEE
                   5070: | Standard for Binary Floating-Point Arithmetic.
                   5071: *----------------------------------------------------------------------------*/
                   5072: 
                   5073: float128 float128_mul( float128 a, float128 b STATUS_PARAM )
                   5074: {
                   5075:     flag aSign, bSign, zSign;
                   5076:     int32 aExp, bExp, zExp;
                   5077:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
                   5078:     float128 z;
                   5079: 
                   5080:     aSig1 = extractFloat128Frac1( a );
                   5081:     aSig0 = extractFloat128Frac0( a );
                   5082:     aExp = extractFloat128Exp( a );
                   5083:     aSign = extractFloat128Sign( a );
                   5084:     bSig1 = extractFloat128Frac1( b );
                   5085:     bSig0 = extractFloat128Frac0( b );
                   5086:     bExp = extractFloat128Exp( b );
                   5087:     bSign = extractFloat128Sign( b );
                   5088:     zSign = aSign ^ bSign;
                   5089:     if ( aExp == 0x7FFF ) {
                   5090:         if (    ( aSig0 | aSig1 )
                   5091:              || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
                   5092:             return propagateFloat128NaN( a, b STATUS_VAR );
                   5093:         }
                   5094:         if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
                   5095:         return packFloat128( zSign, 0x7FFF, 0, 0 );
                   5096:     }
                   5097:     if ( bExp == 0x7FFF ) {
                   5098:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   5099:         if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
                   5100:  invalid:
                   5101:             float_raise( float_flag_invalid STATUS_VAR);
                   5102:             z.low = float128_default_nan_low;
                   5103:             z.high = float128_default_nan_high;
                   5104:             return z;
                   5105:         }
                   5106:         return packFloat128( zSign, 0x7FFF, 0, 0 );
                   5107:     }
                   5108:     if ( aExp == 0 ) {
                   5109:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
                   5110:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   5111:     }
                   5112:     if ( bExp == 0 ) {
                   5113:         if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
                   5114:         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
                   5115:     }
                   5116:     zExp = aExp + bExp - 0x4000;
                   5117:     aSig0 |= LIT64( 0x0001000000000000 );
                   5118:     shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
                   5119:     mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
                   5120:     add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
                   5121:     zSig2 |= ( zSig3 != 0 );
                   5122:     if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
                   5123:         shift128ExtraRightJamming(
                   5124:             zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
                   5125:         ++zExp;
                   5126:     }
                   5127:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   5128: 
                   5129: }
                   5130: 
                   5131: /*----------------------------------------------------------------------------
                   5132: | Returns the result of dividing the quadruple-precision floating-point value
                   5133: | `a' by the corresponding value `b'.  The operation is performed according to
                   5134: | the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5135: *----------------------------------------------------------------------------*/
                   5136: 
                   5137: float128 float128_div( float128 a, float128 b STATUS_PARAM )
                   5138: {
                   5139:     flag aSign, bSign, zSign;
                   5140:     int32 aExp, bExp, zExp;
                   5141:     bits64 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
                   5142:     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
                   5143:     float128 z;
                   5144: 
                   5145:     aSig1 = extractFloat128Frac1( a );
                   5146:     aSig0 = extractFloat128Frac0( a );
                   5147:     aExp = extractFloat128Exp( a );
                   5148:     aSign = extractFloat128Sign( a );
                   5149:     bSig1 = extractFloat128Frac1( b );
                   5150:     bSig0 = extractFloat128Frac0( b );
                   5151:     bExp = extractFloat128Exp( b );
                   5152:     bSign = extractFloat128Sign( b );
                   5153:     zSign = aSign ^ bSign;
                   5154:     if ( aExp == 0x7FFF ) {
                   5155:         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   5156:         if ( bExp == 0x7FFF ) {
                   5157:             if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   5158:             goto invalid;
                   5159:         }
                   5160:         return packFloat128( zSign, 0x7FFF, 0, 0 );
                   5161:     }
                   5162:     if ( bExp == 0x7FFF ) {
                   5163:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   5164:         return packFloat128( zSign, 0, 0, 0 );
                   5165:     }
                   5166:     if ( bExp == 0 ) {
                   5167:         if ( ( bSig0 | bSig1 ) == 0 ) {
                   5168:             if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
                   5169:  invalid:
                   5170:                 float_raise( float_flag_invalid STATUS_VAR);
                   5171:                 z.low = float128_default_nan_low;
                   5172:                 z.high = float128_default_nan_high;
                   5173:                 return z;
                   5174:             }
                   5175:             float_raise( float_flag_divbyzero STATUS_VAR);
                   5176:             return packFloat128( zSign, 0x7FFF, 0, 0 );
                   5177:         }
                   5178:         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
                   5179:     }
                   5180:     if ( aExp == 0 ) {
                   5181:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
                   5182:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   5183:     }
                   5184:     zExp = aExp - bExp + 0x3FFD;
                   5185:     shortShift128Left(
                   5186:         aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
                   5187:     shortShift128Left(
                   5188:         bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
                   5189:     if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
                   5190:         shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
                   5191:         ++zExp;
                   5192:     }
                   5193:     zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
                   5194:     mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
                   5195:     sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
                   5196:     while ( (sbits64) rem0 < 0 ) {
                   5197:         --zSig0;
                   5198:         add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
                   5199:     }
                   5200:     zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
                   5201:     if ( ( zSig1 & 0x3FFF ) <= 4 ) {
                   5202:         mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
                   5203:         sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
                   5204:         while ( (sbits64) rem1 < 0 ) {
                   5205:             --zSig1;
                   5206:             add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
                   5207:         }
                   5208:         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
                   5209:     }
                   5210:     shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
                   5211:     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   5212: 
                   5213: }
                   5214: 
                   5215: /*----------------------------------------------------------------------------
                   5216: | Returns the remainder of the quadruple-precision floating-point value `a'
                   5217: | with respect to the corresponding value `b'.  The operation is performed
                   5218: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5219: *----------------------------------------------------------------------------*/
                   5220: 
                   5221: float128 float128_rem( float128 a, float128 b STATUS_PARAM )
                   5222: {
1.1.1.6 ! root     5223:     flag aSign, zSign;
1.1       root     5224:     int32 aExp, bExp, expDiff;
                   5225:     bits64 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
                   5226:     bits64 allZero, alternateASig0, alternateASig1, sigMean1;
                   5227:     sbits64 sigMean0;
                   5228:     float128 z;
                   5229: 
                   5230:     aSig1 = extractFloat128Frac1( a );
                   5231:     aSig0 = extractFloat128Frac0( a );
                   5232:     aExp = extractFloat128Exp( a );
                   5233:     aSign = extractFloat128Sign( a );
                   5234:     bSig1 = extractFloat128Frac1( b );
                   5235:     bSig0 = extractFloat128Frac0( b );
                   5236:     bExp = extractFloat128Exp( b );
                   5237:     if ( aExp == 0x7FFF ) {
                   5238:         if (    ( aSig0 | aSig1 )
                   5239:              || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
                   5240:             return propagateFloat128NaN( a, b STATUS_VAR );
                   5241:         }
                   5242:         goto invalid;
                   5243:     }
                   5244:     if ( bExp == 0x7FFF ) {
                   5245:         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
                   5246:         return a;
                   5247:     }
                   5248:     if ( bExp == 0 ) {
                   5249:         if ( ( bSig0 | bSig1 ) == 0 ) {
                   5250:  invalid:
                   5251:             float_raise( float_flag_invalid STATUS_VAR);
                   5252:             z.low = float128_default_nan_low;
                   5253:             z.high = float128_default_nan_high;
                   5254:             return z;
                   5255:         }
                   5256:         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
                   5257:     }
                   5258:     if ( aExp == 0 ) {
                   5259:         if ( ( aSig0 | aSig1 ) == 0 ) return a;
                   5260:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   5261:     }
                   5262:     expDiff = aExp - bExp;
                   5263:     if ( expDiff < -1 ) return a;
                   5264:     shortShift128Left(
                   5265:         aSig0 | LIT64( 0x0001000000000000 ),
                   5266:         aSig1,
                   5267:         15 - ( expDiff < 0 ),
                   5268:         &aSig0,
                   5269:         &aSig1
                   5270:     );
                   5271:     shortShift128Left(
                   5272:         bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
                   5273:     q = le128( bSig0, bSig1, aSig0, aSig1 );
                   5274:     if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
                   5275:     expDiff -= 64;
                   5276:     while ( 0 < expDiff ) {
                   5277:         q = estimateDiv128To64( aSig0, aSig1, bSig0 );
                   5278:         q = ( 4 < q ) ? q - 4 : 0;
                   5279:         mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
                   5280:         shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
                   5281:         shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
                   5282:         sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
                   5283:         expDiff -= 61;
                   5284:     }
                   5285:     if ( -64 < expDiff ) {
                   5286:         q = estimateDiv128To64( aSig0, aSig1, bSig0 );
                   5287:         q = ( 4 < q ) ? q - 4 : 0;
                   5288:         q >>= - expDiff;
                   5289:         shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
                   5290:         expDiff += 52;
                   5291:         if ( expDiff < 0 ) {
                   5292:             shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
                   5293:         }
                   5294:         else {
                   5295:             shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
                   5296:         }
                   5297:         mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
                   5298:         sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
                   5299:     }
                   5300:     else {
                   5301:         shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
                   5302:         shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
                   5303:     }
                   5304:     do {
                   5305:         alternateASig0 = aSig0;
                   5306:         alternateASig1 = aSig1;
                   5307:         ++q;
                   5308:         sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
                   5309:     } while ( 0 <= (sbits64) aSig0 );
                   5310:     add128(
1.1.1.4   root     5311:         aSig0, aSig1, alternateASig0, alternateASig1, (bits64 *)&sigMean0, &sigMean1 );
1.1       root     5312:     if (    ( sigMean0 < 0 )
                   5313:          || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
                   5314:         aSig0 = alternateASig0;
                   5315:         aSig1 = alternateASig1;
                   5316:     }
                   5317:     zSign = ( (sbits64) aSig0 < 0 );
                   5318:     if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
                   5319:     return
                   5320:         normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
                   5321: 
                   5322: }
                   5323: 
                   5324: /*----------------------------------------------------------------------------
                   5325: | Returns the square root of the quadruple-precision floating-point value `a'.
                   5326: | The operation is performed according to the IEC/IEEE Standard for Binary
                   5327: | Floating-Point Arithmetic.
                   5328: *----------------------------------------------------------------------------*/
                   5329: 
                   5330: float128 float128_sqrt( float128 a STATUS_PARAM )
                   5331: {
                   5332:     flag aSign;
                   5333:     int32 aExp, zExp;
                   5334:     bits64 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
                   5335:     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
                   5336:     float128 z;
                   5337: 
                   5338:     aSig1 = extractFloat128Frac1( a );
                   5339:     aSig0 = extractFloat128Frac0( a );
                   5340:     aExp = extractFloat128Exp( a );
                   5341:     aSign = extractFloat128Sign( a );
                   5342:     if ( aExp == 0x7FFF ) {
                   5343:         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
                   5344:         if ( ! aSign ) return a;
                   5345:         goto invalid;
                   5346:     }
                   5347:     if ( aSign ) {
                   5348:         if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
                   5349:  invalid:
                   5350:         float_raise( float_flag_invalid STATUS_VAR);
                   5351:         z.low = float128_default_nan_low;
                   5352:         z.high = float128_default_nan_high;
                   5353:         return z;
                   5354:     }
                   5355:     if ( aExp == 0 ) {
                   5356:         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
                   5357:         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
                   5358:     }
                   5359:     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
                   5360:     aSig0 |= LIT64( 0x0001000000000000 );
                   5361:     zSig0 = estimateSqrt32( aExp, aSig0>>17 );
                   5362:     shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
                   5363:     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
                   5364:     doubleZSig0 = zSig0<<1;
                   5365:     mul64To128( zSig0, zSig0, &term0, &term1 );
                   5366:     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
                   5367:     while ( (sbits64) rem0 < 0 ) {
                   5368:         --zSig0;
                   5369:         doubleZSig0 -= 2;
                   5370:         add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
                   5371:     }
                   5372:     zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
                   5373:     if ( ( zSig1 & 0x1FFF ) <= 5 ) {
                   5374:         if ( zSig1 == 0 ) zSig1 = 1;
                   5375:         mul64To128( doubleZSig0, zSig1, &term1, &term2 );
                   5376:         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
                   5377:         mul64To128( zSig1, zSig1, &term2, &term3 );
                   5378:         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
                   5379:         while ( (sbits64) rem1 < 0 ) {
                   5380:             --zSig1;
                   5381:             shortShift128Left( 0, zSig1, 1, &term2, &term3 );
                   5382:             term3 |= 1;
                   5383:             term2 |= doubleZSig0;
                   5384:             add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
                   5385:         }
                   5386:         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
                   5387:     }
                   5388:     shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
                   5389:     return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
                   5390: 
                   5391: }
                   5392: 
                   5393: /*----------------------------------------------------------------------------
                   5394: | Returns 1 if the quadruple-precision floating-point value `a' is equal to
                   5395: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   5396: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5397: *----------------------------------------------------------------------------*/
                   5398: 
1.1.1.2   root     5399: int float128_eq( float128 a, float128 b STATUS_PARAM )
1.1       root     5400: {
                   5401: 
                   5402:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5403:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5404:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5405:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5406:        ) {
                   5407:         if (    float128_is_signaling_nan( a )
                   5408:              || float128_is_signaling_nan( b ) ) {
                   5409:             float_raise( float_flag_invalid STATUS_VAR);
                   5410:         }
                   5411:         return 0;
                   5412:     }
                   5413:     return
                   5414:            ( a.low == b.low )
                   5415:         && (    ( a.high == b.high )
                   5416:              || (    ( a.low == 0 )
                   5417:                   && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
                   5418:            );
                   5419: 
                   5420: }
                   5421: 
                   5422: /*----------------------------------------------------------------------------
                   5423: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5424: | or equal to the corresponding value `b', and 0 otherwise.  The comparison
                   5425: | is performed according to the IEC/IEEE Standard for Binary Floating-Point
                   5426: | Arithmetic.
                   5427: *----------------------------------------------------------------------------*/
                   5428: 
1.1.1.2   root     5429: int float128_le( float128 a, float128 b STATUS_PARAM )
1.1       root     5430: {
                   5431:     flag aSign, bSign;
                   5432: 
                   5433:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5434:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5435:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5436:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5437:        ) {
                   5438:         float_raise( float_flag_invalid STATUS_VAR);
                   5439:         return 0;
                   5440:     }
                   5441:     aSign = extractFloat128Sign( a );
                   5442:     bSign = extractFloat128Sign( b );
                   5443:     if ( aSign != bSign ) {
                   5444:         return
                   5445:                aSign
                   5446:             || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5447:                  == 0 );
                   5448:     }
                   5449:     return
                   5450:           aSign ? le128( b.high, b.low, a.high, a.low )
                   5451:         : le128( a.high, a.low, b.high, b.low );
                   5452: 
                   5453: }
                   5454: 
                   5455: /*----------------------------------------------------------------------------
                   5456: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5457: | the corresponding value `b', and 0 otherwise.  The comparison is performed
                   5458: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5459: *----------------------------------------------------------------------------*/
                   5460: 
1.1.1.2   root     5461: int float128_lt( float128 a, float128 b STATUS_PARAM )
1.1       root     5462: {
                   5463:     flag aSign, bSign;
                   5464: 
                   5465:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5466:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5467:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5468:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5469:        ) {
                   5470:         float_raise( float_flag_invalid STATUS_VAR);
                   5471:         return 0;
                   5472:     }
                   5473:     aSign = extractFloat128Sign( a );
                   5474:     bSign = extractFloat128Sign( b );
                   5475:     if ( aSign != bSign ) {
                   5476:         return
                   5477:                aSign
                   5478:             && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5479:                  != 0 );
                   5480:     }
                   5481:     return
                   5482:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   5483:         : lt128( a.high, a.low, b.high, b.low );
                   5484: 
                   5485: }
                   5486: 
                   5487: /*----------------------------------------------------------------------------
                   5488: | Returns 1 if the quadruple-precision floating-point value `a' is equal to
                   5489: | the corresponding value `b', and 0 otherwise.  The invalid exception is
                   5490: | raised if either operand is a NaN.  Otherwise, the comparison is performed
                   5491: | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5492: *----------------------------------------------------------------------------*/
                   5493: 
1.1.1.2   root     5494: int float128_eq_signaling( float128 a, float128 b STATUS_PARAM )
1.1       root     5495: {
                   5496: 
                   5497:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5498:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5499:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5500:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5501:        ) {
                   5502:         float_raise( float_flag_invalid STATUS_VAR);
                   5503:         return 0;
                   5504:     }
                   5505:     return
                   5506:            ( a.low == b.low )
                   5507:         && (    ( a.high == b.high )
                   5508:              || (    ( a.low == 0 )
                   5509:                   && ( (bits64) ( ( a.high | b.high )<<1 ) == 0 ) )
                   5510:            );
                   5511: 
                   5512: }
                   5513: 
                   5514: /*----------------------------------------------------------------------------
                   5515: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5516: | or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
                   5517: | cause an exception.  Otherwise, the comparison is performed according to the
                   5518: | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
                   5519: *----------------------------------------------------------------------------*/
                   5520: 
1.1.1.2   root     5521: int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
1.1       root     5522: {
                   5523:     flag aSign, bSign;
                   5524: 
                   5525:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5526:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5527:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5528:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5529:        ) {
                   5530:         if (    float128_is_signaling_nan( a )
                   5531:              || float128_is_signaling_nan( b ) ) {
                   5532:             float_raise( float_flag_invalid STATUS_VAR);
                   5533:         }
                   5534:         return 0;
                   5535:     }
                   5536:     aSign = extractFloat128Sign( a );
                   5537:     bSign = extractFloat128Sign( b );
                   5538:     if ( aSign != bSign ) {
                   5539:         return
                   5540:                aSign
                   5541:             || (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5542:                  == 0 );
                   5543:     }
                   5544:     return
                   5545:           aSign ? le128( b.high, b.low, a.high, a.low )
                   5546:         : le128( a.high, a.low, b.high, b.low );
                   5547: 
                   5548: }
                   5549: 
                   5550: /*----------------------------------------------------------------------------
                   5551: | Returns 1 if the quadruple-precision floating-point value `a' is less than
                   5552: | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
                   5553: | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
                   5554: | Standard for Binary Floating-Point Arithmetic.
                   5555: *----------------------------------------------------------------------------*/
                   5556: 
1.1.1.2   root     5557: int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
1.1       root     5558: {
                   5559:     flag aSign, bSign;
                   5560: 
                   5561:     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
                   5562:               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
                   5563:          || (    ( extractFloat128Exp( b ) == 0x7FFF )
                   5564:               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
                   5565:        ) {
                   5566:         if (    float128_is_signaling_nan( a )
                   5567:              || float128_is_signaling_nan( b ) ) {
                   5568:             float_raise( float_flag_invalid STATUS_VAR);
                   5569:         }
                   5570:         return 0;
                   5571:     }
                   5572:     aSign = extractFloat128Sign( a );
                   5573:     bSign = extractFloat128Sign( b );
                   5574:     if ( aSign != bSign ) {
                   5575:         return
                   5576:                aSign
                   5577:             && (    ( ( (bits64) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
                   5578:                  != 0 );
                   5579:     }
                   5580:     return
                   5581:           aSign ? lt128( b.high, b.low, a.high, a.low )
                   5582:         : lt128( a.high, a.low, b.high, b.low );
                   5583: 
                   5584: }
                   5585: 
                   5586: #endif
                   5587: 
                   5588: /* misc functions */
                   5589: float32 uint32_to_float32( unsigned int a STATUS_PARAM )
                   5590: {
                   5591:     return int64_to_float32(a STATUS_VAR);
                   5592: }
                   5593: 
                   5594: float64 uint32_to_float64( unsigned int a STATUS_PARAM )
                   5595: {
                   5596:     return int64_to_float64(a STATUS_VAR);
                   5597: }
                   5598: 
                   5599: unsigned int float32_to_uint32( float32 a STATUS_PARAM )
                   5600: {
                   5601:     int64_t v;
                   5602:     unsigned int res;
                   5603: 
                   5604:     v = float32_to_int64(a STATUS_VAR);
                   5605:     if (v < 0) {
                   5606:         res = 0;
                   5607:         float_raise( float_flag_invalid STATUS_VAR);
                   5608:     } else if (v > 0xffffffff) {
                   5609:         res = 0xffffffff;
                   5610:         float_raise( float_flag_invalid STATUS_VAR);
                   5611:     } else {
                   5612:         res = v;
                   5613:     }
                   5614:     return res;
                   5615: }
                   5616: 
                   5617: unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
                   5618: {
                   5619:     int64_t v;
                   5620:     unsigned int res;
                   5621: 
                   5622:     v = float32_to_int64_round_to_zero(a STATUS_VAR);
                   5623:     if (v < 0) {
                   5624:         res = 0;
                   5625:         float_raise( float_flag_invalid STATUS_VAR);
                   5626:     } else if (v > 0xffffffff) {
                   5627:         res = 0xffffffff;
                   5628:         float_raise( float_flag_invalid STATUS_VAR);
                   5629:     } else {
                   5630:         res = v;
                   5631:     }
                   5632:     return res;
                   5633: }
                   5634: 
                   5635: unsigned int float64_to_uint32( float64 a STATUS_PARAM )
                   5636: {
                   5637:     int64_t v;
                   5638:     unsigned int res;
                   5639: 
                   5640:     v = float64_to_int64(a STATUS_VAR);
                   5641:     if (v < 0) {
                   5642:         res = 0;
                   5643:         float_raise( float_flag_invalid STATUS_VAR);
                   5644:     } else if (v > 0xffffffff) {
                   5645:         res = 0xffffffff;
                   5646:         float_raise( float_flag_invalid STATUS_VAR);
                   5647:     } else {
                   5648:         res = v;
                   5649:     }
                   5650:     return res;
                   5651: }
                   5652: 
                   5653: unsigned int float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
                   5654: {
                   5655:     int64_t v;
                   5656:     unsigned int res;
                   5657: 
                   5658:     v = float64_to_int64_round_to_zero(a STATUS_VAR);
                   5659:     if (v < 0) {
                   5660:         res = 0;
                   5661:         float_raise( float_flag_invalid STATUS_VAR);
                   5662:     } else if (v > 0xffffffff) {
                   5663:         res = 0xffffffff;
                   5664:         float_raise( float_flag_invalid STATUS_VAR);
                   5665:     } else {
                   5666:         res = v;
                   5667:     }
                   5668:     return res;
                   5669: }
                   5670: 
1.1.1.3   root     5671: /* FIXME: This looks broken.  */
                   5672: uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
                   5673: {
                   5674:     int64_t v;
                   5675: 
                   5676:     v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
                   5677:     v += float64_val(a);
                   5678:     v = float64_to_int64(make_float64(v) STATUS_VAR);
                   5679: 
                   5680:     return v - INT64_MIN;
                   5681: }
                   5682: 
                   5683: uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
                   5684: {
                   5685:     int64_t v;
                   5686: 
                   5687:     v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
                   5688:     v += float64_val(a);
                   5689:     v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
                   5690: 
                   5691:     return v - INT64_MIN;
                   5692: }
                   5693: 
1.1       root     5694: #define COMPARE(s, nan_exp)                                                  \
1.1.1.2   root     5695: INLINE int float ## s ## _compare_internal( float ## s a, float ## s b,      \
1.1       root     5696:                                       int is_quiet STATUS_PARAM )            \
                   5697: {                                                                            \
                   5698:     flag aSign, bSign;                                                       \
1.1.1.3   root     5699:     bits ## s av, bv;                                                        \
1.1       root     5700:                                                                              \
                   5701:     if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&                    \
                   5702:          extractFloat ## s ## Frac( a ) ) ||                                 \
                   5703:         ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
                   5704:           extractFloat ## s ## Frac( b ) )) {                                \
                   5705:         if (!is_quiet ||                                                     \
                   5706:             float ## s ## _is_signaling_nan( a ) ||                          \
                   5707:             float ## s ## _is_signaling_nan( b ) ) {                         \
                   5708:             float_raise( float_flag_invalid STATUS_VAR);                     \
                   5709:         }                                                                    \
                   5710:         return float_relation_unordered;                                     \
                   5711:     }                                                                        \
                   5712:     aSign = extractFloat ## s ## Sign( a );                                  \
                   5713:     bSign = extractFloat ## s ## Sign( b );                                  \
1.1.1.3   root     5714:     av = float ## s ## _val(a);                                              \
                   5715:     bv = float ## s ## _val(b);                                              \
1.1       root     5716:     if ( aSign != bSign ) {                                                  \
1.1.1.3   root     5717:         if ( (bits ## s) ( ( av | bv )<<1 ) == 0 ) {                         \
1.1       root     5718:             /* zero case */                                                  \
                   5719:             return float_relation_equal;                                     \
                   5720:         } else {                                                             \
                   5721:             return 1 - (2 * aSign);                                          \
                   5722:         }                                                                    \
                   5723:     } else {                                                                 \
1.1.1.3   root     5724:         if (av == bv) {                                                      \
1.1       root     5725:             return float_relation_equal;                                     \
                   5726:         } else {                                                             \
1.1.1.3   root     5727:             return 1 - 2 * (aSign ^ ( av < bv ));                            \
1.1       root     5728:         }                                                                    \
                   5729:     }                                                                        \
                   5730: }                                                                            \
                   5731:                                                                              \
1.1.1.2   root     5732: int float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM )        \
1.1       root     5733: {                                                                            \
                   5734:     return float ## s ## _compare_internal(a, b, 0 STATUS_VAR);              \
                   5735: }                                                                            \
                   5736:                                                                              \
1.1.1.2   root     5737: int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM )  \
1.1       root     5738: {                                                                            \
                   5739:     return float ## s ## _compare_internal(a, b, 1 STATUS_VAR);              \
                   5740: }
                   5741: 
                   5742: COMPARE(32, 0xff)
                   5743: COMPARE(64, 0x7ff)
1.1.1.3   root     5744: 
                   5745: INLINE int float128_compare_internal( float128 a, float128 b,
                   5746:                                       int is_quiet STATUS_PARAM )
                   5747: {
                   5748:     flag aSign, bSign;
                   5749: 
                   5750:     if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
                   5751:           ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
                   5752:         ( ( extractFloat128Exp( b ) == 0x7fff ) &&
                   5753:           ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
                   5754:         if (!is_quiet ||
                   5755:             float128_is_signaling_nan( a ) ||
                   5756:             float128_is_signaling_nan( b ) ) {
                   5757:             float_raise( float_flag_invalid STATUS_VAR);
                   5758:         }
                   5759:         return float_relation_unordered;
                   5760:     }
                   5761:     aSign = extractFloat128Sign( a );
                   5762:     bSign = extractFloat128Sign( b );
                   5763:     if ( aSign != bSign ) {
                   5764:         if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
                   5765:             /* zero case */
                   5766:             return float_relation_equal;
                   5767:         } else {
                   5768:             return 1 - (2 * aSign);
                   5769:         }
                   5770:     } else {
                   5771:         if (a.low == b.low && a.high == b.high) {
                   5772:             return float_relation_equal;
                   5773:         } else {
                   5774:             return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
                   5775:         }
                   5776:     }
                   5777: }
                   5778: 
                   5779: int float128_compare( float128 a, float128 b STATUS_PARAM )
                   5780: {
                   5781:     return float128_compare_internal(a, b, 0 STATUS_VAR);
                   5782: }
                   5783: 
                   5784: int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
                   5785: {
                   5786:     return float128_compare_internal(a, b, 1 STATUS_VAR);
                   5787: }
                   5788: 
                   5789: /* Multiply A by 2 raised to the power N.  */
                   5790: float32 float32_scalbn( float32 a, int n STATUS_PARAM )
                   5791: {
                   5792:     flag aSign;
                   5793:     int16 aExp;
                   5794:     bits32 aSig;
                   5795: 
                   5796:     aSig = extractFloat32Frac( a );
                   5797:     aExp = extractFloat32Exp( a );
                   5798:     aSign = extractFloat32Sign( a );
                   5799: 
                   5800:     if ( aExp == 0xFF ) {
                   5801:         return a;
                   5802:     }
1.1.1.4   root     5803:     if ( aExp != 0 )
                   5804:         aSig |= 0x00800000;
                   5805:     else if ( aSig == 0 )
                   5806:         return a;
                   5807: 
                   5808:     aExp += n - 1;
                   5809:     aSig <<= 7;
                   5810:     return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
1.1.1.3   root     5811: }
                   5812: 
                   5813: float64 float64_scalbn( float64 a, int n STATUS_PARAM )
                   5814: {
                   5815:     flag aSign;
                   5816:     int16 aExp;
                   5817:     bits64 aSig;
                   5818: 
                   5819:     aSig = extractFloat64Frac( a );
                   5820:     aExp = extractFloat64Exp( a );
                   5821:     aSign = extractFloat64Sign( a );
                   5822: 
                   5823:     if ( aExp == 0x7FF ) {
                   5824:         return a;
                   5825:     }
1.1.1.4   root     5826:     if ( aExp != 0 )
                   5827:         aSig |= LIT64( 0x0010000000000000 );
                   5828:     else if ( aSig == 0 )
                   5829:         return a;
                   5830: 
                   5831:     aExp += n - 1;
                   5832:     aSig <<= 10;
                   5833:     return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
1.1.1.3   root     5834: }
                   5835: 
                   5836: #ifdef FLOATX80
                   5837: floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
                   5838: {
                   5839:     flag aSign;
                   5840:     int16 aExp;
                   5841:     bits64 aSig;
                   5842: 
                   5843:     aSig = extractFloatx80Frac( a );
                   5844:     aExp = extractFloatx80Exp( a );
                   5845:     aSign = extractFloatx80Sign( a );
                   5846: 
                   5847:     if ( aExp == 0x7FF ) {
                   5848:         return a;
                   5849:     }
1.1.1.4   root     5850:     if (aExp == 0 && aSig == 0)
                   5851:         return a;
                   5852: 
1.1.1.3   root     5853:     aExp += n;
1.1.1.4   root     5854:     return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
                   5855:                                           aSign, aExp, aSig, 0 STATUS_VAR );
1.1.1.3   root     5856: }
                   5857: #endif
                   5858: 
                   5859: #ifdef FLOAT128
                   5860: float128 float128_scalbn( float128 a, int n STATUS_PARAM )
                   5861: {
                   5862:     flag aSign;
                   5863:     int32 aExp;
                   5864:     bits64 aSig0, aSig1;
                   5865: 
                   5866:     aSig1 = extractFloat128Frac1( a );
                   5867:     aSig0 = extractFloat128Frac0( a );
                   5868:     aExp = extractFloat128Exp( a );
                   5869:     aSign = extractFloat128Sign( a );
                   5870:     if ( aExp == 0x7FFF ) {
                   5871:         return a;
                   5872:     }
1.1.1.4   root     5873:     if ( aExp != 0 )
                   5874:         aSig0 |= LIT64( 0x0001000000000000 );
                   5875:     else if ( aSig0 == 0 && aSig1 == 0 )
                   5876:         return a;
                   5877: 
                   5878:     aExp += n - 1;
                   5879:     return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
                   5880:                                           STATUS_VAR );
1.1.1.3   root     5881: 
                   5882: }
                   5883: #endif

unix.superglobalmegacorp.com

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