]> git.proxmox.com Git - qemu.git/blob - fpu/softfloat-specialize.h
softfloat: fix default-NaN mode
[qemu.git] / fpu / softfloat-specialize.h
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
33 #if defined(TARGET_MIPS) || defined(TARGET_SH4)
34 #define SNAN_BIT_IS_ONE 1
35 #else
36 #define SNAN_BIT_IS_ONE 0
37 #endif
38
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 *----------------------------------------------------------------------------*/
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)
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
71
72 /*----------------------------------------------------------------------------
73 | Returns 1 if the single-precision floating-point value `a' is a quiet
74 | NaN; otherwise returns 0.
75 *----------------------------------------------------------------------------*/
76
77 int float32_is_quiet_nan( float32 a_ )
78 {
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
85 }
86
87 /*----------------------------------------------------------------------------
88 | Returns 1 if the single-precision floating-point value `a' is a signaling
89 | NaN; otherwise returns 0.
90 *----------------------------------------------------------------------------*/
91
92 int float32_is_signaling_nan( float32 a_ )
93 {
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
100 }
101
102 /*----------------------------------------------------------------------------
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 /*----------------------------------------------------------------------------
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 );
136 z.sign = float32_val(a)>>31;
137 z.low = 0;
138 z.high = ( (bits64) float32_val(a) )<<41;
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 {
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;
155 }
156
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.
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 /*----------------------------------------------------------------------------
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 {
277 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
278 flag aIsLargerSignificand;
279 bits32 av, bv;
280
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 );
285 av = float32_val(a);
286 bv = float32_val(b);
287
288 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
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;
299 }
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);
306 }
307 }
308
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 ))
318 #else
319 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
320 #endif
321
322 /*----------------------------------------------------------------------------
323 | Returns 1 if the double-precision floating-point value `a' is a quiet
324 | NaN; otherwise returns 0.
325 *----------------------------------------------------------------------------*/
326
327 int float64_is_quiet_nan( float64 a_ )
328 {
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
337 }
338
339 /*----------------------------------------------------------------------------
340 | Returns 1 if the double-precision floating-point value `a' is a signaling
341 | NaN; otherwise returns 0.
342 *----------------------------------------------------------------------------*/
343
344 int float64_is_signaling_nan( float64 a_ )
345 {
346 bits64 a = float64_val(a_);
347 #if SNAN_BIT_IS_ONE
348 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
349 #else
350 return
351 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
352 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
353 #endif
354 }
355
356 /*----------------------------------------------------------------------------
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 /*----------------------------------------------------------------------------
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);
390 z.sign = float64_val(a)>>63;
391 z.low = 0;
392 z.high = float64_val(a)<<12;
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 {
403 bits64 mantissa = a.high>>12;
404
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;
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 {
422 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
423 flag aIsLargerSignificand;
424 bits64 av, bv;
425
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 );
430 av = float64_val(a);
431 bv = float64_val(b);
432
433 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
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;
444 }
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);
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 *----------------------------------------------------------------------------*/
461 #if SNAN_BIT_IS_ONE
462 #define floatx80_default_nan_high 0x7FFF
463 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
464 #else
465 #define floatx80_default_nan_high 0xFFFF
466 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
467 #endif
468
469 /*----------------------------------------------------------------------------
470 | Returns 1 if the extended double-precision floating-point value `a' is a
471 | quiet NaN; otherwise returns 0.
472 *----------------------------------------------------------------------------*/
473
474 int floatx80_is_quiet_nan( floatx80 a )
475 {
476 #if SNAN_BIT_IS_ONE
477 bits64 aLow;
478
479 aLow = a.low & ~ LIT64( 0x4000000000000000 );
480 return
481 ( ( a.high & 0x7FFF ) == 0x7FFF )
482 && (bits64) ( aLow<<1 )
483 && ( a.low == aLow );
484 #else
485 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
486 #endif
487 }
488
489 /*----------------------------------------------------------------------------
490 | Returns 1 if the extended double-precision floating-point value `a' is a
491 | signaling NaN; otherwise returns 0.
492 *----------------------------------------------------------------------------*/
493
494 int floatx80_is_signaling_nan( floatx80 a )
495 {
496 #if SNAN_BIT_IS_ONE
497 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
498 #else
499 bits64 aLow;
500
501 aLow = a.low & ~ LIT64( 0x4000000000000000 );
502 return
503 ( ( a.high & 0x7FFF ) == 0x7FFF )
504 && (bits64) ( aLow<<1 )
505 && ( a.low == aLow );
506 #endif
507 }
508
509 /*----------------------------------------------------------------------------
510 | Returns a quiet NaN if the extended double-precision floating point value
511 | `a' is a signaling NaN; otherwise returns `a'.
512 *----------------------------------------------------------------------------*/
513
514 floatx80 floatx80_maybe_silence_nan( floatx80 a )
515 {
516 if (floatx80_is_signaling_nan(a)) {
517 #if SNAN_BIT_IS_ONE
518 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
519 a.low = floatx80_default_nan_low;
520 a.high = floatx80_default_nan_high;
521 # else
522 # error Rules for silencing a signaling NaN are target-specific
523 # endif
524 #else
525 a.low |= LIT64( 0xC000000000000000 );
526 return a;
527 #endif
528 }
529 return a;
530 }
531
532 /*----------------------------------------------------------------------------
533 | Returns the result of converting the extended double-precision floating-
534 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
535 | invalid exception is raised.
536 *----------------------------------------------------------------------------*/
537
538 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
539 {
540 commonNaNT z;
541
542 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
543 z.sign = a.high>>15;
544 z.low = 0;
545 z.high = a.low;
546 return z;
547 }
548
549 /*----------------------------------------------------------------------------
550 | Returns the result of converting the canonical NaN `a' to the extended
551 | double-precision floating-point format.
552 *----------------------------------------------------------------------------*/
553
554 static floatx80 commonNaNToFloatx80( commonNaNT a )
555 {
556 floatx80 z;
557
558 if (a.high)
559 z.low = a.high;
560 else
561 z.low = floatx80_default_nan_low;
562 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
563 return z;
564 }
565
566 /*----------------------------------------------------------------------------
567 | Takes two extended double-precision floating-point values `a' and `b', one
568 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
569 | `b' is a signaling NaN, the invalid exception is raised.
570 *----------------------------------------------------------------------------*/
571
572 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
573 {
574 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
575 flag aIsLargerSignificand;
576
577 aIsQuietNaN = floatx80_is_quiet_nan( a );
578 aIsSignalingNaN = floatx80_is_signaling_nan( a );
579 bIsQuietNaN = floatx80_is_quiet_nan( b );
580 bIsSignalingNaN = floatx80_is_signaling_nan( b );
581
582 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
583
584 if ( STATUS(default_nan_mode) ) {
585 a.low = floatx80_default_nan_low;
586 a.high = floatx80_default_nan_high;
587 return a;
588 }
589
590 if (a.low < b.low) {
591 aIsLargerSignificand = 0;
592 } else if (b.low < a.low) {
593 aIsLargerSignificand = 1;
594 } else {
595 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
596 }
597
598 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
599 aIsLargerSignificand)) {
600 return floatx80_maybe_silence_nan(b);
601 } else {
602 return floatx80_maybe_silence_nan(a);
603 }
604 }
605
606 #endif
607
608 #ifdef FLOAT128
609
610 /*----------------------------------------------------------------------------
611 | The pattern for a default generated quadruple-precision NaN. The `high' and
612 | `low' values hold the most- and least-significant bits, respectively.
613 *----------------------------------------------------------------------------*/
614 #if SNAN_BIT_IS_ONE
615 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
616 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
617 #else
618 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
619 #define float128_default_nan_low LIT64( 0x0000000000000000 )
620 #endif
621
622 /*----------------------------------------------------------------------------
623 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
624 | NaN; otherwise returns 0.
625 *----------------------------------------------------------------------------*/
626
627 int float128_is_quiet_nan( float128 a )
628 {
629 #if SNAN_BIT_IS_ONE
630 return
631 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
632 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
633 #else
634 return
635 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
636 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
637 #endif
638 }
639
640 /*----------------------------------------------------------------------------
641 | Returns 1 if the quadruple-precision floating-point value `a' is a
642 | signaling NaN; otherwise returns 0.
643 *----------------------------------------------------------------------------*/
644
645 int float128_is_signaling_nan( float128 a )
646 {
647 #if SNAN_BIT_IS_ONE
648 return
649 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
650 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
651 #else
652 return
653 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
654 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
655 #endif
656 }
657
658 /*----------------------------------------------------------------------------
659 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
660 | a signaling NaN; otherwise returns `a'.
661 *----------------------------------------------------------------------------*/
662
663 float128 float128_maybe_silence_nan( float128 a )
664 {
665 if (float128_is_signaling_nan(a)) {
666 #if SNAN_BIT_IS_ONE
667 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
668 a.low = float128_default_nan_low;
669 a.high = float128_default_nan_high;
670 # else
671 # error Rules for silencing a signaling NaN are target-specific
672 # endif
673 #else
674 a.high |= LIT64( 0x0000800000000000 );
675 return a;
676 #endif
677 }
678 return a;
679 }
680
681 /*----------------------------------------------------------------------------
682 | Returns the result of converting the quadruple-precision floating-point NaN
683 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
684 | exception is raised.
685 *----------------------------------------------------------------------------*/
686
687 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
688 {
689 commonNaNT z;
690
691 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
692 z.sign = a.high>>63;
693 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
694 return z;
695 }
696
697 /*----------------------------------------------------------------------------
698 | Returns the result of converting the canonical NaN `a' to the quadruple-
699 | precision floating-point format.
700 *----------------------------------------------------------------------------*/
701
702 static float128 commonNaNToFloat128( commonNaNT a )
703 {
704 float128 z;
705
706 shift128Right( a.high, a.low, 16, &z.high, &z.low );
707 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
708 return z;
709 }
710
711 /*----------------------------------------------------------------------------
712 | Takes two quadruple-precision floating-point values `a' and `b', one of
713 | which is a NaN, and returns the appropriate NaN result. If either `a' or
714 | `b' is a signaling NaN, the invalid exception is raised.
715 *----------------------------------------------------------------------------*/
716
717 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
718 {
719 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
720 flag aIsLargerSignificand;
721
722 aIsQuietNaN = float128_is_quiet_nan( a );
723 aIsSignalingNaN = float128_is_signaling_nan( a );
724 bIsQuietNaN = float128_is_quiet_nan( b );
725 bIsSignalingNaN = float128_is_signaling_nan( b );
726
727 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
728
729 if ( STATUS(default_nan_mode) ) {
730 a.low = float128_default_nan_low;
731 a.high = float128_default_nan_high;
732 return a;
733 }
734
735 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
736 aIsLargerSignificand = 0;
737 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
738 aIsLargerSignificand = 1;
739 } else {
740 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
741 }
742
743 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
744 aIsLargerSignificand)) {
745 return float128_maybe_silence_nan(b);
746 } else {
747 return float128_maybe_silence_nan(a);
748 }
749 }
750
751 #endif