|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.