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

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.3 ! root       33: #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
        !            34: #define SNAN_BIT_IS_ONE                1
        !            35: #else
        !            36: #define SNAN_BIT_IS_ONE                0
        !            37: #endif
        !            38: 
1.1       root       39: /*----------------------------------------------------------------------------
                     40: | Underflow tininess-detection mode, statically initialized to default value.
                     41: | (The declaration in `softfloat.h' must match the `int8' type here.)
                     42: *----------------------------------------------------------------------------*/
                     43: int8 float_detect_tininess = float_tininess_after_rounding;
                     44: 
                     45: /*----------------------------------------------------------------------------
                     46: | Raises the exceptions specified by `flags'.  Floating-point traps can be
                     47: | defined here if desired.  It is currently not possible for such a trap
                     48: | to substitute a result value.  If traps are not implemented, this routine
                     49: | should be simply `float_exception_flags |= flags;'.
                     50: *----------------------------------------------------------------------------*/
                     51: 
                     52: void float_raise( int8 flags STATUS_PARAM )
                     53: {
                     54:     STATUS(float_exception_flags) |= flags;
                     55: }
                     56: 
                     57: /*----------------------------------------------------------------------------
                     58: | Internal canonical NaN format.
                     59: *----------------------------------------------------------------------------*/
                     60: typedef struct {
                     61:     flag sign;
                     62:     bits64 high, low;
                     63: } commonNaNT;
                     64: 
                     65: /*----------------------------------------------------------------------------
                     66: | The pattern for a default generated single-precision NaN.
                     67: *----------------------------------------------------------------------------*/
1.1.1.3 ! root       68: #if defined(TARGET_SPARC)
        !            69: #define float32_default_nan make_float32(0x7FFFFFFF)
        !            70: #elif defined(TARGET_POWERPC)
        !            71: #define float32_default_nan make_float32(0x7FC00000)
        !            72: #elif defined(TARGET_HPPA)
        !            73: #define float32_default_nan make_float32(0x7FA00000)
        !            74: #elif SNAN_BIT_IS_ONE
        !            75: #define float32_default_nan make_float32(0x7FBFFFFF)
        !            76: #else
        !            77: #define float32_default_nan make_float32(0xFFC00000)
        !            78: #endif
1.1       root       79: 
                     80: /*----------------------------------------------------------------------------
1.1.1.3 ! root       81: | Returns 1 if the single-precision floating-point value `a' is a quiet
        !            82: | NaN; otherwise returns 0.
1.1       root       83: *----------------------------------------------------------------------------*/
                     84: 
1.1.1.3 ! root       85: int float32_is_nan( float32 a_ )
1.1       root       86: {
1.1.1.3 ! root       87:     uint32_t a = float32_val(a_);
        !            88: #if SNAN_BIT_IS_ONE
        !            89:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
        !            90: #else
        !            91:     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
        !            92: #endif
1.1       root       93: }
                     94: 
                     95: /*----------------------------------------------------------------------------
                     96: | Returns 1 if the single-precision floating-point value `a' is a signaling
                     97: | NaN; otherwise returns 0.
                     98: *----------------------------------------------------------------------------*/
                     99: 
1.1.1.3 ! root      100: int float32_is_signaling_nan( float32 a_ )
1.1       root      101: {
1.1.1.3 ! root      102:     uint32_t a = float32_val(a_);
        !           103: #if SNAN_BIT_IS_ONE
        !           104:     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
        !           105: #else
1.1       root      106:     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
1.1.1.3 ! root      107: #endif
1.1       root      108: }
                    109: 
                    110: /*----------------------------------------------------------------------------
                    111: | Returns the result of converting the single-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 float32ToCommonNaN( float32 a STATUS_PARAM )
                    117: {
                    118:     commonNaNT z;
                    119: 
                    120:     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
1.1.1.3 ! root      121:     z.sign = float32_val(a)>>31;
1.1       root      122:     z.low = 0;
1.1.1.3 ! root      123:     z.high = ( (bits64) float32_val(a) )<<41;
1.1       root      124:     return z;
                    125: }
                    126: 
                    127: /*----------------------------------------------------------------------------
                    128: | Returns the result of converting the canonical NaN `a' to the single-
                    129: | precision floating-point format.
                    130: *----------------------------------------------------------------------------*/
                    131: 
                    132: static float32 commonNaNToFloat32( commonNaNT a )
                    133: {
1.1.1.3 ! root      134:     bits32 mantissa = a.high>>41;
        !           135:     if ( mantissa )
        !           136:         return make_float32(
        !           137:             ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
        !           138:     else
        !           139:         return float32_default_nan;
1.1       root      140: }
                    141: 
                    142: /*----------------------------------------------------------------------------
                    143: | Takes two single-precision floating-point values `a' and `b', one of which
                    144: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    145: | signaling NaN, the invalid exception is raised.
                    146: *----------------------------------------------------------------------------*/
                    147: 
                    148: static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
                    149: {
                    150:     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
1.1.1.3 ! root      151:     bits32 av, bv, res;
1.1       root      152: 
                    153:     aIsNaN = float32_is_nan( a );
                    154:     aIsSignalingNaN = float32_is_signaling_nan( a );
                    155:     bIsNaN = float32_is_nan( b );
                    156:     bIsSignalingNaN = float32_is_signaling_nan( b );
1.1.1.3 ! root      157:     av = float32_val(a);
        !           158:     bv = float32_val(b);
        !           159: #if SNAN_BIT_IS_ONE
        !           160:     av &= ~0x00400000;
        !           161:     bv &= ~0x00400000;
        !           162: #else
        !           163:     av |= 0x00400000;
        !           164:     bv |= 0x00400000;
        !           165: #endif
1.1       root      166:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
                    167:     if ( aIsSignalingNaN ) {
                    168:         if ( bIsSignalingNaN ) goto returnLargerSignificand;
1.1.1.3 ! root      169:         res = bIsNaN ? bv : av;
1.1       root      170:     }
                    171:     else if ( aIsNaN ) {
1.1.1.3 ! root      172:         if ( bIsSignalingNaN | ! bIsNaN )
        !           173:             res = av;
        !           174:         else {
1.1       root      175:  returnLargerSignificand:
1.1.1.3 ! root      176:             if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
        !           177:                 res = bv;
        !           178:             else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
        !           179:                 res = av;
        !           180:             else
        !           181:                 res = ( av < bv ) ? av : bv;
        !           182:         }
1.1       root      183:     }
                    184:     else {
1.1.1.3 ! root      185:         res = bv;
1.1       root      186:     }
1.1.1.3 ! root      187:     return make_float32(res);
1.1       root      188: }
                    189: 
                    190: /*----------------------------------------------------------------------------
                    191: | The pattern for a default generated double-precision NaN.
                    192: *----------------------------------------------------------------------------*/
1.1.1.3 ! root      193: #if defined(TARGET_SPARC)
        !           194: #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
        !           195: #elif defined(TARGET_POWERPC)
        !           196: #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
        !           197: #elif defined(TARGET_HPPA)
        !           198: #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
        !           199: #elif SNAN_BIT_IS_ONE
        !           200: #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
        !           201: #else
        !           202: #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
        !           203: #endif
1.1       root      204: 
                    205: /*----------------------------------------------------------------------------
1.1.1.3 ! root      206: | Returns 1 if the double-precision floating-point value `a' is a quiet
        !           207: | NaN; otherwise returns 0.
1.1       root      208: *----------------------------------------------------------------------------*/
                    209: 
1.1.1.3 ! root      210: int float64_is_nan( float64 a_ )
1.1       root      211: {
1.1.1.3 ! root      212:     bits64 a = float64_val(a_);
        !           213: #if SNAN_BIT_IS_ONE
        !           214:     return
        !           215:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
        !           216:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
        !           217: #else
        !           218:     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
        !           219: #endif
1.1       root      220: }
                    221: 
                    222: /*----------------------------------------------------------------------------
                    223: | Returns 1 if the double-precision floating-point value `a' is a signaling
                    224: | NaN; otherwise returns 0.
                    225: *----------------------------------------------------------------------------*/
                    226: 
1.1.1.3 ! root      227: int float64_is_signaling_nan( float64 a_ )
1.1       root      228: {
1.1.1.3 ! root      229:     bits64 a = float64_val(a_);
        !           230: #if SNAN_BIT_IS_ONE
        !           231:     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
        !           232: #else
1.1       root      233:     return
                    234:            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
                    235:         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
1.1.1.3 ! root      236: #endif
1.1       root      237: }
                    238: 
                    239: /*----------------------------------------------------------------------------
                    240: | Returns the result of converting the double-precision floating-point NaN
                    241: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    242: | exception is raised.
                    243: *----------------------------------------------------------------------------*/
                    244: 
                    245: static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
                    246: {
                    247:     commonNaNT z;
                    248: 
                    249:     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1.1.1.3 ! root      250:     z.sign = float64_val(a)>>63;
1.1       root      251:     z.low = 0;
1.1.1.3 ! root      252:     z.high = float64_val(a)<<12;
1.1       root      253:     return z;
                    254: }
                    255: 
                    256: /*----------------------------------------------------------------------------
                    257: | Returns the result of converting the canonical NaN `a' to the double-
                    258: | precision floating-point format.
                    259: *----------------------------------------------------------------------------*/
                    260: 
                    261: static float64 commonNaNToFloat64( commonNaNT a )
                    262: {
1.1.1.3 ! root      263:     bits64 mantissa = a.high>>12;
1.1       root      264: 
1.1.1.3 ! root      265:     if ( mantissa )
        !           266:         return make_float64(
        !           267:               ( ( (bits64) a.sign )<<63 )
        !           268:             | LIT64( 0x7FF0000000000000 )
        !           269:             | ( a.high>>12 ));
        !           270:     else
        !           271:         return float64_default_nan;
1.1       root      272: }
                    273: 
                    274: /*----------------------------------------------------------------------------
                    275: | Takes two double-precision floating-point values `a' and `b', one of which
                    276: | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
                    277: | signaling NaN, the invalid exception is raised.
                    278: *----------------------------------------------------------------------------*/
                    279: 
                    280: static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
                    281: {
                    282:     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
1.1.1.3 ! root      283:     bits64 av, bv, res;
1.1       root      284: 
                    285:     aIsNaN = float64_is_nan( a );
                    286:     aIsSignalingNaN = float64_is_signaling_nan( a );
                    287:     bIsNaN = float64_is_nan( b );
                    288:     bIsSignalingNaN = float64_is_signaling_nan( b );
1.1.1.3 ! root      289:     av = float64_val(a);
        !           290:     bv = float64_val(b);
        !           291: #if SNAN_BIT_IS_ONE
        !           292:     av &= ~LIT64( 0x0008000000000000 );
        !           293:     bv &= ~LIT64( 0x0008000000000000 );
        !           294: #else
        !           295:     av |= LIT64( 0x0008000000000000 );
        !           296:     bv |= LIT64( 0x0008000000000000 );
        !           297: #endif
1.1       root      298:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
                    299:     if ( aIsSignalingNaN ) {
                    300:         if ( bIsSignalingNaN ) goto returnLargerSignificand;
1.1.1.3 ! root      301:         res = bIsNaN ? bv : av;
1.1       root      302:     }
                    303:     else if ( aIsNaN ) {
1.1.1.3 ! root      304:         if ( bIsSignalingNaN | ! bIsNaN )
        !           305:             res = av;
        !           306:         else {
1.1       root      307:  returnLargerSignificand:
1.1.1.3 ! root      308:             if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
        !           309:                 res = bv;
        !           310:             else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
        !           311:                 res = av;
        !           312:             else
        !           313:                 res = ( av < bv ) ? av : bv;
        !           314:         }
1.1       root      315:     }
                    316:     else {
1.1.1.3 ! root      317:         res = bv;
1.1       root      318:     }
1.1.1.3 ! root      319:     return make_float64(res);
1.1       root      320: }
                    321: 
                    322: #ifdef FLOATX80
                    323: 
                    324: /*----------------------------------------------------------------------------
                    325: | The pattern for a default generated extended double-precision NaN.  The
                    326: | `high' and `low' values hold the most- and least-significant bits,
                    327: | respectively.
                    328: *----------------------------------------------------------------------------*/
1.1.1.3 ! root      329: #if SNAN_BIT_IS_ONE
        !           330: #define floatx80_default_nan_high 0x7FFF
        !           331: #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
        !           332: #else
1.1       root      333: #define floatx80_default_nan_high 0xFFFF
                    334: #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
1.1.1.3 ! root      335: #endif
1.1       root      336: 
                    337: /*----------------------------------------------------------------------------
                    338: | Returns 1 if the extended double-precision floating-point value `a' is a
1.1.1.3 ! root      339: | quiet NaN; otherwise returns 0.
1.1       root      340: *----------------------------------------------------------------------------*/
                    341: 
1.1.1.2   root      342: int floatx80_is_nan( floatx80 a )
1.1       root      343: {
1.1.1.3 ! root      344: #if SNAN_BIT_IS_ONE
        !           345:     bits64 aLow;
1.1       root      346: 
1.1.1.3 ! root      347:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
        !           348:     return
        !           349:            ( ( a.high & 0x7FFF ) == 0x7FFF )
        !           350:         && (bits64) ( aLow<<1 )
        !           351:         && ( a.low == aLow );
        !           352: #else
1.1       root      353:     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
1.1.1.3 ! root      354: #endif
1.1       root      355: }
                    356: 
                    357: /*----------------------------------------------------------------------------
                    358: | Returns 1 if the extended double-precision floating-point value `a' is a
                    359: | signaling NaN; otherwise returns 0.
                    360: *----------------------------------------------------------------------------*/
                    361: 
1.1.1.2   root      362: int floatx80_is_signaling_nan( floatx80 a )
1.1       root      363: {
1.1.1.3 ! root      364: #if SNAN_BIT_IS_ONE
        !           365:     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
        !           366: #else
1.1       root      367:     bits64 aLow;
                    368: 
                    369:     aLow = a.low & ~ LIT64( 0x4000000000000000 );
                    370:     return
                    371:            ( ( a.high & 0x7FFF ) == 0x7FFF )
                    372:         && (bits64) ( aLow<<1 )
                    373:         && ( a.low == aLow );
1.1.1.3 ! root      374: #endif
1.1       root      375: }
                    376: 
                    377: /*----------------------------------------------------------------------------
                    378: | Returns the result of converting the extended double-precision floating-
                    379: | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
                    380: | invalid exception is raised.
                    381: *----------------------------------------------------------------------------*/
                    382: 
                    383: static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
                    384: {
                    385:     commonNaNT z;
                    386: 
                    387:     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
                    388:     z.sign = a.high>>15;
                    389:     z.low = 0;
1.1.1.3 ! root      390:     z.high = a.low;
1.1       root      391:     return z;
                    392: }
                    393: 
                    394: /*----------------------------------------------------------------------------
                    395: | Returns the result of converting the canonical NaN `a' to the extended
                    396: | double-precision floating-point format.
                    397: *----------------------------------------------------------------------------*/
                    398: 
                    399: static floatx80 commonNaNToFloatx80( commonNaNT a )
                    400: {
                    401:     floatx80 z;
                    402: 
1.1.1.3 ! root      403:     if (a.high)
        !           404:         z.low = a.high;
        !           405:     else
        !           406:         z.low = floatx80_default_nan_low;
1.1       root      407:     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
                    408:     return z;
                    409: }
                    410: 
                    411: /*----------------------------------------------------------------------------
                    412: | Takes two extended double-precision floating-point values `a' and `b', one
                    413: | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    414: | `b' is a signaling NaN, the invalid exception is raised.
                    415: *----------------------------------------------------------------------------*/
                    416: 
                    417: static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
                    418: {
                    419:     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
                    420: 
                    421:     aIsNaN = floatx80_is_nan( a );
                    422:     aIsSignalingNaN = floatx80_is_signaling_nan( a );
                    423:     bIsNaN = floatx80_is_nan( b );
                    424:     bIsSignalingNaN = floatx80_is_signaling_nan( b );
1.1.1.3 ! root      425: #if SNAN_BIT_IS_ONE
        !           426:     a.low &= ~LIT64( 0xC000000000000000 );
        !           427:     b.low &= ~LIT64( 0xC000000000000000 );
        !           428: #else
1.1       root      429:     a.low |= LIT64( 0xC000000000000000 );
                    430:     b.low |= LIT64( 0xC000000000000000 );
1.1.1.3 ! root      431: #endif
1.1       root      432:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
                    433:     if ( aIsSignalingNaN ) {
                    434:         if ( bIsSignalingNaN ) goto returnLargerSignificand;
                    435:         return bIsNaN ? b : a;
                    436:     }
                    437:     else if ( aIsNaN ) {
                    438:         if ( bIsSignalingNaN | ! bIsNaN ) return a;
                    439:  returnLargerSignificand:
                    440:         if ( a.low < b.low ) return b;
                    441:         if ( b.low < a.low ) return a;
                    442:         return ( a.high < b.high ) ? a : b;
                    443:     }
                    444:     else {
                    445:         return b;
                    446:     }
                    447: }
                    448: 
                    449: #endif
                    450: 
                    451: #ifdef FLOAT128
                    452: 
                    453: /*----------------------------------------------------------------------------
                    454: | The pattern for a default generated quadruple-precision NaN.  The `high' and
                    455: | `low' values hold the most- and least-significant bits, respectively.
                    456: *----------------------------------------------------------------------------*/
1.1.1.3 ! root      457: #if SNAN_BIT_IS_ONE
        !           458: #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
        !           459: #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
        !           460: #else
1.1       root      461: #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
                    462: #define float128_default_nan_low  LIT64( 0x0000000000000000 )
1.1.1.3 ! root      463: #endif
1.1       root      464: 
                    465: /*----------------------------------------------------------------------------
1.1.1.3 ! root      466: | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
        !           467: | NaN; otherwise returns 0.
1.1       root      468: *----------------------------------------------------------------------------*/
                    469: 
1.1.1.2   root      470: int float128_is_nan( float128 a )
1.1       root      471: {
1.1.1.3 ! root      472: #if SNAN_BIT_IS_ONE
        !           473:     return
        !           474:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
        !           475:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
        !           476: #else
1.1       root      477:     return
                    478:            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
                    479:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
1.1.1.3 ! root      480: #endif
1.1       root      481: }
                    482: 
                    483: /*----------------------------------------------------------------------------
                    484: | Returns 1 if the quadruple-precision floating-point value `a' is a
                    485: | signaling NaN; otherwise returns 0.
                    486: *----------------------------------------------------------------------------*/
                    487: 
1.1.1.2   root      488: int float128_is_signaling_nan( float128 a )
1.1       root      489: {
1.1.1.3 ! root      490: #if SNAN_BIT_IS_ONE
        !           491:     return
        !           492:            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
        !           493:         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
        !           494: #else
1.1       root      495:     return
                    496:            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
                    497:         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
1.1.1.3 ! root      498: #endif
1.1       root      499: }
                    500: 
                    501: /*----------------------------------------------------------------------------
                    502: | Returns the result of converting the quadruple-precision floating-point NaN
                    503: | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
                    504: | exception is raised.
                    505: *----------------------------------------------------------------------------*/
                    506: 
                    507: static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
                    508: {
                    509:     commonNaNT z;
                    510: 
                    511:     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
                    512:     z.sign = a.high>>63;
                    513:     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
                    514:     return z;
                    515: }
                    516: 
                    517: /*----------------------------------------------------------------------------
                    518: | Returns the result of converting the canonical NaN `a' to the quadruple-
                    519: | precision floating-point format.
                    520: *----------------------------------------------------------------------------*/
                    521: 
                    522: static float128 commonNaNToFloat128( commonNaNT a )
                    523: {
                    524:     float128 z;
                    525: 
                    526:     shift128Right( a.high, a.low, 16, &z.high, &z.low );
1.1.1.3 ! root      527:     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
1.1       root      528:     return z;
                    529: }
                    530: 
                    531: /*----------------------------------------------------------------------------
                    532: | Takes two quadruple-precision floating-point values `a' and `b', one of
                    533: | which is a NaN, and returns the appropriate NaN result.  If either `a' or
                    534: | `b' is a signaling NaN, the invalid exception is raised.
                    535: *----------------------------------------------------------------------------*/
                    536: 
                    537: static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
                    538: {
                    539:     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
                    540: 
                    541:     aIsNaN = float128_is_nan( a );
                    542:     aIsSignalingNaN = float128_is_signaling_nan( a );
                    543:     bIsNaN = float128_is_nan( b );
                    544:     bIsSignalingNaN = float128_is_signaling_nan( b );
1.1.1.3 ! root      545: #if SNAN_BIT_IS_ONE
        !           546:     a.high &= ~LIT64( 0x0000800000000000 );
        !           547:     b.high &= ~LIT64( 0x0000800000000000 );
        !           548: #else
1.1       root      549:     a.high |= LIT64( 0x0000800000000000 );
                    550:     b.high |= LIT64( 0x0000800000000000 );
1.1.1.3 ! root      551: #endif
1.1       root      552:     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
                    553:     if ( aIsSignalingNaN ) {
                    554:         if ( bIsSignalingNaN ) goto returnLargerSignificand;
                    555:         return bIsNaN ? b : a;
                    556:     }
                    557:     else if ( aIsNaN ) {
                    558:         if ( bIsSignalingNaN | ! bIsNaN ) return a;
                    559:  returnLargerSignificand:
                    560:         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
                    561:         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
                    562:         return ( a.high < b.high ) ? a : b;
                    563:     }
                    564:     else {
                    565:         return b;
                    566:     }
                    567: }
                    568: 
                    569: #endif

unix.superglobalmegacorp.com

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