target-mips: Implement correct NaN propagation rules
[qemu.git] / fpu / softfloat-specialize.h
blobacdd299f51a3ce12fe8c5f2458066a1abae0a554
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 calling floatXX_maybe_silence_nan() before
165 | returning them.
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 *----------------------------------------------------------------------------*/
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
181 * 3. A (quiet)
182 * 4. B (quiet)
183 * A signaling NaN is always quietened before returning it.
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;
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
208 * 3. A (quiet)
209 * 4. B (quiet)
210 * A signaling NaN is always silenced before returning it.
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;
222 #else
223 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
224 flag aIsLargerSignificand)
226 /* This implements x87 NaN propagation rules:
227 * SNaN + QNaN => return the QNaN
228 * two SNaNs => return the one with the larger significand, silenced
229 * two QNaNs => return the one with the larger significand
230 * SNaN and a non-NaN => return the SNaN, silenced
231 * QNaN and a non-NaN => return the QNaN
233 * If we get down to comparing significands and they are the same,
234 * return the NaN with the positive sign bit (if any).
236 if (aIsSNaN) {
237 if (bIsSNaN) {
238 return aIsLargerSignificand ? 0 : 1;
240 return bIsQNaN ? 1 : 0;
242 else if (aIsQNaN) {
243 if (bIsSNaN || !bIsQNaN)
244 return 0;
245 else {
246 return aIsLargerSignificand ? 0 : 1;
248 } else {
249 return 1;
252 #endif
254 /*----------------------------------------------------------------------------
255 | Takes two single-precision floating-point values `a' and `b', one of which
256 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
257 | signaling NaN, the invalid exception is raised.
258 *----------------------------------------------------------------------------*/
260 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
262 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
263 flag aIsLargerSignificand;
264 bits32 av, bv;
266 if ( STATUS(default_nan_mode) )
267 return float32_default_nan;
269 aIsQuietNaN = float32_is_quiet_nan( a );
270 aIsSignalingNaN = float32_is_signaling_nan( a );
271 bIsQuietNaN = float32_is_quiet_nan( b );
272 bIsSignalingNaN = float32_is_signaling_nan( b );
273 av = float32_val(a);
274 bv = float32_val(b);
276 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
278 if ((bits32)(av<<1) < (bits32)(bv<<1)) {
279 aIsLargerSignificand = 0;
280 } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
281 aIsLargerSignificand = 1;
282 } else {
283 aIsLargerSignificand = (av < bv) ? 1 : 0;
286 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
287 aIsLargerSignificand)) {
288 return float32_maybe_silence_nan(b);
289 } else {
290 return float32_maybe_silence_nan(a);
294 /*----------------------------------------------------------------------------
295 | The pattern for a default generated double-precision NaN.
296 *----------------------------------------------------------------------------*/
297 #if defined(TARGET_SPARC)
298 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
299 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
300 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
301 #elif SNAN_BIT_IS_ONE
302 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
303 #else
304 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
305 #endif
307 /*----------------------------------------------------------------------------
308 | Returns 1 if the double-precision floating-point value `a' is a quiet
309 | NaN; otherwise returns 0.
310 *----------------------------------------------------------------------------*/
312 int float64_is_quiet_nan( float64 a_ )
314 bits64 a = float64_val(a_);
315 #if SNAN_BIT_IS_ONE
316 return
317 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
318 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
319 #else
320 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
321 #endif
324 /*----------------------------------------------------------------------------
325 | Returns 1 if the double-precision floating-point value `a' is a signaling
326 | NaN; otherwise returns 0.
327 *----------------------------------------------------------------------------*/
329 int float64_is_signaling_nan( float64 a_ )
331 bits64 a = float64_val(a_);
332 #if SNAN_BIT_IS_ONE
333 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
334 #else
335 return
336 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
337 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
338 #endif
341 /*----------------------------------------------------------------------------
342 | Returns a quiet NaN if the double-precision floating point value `a' is a
343 | signaling NaN; otherwise returns `a'.
344 *----------------------------------------------------------------------------*/
346 float64 float64_maybe_silence_nan( float64 a_ )
348 if (float64_is_signaling_nan(a_)) {
349 #if SNAN_BIT_IS_ONE
350 # if defined(TARGET_MIPS)
351 return float64_default_nan;
352 # else
353 # error Rules for silencing a signaling NaN are target-specific
354 # endif
355 #else
356 bits64 a = float64_val(a_);
357 a |= LIT64( 0x0008000000000000 );
358 return make_float64(a);
359 #endif
361 return a_;
364 /*----------------------------------------------------------------------------
365 | Returns the result of converting the double-precision floating-point NaN
366 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
367 | exception is raised.
368 *----------------------------------------------------------------------------*/
370 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
372 commonNaNT z;
374 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
375 z.sign = float64_val(a)>>63;
376 z.low = 0;
377 z.high = float64_val(a)<<12;
378 return z;
381 /*----------------------------------------------------------------------------
382 | Returns the result of converting the canonical NaN `a' to the double-
383 | precision floating-point format.
384 *----------------------------------------------------------------------------*/
386 static float64 commonNaNToFloat64( commonNaNT a )
388 bits64 mantissa = a.high>>12;
390 if ( mantissa )
391 return make_float64(
392 ( ( (bits64) a.sign )<<63 )
393 | LIT64( 0x7FF0000000000000 )
394 | ( a.high>>12 ));
395 else
396 return float64_default_nan;
399 /*----------------------------------------------------------------------------
400 | Takes two double-precision floating-point values `a' and `b', one of which
401 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
402 | signaling NaN, the invalid exception is raised.
403 *----------------------------------------------------------------------------*/
405 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
407 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
408 flag aIsLargerSignificand;
409 bits64 av, bv;
411 if ( STATUS(default_nan_mode) )
412 return float64_default_nan;
414 aIsQuietNaN = float64_is_quiet_nan( a );
415 aIsSignalingNaN = float64_is_signaling_nan( a );
416 bIsQuietNaN = float64_is_quiet_nan( b );
417 bIsSignalingNaN = float64_is_signaling_nan( b );
418 av = float64_val(a);
419 bv = float64_val(b);
421 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
423 if ((bits64)(av<<1) < (bits64)(bv<<1)) {
424 aIsLargerSignificand = 0;
425 } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
426 aIsLargerSignificand = 1;
427 } else {
428 aIsLargerSignificand = (av < bv) ? 1 : 0;
431 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
432 aIsLargerSignificand)) {
433 return float64_maybe_silence_nan(b);
434 } else {
435 return float64_maybe_silence_nan(a);
439 #ifdef FLOATX80
441 /*----------------------------------------------------------------------------
442 | The pattern for a default generated extended double-precision NaN. The
443 | `high' and `low' values hold the most- and least-significant bits,
444 | respectively.
445 *----------------------------------------------------------------------------*/
446 #if SNAN_BIT_IS_ONE
447 #define floatx80_default_nan_high 0x7FFF
448 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
449 #else
450 #define floatx80_default_nan_high 0xFFFF
451 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
452 #endif
454 /*----------------------------------------------------------------------------
455 | Returns 1 if the extended double-precision floating-point value `a' is a
456 | quiet NaN; otherwise returns 0.
457 *----------------------------------------------------------------------------*/
459 int floatx80_is_quiet_nan( floatx80 a )
461 #if SNAN_BIT_IS_ONE
462 bits64 aLow;
464 aLow = a.low & ~ LIT64( 0x4000000000000000 );
465 return
466 ( ( a.high & 0x7FFF ) == 0x7FFF )
467 && (bits64) ( aLow<<1 )
468 && ( a.low == aLow );
469 #else
470 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
471 #endif
474 /*----------------------------------------------------------------------------
475 | Returns 1 if the extended double-precision floating-point value `a' is a
476 | signaling NaN; otherwise returns 0.
477 *----------------------------------------------------------------------------*/
479 int floatx80_is_signaling_nan( floatx80 a )
481 #if SNAN_BIT_IS_ONE
482 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
483 #else
484 bits64 aLow;
486 aLow = a.low & ~ LIT64( 0x4000000000000000 );
487 return
488 ( ( a.high & 0x7FFF ) == 0x7FFF )
489 && (bits64) ( aLow<<1 )
490 && ( a.low == aLow );
491 #endif
494 /*----------------------------------------------------------------------------
495 | Returns a quiet NaN if the extended double-precision floating point value
496 | `a' is a signaling NaN; otherwise returns `a'.
497 *----------------------------------------------------------------------------*/
499 floatx80 floatx80_maybe_silence_nan( floatx80 a )
501 if (floatx80_is_signaling_nan(a)) {
502 #if SNAN_BIT_IS_ONE
503 # if defined(TARGET_MIPS)
504 a.low = floatx80_default_nan_low;
505 a.high = floatx80_default_nan_high;
506 # else
507 # error Rules for silencing a signaling NaN are target-specific
508 # endif
509 #else
510 a.low |= LIT64( 0xC000000000000000 );
511 return a;
512 #endif
514 return a;
517 /*----------------------------------------------------------------------------
518 | Returns the result of converting the extended double-precision floating-
519 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
520 | invalid exception is raised.
521 *----------------------------------------------------------------------------*/
523 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
525 commonNaNT z;
527 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
528 z.sign = a.high>>15;
529 z.low = 0;
530 z.high = a.low;
531 return z;
534 /*----------------------------------------------------------------------------
535 | Returns the result of converting the canonical NaN `a' to the extended
536 | double-precision floating-point format.
537 *----------------------------------------------------------------------------*/
539 static floatx80 commonNaNToFloatx80( commonNaNT a )
541 floatx80 z;
543 if (a.high)
544 z.low = a.high;
545 else
546 z.low = floatx80_default_nan_low;
547 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
548 return z;
551 /*----------------------------------------------------------------------------
552 | Takes two extended double-precision floating-point values `a' and `b', one
553 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
554 | `b' is a signaling NaN, the invalid exception is raised.
555 *----------------------------------------------------------------------------*/
557 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
559 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
560 flag aIsLargerSignificand;
562 if ( STATUS(default_nan_mode) ) {
563 a.low = floatx80_default_nan_low;
564 a.high = floatx80_default_nan_high;
565 return a;
568 aIsQuietNaN = floatx80_is_quiet_nan( a );
569 aIsSignalingNaN = floatx80_is_signaling_nan( a );
570 bIsQuietNaN = floatx80_is_quiet_nan( b );
571 bIsSignalingNaN = floatx80_is_signaling_nan( b );
573 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
575 if (a.low < b.low) {
576 aIsLargerSignificand = 0;
577 } else if (b.low < a.low) {
578 aIsLargerSignificand = 1;
579 } else {
580 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
583 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
584 aIsLargerSignificand)) {
585 return floatx80_maybe_silence_nan(b);
586 } else {
587 return floatx80_maybe_silence_nan(a);
591 #endif
593 #ifdef FLOAT128
595 /*----------------------------------------------------------------------------
596 | The pattern for a default generated quadruple-precision NaN. The `high' and
597 | `low' values hold the most- and least-significant bits, respectively.
598 *----------------------------------------------------------------------------*/
599 #if SNAN_BIT_IS_ONE
600 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
601 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
602 #else
603 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
604 #define float128_default_nan_low LIT64( 0x0000000000000000 )
605 #endif
607 /*----------------------------------------------------------------------------
608 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
609 | NaN; otherwise returns 0.
610 *----------------------------------------------------------------------------*/
612 int float128_is_quiet_nan( float128 a )
614 #if SNAN_BIT_IS_ONE
615 return
616 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
617 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
618 #else
619 return
620 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
621 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
622 #endif
625 /*----------------------------------------------------------------------------
626 | Returns 1 if the quadruple-precision floating-point value `a' is a
627 | signaling NaN; otherwise returns 0.
628 *----------------------------------------------------------------------------*/
630 int float128_is_signaling_nan( float128 a )
632 #if SNAN_BIT_IS_ONE
633 return
634 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
635 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
636 #else
637 return
638 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
639 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
640 #endif
643 /*----------------------------------------------------------------------------
644 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
645 | a signaling NaN; otherwise returns `a'.
646 *----------------------------------------------------------------------------*/
648 float128 float128_maybe_silence_nan( float128 a )
650 if (float128_is_signaling_nan(a)) {
651 #if SNAN_BIT_IS_ONE
652 # if defined(TARGET_MIPS)
653 a.low = float128_default_nan_low;
654 a.high = float128_default_nan_high;
655 # else
656 # error Rules for silencing a signaling NaN are target-specific
657 # endif
658 #else
659 a.high |= LIT64( 0x0000800000000000 );
660 return a;
661 #endif
663 return a;
666 /*----------------------------------------------------------------------------
667 | Returns the result of converting the quadruple-precision floating-point NaN
668 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
669 | exception is raised.
670 *----------------------------------------------------------------------------*/
672 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
674 commonNaNT z;
676 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
677 z.sign = a.high>>63;
678 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
679 return z;
682 /*----------------------------------------------------------------------------
683 | Returns the result of converting the canonical NaN `a' to the quadruple-
684 | precision floating-point format.
685 *----------------------------------------------------------------------------*/
687 static float128 commonNaNToFloat128( commonNaNT a )
689 float128 z;
691 shift128Right( a.high, a.low, 16, &z.high, &z.low );
692 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
693 return z;
696 /*----------------------------------------------------------------------------
697 | Takes two quadruple-precision floating-point values `a' and `b', one of
698 | which is a NaN, and returns the appropriate NaN result. If either `a' or
699 | `b' is a signaling NaN, the invalid exception is raised.
700 *----------------------------------------------------------------------------*/
702 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
704 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
705 flag aIsLargerSignificand;
707 if ( STATUS(default_nan_mode) ) {
708 a.low = float128_default_nan_low;
709 a.high = float128_default_nan_high;
710 return a;
713 aIsQuietNaN = float128_is_quiet_nan( a );
714 aIsSignalingNaN = float128_is_signaling_nan( a );
715 bIsQuietNaN = float128_is_quiet_nan( b );
716 bIsSignalingNaN = float128_is_signaling_nan( b );
718 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
720 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
721 aIsLargerSignificand = 0;
722 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
723 aIsLargerSignificand = 1;
724 } else {
725 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
728 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
729 aIsLargerSignificand)) {
730 return float128_maybe_silence_nan(b);
731 } else {
732 return float128_maybe_silence_nan(a);
736 #endif