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

1.1       root        1: 
                      2: /*============================================================================
                      3: 
                      4: This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
                      5: Arithmetic Package, Release 2b.
                      6: 
                      7: Written by John R. Hauser.  This work was made possible in part by the
                      8: International Computer Science Institute, located at Suite 600, 1947 Center
                      9: Street, Berkeley, California 94704.  Funding was partially provided by the
                     10: National Science Foundation under grant MIP-9311980.  The original version
                     11: of this code was written as part of a project to build a fixed-point vector
                     12: processor in collaboration with the University of California at Berkeley,
                     13: overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
                     14: is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
                     15: arithmetic/SoftFloat.html'.
                     16: 
                     17: THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
                     18: been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
                     19: RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
                     20: AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
                     21: COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
                     22: EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
                     23: INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
                     24: OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
                     25: 
                     26: Derivative works are acceptable, even for commercial purposes, so long as
                     27: (1) the source code for the derivative work includes prominent notice that
                     28: the work is derivative, and (2) the source code includes prominent notice with
                     29: these four paragraphs for those parts of this code that are retained.
                     30: 
                     31: =============================================================================*/
                     32: 
1.1.1.7 ! root       33: #if defined(TARGET_MIPS) || defined(TARGET_SH4)
1.1.1.3   root       34: #define SNAN_BIT_IS_ONE                1
                     35: #else
                     36: #define SNAN_BIT_IS_ONE                0
                     37: #endif
                     38: 
1.1       root       39: /*----------------------------------------------------------------------------
                     40: | Raises the exceptions specified by `flags'.  Floating-point traps can be
                     41: | defined here if desired.  It is currently not possible for such a trap
                     42: | to substitute a result value.  If traps are not implemented, this routine
                     43: | should be simply `float_exception_flags |= flags;'.
                     44: *----------------------------------------------------------------------------*/
                     45: 
                     46: void float_raise( int8 flags STATUS_PARAM )
                     47: {
                     48:     STATUS(float_exception_flags) |= flags;
                     49: }
                     50: 
                     51: /*----------------------------------------------------------------------------
                     52: | Internal canonical NaN format.
                     53: *----------------------------------------------------------------------------*/
                     54: typedef struct {
                     55:     flag sign;
                     56:     bits64 high, low;
                     57: } commonNaNT;
                     58: 
                     59: /*----------------------------------------------------------------------------
                     60: | The pattern for a default generated single-precision NaN.
                     61: *----------------------------------------------------------------------------*/
1.1.1.3   root       62: #if defined(TARGET_SPARC)
                     63: #define float32_default_nan make_float32(0x7FFFFFFF)
1.1.1.7 ! root       64: #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
1.1.1.3   root       65: #define float32_default_nan make_float32(0x7FC00000)
                     66: #elif SNAN_BIT_IS_ONE
                     67: #define float32_default_nan make_float32(0x7FBFFFFF)
                     68: #else
                     69: #define float32_default_nan make_float32(0xFFC00000)
                     70: #endif
1.1       root       71: 
                     72: /*----------------------------------------------------------------------------
1.1.1.3   root       73: | Returns 1 if the single-precision floating-point value `a' is a quiet
                     74: | NaN; otherwise returns 0.
1.1       root       75: *----------------------------------------------------------------------------*/
                     76: 
1.1.1.7 ! root       77: int float32_is_quiet_nan( float32 a_ )
1.1       root       78: {
1.1.1.3   root       79:     uint32_t a = float32_val(a_);
                     80: #if SNAN_BIT_IS_ONE
                     81:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
                     82: #else
                     83:     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
                     84: #endif
1.1       root       85: }
                     86: 
                     87: /*----------------------------------------------------------------------------
                     88: | Returns 1 if the single-precision floating-point value `a' is a signaling
                     89: | NaN; otherwise returns 0.
                     90: *----------------------------------------------------------------------------*/
                     91: 
1.1.1.3   root       92: int float32_is_signaling_nan( float32 a_ )
1.1       root       93: {
1.1.1.3   root       94:     uint32_t a = float32_val(a_);
                     95: #if SNAN_BIT_IS_ONE
                     96:     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
                     97: #else
1.1       root       98:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
1.1.1.3   root       99: #endif
1.1       root      100: }
                    101: 
                    102: /*----------------------------------------------------------------------------
1.1.1.7 ! root      103: | Returns a quiet NaN if the single-precision floating point value `a' is a
        !           104: | signaling NaN; otherwise returns `a'.
        !           105: *----------------------------------------------------------------------------*/
        !           106: 
        !           107: float32 float32_maybe_silence_nan( float32 a_ )
        !           108: {
        !           109:     if (float32_is_signaling_nan(a_)) {
        !           110: #if SNAN_BIT_IS_ONE
        !           111: #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
        !           112:         return float32_default_nan;
        !           113: #  else
        !           114: #    error Rules for silencing a signaling NaN are target-specific
        !           115: #  endif
        !           116: #else
        !           117:         bits32 a = float32_val(a_);
        !           118:         a |= (1 << 22);
        !           119:         return make_float32(a);
        !           120: #endif
        !           121:     }
        !           122:     return a_;
        !           123: }
        !           124: 
        !           125: /*----------------------------------------------------------------------------
1.1       root      126: | Returns the result of converting the single-precision floating-point NaN
                    127: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    128: | exception is raised.
                    129: *----------------------------------------------------------------------------*/
                    130: 
                    131: static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
                    132: {
                    133:     commonNaNT z;
                    134: 
                    135:     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
1.1.1.3   root      136:     z.sign = float32_val(a)>>31;
1.1       root      137:     z.low = 0;
1.1.1.3   root      138:     z.high = ( (bits64) float32_val(a) )<<41;
1.1       root      139:     return z;
                    140: }
                    141: 
                    142: /*----------------------------------------------------------------------------
                    143: | Returns the result of converting the canonical NaN `a' to the single-
                    144: | precision floating-point format.
                    145: *----------------------------------------------------------------------------*/
                    146: 
                    147: static float32 commonNaNToFloat32( commonNaNT a )
                    148: {
1.1.1.3   root      149:     bits32 mantissa = a.high>>41;
                    150:     if ( mantissa )
                    151:         return make_float32(
                    152:             ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
                    153:     else
                    154:         return float32_default_nan;
1.1       root      155: }
                    156: 
                    157: /*----------------------------------------------------------------------------
1.1.1.7 ! root      158: | Select which NaN to propagate for a two-input operation.
        !           159: | IEEE754 doesn't specify all the details of this, so the
        !           160: | algorithm is target-specific.
        !           161: | The routine is passed various bits of information about the
        !           162: | two NaNs and should return 0 to select NaN a and 1 for NaN b.
        !           163: | Note that signalling NaNs are always squashed to quiet NaNs
        !           164: | by the caller, by calling floatXX_maybe_silence_nan() before
        !           165: | returning them.
        !           166: |
        !           167: | aIsLargerSignificand is only valid if both a and b are NaNs
        !           168: | of some kind, and is true if a has the larger significand,
        !           169: | or if both a and b have the same significand but a is
        !           170: | positive but b is negative. It is only needed for the x87
        !           171: | tie-break rule.
        !           172: *----------------------------------------------------------------------------*/
        !           173: 
        !           174: #if defined(TARGET_ARM)
        !           175: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
        !           176:                     flag aIsLargerSignificand)
        !           177: {
        !           178:     /* ARM mandated NaN propagation rules: take the first of:
        !           179:      *  1. A if it is signaling
        !           180:      *  2. B if it is signaling
        !           181:      *  3. A (quiet)
        !           182:      *  4. B (quiet)
        !           183:      * A signaling NaN is always quietened before returning it.
        !           184:      */
        !           185:     if (aIsSNaN) {
        !           186:         return 0;
        !           187:     } else if (bIsSNaN) {
        !           188:         return 1;
        !           189:     } else if (aIsQNaN) {
        !           190:         return 0;
        !           191:     } else {
        !           192:         return 1;
        !           193:     }
        !           194: }
        !           195: #elif defined(TARGET_MIPS)
        !           196: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
        !           197:                     flag aIsLargerSignificand)
        !           198: {
        !           199:     /* According to MIPS specifications, if one of the two operands is
        !           200:      * a sNaN, a new qNaN has to be generated. This is done in
        !           201:      * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
        !           202:      * says: "When possible, this QNaN result is one of the operand QNaN
        !           203:      * values." In practice it seems that most implementations choose
        !           204:      * the first operand if both operands are qNaN. In short this gives
        !           205:      * the following rules:
        !           206:      *  1. A if it is signaling
        !           207:      *  2. B if it is signaling
        !           208:      *  3. A (quiet)
        !           209:      *  4. B (quiet)
        !           210:      * A signaling NaN is always silenced before returning it.
        !           211:      */
        !           212:     if (aIsSNaN) {
        !           213:         return 0;
        !           214:     } else if (bIsSNaN) {
        !           215:         return 1;
        !           216:     } else if (aIsQNaN) {
        !           217:         return 0;
        !           218:     } else {
        !           219:         return 1;
        !           220:     }
        !           221: }
        !           222: #elif defined(TARGET_PPC)
        !           223: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
        !           224:                    flag aIsLargerSignificand)
        !           225: {
        !           226:     /* PowerPC propagation rules:
        !           227:      *  1. A if it sNaN or qNaN
        !           228:      *  2. B if it sNaN or qNaN
        !           229:      * A signaling NaN is always silenced before returning it.
        !           230:      */
        !           231:     if (aIsSNaN || aIsQNaN) {
        !           232:         return 0;
        !           233:     } else {
        !           234:         return 1;
        !           235:     }
        !           236: }
        !           237: #else
        !           238: static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
        !           239:                     flag aIsLargerSignificand)
        !           240: {
        !           241:     /* This implements x87 NaN propagation rules:
        !           242:      * SNaN + QNaN => return the QNaN
        !           243:      * two SNaNs => return the one with the larger significand, silenced
        !           244:      * two QNaNs => return the one with the larger significand
        !           245:      * SNaN and a non-NaN => return the SNaN, silenced
        !           246:      * QNaN and a non-NaN => return the QNaN
        !           247:      *
        !           248:      * If we get down to comparing significands and they are the same,
        !           249:      * return the NaN with the positive sign bit (if any).
        !           250:      */
        !           251:     if (aIsSNaN) {
        !           252:         if (bIsSNaN) {
        !           253:             return aIsLargerSignificand ? 0 : 1;
        !           254:         }
        !           255:         return bIsQNaN ? 1 : 0;
        !           256:     }
        !           257:     else if (aIsQNaN) {
        !           258:         if (bIsSNaN || !bIsQNaN)
        !           259:             return 0;
        !           260:         else {
        !           261:             return aIsLargerSignificand ? 0 : 1;
        !           262:         }
        !           263:     } else {
        !           264:         return 1;
        !           265:     }
        !           266: }
        !           267: #endif
        !           268: 
        !           269: /*----------------------------------------------------------------------------
1.1       root      270: | Takes two single-precision floating-point values `a' and `b', one of which
                    271: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    272: | signaling NaN, the invalid exception is raised.
                    273: *----------------------------------------------------------------------------*/
                    274: 
                    275: static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
                    276: {
1.1.1.7 ! root      277:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
        !           278:     flag aIsLargerSignificand;
        !           279:     bits32 av, bv;
1.1.1.4   root      280: 
1.1.1.7 ! root      281:     aIsQuietNaN = float32_is_quiet_nan( a );
1.1       root      282:     aIsSignalingNaN = float32_is_signaling_nan( a );
1.1.1.7 ! root      283:     bIsQuietNaN = float32_is_quiet_nan( b );
1.1       root      284:     bIsSignalingNaN = float32_is_signaling_nan( b );
1.1.1.3   root      285:     av = float32_val(a);
                    286:     bv = float32_val(b);
1.1.1.7 ! root      287: 
1.1       root      288:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.7 ! root      289: 
        !           290:     if ( STATUS(default_nan_mode) )
        !           291:         return float32_default_nan;
        !           292: 
        !           293:     if ((bits32)(av<<1) < (bits32)(bv<<1)) {
        !           294:         aIsLargerSignificand = 0;
        !           295:     } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
        !           296:         aIsLargerSignificand = 1;
        !           297:     } else {
        !           298:         aIsLargerSignificand = (av < bv) ? 1 : 0;
1.1       root      299:     }
1.1.1.7 ! root      300: 
        !           301:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
        !           302:                 aIsLargerSignificand)) {
        !           303:         return float32_maybe_silence_nan(b);
        !           304:     } else {
        !           305:         return float32_maybe_silence_nan(a);
1.1       root      306:     }
                    307: }
                    308: 
                    309: /*----------------------------------------------------------------------------
                    310: | The pattern for a default generated double-precision NaN.
                    311: *----------------------------------------------------------------------------*/
1.1.1.3   root      312: #if defined(TARGET_SPARC)
                    313: #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
1.1.1.7 ! root      314: #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
1.1.1.3   root      315: #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
                    316: #elif SNAN_BIT_IS_ONE
                    317: #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
                    318: #else
                    319: #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
                    320: #endif
1.1       root      321: 
                    322: /*----------------------------------------------------------------------------
1.1.1.3   root      323: | Returns 1 if the double-precision floating-point value `a' is a quiet
                    324: | NaN; otherwise returns 0.
1.1       root      325: *----------------------------------------------------------------------------*/
                    326: 
1.1.1.7 ! root      327: int float64_is_quiet_nan( float64 a_ )
1.1       root      328: {
1.1.1.3   root      329:     bits64 a = float64_val(a_);
                    330: #if SNAN_BIT_IS_ONE
                    331:     return
                    332:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    333:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
                    334: #else
                    335:     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
                    336: #endif
1.1       root      337: }
                    338: 
                    339: /*----------------------------------------------------------------------------
                    340: | Returns 1 if the double-precision floating-point value `a' is a signaling
                    341: | NaN; otherwise returns 0.
                    342: *----------------------------------------------------------------------------*/
                    343: 
1.1.1.3   root      344: int float64_is_signaling_nan( float64 a_ )
1.1       root      345: {
1.1.1.3   root      346:     bits64 a = float64_val(a_);
                    347: #if SNAN_BIT_IS_ONE
                    348:     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
                    349: #else
1.1       root      350:     return
                    351:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    352:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
1.1.1.3   root      353: #endif
1.1       root      354: }
                    355: 
                    356: /*----------------------------------------------------------------------------
1.1.1.7 ! root      357: | Returns a quiet NaN if the double-precision floating point value `a' is a
        !           358: | signaling NaN; otherwise returns `a'.
        !           359: *----------------------------------------------------------------------------*/
        !           360: 
        !           361: float64 float64_maybe_silence_nan( float64 a_ )
        !           362: {
        !           363:     if (float64_is_signaling_nan(a_)) {
        !           364: #if SNAN_BIT_IS_ONE
        !           365: #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
        !           366:         return float64_default_nan;
        !           367: #  else
        !           368: #    error Rules for silencing a signaling NaN are target-specific
        !           369: #  endif
        !           370: #else
        !           371:         bits64 a = float64_val(a_);
        !           372:         a |= LIT64( 0x0008000000000000 );
        !           373:         return make_float64(a);
        !           374: #endif
        !           375:     }
        !           376:     return a_;
        !           377: }
        !           378: 
        !           379: /*----------------------------------------------------------------------------
1.1       root      380: | Returns the result of converting the double-precision floating-point NaN
                    381: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    382: | exception is raised.
                    383: *----------------------------------------------------------------------------*/
                    384: 
                    385: static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
                    386: {
                    387:     commonNaNT z;
                    388: 
                    389:     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.3   root      390:     z.sign = float64_val(a)>>63;
1.1       root      391:     z.low = 0;
1.1.1.3   root      392:     z.high = float64_val(a)<<12;
1.1       root      393:     return z;
                    394: }
                    395: 
                    396: /*----------------------------------------------------------------------------
                    397: | Returns the result of converting the canonical NaN `a' to the double-
                    398: | precision floating-point format.
                    399: *----------------------------------------------------------------------------*/
                    400: 
                    401: static float64 commonNaNToFloat64( commonNaNT a )
                    402: {
1.1.1.3   root      403:     bits64 mantissa = a.high>>12;
1.1       root      404: 
1.1.1.3   root      405:     if ( mantissa )
                    406:         return make_float64(
                    407:               ( ( (bits64) a.sign )<<63 )
                    408:             | LIT64( 0x7FF0000000000000 )
                    409:             | ( a.high>>12 ));
                    410:     else
                    411:         return float64_default_nan;
1.1       root      412: }
                    413: 
                    414: /*----------------------------------------------------------------------------
                    415: | Takes two double-precision floating-point values `a' and `b', one of which
                    416: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    417: | signaling NaN, the invalid exception is raised.
                    418: *----------------------------------------------------------------------------*/
                    419: 
                    420: static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
                    421: {
1.1.1.7 ! root      422:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
        !           423:     flag aIsLargerSignificand;
        !           424:     bits64 av, bv;
1.1       root      425: 
1.1.1.7 ! root      426:     aIsQuietNaN = float64_is_quiet_nan( a );
1.1       root      427:     aIsSignalingNaN = float64_is_signaling_nan( a );
1.1.1.7 ! root      428:     bIsQuietNaN = float64_is_quiet_nan( b );
1.1       root      429:     bIsSignalingNaN = float64_is_signaling_nan( b );
1.1.1.3   root      430:     av = float64_val(a);
                    431:     bv = float64_val(b);
1.1.1.7 ! root      432: 
1.1       root      433:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.7 ! root      434: 
        !           435:     if ( STATUS(default_nan_mode) )
        !           436:         return float64_default_nan;
        !           437: 
        !           438:     if ((bits64)(av<<1) < (bits64)(bv<<1)) {
        !           439:         aIsLargerSignificand = 0;
        !           440:     } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
        !           441:         aIsLargerSignificand = 1;
        !           442:     } else {
        !           443:         aIsLargerSignificand = (av < bv) ? 1 : 0;
1.1       root      444:     }
1.1.1.7 ! root      445: 
        !           446:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
        !           447:                 aIsLargerSignificand)) {
        !           448:         return float64_maybe_silence_nan(b);
        !           449:     } else {
        !           450:         return float64_maybe_silence_nan(a);
1.1       root      451:     }
                    452: }
                    453: 
                    454: #ifdef FLOATX80
                    455: 
                    456: /*----------------------------------------------------------------------------
                    457: | The pattern for a default generated extended double-precision NaN.  The
                    458: | `high' and `low' values hold the most- and least-significant bits,
                    459: | respectively.
                    460: *----------------------------------------------------------------------------*/
1.1.1.3   root      461: #if SNAN_BIT_IS_ONE
                    462: #define floatx80_default_nan_high 0x7FFF
                    463: #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
                    464: #else
1.1       root      465: #define floatx80_default_nan_high 0xFFFF
                    466: #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
1.1.1.3   root      467: #endif
1.1       root      468: 
                    469: /*----------------------------------------------------------------------------
                    470: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.7 ! root      471: | quiet NaN; otherwise returns 0. This slightly differs from the same
        !           472: | function for other types as floatx80 has an explicit bit.
1.1       root      473: *----------------------------------------------------------------------------*/
                    474: 
1.1.1.7 ! root      475: int floatx80_is_quiet_nan( floatx80 a )
1.1       root      476: {
1.1.1.3   root      477: #if SNAN_BIT_IS_ONE
                    478:     bits64 aLow;
1.1       root      479: 
1.1.1.3   root      480:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    481:     return
                    482:            ( ( a.high & 0x7FFF ) == 0x7FFF )
                    483:         && (bits64) ( aLow<<1 )
                    484:         && ( a.low == aLow );
                    485: #else
1.1.1.7 ! root      486:     return ( ( a.high & 0x7FFF ) == 0x7FFF )
        !           487:         && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
1.1.1.3   root      488: #endif
1.1       root      489: }
                    490: 
                    491: /*----------------------------------------------------------------------------
                    492: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.7 ! root      493: | signaling NaN; otherwise returns 0. This slightly differs from the same
        !           494: | function for other types as floatx80 has an explicit bit.
1.1       root      495: *----------------------------------------------------------------------------*/
                    496: 
1.1.1.2   root      497: int floatx80_is_signaling_nan( floatx80 a )
1.1       root      498: {
1.1.1.3   root      499: #if SNAN_BIT_IS_ONE
1.1.1.7 ! root      500:     return ( ( a.high & 0x7FFF ) == 0x7FFF )
        !           501:         && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
1.1.1.3   root      502: #else
1.1       root      503:     bits64 aLow;
                    504: 
                    505:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    506:     return
                    507:            ( ( a.high & 0x7FFF ) == 0x7FFF )
                    508:         && (bits64) ( aLow<<1 )
                    509:         && ( a.low == aLow );
1.1.1.3   root      510: #endif
1.1       root      511: }
                    512: 
                    513: /*----------------------------------------------------------------------------
1.1.1.7 ! root      514: | Returns a quiet NaN if the extended double-precision floating point value
        !           515: | `a' is a signaling NaN; otherwise returns `a'.
        !           516: *----------------------------------------------------------------------------*/
        !           517: 
        !           518: floatx80 floatx80_maybe_silence_nan( floatx80 a )
        !           519: {
        !           520:     if (floatx80_is_signaling_nan(a)) {
        !           521: #if SNAN_BIT_IS_ONE
        !           522: #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
        !           523:         a.low = floatx80_default_nan_low;
        !           524:         a.high = floatx80_default_nan_high;
        !           525: #  else
        !           526: #    error Rules for silencing a signaling NaN are target-specific
        !           527: #  endif
        !           528: #else
        !           529:         a.low |= LIT64( 0xC000000000000000 );
        !           530:         return a;
        !           531: #endif
        !           532:     }
        !           533:     return a;
        !           534: }
        !           535: 
        !           536: /*----------------------------------------------------------------------------
1.1       root      537: | Returns the result of converting the extended double-precision floating-
                    538: | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
                    539: | invalid exception is raised.
                    540: *----------------------------------------------------------------------------*/
                    541: 
                    542: static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
                    543: {
                    544:     commonNaNT z;
                    545: 
                    546:     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
                    547:     z.sign = a.high>>15;
                    548:     z.low = 0;
1.1.1.3   root      549:     z.high = a.low;
1.1       root      550:     return z;
                    551: }
                    552: 
                    553: /*----------------------------------------------------------------------------
                    554: | Returns the result of converting the canonical NaN `a' to the extended
                    555: | double-precision floating-point format.
                    556: *----------------------------------------------------------------------------*/
                    557: 
                    558: static floatx80 commonNaNToFloatx80( commonNaNT a )
                    559: {
                    560:     floatx80 z;
                    561: 
1.1.1.3   root      562:     if (a.high)
                    563:         z.low = a.high;
                    564:     else
                    565:         z.low = floatx80_default_nan_low;
1.1       root      566:     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
                    567:     return z;
                    568: }
                    569: 
                    570: /*----------------------------------------------------------------------------
                    571: | Takes two extended double-precision floating-point values `a' and `b', one
                    572: | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    573: | `b' is a signaling NaN, the invalid exception is raised.
                    574: *----------------------------------------------------------------------------*/
                    575: 
                    576: static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
                    577: {
1.1.1.7 ! root      578:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
        !           579:     flag aIsLargerSignificand;
        !           580: 
        !           581:     aIsQuietNaN = floatx80_is_quiet_nan( a );
        !           582:     aIsSignalingNaN = floatx80_is_signaling_nan( a );
        !           583:     bIsQuietNaN = floatx80_is_quiet_nan( b );
        !           584:     bIsSignalingNaN = floatx80_is_signaling_nan( b );
        !           585: 
        !           586:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1       root      587: 
1.1.1.4   root      588:     if ( STATUS(default_nan_mode) ) {
                    589:         a.low = floatx80_default_nan_low;
                    590:         a.high = floatx80_default_nan_high;
                    591:         return a;
                    592:     }
                    593: 
1.1.1.7 ! root      594:     if (a.low < b.low) {
        !           595:         aIsLargerSignificand = 0;
        !           596:     } else if (b.low < a.low) {
        !           597:         aIsLargerSignificand = 1;
        !           598:     } else {
        !           599:         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1.1       root      600:     }
1.1.1.7 ! root      601: 
        !           602:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
        !           603:                 aIsLargerSignificand)) {
        !           604:         return floatx80_maybe_silence_nan(b);
        !           605:     } else {
        !           606:         return floatx80_maybe_silence_nan(a);
1.1       root      607:     }
                    608: }
                    609: 
                    610: #endif
                    611: 
                    612: #ifdef FLOAT128
                    613: 
                    614: /*----------------------------------------------------------------------------
                    615: | The pattern for a default generated quadruple-precision NaN.  The `high' and
                    616: | `low' values hold the most- and least-significant bits, respectively.
                    617: *----------------------------------------------------------------------------*/
1.1.1.3   root      618: #if SNAN_BIT_IS_ONE
                    619: #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
                    620: #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
                    621: #else
1.1       root      622: #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
                    623: #define float128_default_nan_low  LIT64( 0x0000000000000000 )
1.1.1.3   root      624: #endif
1.1       root      625: 
                    626: /*----------------------------------------------------------------------------
1.1.1.3   root      627: | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
                    628: | NaN; otherwise returns 0.
1.1       root      629: *----------------------------------------------------------------------------*/
                    630: 
1.1.1.7 ! root      631: int float128_is_quiet_nan( float128 a )
1.1       root      632: {
1.1.1.3   root      633: #if SNAN_BIT_IS_ONE
                    634:     return
                    635:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    636:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
                    637: #else
1.1       root      638:     return
                    639:            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
                    640:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
1.1.1.3   root      641: #endif
1.1       root      642: }
                    643: 
                    644: /*----------------------------------------------------------------------------
                    645: | Returns 1 if the quadruple-precision floating-point value `a' is a
                    646: | signaling NaN; otherwise returns 0.
                    647: *----------------------------------------------------------------------------*/
                    648: 
1.1.1.2   root      649: int float128_is_signaling_nan( float128 a )
1.1       root      650: {
1.1.1.3   root      651: #if SNAN_BIT_IS_ONE
                    652:     return
                    653:            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
                    654:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
                    655: #else
1.1       root      656:     return
                    657:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    658:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
1.1.1.3   root      659: #endif
1.1       root      660: }
                    661: 
                    662: /*----------------------------------------------------------------------------
1.1.1.7 ! root      663: | Returns a quiet NaN if the quadruple-precision floating point value `a' is
        !           664: | a signaling NaN; otherwise returns `a'.
        !           665: *----------------------------------------------------------------------------*/
        !           666: 
        !           667: float128 float128_maybe_silence_nan( float128 a )
        !           668: {
        !           669:     if (float128_is_signaling_nan(a)) {
        !           670: #if SNAN_BIT_IS_ONE
        !           671: #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
        !           672:         a.low = float128_default_nan_low;
        !           673:         a.high = float128_default_nan_high;
        !           674: #  else
        !           675: #    error Rules for silencing a signaling NaN are target-specific
        !           676: #  endif
        !           677: #else
        !           678:         a.high |= LIT64( 0x0000800000000000 );
        !           679:         return a;
        !           680: #endif
        !           681:     }
        !           682:     return a;
        !           683: }
        !           684: 
        !           685: /*----------------------------------------------------------------------------
1.1       root      686: | Returns the result of converting the quadruple-precision floating-point NaN
                    687: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    688: | exception is raised.
                    689: *----------------------------------------------------------------------------*/
                    690: 
                    691: static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
                    692: {
                    693:     commonNaNT z;
                    694: 
                    695:     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
                    696:     z.sign = a.high>>63;
                    697:     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
                    698:     return z;
                    699: }
                    700: 
                    701: /*----------------------------------------------------------------------------
                    702: | Returns the result of converting the canonical NaN `a' to the quadruple-
                    703: | precision floating-point format.
                    704: *----------------------------------------------------------------------------*/
                    705: 
                    706: static float128 commonNaNToFloat128( commonNaNT a )
                    707: {
                    708:     float128 z;
                    709: 
                    710:     shift128Right( a.high, a.low, 16, &z.high, &z.low );
1.1.1.3   root      711:     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
1.1       root      712:     return z;
                    713: }
                    714: 
                    715: /*----------------------------------------------------------------------------
                    716: | Takes two quadruple-precision floating-point values `a' and `b', one of
                    717: | which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    718: | `b' is a signaling NaN, the invalid exception is raised.
                    719: *----------------------------------------------------------------------------*/
                    720: 
                    721: static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
                    722: {
1.1.1.7 ! root      723:     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
        !           724:     flag aIsLargerSignificand;
        !           725: 
        !           726:     aIsQuietNaN = float128_is_quiet_nan( a );
        !           727:     aIsSignalingNaN = float128_is_signaling_nan( a );
        !           728:     bIsQuietNaN = float128_is_quiet_nan( b );
        !           729:     bIsSignalingNaN = float128_is_signaling_nan( b );
        !           730: 
        !           731:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1.1       root      732: 
1.1.1.4   root      733:     if ( STATUS(default_nan_mode) ) {
                    734:         a.low = float128_default_nan_low;
                    735:         a.high = float128_default_nan_high;
                    736:         return a;
                    737:     }
                    738: 
1.1.1.7 ! root      739:     if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
        !           740:         aIsLargerSignificand = 0;
        !           741:     } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
        !           742:         aIsLargerSignificand = 1;
        !           743:     } else {
        !           744:         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1.1       root      745:     }
1.1.1.7 ! root      746: 
        !           747:     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
        !           748:                 aIsLargerSignificand)) {
        !           749:         return float128_maybe_silence_nan(b);
        !           750:     } else {
        !           751:         return float128_maybe_silence_nan(a);
1.1       root      752:     }
                    753: }
                    754: 
                    755: #endif

unix.superglobalmegacorp.com

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