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

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: 
                     38: /*----------------------------------------------------------------------------
                     39: | Raises the exceptions specified by `flags'.  Floating-point traps can be
                     40: | defined here if desired.  It is currently not possible for such a trap
                     41: | to substitute a result value.  If traps are not implemented, this routine
                     42: | should be simply `float_exception_flags |= flags;'.
                     43: *----------------------------------------------------------------------------*/
                     44: 
                     45: void float_raise( int8 flags STATUS_PARAM )
                     46: {
                     47:     STATUS(float_exception_flags) |= flags;
                     48: }
                     49: 
                     50: /*----------------------------------------------------------------------------
                     51: | Internal canonical NaN format.
                     52: *----------------------------------------------------------------------------*/
                     53: typedef struct {
                     54:     flag sign;
1.1.1.8 ! root       55:     uint64_t high, low;
1.1       root       56: } commonNaNT;
                     57: 
                     58: /*----------------------------------------------------------------------------
1.1.1.8 ! root       59: | Returns 1 if the half-precision floating-point value `a' is a quiet
        !            60: | NaN; otherwise returns 0.
1.1       root       61: *----------------------------------------------------------------------------*/
1.1.1.8 ! root       62: 
        !            63: int float16_is_quiet_nan(float16 a_)
        !            64: {
        !            65:     uint16_t a = float16_val(a_);
        !            66: #if SNAN_BIT_IS_ONE
        !            67:     return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
        !            68: #else
        !            69:     return ((a & ~0x8000) >= 0x7c80);
        !            70: #endif
        !            71: }
        !            72: 
        !            73: /*----------------------------------------------------------------------------
        !            74: | Returns 1 if the half-precision floating-point value `a' is a signaling
        !            75: | NaN; otherwise returns 0.
        !            76: *----------------------------------------------------------------------------*/
        !            77: 
        !            78: int float16_is_signaling_nan(float16 a_)
        !            79: {
        !            80:     uint16_t a = float16_val(a_);
        !            81: #if SNAN_BIT_IS_ONE
        !            82:     return ((a & ~0x8000) >= 0x7c80);
        !            83: #else
        !            84:     return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
        !            85: #endif
        !            86: }
        !            87: 
        !            88: /*----------------------------------------------------------------------------
        !            89: | Returns a quiet NaN if the half-precision floating point value `a' is a
        !            90: | signaling NaN; otherwise returns `a'.
        !            91: *----------------------------------------------------------------------------*/
        !            92: float16 float16_maybe_silence_nan(float16 a_)
        !            93: {
        !            94:     if (float16_is_signaling_nan(a_)) {
        !            95: #if SNAN_BIT_IS_ONE
        !            96: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
        !            97:         return float16_default_nan;
        !            98: #  else
        !            99: #    error Rules for silencing a signaling NaN are target-specific
        !           100: #  endif
1.1.1.3   root      101: #else
1.1.1.8 ! root      102:         uint16_t a = float16_val(a_);
        !           103:         a |= (1 << 9);
        !           104:         return make_float16(a);
1.1.1.3   root      105: #endif
1.1.1.8 ! root      106:     }
        !           107:     return a_;
        !           108: }
        !           109: 
        !           110: /*----------------------------------------------------------------------------
        !           111: | Returns the result of converting the half-precision floating-point NaN
        !           112: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
        !           113: | exception is raised.
        !           114: *----------------------------------------------------------------------------*/
        !           115: 
        !           116: static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
        !           117: {
        !           118:     commonNaNT z;
        !           119: 
        !           120:     if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
        !           121:     z.sign = float16_val(a) >> 15;
        !           122:     z.low = 0;
        !           123:     z.high = ((uint64_t) float16_val(a))<<54;
        !           124:     return z;
        !           125: }
        !           126: 
        !           127: /*----------------------------------------------------------------------------
        !           128: | Returns the result of converting the canonical NaN `a' to the half-
        !           129: | precision floating-point format.
        !           130: *----------------------------------------------------------------------------*/
        !           131: 
        !           132: static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
        !           133: {
        !           134:     uint16_t mantissa = a.high>>54;
        !           135: 
        !           136:     if (STATUS(default_nan_mode)) {
        !           137:         return float16_default_nan;
        !           138:     }
        !           139: 
        !           140:     if (mantissa) {
        !           141:         return make_float16(((((uint16_t) a.sign) << 15)
        !           142:                              | (0x1F << 10) | mantissa));
        !           143:     } else {
        !           144:         return float16_default_nan;
        !           145:     }
        !           146: }
1.1       root      147: 
                    148: /*----------------------------------------------------------------------------
1.1.1.3   root      149: | Returns 1 if the single-precision floating-point value `a' is a quiet
                    150: | NaN; otherwise returns 0.
1.1       root      151: *----------------------------------------------------------------------------*/
                    152: 
1.1.1.7   root      153: int float32_is_quiet_nan( float32 a_ )
1.1       root      154: {
1.1.1.3   root      155:     uint32_t a = float32_val(a_);
                    156: #if SNAN_BIT_IS_ONE
                    157:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
                    158: #else
1.1.1.8 ! root      159:     return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
1.1.1.3   root      160: #endif
1.1       root      161: }
                    162: 
                    163: /*----------------------------------------------------------------------------
                    164: | Returns 1 if the single-precision floating-point value `a' is a signaling
                    165: | NaN; otherwise returns 0.
                    166: *----------------------------------------------------------------------------*/
                    167: 
1.1.1.3   root      168: int float32_is_signaling_nan( float32 a_ )
1.1       root      169: {
1.1.1.3   root      170:     uint32_t a = float32_val(a_);
                    171: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      172:     return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
1.1.1.3   root      173: #else
1.1       root      174:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
1.1.1.3   root      175: #endif
1.1       root      176: }
                    177: 
                    178: /*----------------------------------------------------------------------------
1.1.1.7   root      179: | Returns a quiet NaN if the single-precision floating point value `a' is a
                    180: | signaling NaN; otherwise returns `a'.
                    181: *----------------------------------------------------------------------------*/
                    182: 
                    183: float32 float32_maybe_silence_nan( float32 a_ )
                    184: {
                    185:     if (float32_is_signaling_nan(a_)) {
                    186: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      187: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      188:         return float32_default_nan;
                    189: #  else
                    190: #    error Rules for silencing a signaling NaN are target-specific
                    191: #  endif
                    192: #else
1.1.1.8 ! root      193:         uint32_t a = float32_val(a_);
1.1.1.7   root      194:         a |= (1 << 22);
                    195:         return make_float32(a);
                    196: #endif
                    197:     }
                    198:     return a_;
                    199: }
                    200: 
                    201: /*----------------------------------------------------------------------------
1.1       root      202: | Returns the result of converting the single-precision floating-point NaN
                    203: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    204: | exception is raised.
                    205: *----------------------------------------------------------------------------*/
                    206: 
                    207: static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
                    208: {
                    209:     commonNaNT z;
                    210: 
                    211:     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
1.1.1.3   root      212:     z.sign = float32_val(a)>>31;
1.1       root      213:     z.low = 0;
1.1.1.8 ! root      214:     z.high = ( (uint64_t) float32_val(a) )<<41;
1.1       root      215:     return z;
                    216: }
                    217: 
                    218: /*----------------------------------------------------------------------------
                    219: | Returns the result of converting the canonical NaN `a' to the single-
                    220: | precision floating-point format.
                    221: *----------------------------------------------------------------------------*/
                    222: 
1.1.1.8 ! root      223: static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
1.1       root      224: {
1.1.1.8 ! root      225:     uint32_t mantissa = a.high>>41;
        !           226: 
        !           227:     if ( STATUS(default_nan_mode) ) {
        !           228:         return float32_default_nan;
        !           229:     }
        !           230: 
1.1.1.3   root      231:     if ( mantissa )
                    232:         return make_float32(
1.1.1.8 ! root      233:             ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
1.1.1.3   root      234:     else
                    235:         return float32_default_nan;
1.1       root      236: }
                    237: 
                    238: /*----------------------------------------------------------------------------
1.1.1.7   root      239: | Select which NaN to propagate for a two-input operation.
                    240: | IEEE754 doesn't specify all the details of this, so the
                    241: | algorithm is target-specific.
                    242: | The routine is passed various bits of information about the
                    243: | two NaNs and should return 0 to select NaN a and 1 for NaN b.
                    244: | Note that signalling NaNs are always squashed to quiet NaNs
                    245: | by the caller, by calling floatXX_maybe_silence_nan() before
                    246: | returning them.
                    247: |
                    248: | aIsLargerSignificand is only valid if both a and b are NaNs
                    249: | of some kind, and is true if a has the larger significand,
                    250: | or if both a and b have the same significand but a is
                    251: | positive but b is negative. It is only needed for the x87
                    252: | tie-break rule.
                    253: *----------------------------------------------------------------------------*/
                    254: 
                    255: #if defined(TARGET_ARM)
                    256: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    257:                     flag aIsLargerSignificand)
                    258: {
                    259:     /* ARM mandated NaN propagation rules: take the first of:
                    260:      *  1. A if it is signaling
                    261:      *  2. B if it is signaling
                    262:      *  3. A (quiet)
                    263:      *  4. B (quiet)
                    264:      * A signaling NaN is always quietened before returning it.
                    265:      */
                    266:     if (aIsSNaN) {
                    267:         return 0;
                    268:     } else if (bIsSNaN) {
                    269:         return 1;
                    270:     } else if (aIsQNaN) {
                    271:         return 0;
                    272:     } else {
                    273:         return 1;
                    274:     }
                    275: }
                    276: #elif defined(TARGET_MIPS)
                    277: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    278:                     flag aIsLargerSignificand)
                    279: {
                    280:     /* According to MIPS specifications, if one of the two operands is
                    281:      * a sNaN, a new qNaN has to be generated. This is done in
                    282:      * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
                    283:      * says: "When possible, this QNaN result is one of the operand QNaN
                    284:      * values." In practice it seems that most implementations choose
                    285:      * the first operand if both operands are qNaN. In short this gives
                    286:      * the following rules:
                    287:      *  1. A if it is signaling
                    288:      *  2. B if it is signaling
                    289:      *  3. A (quiet)
                    290:      *  4. B (quiet)
                    291:      * A signaling NaN is always silenced before returning it.
                    292:      */
                    293:     if (aIsSNaN) {
                    294:         return 0;
                    295:     } else if (bIsSNaN) {
                    296:         return 1;
                    297:     } else if (aIsQNaN) {
                    298:         return 0;
                    299:     } else {
                    300:         return 1;
                    301:     }
                    302: }
                    303: #elif defined(TARGET_PPC)
                    304: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    305:                    flag aIsLargerSignificand)
                    306: {
                    307:     /* PowerPC propagation rules:
                    308:      *  1. A if it sNaN or qNaN
                    309:      *  2. B if it sNaN or qNaN
                    310:      * A signaling NaN is always silenced before returning it.
                    311:      */
                    312:     if (aIsSNaN || aIsQNaN) {
                    313:         return 0;
                    314:     } else {
                    315:         return 1;
                    316:     }
                    317: }
                    318: #else
                    319: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    320:                     flag aIsLargerSignificand)
                    321: {
                    322:     /* This implements x87 NaN propagation rules:
                    323:      * SNaN + QNaN => return the QNaN
                    324:      * two SNaNs => return the one with the larger significand, silenced
                    325:      * two QNaNs => return the one with the larger significand
                    326:      * SNaN and a non-NaN => return the SNaN, silenced
                    327:      * QNaN and a non-NaN => return the QNaN
                    328:      *
                    329:      * If we get down to comparing significands and they are the same,
                    330:      * return the NaN with the positive sign bit (if any).
                    331:      */
                    332:     if (aIsSNaN) {
                    333:         if (bIsSNaN) {
                    334:             return aIsLargerSignificand ? 0 : 1;
                    335:         }
                    336:         return bIsQNaN ? 1 : 0;
                    337:     }
                    338:     else if (aIsQNaN) {
                    339:         if (bIsSNaN || !bIsQNaN)
                    340:             return 0;
                    341:         else {
                    342:             return aIsLargerSignificand ? 0 : 1;
                    343:         }
                    344:     } else {
                    345:         return 1;
                    346:     }
                    347: }
                    348: #endif
                    349: 
                    350: /*----------------------------------------------------------------------------
1.1       root      351: | Takes two single-precision floating-point values `a' and `b', one of which
                    352: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    353: | signaling NaN, the invalid exception is raised.
                    354: *----------------------------------------------------------------------------*/
                    355: 
                    356: static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
                    357: {
1.1.1.7   root      358:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    359:     flag aIsLargerSignificand;
1.1.1.8 ! root      360:     uint32_t av, bv;
1.1.1.4   root      361: 
1.1.1.7   root      362:     aIsQuietNaN = float32_is_quiet_nan( a );
1.1       root      363:     aIsSignalingNaN = float32_is_signaling_nan( a );
1.1.1.7   root      364:     bIsQuietNaN = float32_is_quiet_nan( b );
1.1       root      365:     bIsSignalingNaN = float32_is_signaling_nan( b );
1.1.1.3   root      366:     av = float32_val(a);
                    367:     bv = float32_val(b);
1.1.1.7   root      368: 
1.1       root      369:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.7   root      370: 
                    371:     if ( STATUS(default_nan_mode) )
                    372:         return float32_default_nan;
                    373: 
1.1.1.8 ! root      374:     if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
1.1.1.7   root      375:         aIsLargerSignificand = 0;
1.1.1.8 ! root      376:     } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
1.1.1.7   root      377:         aIsLargerSignificand = 1;
                    378:     } else {
                    379:         aIsLargerSignificand = (av < bv) ? 1 : 0;
1.1       root      380:     }
1.1.1.7   root      381: 
                    382:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    383:                 aIsLargerSignificand)) {
                    384:         return float32_maybe_silence_nan(b);
                    385:     } else {
                    386:         return float32_maybe_silence_nan(a);
1.1       root      387:     }
                    388: }
                    389: 
                    390: /*----------------------------------------------------------------------------
1.1.1.3   root      391: | Returns 1 if the double-precision floating-point value `a' is a quiet
                    392: | NaN; otherwise returns 0.
1.1       root      393: *----------------------------------------------------------------------------*/
                    394: 
1.1.1.7   root      395: int float64_is_quiet_nan( float64 a_ )
1.1       root      396: {
1.1.1.8 ! root      397:     uint64_t a = float64_val(a_);
1.1.1.3   root      398: #if SNAN_BIT_IS_ONE
                    399:     return
                    400:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    401:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    402: #else
1.1.1.8 ! root      403:     return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
1.1.1.3   root      404: #endif
1.1       root      405: }
                    406: 
                    407: /*----------------------------------------------------------------------------
                    408: | Returns 1 if the double-precision floating-point value `a' is a signaling
                    409: | NaN; otherwise returns 0.
                    410: *----------------------------------------------------------------------------*/
                    411: 
1.1.1.3   root      412: int float64_is_signaling_nan( float64 a_ )
1.1       root      413: {
1.1.1.8 ! root      414:     uint64_t a = float64_val(a_);
1.1.1.3   root      415: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      416:     return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
1.1.1.3   root      417: #else
1.1       root      418:     return
                    419:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    420:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
1.1.1.3   root      421: #endif
1.1       root      422: }
                    423: 
                    424: /*----------------------------------------------------------------------------
1.1.1.7   root      425: | Returns a quiet NaN if the double-precision floating point value `a' is a
                    426: | signaling NaN; otherwise returns `a'.
                    427: *----------------------------------------------------------------------------*/
                    428: 
                    429: float64 float64_maybe_silence_nan( float64 a_ )
                    430: {
                    431:     if (float64_is_signaling_nan(a_)) {
                    432: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      433: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      434:         return float64_default_nan;
                    435: #  else
                    436: #    error Rules for silencing a signaling NaN are target-specific
                    437: #  endif
                    438: #else
1.1.1.8 ! root      439:         uint64_t a = float64_val(a_);
1.1.1.7   root      440:         a |= LIT64( 0x0008000000000000 );
                    441:         return make_float64(a);
                    442: #endif
                    443:     }
                    444:     return a_;
                    445: }
                    446: 
                    447: /*----------------------------------------------------------------------------
1.1       root      448: | Returns the result of converting the double-precision floating-point NaN
                    449: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    450: | exception is raised.
                    451: *----------------------------------------------------------------------------*/
                    452: 
                    453: static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
                    454: {
                    455:     commonNaNT z;
                    456: 
                    457:     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.3   root      458:     z.sign = float64_val(a)>>63;
1.1       root      459:     z.low = 0;
1.1.1.3   root      460:     z.high = float64_val(a)<<12;
1.1       root      461:     return z;
                    462: }
                    463: 
                    464: /*----------------------------------------------------------------------------
                    465: | Returns the result of converting the canonical NaN `a' to the double-
                    466: | precision floating-point format.
                    467: *----------------------------------------------------------------------------*/
                    468: 
1.1.1.8 ! root      469: static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
1.1       root      470: {
1.1.1.8 ! root      471:     uint64_t mantissa = a.high>>12;
        !           472: 
        !           473:     if ( STATUS(default_nan_mode) ) {
        !           474:         return float64_default_nan;
        !           475:     }
1.1       root      476: 
1.1.1.3   root      477:     if ( mantissa )
                    478:         return make_float64(
1.1.1.8 ! root      479:               ( ( (uint64_t) a.sign )<<63 )
1.1.1.3   root      480:             | LIT64( 0x7FF0000000000000 )
                    481:             | ( a.high>>12 ));
                    482:     else
                    483:         return float64_default_nan;
1.1       root      484: }
                    485: 
                    486: /*----------------------------------------------------------------------------
                    487: | Takes two double-precision floating-point values `a' and `b', one of which
                    488: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    489: | signaling NaN, the invalid exception is raised.
                    490: *----------------------------------------------------------------------------*/
                    491: 
                    492: static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
                    493: {
1.1.1.7   root      494:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    495:     flag aIsLargerSignificand;
1.1.1.8 ! root      496:     uint64_t av, bv;
1.1       root      497: 
1.1.1.7   root      498:     aIsQuietNaN = float64_is_quiet_nan( a );
1.1       root      499:     aIsSignalingNaN = float64_is_signaling_nan( a );
1.1.1.7   root      500:     bIsQuietNaN = float64_is_quiet_nan( b );
1.1       root      501:     bIsSignalingNaN = float64_is_signaling_nan( b );
1.1.1.3   root      502:     av = float64_val(a);
                    503:     bv = float64_val(b);
1.1.1.7   root      504: 
1.1       root      505:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.7   root      506: 
                    507:     if ( STATUS(default_nan_mode) )
                    508:         return float64_default_nan;
                    509: 
1.1.1.8 ! root      510:     if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
1.1.1.7   root      511:         aIsLargerSignificand = 0;
1.1.1.8 ! root      512:     } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
1.1.1.7   root      513:         aIsLargerSignificand = 1;
                    514:     } else {
                    515:         aIsLargerSignificand = (av < bv) ? 1 : 0;
1.1       root      516:     }
1.1.1.7   root      517: 
                    518:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    519:                 aIsLargerSignificand)) {
                    520:         return float64_maybe_silence_nan(b);
                    521:     } else {
                    522:         return float64_maybe_silence_nan(a);
1.1       root      523:     }
                    524: }
                    525: 
                    526: /*----------------------------------------------------------------------------
                    527: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.7   root      528: | quiet NaN; otherwise returns 0. This slightly differs from the same
                    529: | function for other types as floatx80 has an explicit bit.
1.1       root      530: *----------------------------------------------------------------------------*/
                    531: 
1.1.1.7   root      532: int floatx80_is_quiet_nan( floatx80 a )
1.1       root      533: {
1.1.1.3   root      534: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      535:     uint64_t aLow;
1.1       root      536: 
1.1.1.3   root      537:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    538:     return
                    539:            ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8 ! root      540:         && (uint64_t) ( aLow<<1 )
1.1.1.3   root      541:         && ( a.low == aLow );
                    542: #else
1.1.1.7   root      543:     return ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8 ! root      544:         && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
1.1.1.3   root      545: #endif
1.1       root      546: }
                    547: 
                    548: /*----------------------------------------------------------------------------
                    549: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.7   root      550: | signaling NaN; otherwise returns 0. This slightly differs from the same
                    551: | function for other types as floatx80 has an explicit bit.
1.1       root      552: *----------------------------------------------------------------------------*/
                    553: 
1.1.1.2   root      554: int floatx80_is_signaling_nan( floatx80 a )
1.1       root      555: {
1.1.1.3   root      556: #if SNAN_BIT_IS_ONE
1.1.1.7   root      557:     return ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8 ! root      558:         && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
1.1.1.3   root      559: #else
1.1.1.8 ! root      560:     uint64_t aLow;
1.1       root      561: 
                    562:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    563:     return
                    564:            ( ( a.high & 0x7FFF ) == 0x7FFF )
1.1.1.8 ! root      565:         && (uint64_t) ( aLow<<1 )
1.1       root      566:         && ( a.low == aLow );
1.1.1.3   root      567: #endif
1.1       root      568: }
                    569: 
                    570: /*----------------------------------------------------------------------------
1.1.1.7   root      571: | Returns a quiet NaN if the extended double-precision floating point value
                    572: | `a' is a signaling NaN; otherwise returns `a'.
                    573: *----------------------------------------------------------------------------*/
                    574: 
                    575: floatx80 floatx80_maybe_silence_nan( floatx80 a )
                    576: {
                    577:     if (floatx80_is_signaling_nan(a)) {
                    578: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      579: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      580:         a.low = floatx80_default_nan_low;
                    581:         a.high = floatx80_default_nan_high;
                    582: #  else
                    583: #    error Rules for silencing a signaling NaN are target-specific
                    584: #  endif
                    585: #else
                    586:         a.low |= LIT64( 0xC000000000000000 );
                    587:         return a;
                    588: #endif
                    589:     }
                    590:     return a;
                    591: }
                    592: 
                    593: /*----------------------------------------------------------------------------
1.1       root      594: | Returns the result of converting the extended double-precision floating-
                    595: | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
                    596: | invalid exception is raised.
                    597: *----------------------------------------------------------------------------*/
                    598: 
                    599: static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
                    600: {
                    601:     commonNaNT z;
                    602: 
                    603:     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.8 ! root      604:     if ( a.low >> 63 ) {
        !           605:         z.sign = a.high >> 15;
        !           606:         z.low = 0;
        !           607:         z.high = a.low << 1;
        !           608:     } else {
        !           609:         z.sign = floatx80_default_nan_high >> 15;
        !           610:         z.low = 0;
        !           611:         z.high = floatx80_default_nan_low << 1;
        !           612:     }
1.1       root      613:     return z;
                    614: }
                    615: 
                    616: /*----------------------------------------------------------------------------
                    617: | Returns the result of converting the canonical NaN `a' to the extended
                    618: | double-precision floating-point format.
                    619: *----------------------------------------------------------------------------*/
                    620: 
1.1.1.8 ! root      621: static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
1.1       root      622: {
                    623:     floatx80 z;
                    624: 
1.1.1.8 ! root      625:     if ( STATUS(default_nan_mode) ) {
1.1.1.3   root      626:         z.low = floatx80_default_nan_low;
1.1.1.8 ! root      627:         z.high = floatx80_default_nan_high;
        !           628:         return z;
        !           629:     }
        !           630: 
        !           631:     if (a.high >> 1) {
        !           632:         z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
        !           633:         z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
        !           634:     } else {
        !           635:         z.low = floatx80_default_nan_low;
        !           636:         z.high = floatx80_default_nan_high;
        !           637:     }
        !           638: 
1.1       root      639:     return z;
                    640: }
                    641: 
                    642: /*----------------------------------------------------------------------------
                    643: | Takes two extended double-precision floating-point values `a' and `b', one
                    644: | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    645: | `b' is a signaling NaN, the invalid exception is raised.
                    646: *----------------------------------------------------------------------------*/
                    647: 
                    648: static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
                    649: {
1.1.1.7   root      650:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    651:     flag aIsLargerSignificand;
                    652: 
                    653:     aIsQuietNaN = floatx80_is_quiet_nan( a );
                    654:     aIsSignalingNaN = floatx80_is_signaling_nan( a );
                    655:     bIsQuietNaN = floatx80_is_quiet_nan( b );
                    656:     bIsSignalingNaN = floatx80_is_signaling_nan( b );
                    657: 
                    658:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1       root      659: 
1.1.1.4   root      660:     if ( STATUS(default_nan_mode) ) {
                    661:         a.low = floatx80_default_nan_low;
                    662:         a.high = floatx80_default_nan_high;
                    663:         return a;
                    664:     }
                    665: 
1.1.1.7   root      666:     if (a.low < b.low) {
                    667:         aIsLargerSignificand = 0;
                    668:     } else if (b.low < a.low) {
                    669:         aIsLargerSignificand = 1;
                    670:     } else {
                    671:         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1.1       root      672:     }
1.1.1.7   root      673: 
                    674:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    675:                 aIsLargerSignificand)) {
                    676:         return floatx80_maybe_silence_nan(b);
                    677:     } else {
                    678:         return floatx80_maybe_silence_nan(a);
1.1       root      679:     }
                    680: }
                    681: 
                    682: /*----------------------------------------------------------------------------
1.1.1.3   root      683: | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
                    684: | NaN; otherwise returns 0.
1.1       root      685: *----------------------------------------------------------------------------*/
                    686: 
1.1.1.7   root      687: int float128_is_quiet_nan( float128 a )
1.1       root      688: {
1.1.1.3   root      689: #if SNAN_BIT_IS_ONE
                    690:     return
                    691:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    692:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
                    693: #else
1.1       root      694:     return
1.1.1.8 ! root      695:            ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
1.1       root      696:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
1.1.1.3   root      697: #endif
1.1       root      698: }
                    699: 
                    700: /*----------------------------------------------------------------------------
                    701: | Returns 1 if the quadruple-precision floating-point value `a' is a
                    702: | signaling NaN; otherwise returns 0.
                    703: *----------------------------------------------------------------------------*/
                    704: 
1.1.1.2   root      705: int float128_is_signaling_nan( float128 a )
1.1       root      706: {
1.1.1.3   root      707: #if SNAN_BIT_IS_ONE
                    708:     return
1.1.1.8 ! root      709:            ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
1.1.1.3   root      710:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
                    711: #else
1.1       root      712:     return
                    713:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    714:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
1.1.1.3   root      715: #endif
1.1       root      716: }
                    717: 
                    718: /*----------------------------------------------------------------------------
1.1.1.7   root      719: | Returns a quiet NaN if the quadruple-precision floating point value `a' is
                    720: | a signaling NaN; otherwise returns `a'.
                    721: *----------------------------------------------------------------------------*/
                    722: 
                    723: float128 float128_maybe_silence_nan( float128 a )
                    724: {
                    725:     if (float128_is_signaling_nan(a)) {
                    726: #if SNAN_BIT_IS_ONE
1.1.1.8 ! root      727: #  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
1.1.1.7   root      728:         a.low = float128_default_nan_low;
                    729:         a.high = float128_default_nan_high;
                    730: #  else
                    731: #    error Rules for silencing a signaling NaN are target-specific
                    732: #  endif
                    733: #else
                    734:         a.high |= LIT64( 0x0000800000000000 );
                    735:         return a;
                    736: #endif
                    737:     }
                    738:     return a;
                    739: }
                    740: 
                    741: /*----------------------------------------------------------------------------
1.1       root      742: | Returns the result of converting the quadruple-precision floating-point NaN
                    743: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    744: | exception is raised.
                    745: *----------------------------------------------------------------------------*/
                    746: 
                    747: static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
                    748: {
                    749:     commonNaNT z;
                    750: 
                    751:     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
                    752:     z.sign = a.high>>63;
                    753:     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
                    754:     return z;
                    755: }
                    756: 
                    757: /*----------------------------------------------------------------------------
                    758: | Returns the result of converting the canonical NaN `a' to the quadruple-
                    759: | precision floating-point format.
                    760: *----------------------------------------------------------------------------*/
                    761: 
1.1.1.8 ! root      762: static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
1.1       root      763: {
                    764:     float128 z;
                    765: 
1.1.1.8 ! root      766:     if ( STATUS(default_nan_mode) ) {
        !           767:         z.low = float128_default_nan_low;
        !           768:         z.high = float128_default_nan_high;
        !           769:         return z;
        !           770:     }
        !           771: 
1.1       root      772:     shift128Right( a.high, a.low, 16, &z.high, &z.low );
1.1.1.8 ! root      773:     z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
1.1       root      774:     return z;
                    775: }
                    776: 
                    777: /*----------------------------------------------------------------------------
                    778: | Takes two quadruple-precision floating-point values `a' and `b', one of
                    779: | which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    780: | `b' is a signaling NaN, the invalid exception is raised.
                    781: *----------------------------------------------------------------------------*/
                    782: 
                    783: static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
                    784: {
1.1.1.7   root      785:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
                    786:     flag aIsLargerSignificand;
                    787: 
                    788:     aIsQuietNaN = float128_is_quiet_nan( a );
                    789:     aIsSignalingNaN = float128_is_signaling_nan( a );
                    790:     bIsQuietNaN = float128_is_quiet_nan( b );
                    791:     bIsSignalingNaN = float128_is_signaling_nan( b );
                    792: 
                    793:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1       root      794: 
1.1.1.4   root      795:     if ( STATUS(default_nan_mode) ) {
                    796:         a.low = float128_default_nan_low;
                    797:         a.high = float128_default_nan_high;
                    798:         return a;
                    799:     }
                    800: 
1.1.1.7   root      801:     if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
                    802:         aIsLargerSignificand = 0;
                    803:     } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
                    804:         aIsLargerSignificand = 1;
                    805:     } else {
                    806:         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1.1       root      807:     }
1.1.1.7   root      808: 
                    809:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
                    810:                 aIsLargerSignificand)) {
                    811:         return float128_maybe_silence_nan(b);
                    812:     } else {
                    813:         return float128_maybe_silence_nan(a);
1.1       root      814:     }
                    815: }
                    816: 

unix.superglobalmegacorp.com

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