Annotation of qemu/fpu/softfloat-specialize.h, revision 1.1.1.10

1.1.1.8   root        1: /*
                      2:  * QEMU float support
                      3:  *
                      4:  * Derived from SoftFloat.
                      5:  */
1.1       root        6: 
                      7: /*============================================================================
                      8: 
                      9: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
                     10: Arithmetic Package, Release 2b.
                     11: 
                     12: Written by John R. Hauser.  This work was made possible in part by the
                     13: International Computer Science Institute, located at Suite 600, 1947 Center
                     14: Street, Berkeley, California 94704.  Funding was partially provided by the
                     15: National Science Foundation under grant MIP-9311980.  The original version
                     16: of this code was written as part of a project to build a fixed-point vector
                     17: processor in collaboration with the University of California at Berkeley,
                     18: overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
                     19: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
                     20: arithmetic/SoftFloat.html'.
                     21: 
                     22: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
                     23: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
                     24: RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
                     25: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
                     26: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
                     27: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
                     28: INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
                     29: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
                     30: 
                     31: Derivative works are acceptable, even for commercial purposes, so long as
                     32: (1) the source code for the derivative work includes prominent notice that
                     33: the work is derivative, and (2) the source code includes prominent notice with
                     34: these four paragraphs for those parts of this code that are retained.
                     35: 
                     36: =============================================================================*/
                     37: 
1.1.1.9   root       38: #if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
                     39: #define SNAN_BIT_IS_ONE                1
                     40: #else
                     41: #define SNAN_BIT_IS_ONE                0
                     42: #endif
                     43: 
                     44: /*----------------------------------------------------------------------------
                     45: | The pattern for a default generated half-precision NaN.
                     46: *----------------------------------------------------------------------------*/
                     47: #if defined(TARGET_ARM)
                     48: const float16 float16_default_nan = const_float16(0x7E00);
                     49: #elif SNAN_BIT_IS_ONE
                     50: const float16 float16_default_nan = const_float16(0x7DFF);
                     51: #else
                     52: const float16 float16_default_nan = const_float16(0xFE00);
                     53: #endif
                     54: 
                     55: /*----------------------------------------------------------------------------
                     56: | The pattern for a default generated single-precision NaN.
                     57: *----------------------------------------------------------------------------*/
                     58: #if defined(TARGET_SPARC)
                     59: const float32 float32_default_nan = const_float32(0x7FFFFFFF);
                     60: #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
                     61: const float32 float32_default_nan = const_float32(0x7FC00000);
                     62: #elif SNAN_BIT_IS_ONE
                     63: const float32 float32_default_nan = const_float32(0x7FBFFFFF);
                     64: #else
                     65: const float32 float32_default_nan = const_float32(0xFFC00000);
                     66: #endif
                     67: 
                     68: /*----------------------------------------------------------------------------
                     69: | The pattern for a default generated double-precision NaN.
                     70: *----------------------------------------------------------------------------*/
                     71: #if defined(TARGET_SPARC)
                     72: const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF ));
                     73: #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
                     74: const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 ));
                     75: #elif SNAN_BIT_IS_ONE
                     76: const float64 float64_default_nan = const_float64(LIT64( 0x7FF7FFFFFFFFFFFF ));
                     77: #else
                     78: const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 ));
                     79: #endif
                     80: 
                     81: /*----------------------------------------------------------------------------
                     82: | The pattern for a default generated extended double-precision NaN.
                     83: *----------------------------------------------------------------------------*/
                     84: #if SNAN_BIT_IS_ONE
                     85: #define floatx80_default_nan_high 0x7FFF
                     86: #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
                     87: #else
                     88: #define floatx80_default_nan_high 0xFFFF
                     89: #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
                     90: #endif
                     91: 
1.1.1.10! root       92: const floatx80 floatx80_default_nan
        !            93:     = make_floatx80_init(floatx80_default_nan_high, floatx80_default_nan_low);
1.1.1.9   root       94: 
                     95: /*----------------------------------------------------------------------------
                     96: | The pattern for a default generated quadruple-precision NaN.  The `high' and
                     97: | `low' values hold the most- and least-significant bits, respectively.
                     98: *----------------------------------------------------------------------------*/
                     99: #if SNAN_BIT_IS_ONE
                    100: #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
                    101: #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
                    102: #else
                    103: #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
                    104: #define float128_default_nan_low  LIT64( 0x0000000000000000 )
                    105: #endif
                    106: 
1.1.1.10! root      107: const float128 float128_default_nan
        !           108:     = make_float128_init(float128_default_nan_high, float128_default_nan_low);
1.1.1.9   root      109: 
1.1       root      110: /*----------------------------------------------------------------------------
                    111: | Raises the exceptions specified by `flags'.  Floating-point traps can be
                    112: | defined here if desired.  It is currently not possible for such a trap
                    113: | to substitute a result value.  If traps are not implemented, this routine
                    114: | should be simply `float_exception_flags |= flags;'.
                    115: *----------------------------------------------------------------------------*/
                    116: 
                    117: void float_raise( int8 flags STATUS_PARAM )
                    118: {
                    119:     STATUS(float_exception_flags) |= flags;
                    120: }
                    121: 
                    122: /*----------------------------------------------------------------------------
                    123: | Internal canonical NaN format.
                    124: *----------------------------------------------------------------------------*/
                    125: typedef struct {
                    126:     flag sign;
1.1.1.8   root      127:     uint64_t high, low;
1.1       root      128: } commonNaNT;
                    129: 
                    130: /*----------------------------------------------------------------------------
1.1.1.8   root      131: | Returns 1 if the half-precision floating-point value `a' is a quiet
                    132: | NaN; otherwise returns 0.
1.1       root      133: *----------------------------------------------------------------------------*/
1.1.1.8   root      134: 
                    135: int float16_is_quiet_nan(float16 a_)
                    136: {
                    137:     uint16_t a = float16_val(a_);
                    138: #if SNAN_BIT_IS_ONE
                    139:     return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
                    140: #else
                    141:     return ((a & ~0x8000) >= 0x7c80);
                    142: #endif
                    143: }
                    144: 
                    145: /*----------------------------------------------------------------------------
                    146: | Returns 1 if the half-precision floating-point value `a' is a signaling
                    147: | NaN; otherwise returns 0.
                    148: *----------------------------------------------------------------------------*/
                    149: 
                    150: int float16_is_signaling_nan(float16 a_)
                    151: {
                    152:     uint16_t a = float16_val(a_);
                    153: #if SNAN_BIT_IS_ONE
                    154:     return ((a & ~0x8000) >= 0x7c80);
                    155: #else
                    156:     return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
                    157: #endif
                    158: }
                    159: 
                    160: /*----------------------------------------------------------------------------
                    161: | Returns a quiet NaN if the half-precision floating point value `a' is a
                    162: | signaling NaN; otherwise returns `a'.
                    163: *----------------------------------------------------------------------------*/
                    164: float16 float16_maybe_silence_nan(float16 a_)
                    165: {
                    166:     if (float16_is_signaling_nan(a_)) {
                    167: #if SNAN_BIT_IS_ONE
                    168: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
                    169:         return float16_default_nan;
                    170: #  else
                    171: #    error Rules for silencing a signaling NaN are target-specific
                    172: #  endif
1.1.1.3   root      173: #else
1.1.1.8   root      174:         uint16_t a = float16_val(a_);
                    175:         a |= (1 << 9);
                    176:         return make_float16(a);
1.1.1.3   root      177: #endif
1.1.1.8   root      178:     }
                    179:     return a_;
                    180: }
                    181: 
                    182: /*----------------------------------------------------------------------------
                    183: | Returns the result of converting the half-precision floating-point NaN
                    184: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    185: | exception is raised.
                    186: *----------------------------------------------------------------------------*/
                    187: 
                    188: static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
                    189: {
                    190:     commonNaNT z;
                    191: 
                    192:     if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
                    193:     z.sign = float16_val(a) >> 15;
                    194:     z.low = 0;
                    195:     z.high = ((uint64_t) float16_val(a))<<54;
                    196:     return z;
                    197: }
                    198: 
                    199: /*----------------------------------------------------------------------------
                    200: | Returns the result of converting the canonical NaN `a' to the half-
                    201: | precision floating-point format.
                    202: *----------------------------------------------------------------------------*/
                    203: 
                    204: static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
                    205: {
                    206:     uint16_t mantissa = a.high>>54;
                    207: 
                    208:     if (STATUS(default_nan_mode)) {
                    209:         return float16_default_nan;
                    210:     }
                    211: 
                    212:     if (mantissa) {
                    213:         return make_float16(((((uint16_t) a.sign) << 15)
                    214:                              | (0x1F << 10) | mantissa));
                    215:     } else {
                    216:         return float16_default_nan;
                    217:     }
                    218: }
1.1       root      219: 
                    220: /*----------------------------------------------------------------------------
1.1.1.3   root      221: | Returns 1 if the single-precision floating-point value `a' is a quiet
                    222: | NaN; otherwise returns 0.
1.1       root      223: *----------------------------------------------------------------------------*/
                    224: 
1.1.1.7   root      225: int float32_is_quiet_nan( float32 a_ )
1.1       root      226: {
1.1.1.3   root      227:     uint32_t a = float32_val(a_);
                    228: #if SNAN_BIT_IS_ONE
                    229:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
                    230: #else
1.1.1.8   root      231:     return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
1.1.1.3   root      232: #endif
1.1       root      233: }
                    234: 
                    235: /*----------------------------------------------------------------------------
                    236: | Returns 1 if the single-precision floating-point value `a' is a signaling
                    237: | NaN; otherwise returns 0.
                    238: *----------------------------------------------------------------------------*/
                    239: 
1.1.1.3   root      240: int float32_is_signaling_nan( float32 a_ )
1.1       root      241: {
1.1.1.3   root      242:     uint32_t a = float32_val(a_);
                    243: #if SNAN_BIT_IS_ONE
1.1.1.8   root      244:     return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
1.1.1.3   root      245: #else
1.1       root      246:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
1.1.1.3   root      247: #endif
1.1       root      248: }
                    249: 
                    250: /*----------------------------------------------------------------------------
1.1.1.7   root      251: | Returns a quiet NaN if the single-precision floating point value `a' is a
                    252: | signaling NaN; otherwise returns `a'.
                    253: *----------------------------------------------------------------------------*/
                    254: 
                    255: float32 float32_maybe_silence_nan( float32 a_ )
                    256: {
                    257:     if (float32_is_signaling_nan(a_)) {
                    258: #if SNAN_BIT_IS_ONE
1.1.1.8   root      259: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      260:         return float32_default_nan;
                    261: #  else
                    262: #    error Rules for silencing a signaling NaN are target-specific
                    263: #  endif
                    264: #else
1.1.1.8   root      265:         uint32_t a = float32_val(a_);
1.1.1.7   root      266:         a |= (1 << 22);
                    267:         return make_float32(a);
                    268: #endif
                    269:     }
                    270:     return a_;
                    271: }
                    272: 
                    273: /*----------------------------------------------------------------------------
1.1       root      274: | Returns the result of converting the single-precision floating-point NaN
                    275: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    276: | exception is raised.
                    277: *----------------------------------------------------------------------------*/
                    278: 
                    279: static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
                    280: {
                    281:     commonNaNT z;
                    282: 
                    283:     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
1.1.1.3   root      284:     z.sign = float32_val(a)>>31;
1.1       root      285:     z.low = 0;
1.1.1.8   root      286:     z.high = ( (uint64_t) float32_val(a) )<<41;
1.1       root      287:     return z;
                    288: }
                    289: 
                    290: /*----------------------------------------------------------------------------
                    291: | Returns the result of converting the canonical NaN `a' to the single-
                    292: | precision floating-point format.
                    293: *----------------------------------------------------------------------------*/
                    294: 
1.1.1.8   root      295: static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
1.1       root      296: {
1.1.1.8   root      297:     uint32_t mantissa = a.high>>41;
                    298: 
                    299:     if ( STATUS(default_nan_mode) ) {
                    300:         return float32_default_nan;
                    301:     }
                    302: 
1.1.1.3   root      303:     if ( mantissa )
                    304:         return make_float32(
1.1.1.8   root      305:             ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
1.1.1.3   root      306:     else
                    307:         return float32_default_nan;
1.1       root      308: }
                    309: 
                    310: /*----------------------------------------------------------------------------
1.1.1.7   root      311: | Select which NaN to propagate for a two-input operation.
                    312: | IEEE754 doesn't specify all the details of this, so the
                    313: | algorithm is target-specific.
                    314: | The routine is passed various bits of information about the
                    315: | two NaNs and should return 0 to select NaN a and 1 for NaN b.
                    316: | Note that signalling NaNs are always squashed to quiet NaNs
                    317: | by the caller, by calling floatXX_maybe_silence_nan() before
                    318: | returning them.
                    319: |
                    320: | aIsLargerSignificand is only valid if both a and b are NaNs
                    321: | of some kind, and is true if a has the larger significand,
                    322: | or if both a and b have the same significand but a is
                    323: | positive but b is negative. It is only needed for the x87
                    324: | tie-break rule.
                    325: *----------------------------------------------------------------------------*/
                    326: 
                    327: #if defined(TARGET_ARM)
                    328: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    329:                     flag aIsLargerSignificand)
                    330: {
                    331:     /* ARM mandated NaN propagation rules: take the first of:
                    332:      *  1. A if it is signaling
                    333:      *  2. B if it is signaling
                    334:      *  3. A (quiet)
                    335:      *  4. B (quiet)
                    336:      * A signaling NaN is always quietened before returning it.
                    337:      */
                    338:     if (aIsSNaN) {
                    339:         return 0;
                    340:     } else if (bIsSNaN) {
                    341:         return 1;
                    342:     } else if (aIsQNaN) {
                    343:         return 0;
                    344:     } else {
                    345:         return 1;
                    346:     }
                    347: }
                    348: #elif defined(TARGET_MIPS)
                    349: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    350:                     flag aIsLargerSignificand)
                    351: {
                    352:     /* According to MIPS specifications, if one of the two operands is
                    353:      * a sNaN, a new qNaN has to be generated. This is done in
                    354:      * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
                    355:      * says: "When possible, this QNaN result is one of the operand QNaN
                    356:      * values." In practice it seems that most implementations choose
                    357:      * the first operand if both operands are qNaN. In short this gives
                    358:      * the following rules:
                    359:      *  1. A if it is signaling
                    360:      *  2. B if it is signaling
                    361:      *  3. A (quiet)
                    362:      *  4. B (quiet)
                    363:      * A signaling NaN is always silenced before returning it.
                    364:      */
                    365:     if (aIsSNaN) {
                    366:         return 0;
                    367:     } else if (bIsSNaN) {
                    368:         return 1;
                    369:     } else if (aIsQNaN) {
                    370:         return 0;
                    371:     } else {
                    372:         return 1;
                    373:     }
                    374: }
                    375: #elif defined(TARGET_PPC)
                    376: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    377:                    flag aIsLargerSignificand)
                    378: {
                    379:     /* PowerPC propagation rules:
                    380:      *  1. A if it sNaN or qNaN
                    381:      *  2. B if it sNaN or qNaN
                    382:      * A signaling NaN is always silenced before returning it.
                    383:      */
                    384:     if (aIsSNaN || aIsQNaN) {
                    385:         return 0;
                    386:     } else {
                    387:         return 1;
                    388:     }
                    389: }
                    390: #else
                    391: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    392:                     flag aIsLargerSignificand)
                    393: {
                    394:     /* This implements x87 NaN propagation rules:
                    395:      * SNaN + QNaN => return the QNaN
                    396:      * two SNaNs => return the one with the larger significand, silenced
                    397:      * two QNaNs => return the one with the larger significand
                    398:      * SNaN and a non-NaN => return the SNaN, silenced
                    399:      * QNaN and a non-NaN => return the QNaN
                    400:      *
                    401:      * If we get down to comparing significands and they are the same,
                    402:      * return the NaN with the positive sign bit (if any).
                    403:      */
                    404:     if (aIsSNaN) {
                    405:         if (bIsSNaN) {
                    406:             return aIsLargerSignificand ? 0 : 1;
                    407:         }
                    408:         return bIsQNaN ? 1 : 0;
                    409:     }
                    410:     else if (aIsQNaN) {
                    411:         if (bIsSNaN || !bIsQNaN)
                    412:             return 0;
                    413:         else {
                    414:             return aIsLargerSignificand ? 0 : 1;
                    415:         }
                    416:     } else {
                    417:         return 1;
                    418:     }
                    419: }
                    420: #endif
                    421: 
                    422: /*----------------------------------------------------------------------------
1.1.1.9   root      423: | Select which NaN to propagate for a three-input operation.
                    424: | For the moment we assume that no CPU needs the 'larger significand'
                    425: | information.
                    426: | Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
                    427: *----------------------------------------------------------------------------*/
                    428: #if defined(TARGET_ARM)
                    429: static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    430:                          flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
                    431: {
                    432:     /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
                    433:      * the default NaN
                    434:      */
                    435:     if (infzero && cIsQNaN) {
                    436:         float_raise(float_flag_invalid STATUS_VAR);
                    437:         return 3;
                    438:     }
                    439: 
                    440:     /* This looks different from the ARM ARM pseudocode, because the ARM ARM
                    441:      * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
                    442:      */
                    443:     if (cIsSNaN) {
                    444:         return 2;
                    445:     } else if (aIsSNaN) {
                    446:         return 0;
                    447:     } else if (bIsSNaN) {
                    448:         return 1;
                    449:     } else if (cIsQNaN) {
                    450:         return 2;
                    451:     } else if (aIsQNaN) {
                    452:         return 0;
                    453:     } else {
                    454:         return 1;
                    455:     }
                    456: }
                    457: #elif defined(TARGET_PPC)
                    458: static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    459:                          flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
                    460: {
                    461:     /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
                    462:      * to return an input NaN if we have one (ie c) rather than generating
                    463:      * a default NaN
                    464:      */
                    465:     if (infzero) {
                    466:         float_raise(float_flag_invalid STATUS_VAR);
                    467:         return 2;
                    468:     }
                    469: 
                    470:     /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
                    471:      * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
                    472:      */
                    473:     if (aIsSNaN || aIsQNaN) {
                    474:         return 0;
                    475:     } else if (cIsSNaN || cIsQNaN) {
                    476:         return 2;
                    477:     } else {
                    478:         return 1;
                    479:     }
                    480: }
                    481: #else
                    482: /* A default implementation: prefer a to b to c.
                    483:  * This is unlikely to actually match any real implementation.
                    484:  */
                    485: static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    486:                          flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
                    487: {
                    488:     if (aIsSNaN || aIsQNaN) {
                    489:         return 0;
                    490:     } else if (bIsSNaN || bIsQNaN) {
                    491:         return 1;
                    492:     } else {
                    493:         return 2;
                    494:     }
                    495: }
                    496: #endif
                    497: 
                    498: /*----------------------------------------------------------------------------
1.1       root      499: | Takes two single-precision floating-point values `a' and `b', one of which
                    500: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    501: | signaling NaN, the invalid exception is raised.
                    502: *----------------------------------------------------------------------------*/
                    503: 
                    504: static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
                    505: {
1.1.1.7   root      506:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    507:     flag aIsLargerSignificand;
1.1.1.8   root      508:     uint32_t av, bv;
1.1.1.4   root      509: 
1.1.1.7   root      510:     aIsQuietNaN = float32_is_quiet_nan( a );
1.1       root      511:     aIsSignalingNaN = float32_is_signaling_nan( a );
1.1.1.7   root      512:     bIsQuietNaN = float32_is_quiet_nan( b );
1.1       root      513:     bIsSignalingNaN = float32_is_signaling_nan( b );
1.1.1.3   root      514:     av = float32_val(a);
                    515:     bv = float32_val(b);
1.1.1.7   root      516: 
1.1       root      517:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.7   root      518: 
                    519:     if ( STATUS(default_nan_mode) )
                    520:         return float32_default_nan;
                    521: 
1.1.1.8   root      522:     if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
1.1.1.7   root      523:         aIsLargerSignificand = 0;
1.1.1.8   root      524:     } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
1.1.1.7   root      525:         aIsLargerSignificand = 1;
                    526:     } else {
                    527:         aIsLargerSignificand = (av < bv) ? 1 : 0;
1.1       root      528:     }
1.1.1.7   root      529: 
                    530:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    531:                 aIsLargerSignificand)) {
                    532:         return float32_maybe_silence_nan(b);
                    533:     } else {
                    534:         return float32_maybe_silence_nan(a);
1.1       root      535:     }
                    536: }
                    537: 
                    538: /*----------------------------------------------------------------------------
1.1.1.9   root      539: | Takes three single-precision floating-point values `a', `b' and `c', one of
                    540: | which is a NaN, and returns the appropriate NaN result.  If any of  `a',
                    541: | `b' or `c' is a signaling NaN, the invalid exception is raised.
                    542: | The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
                    543: | obviously c is a NaN, and whether to propagate c or some other NaN is
                    544: | implementation defined).
                    545: *----------------------------------------------------------------------------*/
                    546: 
                    547: static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
                    548:                                          float32 c, flag infzero STATUS_PARAM)
                    549: {
                    550:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    551:         cIsQuietNaN, cIsSignalingNaN;
                    552:     int which;
                    553: 
                    554:     aIsQuietNaN = float32_is_quiet_nan(a);
                    555:     aIsSignalingNaN = float32_is_signaling_nan(a);
                    556:     bIsQuietNaN = float32_is_quiet_nan(b);
                    557:     bIsSignalingNaN = float32_is_signaling_nan(b);
                    558:     cIsQuietNaN = float32_is_quiet_nan(c);
                    559:     cIsSignalingNaN = float32_is_signaling_nan(c);
                    560: 
                    561:     if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
                    562:         float_raise(float_flag_invalid STATUS_VAR);
                    563:     }
                    564: 
                    565:     which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
                    566:                           bIsQuietNaN, bIsSignalingNaN,
                    567:                           cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
                    568: 
                    569:     if (STATUS(default_nan_mode)) {
                    570:         /* Note that this check is after pickNaNMulAdd so that function
                    571:          * has an opportunity to set the Invalid flag.
                    572:          */
                    573:         return float32_default_nan;
                    574:     }
                    575: 
                    576:     switch (which) {
                    577:     case 0:
                    578:         return float32_maybe_silence_nan(a);
                    579:     case 1:
                    580:         return float32_maybe_silence_nan(b);
                    581:     case 2:
                    582:         return float32_maybe_silence_nan(c);
                    583:     case 3:
                    584:     default:
                    585:         return float32_default_nan;
                    586:     }
                    587: }
                    588: 
                    589: /*----------------------------------------------------------------------------
1.1.1.3   root      590: | Returns 1 if the double-precision floating-point value `a' is a quiet
                    591: | NaN; otherwise returns 0.
1.1       root      592: *----------------------------------------------------------------------------*/
                    593: 
1.1.1.7   root      594: int float64_is_quiet_nan( float64 a_ )
1.1       root      595: {
1.1.1.8   root      596:     uint64_t a = float64_val(a_);
1.1.1.3   root      597: #if SNAN_BIT_IS_ONE
                    598:     return
                    599:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    600:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    601: #else
1.1.1.8   root      602:     return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
1.1.1.3   root      603: #endif
1.1       root      604: }
                    605: 
                    606: /*----------------------------------------------------------------------------
                    607: | Returns 1 if the double-precision floating-point value `a' is a signaling
                    608: | NaN; otherwise returns 0.
                    609: *----------------------------------------------------------------------------*/
                    610: 
1.1.1.3   root      611: int float64_is_signaling_nan( float64 a_ )
1.1       root      612: {
1.1.1.8   root      613:     uint64_t a = float64_val(a_);
1.1.1.3   root      614: #if SNAN_BIT_IS_ONE
1.1.1.8   root      615:     return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
1.1.1.3   root      616: #else
1.1       root      617:     return
                    618:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    619:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
1.1.1.3   root      620: #endif
1.1       root      621: }
                    622: 
                    623: /*----------------------------------------------------------------------------
1.1.1.7   root      624: | Returns a quiet NaN if the double-precision floating point value `a' is a
                    625: | signaling NaN; otherwise returns `a'.
                    626: *----------------------------------------------------------------------------*/
                    627: 
                    628: float64 float64_maybe_silence_nan( float64 a_ )
                    629: {
                    630:     if (float64_is_signaling_nan(a_)) {
                    631: #if SNAN_BIT_IS_ONE
1.1.1.8   root      632: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      633:         return float64_default_nan;
                    634: #  else
                    635: #    error Rules for silencing a signaling NaN are target-specific
                    636: #  endif
                    637: #else
1.1.1.8   root      638:         uint64_t a = float64_val(a_);
1.1.1.7   root      639:         a |= LIT64( 0x0008000000000000 );
                    640:         return make_float64(a);
                    641: #endif
                    642:     }
                    643:     return a_;
                    644: }
                    645: 
                    646: /*----------------------------------------------------------------------------
1.1       root      647: | Returns the result of converting the double-precision floating-point NaN
                    648: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    649: | exception is raised.
                    650: *----------------------------------------------------------------------------*/
                    651: 
                    652: static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
                    653: {
                    654:     commonNaNT z;
                    655: 
                    656:     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.3   root      657:     z.sign = float64_val(a)>>63;
1.1       root      658:     z.low = 0;
1.1.1.3   root      659:     z.high = float64_val(a)<<12;
1.1       root      660:     return z;
                    661: }
                    662: 
                    663: /*----------------------------------------------------------------------------
                    664: | Returns the result of converting the canonical NaN `a' to the double-
                    665: | precision floating-point format.
                    666: *----------------------------------------------------------------------------*/
                    667: 
1.1.1.8   root      668: static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
1.1       root      669: {
1.1.1.8   root      670:     uint64_t mantissa = a.high>>12;
                    671: 
                    672:     if ( STATUS(default_nan_mode) ) {
                    673:         return float64_default_nan;
                    674:     }
1.1       root      675: 
1.1.1.3   root      676:     if ( mantissa )
                    677:         return make_float64(
1.1.1.8   root      678:               ( ( (uint64_t) a.sign )<<63 )
1.1.1.3   root      679:             | LIT64( 0x7FF0000000000000 )
                    680:             | ( a.high>>12 ));
                    681:     else
                    682:         return float64_default_nan;
1.1       root      683: }
                    684: 
                    685: /*----------------------------------------------------------------------------
                    686: | Takes two double-precision floating-point values `a' and `b', one of which
                    687: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    688: | signaling NaN, the invalid exception is raised.
                    689: *----------------------------------------------------------------------------*/
                    690: 
                    691: static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
                    692: {
1.1.1.7   root      693:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    694:     flag aIsLargerSignificand;
1.1.1.8   root      695:     uint64_t av, bv;
1.1       root      696: 
1.1.1.7   root      697:     aIsQuietNaN = float64_is_quiet_nan( a );
1.1       root      698:     aIsSignalingNaN = float64_is_signaling_nan( a );
1.1.1.7   root      699:     bIsQuietNaN = float64_is_quiet_nan( b );
1.1       root      700:     bIsSignalingNaN = float64_is_signaling_nan( b );
1.1.1.3   root      701:     av = float64_val(a);
                    702:     bv = float64_val(b);
1.1.1.7   root      703: 
1.1       root      704:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.7   root      705: 
                    706:     if ( STATUS(default_nan_mode) )
                    707:         return float64_default_nan;
                    708: 
1.1.1.8   root      709:     if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
1.1.1.7   root      710:         aIsLargerSignificand = 0;
1.1.1.8   root      711:     } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
1.1.1.7   root      712:         aIsLargerSignificand = 1;
                    713:     } else {
                    714:         aIsLargerSignificand = (av < bv) ? 1 : 0;
1.1       root      715:     }
1.1.1.7   root      716: 
                    717:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    718:                 aIsLargerSignificand)) {
                    719:         return float64_maybe_silence_nan(b);
                    720:     } else {
                    721:         return float64_maybe_silence_nan(a);
1.1       root      722:     }
                    723: }
                    724: 
                    725: /*----------------------------------------------------------------------------
1.1.1.9   root      726: | Takes three double-precision floating-point values `a', `b' and `c', one of
                    727: | which is a NaN, and returns the appropriate NaN result.  If any of  `a',
                    728: | `b' or `c' is a signaling NaN, the invalid exception is raised.
                    729: | The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
                    730: | obviously c is a NaN, and whether to propagate c or some other NaN is
                    731: | implementation defined).
                    732: *----------------------------------------------------------------------------*/
                    733: 
                    734: static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
                    735:                                          float64 c, flag infzero STATUS_PARAM)
                    736: {
                    737:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    738:         cIsQuietNaN, cIsSignalingNaN;
                    739:     int which;
                    740: 
                    741:     aIsQuietNaN = float64_is_quiet_nan(a);
                    742:     aIsSignalingNaN = float64_is_signaling_nan(a);
                    743:     bIsQuietNaN = float64_is_quiet_nan(b);
                    744:     bIsSignalingNaN = float64_is_signaling_nan(b);
                    745:     cIsQuietNaN = float64_is_quiet_nan(c);
                    746:     cIsSignalingNaN = float64_is_signaling_nan(c);
                    747: 
                    748:     if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
                    749:         float_raise(float_flag_invalid STATUS_VAR);
                    750:     }
                    751: 
                    752:     which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
                    753:                           bIsQuietNaN, bIsSignalingNaN,
                    754:                           cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
                    755: 
                    756:     if (STATUS(default_nan_mode)) {
                    757:         /* Note that this check is after pickNaNMulAdd so that function
                    758:          * has an opportunity to set the Invalid flag.
                    759:          */
                    760:         return float64_default_nan;
                    761:     }
                    762: 
                    763:     switch (which) {
                    764:     case 0:
                    765:         return float64_maybe_silence_nan(a);
                    766:     case 1:
                    767:         return float64_maybe_silence_nan(b);
                    768:     case 2:
                    769:         return float64_maybe_silence_nan(c);
                    770:     case 3:
                    771:     default:
                    772:         return float64_default_nan;
                    773:     }
                    774: }
                    775: 
                    776: /*----------------------------------------------------------------------------
1.1       root      777: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.7   root      778: | quiet NaN; otherwise returns 0. This slightly differs from the same
                    779: | function for other types as floatx80 has an explicit bit.
1.1       root      780: *----------------------------------------------------------------------------*/
                    781: 
1.1.1.7   root      782: int floatx80_is_quiet_nan( floatx80 a )
1.1       root      783: {
1.1.1.3   root      784: #if SNAN_BIT_IS_ONE
1.1.1.8   root      785:     uint64_t aLow;
1.1       root      786: 
1.1.1.3   root      787:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    788:     return
                    789:            ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8   root      790:         && (uint64_t) ( aLow<<1 )
1.1.1.3   root      791:         && ( a.low == aLow );
                    792: #else
1.1.1.7   root      793:     return ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8   root      794:         && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
1.1.1.3   root      795: #endif
1.1       root      796: }
                    797: 
                    798: /*----------------------------------------------------------------------------
                    799: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.7   root      800: | signaling NaN; otherwise returns 0. This slightly differs from the same
                    801: | function for other types as floatx80 has an explicit bit.
1.1       root      802: *----------------------------------------------------------------------------*/
                    803: 
1.1.1.2   root      804: int floatx80_is_signaling_nan( floatx80 a )
1.1       root      805: {
1.1.1.3   root      806: #if SNAN_BIT_IS_ONE
1.1.1.7   root      807:     return ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8   root      808:         && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
1.1.1.3   root      809: #else
1.1.1.8   root      810:     uint64_t aLow;
1.1       root      811: 
                    812:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    813:     return
                    814:            ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8   root      815:         && (uint64_t) ( aLow<<1 )
1.1       root      816:         && ( a.low == aLow );
1.1.1.3   root      817: #endif
1.1       root      818: }
                    819: 
                    820: /*----------------------------------------------------------------------------
1.1.1.7   root      821: | Returns a quiet NaN if the extended double-precision floating point value
                    822: | `a' is a signaling NaN; otherwise returns `a'.
                    823: *----------------------------------------------------------------------------*/
                    824: 
                    825: floatx80 floatx80_maybe_silence_nan( floatx80 a )
                    826: {
                    827:     if (floatx80_is_signaling_nan(a)) {
                    828: #if SNAN_BIT_IS_ONE
1.1.1.8   root      829: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      830:         a.low = floatx80_default_nan_low;
                    831:         a.high = floatx80_default_nan_high;
                    832: #  else
                    833: #    error Rules for silencing a signaling NaN are target-specific
                    834: #  endif
                    835: #else
                    836:         a.low |= LIT64( 0xC000000000000000 );
                    837:         return a;
                    838: #endif
                    839:     }
                    840:     return a;
                    841: }
                    842: 
                    843: /*----------------------------------------------------------------------------
1.1       root      844: | Returns the result of converting the extended double-precision floating-
                    845: | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
                    846: | invalid exception is raised.
                    847: *----------------------------------------------------------------------------*/
                    848: 
                    849: static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
                    850: {
                    851:     commonNaNT z;
                    852: 
                    853:     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.8   root      854:     if ( a.low >> 63 ) {
                    855:         z.sign = a.high >> 15;
                    856:         z.low = 0;
                    857:         z.high = a.low << 1;
                    858:     } else {
                    859:         z.sign = floatx80_default_nan_high >> 15;
                    860:         z.low = 0;
                    861:         z.high = floatx80_default_nan_low << 1;
                    862:     }
1.1       root      863:     return z;
                    864: }
                    865: 
                    866: /*----------------------------------------------------------------------------
                    867: | Returns the result of converting the canonical NaN `a' to the extended
                    868: | double-precision floating-point format.
                    869: *----------------------------------------------------------------------------*/
                    870: 
1.1.1.8   root      871: static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
1.1       root      872: {
                    873:     floatx80 z;
                    874: 
1.1.1.8   root      875:     if ( STATUS(default_nan_mode) ) {
1.1.1.3   root      876:         z.low = floatx80_default_nan_low;
1.1.1.8   root      877:         z.high = floatx80_default_nan_high;
                    878:         return z;
                    879:     }
                    880: 
                    881:     if (a.high >> 1) {
                    882:         z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
                    883:         z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
                    884:     } else {
                    885:         z.low = floatx80_default_nan_low;
                    886:         z.high = floatx80_default_nan_high;
                    887:     }
                    888: 
1.1       root      889:     return z;
                    890: }
                    891: 
                    892: /*----------------------------------------------------------------------------
                    893: | Takes two extended double-precision floating-point values `a' and `b', one
                    894: | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    895: | `b' is a signaling NaN, the invalid exception is raised.
                    896: *----------------------------------------------------------------------------*/
                    897: 
                    898: static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
                    899: {
1.1.1.7   root      900:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    901:     flag aIsLargerSignificand;
                    902: 
                    903:     aIsQuietNaN = floatx80_is_quiet_nan( a );
                    904:     aIsSignalingNaN = floatx80_is_signaling_nan( a );
                    905:     bIsQuietNaN = floatx80_is_quiet_nan( b );
                    906:     bIsSignalingNaN = floatx80_is_signaling_nan( b );
                    907: 
                    908:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1       root      909: 
1.1.1.4   root      910:     if ( STATUS(default_nan_mode) ) {
                    911:         a.low = floatx80_default_nan_low;
                    912:         a.high = floatx80_default_nan_high;
                    913:         return a;
                    914:     }
                    915: 
1.1.1.7   root      916:     if (a.low < b.low) {
                    917:         aIsLargerSignificand = 0;
                    918:     } else if (b.low < a.low) {
                    919:         aIsLargerSignificand = 1;
                    920:     } else {
                    921:         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1.1       root      922:     }
1.1.1.7   root      923: 
                    924:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    925:                 aIsLargerSignificand)) {
                    926:         return floatx80_maybe_silence_nan(b);
                    927:     } else {
                    928:         return floatx80_maybe_silence_nan(a);
1.1       root      929:     }
                    930: }
                    931: 
                    932: /*----------------------------------------------------------------------------
1.1.1.3   root      933: | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
                    934: | NaN; otherwise returns 0.
1.1       root      935: *----------------------------------------------------------------------------*/
                    936: 
1.1.1.7   root      937: int float128_is_quiet_nan( float128 a )
1.1       root      938: {
1.1.1.3   root      939: #if SNAN_BIT_IS_ONE
                    940:     return
                    941:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    942:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
                    943: #else
1.1       root      944:     return
1.1.1.8   root      945:            ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
1.1       root      946:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
1.1.1.3   root      947: #endif
1.1       root      948: }
                    949: 
                    950: /*----------------------------------------------------------------------------
                    951: | Returns 1 if the quadruple-precision floating-point value `a' is a
                    952: | signaling NaN; otherwise returns 0.
                    953: *----------------------------------------------------------------------------*/
                    954: 
1.1.1.2   root      955: int float128_is_signaling_nan( float128 a )
1.1       root      956: {
1.1.1.3   root      957: #if SNAN_BIT_IS_ONE
                    958:     return
1.1.1.8   root      959:            ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
1.1.1.3   root      960:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
                    961: #else
1.1       root      962:     return
                    963:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    964:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
1.1.1.3   root      965: #endif
1.1       root      966: }
                    967: 
                    968: /*----------------------------------------------------------------------------
1.1.1.7   root      969: | Returns a quiet NaN if the quadruple-precision floating point value `a' is
                    970: | a signaling NaN; otherwise returns `a'.
                    971: *----------------------------------------------------------------------------*/
                    972: 
                    973: float128 float128_maybe_silence_nan( float128 a )
                    974: {
                    975:     if (float128_is_signaling_nan(a)) {
                    976: #if SNAN_BIT_IS_ONE
1.1.1.8   root      977: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      978:         a.low = float128_default_nan_low;
                    979:         a.high = float128_default_nan_high;
                    980: #  else
                    981: #    error Rules for silencing a signaling NaN are target-specific
                    982: #  endif
                    983: #else
                    984:         a.high |= LIT64( 0x0000800000000000 );
                    985:         return a;
                    986: #endif
                    987:     }
                    988:     return a;
                    989: }
                    990: 
                    991: /*----------------------------------------------------------------------------
1.1       root      992: | Returns the result of converting the quadruple-precision floating-point NaN
                    993: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    994: | exception is raised.
                    995: *----------------------------------------------------------------------------*/
                    996: 
                    997: static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
                    998: {
                    999:     commonNaNT z;
                   1000: 
                   1001:     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
                   1002:     z.sign = a.high>>63;
                   1003:     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
                   1004:     return z;
                   1005: }
                   1006: 
                   1007: /*----------------------------------------------------------------------------
                   1008: | Returns the result of converting the canonical NaN `a' to the quadruple-
                   1009: | precision floating-point format.
                   1010: *----------------------------------------------------------------------------*/
                   1011: 
1.1.1.8   root     1012: static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
1.1       root     1013: {
                   1014:     float128 z;
                   1015: 
1.1.1.8   root     1016:     if ( STATUS(default_nan_mode) ) {
                   1017:         z.low = float128_default_nan_low;
                   1018:         z.high = float128_default_nan_high;
                   1019:         return z;
                   1020:     }
                   1021: 
1.1       root     1022:     shift128Right( a.high, a.low, 16, &z.high, &z.low );
1.1.1.8   root     1023:     z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
1.1       root     1024:     return z;
                   1025: }
                   1026: 
                   1027: /*----------------------------------------------------------------------------
                   1028: | Takes two quadruple-precision floating-point values `a' and `b', one of
                   1029: | which is a NaN, and returns the appropriate NaN result.  If either `a' or
                   1030: | `b' is a signaling NaN, the invalid exception is raised.
                   1031: *----------------------------------------------------------------------------*/
                   1032: 
                   1033: static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
                   1034: {
1.1.1.7   root     1035:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                   1036:     flag aIsLargerSignificand;
                   1037: 
                   1038:     aIsQuietNaN = float128_is_quiet_nan( a );
                   1039:     aIsSignalingNaN = float128_is_signaling_nan( a );
                   1040:     bIsQuietNaN = float128_is_quiet_nan( b );
                   1041:     bIsSignalingNaN = float128_is_signaling_nan( b );
                   1042: 
                   1043:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1       root     1044: 
1.1.1.4   root     1045:     if ( STATUS(default_nan_mode) ) {
                   1046:         a.low = float128_default_nan_low;
                   1047:         a.high = float128_default_nan_high;
                   1048:         return a;
                   1049:     }
                   1050: 
1.1.1.7   root     1051:     if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
                   1052:         aIsLargerSignificand = 0;
                   1053:     } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
                   1054:         aIsLargerSignificand = 1;
                   1055:     } else {
                   1056:         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1.1       root     1057:     }
1.1.1.7   root     1058: 
                   1059:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                   1060:                 aIsLargerSignificand)) {
                   1061:         return float128_maybe_silence_nan(b);
                   1062:     } else {
                   1063:         return float128_maybe_silence_nan(a);
1.1       root     1064:     }
                   1065: }
                   1066: 

unix.superglobalmegacorp.com

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