softfloat: fix float{32,64}_maybe_silence_nan() for MIPS
[qemu.git] / fpu / softfloat-specialize.h
blobbc6f0c1e5b04d0c524a646d110fd293c85817afb
2 /*============================================================================
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2b.
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'.
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.
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.
31 =============================================================================*/
33 #if defined(TARGET_MIPS)
34 #define SNAN_BIT_IS_ONE 1
35 #else
36 #define SNAN_BIT_IS_ONE 0
37 #endif
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 *----------------------------------------------------------------------------*/
46 void float_raise( int8 flags STATUS_PARAM )
48 STATUS(float_exception_flags) |= flags;
51 /*----------------------------------------------------------------------------
52 | Internal canonical NaN format.
53 *----------------------------------------------------------------------------*/
54 typedef struct {
55 flag sign;
56 bits64 high, low;
57 } commonNaNT;
59 /*----------------------------------------------------------------------------
60 | The pattern for a default generated single-precision NaN.
61 *----------------------------------------------------------------------------*/
62 #if defined(TARGET_SPARC)
63 #define float32_default_nan make_float32(0x7FFFFFFF)
64 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
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
72 /*----------------------------------------------------------------------------
73 | Returns 1 if the single-precision floating-point value `a' is a quiet
74 | NaN; otherwise returns 0.
75 *----------------------------------------------------------------------------*/
77 int float32_is_quiet_nan( float32 a_ )
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
87 /*----------------------------------------------------------------------------
88 | Returns 1 if the single-precision floating-point value `a' is a signaling
89 | NaN; otherwise returns 0.
90 *----------------------------------------------------------------------------*/
92 int float32_is_signaling_nan( float32 a_ )
94 uint32_t a = float32_val(a_);
95 #if SNAN_BIT_IS_ONE
96 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
97 #else
98 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99 #endif
102 /*----------------------------------------------------------------------------
103 | Returns a quiet NaN if the single-precision floating point value `a' is a
104 | signaling NaN; otherwise returns `a'.
105 *----------------------------------------------------------------------------*/
107 float32 float32_maybe_silence_nan( float32 a_ )
109 if (float32_is_signaling_nan(a_)) {
110 #if SNAN_BIT_IS_ONE
111 # if defined(TARGET_MIPS)
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
122 return a_;
125 /*----------------------------------------------------------------------------
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 *----------------------------------------------------------------------------*/
131 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
133 commonNaNT z;
135 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
136 z.sign = float32_val(a)>>31;
137 z.low = 0;
138 z.high = ( (bits64) float32_val(a) )<<41;
139 return z;
142 /*----------------------------------------------------------------------------
143 | Returns the result of converting the canonical NaN `a' to the single-
144 | precision floating-point format.
145 *----------------------------------------------------------------------------*/
147 static float32 commonNaNToFloat32( commonNaNT a )
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;
157 /*----------------------------------------------------------------------------
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 flipping the SNaN bit before returning them.
166 | aIsLargerSignificand is only valid if both a and b are NaNs
167 | of some kind, and is true if a has the larger significand,
168 | or if both a and b have the same significand but a is
169 | positive but b is negative. It is only needed for the x87
170 | tie-break rule.
171 *----------------------------------------------------------------------------*/
173 #if defined(TARGET_ARM)
174 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
175 flag aIsLargerSignificand)
177 /* ARM mandated NaN propagation rules: take the first of:
178 * 1. A if it is signaling
179 * 2. B if it is signaling
180 * 3. A (quiet)
181 * 4. B (quiet)
182 * A signaling NaN is always quietened before returning it.
184 if (aIsSNaN) {
185 return 0;
186 } else if (bIsSNaN) {
187 return 1;
188 } else if (aIsQNaN) {
189 return 0;
190 } else {
191 return 1;
194 #else
195 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
196 flag aIsLargerSignificand)
198 /* This implements x87 NaN propagation rules:
199 * SNaN + QNaN => return the QNaN
200 * two SNaNs => return the one with the larger significand, silenced
201 * two QNaNs => return the one with the larger significand
202 * SNaN and a non-NaN => return the SNaN, silenced
203 * QNaN and a non-NaN => return the QNaN
205 * If we get down to comparing significands and they are the same,
206 * return the NaN with the positive sign bit (if any).
208 if (aIsSNaN) {
209 if (bIsSNaN) {
210 return aIsLargerSignificand ? 0 : 1;
212 return bIsQNaN ? 1 : 0;
214 else if (aIsQNaN) {
215 if (bIsSNaN || !bIsQNaN)
216 return 0;
217 else {
218 return aIsLargerSignificand ? 0 : 1;
220 } else {
221 return 1;
224 #endif
226 /*----------------------------------------------------------------------------
227 | Takes two single-precision floating-point values `a' and `b', one of which
228 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
229 | signaling NaN, the invalid exception is raised.
230 *----------------------------------------------------------------------------*/
232 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
234 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
235 flag aIsLargerSignificand;
236 bits32 av, bv, res;
238 if ( STATUS(default_nan_mode) )
239 return float32_default_nan;
241 aIsQuietNaN = float32_is_quiet_nan( a );
242 aIsSignalingNaN = float32_is_signaling_nan( a );
243 bIsQuietNaN = float32_is_quiet_nan( b );
244 bIsSignalingNaN = float32_is_signaling_nan( b );
245 av = float32_val(a);
246 bv = float32_val(b);
247 #if SNAN_BIT_IS_ONE
248 av &= ~0x00400000;
249 bv &= ~0x00400000;
250 #else
251 av |= 0x00400000;
252 bv |= 0x00400000;
253 #endif
254 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
256 if ((bits32)(av<<1) < (bits32)(bv<<1)) {
257 aIsLargerSignificand = 0;
258 } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
259 aIsLargerSignificand = 1;
260 } else {
261 aIsLargerSignificand = (av < bv) ? 1 : 0;
264 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
265 aIsLargerSignificand)) {
266 res = bv;
267 } else {
268 res = av;
271 return make_float32(res);
274 /*----------------------------------------------------------------------------
275 | The pattern for a default generated double-precision NaN.
276 *----------------------------------------------------------------------------*/
277 #if defined(TARGET_SPARC)
278 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
279 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
280 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
281 #elif SNAN_BIT_IS_ONE
282 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
283 #else
284 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
285 #endif
287 /*----------------------------------------------------------------------------
288 | Returns 1 if the double-precision floating-point value `a' is a quiet
289 | NaN; otherwise returns 0.
290 *----------------------------------------------------------------------------*/
292 int float64_is_quiet_nan( float64 a_ )
294 bits64 a = float64_val(a_);
295 #if SNAN_BIT_IS_ONE
296 return
297 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
298 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
299 #else
300 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
301 #endif
304 /*----------------------------------------------------------------------------
305 | Returns 1 if the double-precision floating-point value `a' is a signaling
306 | NaN; otherwise returns 0.
307 *----------------------------------------------------------------------------*/
309 int float64_is_signaling_nan( float64 a_ )
311 bits64 a = float64_val(a_);
312 #if SNAN_BIT_IS_ONE
313 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
314 #else
315 return
316 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
317 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
318 #endif
321 /*----------------------------------------------------------------------------
322 | Returns a quiet NaN if the double-precision floating point value `a' is a
323 | signaling NaN; otherwise returns `a'.
324 *----------------------------------------------------------------------------*/
326 float64 float64_maybe_silence_nan( float64 a_ )
328 if (float64_is_signaling_nan(a_)) {
329 #if SNAN_BIT_IS_ONE
330 # if defined(TARGET_MIPS)
331 return float64_default_nan;
332 # else
333 # error Rules for silencing a signaling NaN are target-specific
334 # endif
335 #else
336 bits64 a = float64_val(a_);
337 a |= LIT64( 0x0008000000000000 );
338 return make_float64(a);
339 #endif
341 return a_;
344 /*----------------------------------------------------------------------------
345 | Returns the result of converting the double-precision floating-point NaN
346 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
347 | exception is raised.
348 *----------------------------------------------------------------------------*/
350 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
352 commonNaNT z;
354 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
355 z.sign = float64_val(a)>>63;
356 z.low = 0;
357 z.high = float64_val(a)<<12;
358 return z;
361 /*----------------------------------------------------------------------------
362 | Returns the result of converting the canonical NaN `a' to the double-
363 | precision floating-point format.
364 *----------------------------------------------------------------------------*/
366 static float64 commonNaNToFloat64( commonNaNT a )
368 bits64 mantissa = a.high>>12;
370 if ( mantissa )
371 return make_float64(
372 ( ( (bits64) a.sign )<<63 )
373 | LIT64( 0x7FF0000000000000 )
374 | ( a.high>>12 ));
375 else
376 return float64_default_nan;
379 /*----------------------------------------------------------------------------
380 | Takes two double-precision floating-point values `a' and `b', one of which
381 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
382 | signaling NaN, the invalid exception is raised.
383 *----------------------------------------------------------------------------*/
385 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
387 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
388 flag aIsLargerSignificand;
389 bits64 av, bv, res;
391 if ( STATUS(default_nan_mode) )
392 return float64_default_nan;
394 aIsQuietNaN = float64_is_quiet_nan( a );
395 aIsSignalingNaN = float64_is_signaling_nan( a );
396 bIsQuietNaN = float64_is_quiet_nan( b );
397 bIsSignalingNaN = float64_is_signaling_nan( b );
398 av = float64_val(a);
399 bv = float64_val(b);
400 #if SNAN_BIT_IS_ONE
401 av &= ~LIT64( 0x0008000000000000 );
402 bv &= ~LIT64( 0x0008000000000000 );
403 #else
404 av |= LIT64( 0x0008000000000000 );
405 bv |= LIT64( 0x0008000000000000 );
406 #endif
407 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
409 if ((bits64)(av<<1) < (bits64)(bv<<1)) {
410 aIsLargerSignificand = 0;
411 } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
412 aIsLargerSignificand = 1;
413 } else {
414 aIsLargerSignificand = (av < bv) ? 1 : 0;
417 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
418 aIsLargerSignificand)) {
419 res = bv;
420 } else {
421 res = av;
424 return make_float64(res);
427 #ifdef FLOATX80
429 /*----------------------------------------------------------------------------
430 | The pattern for a default generated extended double-precision NaN. The
431 | `high' and `low' values hold the most- and least-significant bits,
432 | respectively.
433 *----------------------------------------------------------------------------*/
434 #if SNAN_BIT_IS_ONE
435 #define floatx80_default_nan_high 0x7FFF
436 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
437 #else
438 #define floatx80_default_nan_high 0xFFFF
439 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
440 #endif
442 /*----------------------------------------------------------------------------
443 | Returns 1 if the extended double-precision floating-point value `a' is a
444 | quiet NaN; otherwise returns 0.
445 *----------------------------------------------------------------------------*/
447 int floatx80_is_quiet_nan( floatx80 a )
449 #if SNAN_BIT_IS_ONE
450 bits64 aLow;
452 aLow = a.low & ~ LIT64( 0x4000000000000000 );
453 return
454 ( ( a.high & 0x7FFF ) == 0x7FFF )
455 && (bits64) ( aLow<<1 )
456 && ( a.low == aLow );
457 #else
458 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
459 #endif
462 /*----------------------------------------------------------------------------
463 | Returns 1 if the extended double-precision floating-point value `a' is a
464 | signaling NaN; otherwise returns 0.
465 *----------------------------------------------------------------------------*/
467 int floatx80_is_signaling_nan( floatx80 a )
469 #if SNAN_BIT_IS_ONE
470 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
471 #else
472 bits64 aLow;
474 aLow = a.low & ~ LIT64( 0x4000000000000000 );
475 return
476 ( ( a.high & 0x7FFF ) == 0x7FFF )
477 && (bits64) ( aLow<<1 )
478 && ( a.low == aLow );
479 #endif
482 /*----------------------------------------------------------------------------
483 | Returns the result of converting the extended double-precision floating-
484 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
485 | invalid exception is raised.
486 *----------------------------------------------------------------------------*/
488 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
490 commonNaNT z;
492 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
493 z.sign = a.high>>15;
494 z.low = 0;
495 z.high = a.low;
496 return z;
499 /*----------------------------------------------------------------------------
500 | Returns the result of converting the canonical NaN `a' to the extended
501 | double-precision floating-point format.
502 *----------------------------------------------------------------------------*/
504 static floatx80 commonNaNToFloatx80( commonNaNT a )
506 floatx80 z;
508 if (a.high)
509 z.low = a.high;
510 else
511 z.low = floatx80_default_nan_low;
512 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
513 return z;
516 /*----------------------------------------------------------------------------
517 | Takes two extended double-precision floating-point values `a' and `b', one
518 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
519 | `b' is a signaling NaN, the invalid exception is raised.
520 *----------------------------------------------------------------------------*/
522 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
524 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
525 flag aIsLargerSignificand;
527 if ( STATUS(default_nan_mode) ) {
528 a.low = floatx80_default_nan_low;
529 a.high = floatx80_default_nan_high;
530 return a;
533 aIsQuietNaN = floatx80_is_quiet_nan( a );
534 aIsSignalingNaN = floatx80_is_signaling_nan( a );
535 bIsQuietNaN = floatx80_is_quiet_nan( b );
536 bIsSignalingNaN = floatx80_is_signaling_nan( b );
537 #if SNAN_BIT_IS_ONE
538 a.low &= ~LIT64( 0xC000000000000000 );
539 b.low &= ~LIT64( 0xC000000000000000 );
540 #else
541 a.low |= LIT64( 0xC000000000000000 );
542 b.low |= LIT64( 0xC000000000000000 );
543 #endif
544 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
546 if (a.low < b.low) {
547 aIsLargerSignificand = 0;
548 } else if (b.low < a.low) {
549 aIsLargerSignificand = 1;
550 } else {
551 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
554 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
555 aIsLargerSignificand)) {
556 return b;
557 } else {
558 return a;
562 #endif
564 #ifdef FLOAT128
566 /*----------------------------------------------------------------------------
567 | The pattern for a default generated quadruple-precision NaN. The `high' and
568 | `low' values hold the most- and least-significant bits, respectively.
569 *----------------------------------------------------------------------------*/
570 #if SNAN_BIT_IS_ONE
571 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
572 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
573 #else
574 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
575 #define float128_default_nan_low LIT64( 0x0000000000000000 )
576 #endif
578 /*----------------------------------------------------------------------------
579 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
580 | NaN; otherwise returns 0.
581 *----------------------------------------------------------------------------*/
583 int float128_is_quiet_nan( float128 a )
585 #if SNAN_BIT_IS_ONE
586 return
587 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
588 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
589 #else
590 return
591 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
592 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
593 #endif
596 /*----------------------------------------------------------------------------
597 | Returns 1 if the quadruple-precision floating-point value `a' is a
598 | signaling NaN; otherwise returns 0.
599 *----------------------------------------------------------------------------*/
601 int float128_is_signaling_nan( float128 a )
603 #if SNAN_BIT_IS_ONE
604 return
605 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
606 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
607 #else
608 return
609 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
610 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
611 #endif
614 /*----------------------------------------------------------------------------
615 | Returns the result of converting the quadruple-precision floating-point NaN
616 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
617 | exception is raised.
618 *----------------------------------------------------------------------------*/
620 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
622 commonNaNT z;
624 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
625 z.sign = a.high>>63;
626 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
627 return z;
630 /*----------------------------------------------------------------------------
631 | Returns the result of converting the canonical NaN `a' to the quadruple-
632 | precision floating-point format.
633 *----------------------------------------------------------------------------*/
635 static float128 commonNaNToFloat128( commonNaNT a )
637 float128 z;
639 shift128Right( a.high, a.low, 16, &z.high, &z.low );
640 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
641 return z;
644 /*----------------------------------------------------------------------------
645 | Takes two quadruple-precision floating-point values `a' and `b', one of
646 | which is a NaN, and returns the appropriate NaN result. If either `a' or
647 | `b' is a signaling NaN, the invalid exception is raised.
648 *----------------------------------------------------------------------------*/
650 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
652 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
653 flag aIsLargerSignificand;
655 if ( STATUS(default_nan_mode) ) {
656 a.low = float128_default_nan_low;
657 a.high = float128_default_nan_high;
658 return a;
661 aIsQuietNaN = float128_is_quiet_nan( a );
662 aIsSignalingNaN = float128_is_signaling_nan( a );
663 bIsQuietNaN = float128_is_quiet_nan( b );
664 bIsSignalingNaN = float128_is_signaling_nan( b );
665 #if SNAN_BIT_IS_ONE
666 a.high &= ~LIT64( 0x0000800000000000 );
667 b.high &= ~LIT64( 0x0000800000000000 );
668 #else
669 a.high |= LIT64( 0x0000800000000000 );
670 b.high |= LIT64( 0x0000800000000000 );
671 #endif
672 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
674 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
675 aIsLargerSignificand = 0;
676 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
677 aIsLargerSignificand = 1;
678 } else {
679 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
682 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
683 aIsLargerSignificand)) {
684 return b;
685 } else {
686 return a;
690 #endif