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) || defined(TARGET_SH4)
34 #define SNAN_BIT_IS_ONE 1
36 #define SNAN_BIT_IS_ONE 0
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 *----------------------------------------------------------------------------*/
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_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65 #define float32_default_nan make_float32(0x7FC00000)
67 #define float32_default_nan make_float32(0x7FBFFFFF)
69 #define float32_default_nan make_float32(0xFFC00000)
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_
);
81 return ( ( ( a
>>22 ) & 0x1FF ) == 0x1FE ) && ( a
& 0x003FFFFF );
83 return ( 0xFF800000 <= (bits32
) ( a
<<1 ) );
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_
);
96 return ( 0xFF800000 <= (bits32
) ( a
<<1 ) );
98 return ( ( ( a
>>22 ) & 0x1FF ) == 0x1FE ) && ( a
& 0x003FFFFF );
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_
)) {
111 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
112 return float32_default_nan
;
114 # error Rules for silencing a signaling NaN are target-specific
117 bits32 a
= float32_val(a_
);
119 return make_float32(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
)
135 if ( float32_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
136 z
.sign
= float32_val(a
)>>31;
138 z
.high
= ( (bits64
) float32_val(a
) )<<41;
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;
152 ( ( (bits32
) a
.sign
)<<31 ) | 0x7F800000 | ( a
.high
>>41 ) );
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 calling floatXX_maybe_silence_nan() before
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
172 *----------------------------------------------------------------------------*/
174 #if defined(TARGET_ARM)
175 static int pickNaN(flag aIsQNaN
, flag aIsSNaN
, flag bIsQNaN
, flag bIsSNaN
,
176 flag aIsLargerSignificand
)
178 /* ARM mandated NaN propagation rules: take the first of:
179 * 1. A if it is signaling
180 * 2. B if it is signaling
183 * A signaling NaN is always quietened before returning it.
187 } else if (bIsSNaN
) {
189 } else if (aIsQNaN
) {
195 #elif defined(TARGET_MIPS)
196 static int pickNaN(flag aIsQNaN
, flag aIsSNaN
, flag bIsQNaN
, flag bIsSNaN
,
197 flag aIsLargerSignificand
)
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
210 * A signaling NaN is always silenced before returning it.
214 } else if (bIsSNaN
) {
216 } else if (aIsQNaN
) {
222 #elif defined(TARGET_PPC)
223 static int pickNaN(flag aIsQNaN
, flag aIsSNaN
, flag bIsQNaN
, flag bIsSNaN
,
224 flag aIsLargerSignificand
)
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.
231 if (aIsSNaN
|| aIsQNaN
) {
238 static int pickNaN(flag aIsQNaN
, flag aIsSNaN
, flag bIsQNaN
, flag bIsSNaN
,
239 flag aIsLargerSignificand
)
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
248 * If we get down to comparing significands and they are the same,
249 * return the NaN with the positive sign bit (if any).
253 return aIsLargerSignificand
? 0 : 1;
255 return bIsQNaN
? 1 : 0;
258 if (bIsSNaN
|| !bIsQNaN
)
261 return aIsLargerSignificand
? 0 : 1;
269 /*----------------------------------------------------------------------------
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 *----------------------------------------------------------------------------*/
275 static float32
propagateFloat32NaN( float32 a
, float32 b STATUS_PARAM
)
277 flag aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
;
278 flag aIsLargerSignificand
;
281 aIsQuietNaN
= float32_is_quiet_nan( a
);
282 aIsSignalingNaN
= float32_is_signaling_nan( a
);
283 bIsQuietNaN
= float32_is_quiet_nan( b
);
284 bIsSignalingNaN
= float32_is_signaling_nan( b
);
288 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
290 if ( STATUS(default_nan_mode
) )
291 return float32_default_nan
;
293 if ((bits32
)(av
<<1) < (bits32
)(bv
<<1)) {
294 aIsLargerSignificand
= 0;
295 } else if ((bits32
)(bv
<<1) < (bits32
)(av
<<1)) {
296 aIsLargerSignificand
= 1;
298 aIsLargerSignificand
= (av
< bv
) ? 1 : 0;
301 if (pickNaN(aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
,
302 aIsLargerSignificand
)) {
303 return float32_maybe_silence_nan(b
);
305 return float32_maybe_silence_nan(a
);
309 /*----------------------------------------------------------------------------
310 | The pattern for a default generated double-precision NaN.
311 *----------------------------------------------------------------------------*/
312 #if defined(TARGET_SPARC)
313 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
314 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
315 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
316 #elif SNAN_BIT_IS_ONE
317 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
319 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
322 /*----------------------------------------------------------------------------
323 | Returns 1 if the double-precision floating-point value `a' is a quiet
324 | NaN; otherwise returns 0.
325 *----------------------------------------------------------------------------*/
327 int float64_is_quiet_nan( float64 a_
)
329 bits64 a
= float64_val(a_
);
332 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
333 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
335 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
339 /*----------------------------------------------------------------------------
340 | Returns 1 if the double-precision floating-point value `a' is a signaling
341 | NaN; otherwise returns 0.
342 *----------------------------------------------------------------------------*/
344 int float64_is_signaling_nan( float64 a_
)
346 bits64 a
= float64_val(a_
);
348 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
351 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
352 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
356 /*----------------------------------------------------------------------------
357 | Returns a quiet NaN if the double-precision floating point value `a' is a
358 | signaling NaN; otherwise returns `a'.
359 *----------------------------------------------------------------------------*/
361 float64
float64_maybe_silence_nan( float64 a_
)
363 if (float64_is_signaling_nan(a_
)) {
365 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
366 return float64_default_nan
;
368 # error Rules for silencing a signaling NaN are target-specific
371 bits64 a
= float64_val(a_
);
372 a
|= LIT64( 0x0008000000000000 );
373 return make_float64(a
);
379 /*----------------------------------------------------------------------------
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 *----------------------------------------------------------------------------*/
385 static commonNaNT
float64ToCommonNaN( float64 a STATUS_PARAM
)
389 if ( float64_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
390 z
.sign
= float64_val(a
)>>63;
392 z
.high
= float64_val(a
)<<12;
396 /*----------------------------------------------------------------------------
397 | Returns the result of converting the canonical NaN `a' to the double-
398 | precision floating-point format.
399 *----------------------------------------------------------------------------*/
401 static float64
commonNaNToFloat64( commonNaNT a
)
403 bits64 mantissa
= a
.high
>>12;
407 ( ( (bits64
) a
.sign
)<<63 )
408 | LIT64( 0x7FF0000000000000 )
411 return float64_default_nan
;
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 *----------------------------------------------------------------------------*/
420 static float64
propagateFloat64NaN( float64 a
, float64 b STATUS_PARAM
)
422 flag aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
;
423 flag aIsLargerSignificand
;
426 aIsQuietNaN
= float64_is_quiet_nan( a
);
427 aIsSignalingNaN
= float64_is_signaling_nan( a
);
428 bIsQuietNaN
= float64_is_quiet_nan( b
);
429 bIsSignalingNaN
= float64_is_signaling_nan( b
);
433 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
435 if ( STATUS(default_nan_mode
) )
436 return float64_default_nan
;
438 if ((bits64
)(av
<<1) < (bits64
)(bv
<<1)) {
439 aIsLargerSignificand
= 0;
440 } else if ((bits64
)(bv
<<1) < (bits64
)(av
<<1)) {
441 aIsLargerSignificand
= 1;
443 aIsLargerSignificand
= (av
< bv
) ? 1 : 0;
446 if (pickNaN(aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
,
447 aIsLargerSignificand
)) {
448 return float64_maybe_silence_nan(b
);
450 return float64_maybe_silence_nan(a
);
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,
460 *----------------------------------------------------------------------------*/
462 #define floatx80_default_nan_high 0x7FFF
463 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
465 #define floatx80_default_nan_high 0xFFFF
466 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
469 /*----------------------------------------------------------------------------
470 | Returns 1 if the extended double-precision floating-point value `a' is a
471 | quiet NaN; otherwise returns 0. This slightly differs from the same
472 | function for other types as floatx80 has an explicit bit.
473 *----------------------------------------------------------------------------*/
475 int floatx80_is_quiet_nan( floatx80 a
)
480 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
482 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
483 && (bits64
) ( aLow
<<1 )
484 && ( a
.low
== aLow
);
486 return ( ( a
.high
& 0x7FFF ) == 0x7FFF )
487 && (LIT64( 0x8000000000000000 ) <= ((bits64
) ( a
.low
<<1 )));
491 /*----------------------------------------------------------------------------
492 | Returns 1 if the extended double-precision floating-point value `a' is a
493 | signaling NaN; otherwise returns 0. This slightly differs from the same
494 | function for other types as floatx80 has an explicit bit.
495 *----------------------------------------------------------------------------*/
497 int floatx80_is_signaling_nan( floatx80 a
)
500 return ( ( a
.high
& 0x7FFF ) == 0x7FFF )
501 && (LIT64( 0x8000000000000000 ) <= ((bits64
) ( a
.low
<<1 )));
505 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
507 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
508 && (bits64
) ( aLow
<<1 )
509 && ( a
.low
== aLow
);
513 /*----------------------------------------------------------------------------
514 | Returns a quiet NaN if the extended double-precision floating point value
515 | `a' is a signaling NaN; otherwise returns `a'.
516 *----------------------------------------------------------------------------*/
518 floatx80
floatx80_maybe_silence_nan( floatx80 a
)
520 if (floatx80_is_signaling_nan(a
)) {
522 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
523 a
.low
= floatx80_default_nan_low
;
524 a
.high
= floatx80_default_nan_high
;
526 # error Rules for silencing a signaling NaN are target-specific
529 a
.low
|= LIT64( 0xC000000000000000 );
536 /*----------------------------------------------------------------------------
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 *----------------------------------------------------------------------------*/
542 static commonNaNT
floatx80ToCommonNaN( floatx80 a STATUS_PARAM
)
546 if ( floatx80_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
553 /*----------------------------------------------------------------------------
554 | Returns the result of converting the canonical NaN `a' to the extended
555 | double-precision floating-point format.
556 *----------------------------------------------------------------------------*/
558 static floatx80
commonNaNToFloatx80( commonNaNT a
)
565 z
.low
= floatx80_default_nan_low
;
566 z
.high
= ( ( (bits16
) a
.sign
)<<15 ) | 0x7FFF;
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 *----------------------------------------------------------------------------*/
576 static floatx80
propagateFloatx80NaN( floatx80 a
, floatx80 b STATUS_PARAM
)
578 flag aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
;
579 flag aIsLargerSignificand
;
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
);
586 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
588 if ( STATUS(default_nan_mode
) ) {
589 a
.low
= floatx80_default_nan_low
;
590 a
.high
= floatx80_default_nan_high
;
595 aIsLargerSignificand
= 0;
596 } else if (b
.low
< a
.low
) {
597 aIsLargerSignificand
= 1;
599 aIsLargerSignificand
= (a
.high
< b
.high
) ? 1 : 0;
602 if (pickNaN(aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
,
603 aIsLargerSignificand
)) {
604 return floatx80_maybe_silence_nan(b
);
606 return floatx80_maybe_silence_nan(a
);
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 *----------------------------------------------------------------------------*/
619 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
620 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
622 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
623 #define float128_default_nan_low LIT64( 0x0000000000000000 )
626 /*----------------------------------------------------------------------------
627 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
628 | NaN; otherwise returns 0.
629 *----------------------------------------------------------------------------*/
631 int float128_is_quiet_nan( float128 a
)
635 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
636 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
639 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
640 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
644 /*----------------------------------------------------------------------------
645 | Returns 1 if the quadruple-precision floating-point value `a' is a
646 | signaling NaN; otherwise returns 0.
647 *----------------------------------------------------------------------------*/
649 int float128_is_signaling_nan( float128 a
)
653 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
654 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
657 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
658 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
662 /*----------------------------------------------------------------------------
663 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
664 | a signaling NaN; otherwise returns `a'.
665 *----------------------------------------------------------------------------*/
667 float128
float128_maybe_silence_nan( float128 a
)
669 if (float128_is_signaling_nan(a
)) {
671 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
672 a
.low
= float128_default_nan_low
;
673 a
.high
= float128_default_nan_high
;
675 # error Rules for silencing a signaling NaN are target-specific
678 a
.high
|= LIT64( 0x0000800000000000 );
685 /*----------------------------------------------------------------------------
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 *----------------------------------------------------------------------------*/
691 static commonNaNT
float128ToCommonNaN( float128 a STATUS_PARAM
)
695 if ( float128_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
697 shortShift128Left( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
701 /*----------------------------------------------------------------------------
702 | Returns the result of converting the canonical NaN `a' to the quadruple-
703 | precision floating-point format.
704 *----------------------------------------------------------------------------*/
706 static float128
commonNaNToFloat128( commonNaNT a
)
710 shift128Right( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
711 z
.high
|= ( ( (bits64
) a
.sign
)<<63 ) | LIT64( 0x7FFF000000000000 );
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 *----------------------------------------------------------------------------*/
721 static float128
propagateFloat128NaN( float128 a
, float128 b STATUS_PARAM
)
723 flag aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
;
724 flag aIsLargerSignificand
;
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
);
731 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
733 if ( STATUS(default_nan_mode
) ) {
734 a
.low
= float128_default_nan_low
;
735 a
.high
= float128_default_nan_high
;
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;
744 aIsLargerSignificand
= (a
.high
< b
.high
) ? 1 : 0;
747 if (pickNaN(aIsQuietNaN
, aIsSignalingNaN
, bIsQuietNaN
, bIsSignalingNaN
,
748 aIsLargerSignificand
)) {
749 return float128_maybe_silence_nan(b
);
751 return float128_maybe_silence_nan(a
);