Fix conversions from pointer to int and vice versa
[qemu.git] / fpu / softfloat-specialize.h
blobadc5adad6a3f9d0395bbbac49359d7be20a28fb1
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 /*----------------------------------------------------------------------------
34 | Raises the exceptions specified by `flags'. Floating-point traps can be
35 | defined here if desired. It is currently not possible for such a trap
36 | to substitute a result value. If traps are not implemented, this routine
37 | should be simply `float_exception_flags |= flags;'.
38 *----------------------------------------------------------------------------*/
40 void float_raise( int8 flags STATUS_PARAM )
42 STATUS(float_exception_flags) |= flags;
45 /*----------------------------------------------------------------------------
46 | Internal canonical NaN format.
47 *----------------------------------------------------------------------------*/
48 typedef struct {
49 flag sign;
50 bits64 high, low;
51 } commonNaNT;
53 /*----------------------------------------------------------------------------
54 | Returns 1 if the half-precision floating-point value `a' is a quiet
55 | NaN; otherwise returns 0.
56 *----------------------------------------------------------------------------*/
58 int float16_is_quiet_nan(float16 a_)
60 uint16_t a = float16_val(a_);
61 #if SNAN_BIT_IS_ONE
62 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
63 #else
64 return ((a & ~0x8000) >= 0x7c80);
65 #endif
68 /*----------------------------------------------------------------------------
69 | Returns 1 if the half-precision floating-point value `a' is a signaling
70 | NaN; otherwise returns 0.
71 *----------------------------------------------------------------------------*/
73 int float16_is_signaling_nan(float16 a_)
75 uint16_t a = float16_val(a_);
76 #if SNAN_BIT_IS_ONE
77 return ((a & ~0x8000) >= 0x7c80);
78 #else
79 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
80 #endif
83 /*----------------------------------------------------------------------------
84 | Returns a quiet NaN if the half-precision floating point value `a' is a
85 | signaling NaN; otherwise returns `a'.
86 *----------------------------------------------------------------------------*/
87 float16 float16_maybe_silence_nan(float16 a_)
89 if (float16_is_signaling_nan(a_)) {
90 #if SNAN_BIT_IS_ONE
91 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
92 return float16_default_nan;
93 # else
94 # error Rules for silencing a signaling NaN are target-specific
95 # endif
96 #else
97 uint16_t a = float16_val(a_);
98 a |= (1 << 9);
99 return make_float16(a);
100 #endif
102 return a_;
105 /*----------------------------------------------------------------------------
106 | Returns the result of converting the half-precision floating-point NaN
107 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
108 | exception is raised.
109 *----------------------------------------------------------------------------*/
111 static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
113 commonNaNT z;
115 if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
116 z.sign = float16_val(a) >> 15;
117 z.low = 0;
118 z.high = ((bits64) float16_val(a))<<54;
119 return z;
122 /*----------------------------------------------------------------------------
123 | Returns the result of converting the canonical NaN `a' to the half-
124 | precision floating-point format.
125 *----------------------------------------------------------------------------*/
127 static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
129 uint16_t mantissa = a.high>>54;
131 if (STATUS(default_nan_mode)) {
132 return float16_default_nan;
135 if (mantissa) {
136 return make_float16(((((uint16_t) a.sign) << 15)
137 | (0x1F << 10) | mantissa));
138 } else {
139 return float16_default_nan;
143 /*----------------------------------------------------------------------------
144 | Returns 1 if the single-precision floating-point value `a' is a quiet
145 | NaN; otherwise returns 0.
146 *----------------------------------------------------------------------------*/
148 int float32_is_quiet_nan( float32 a_ )
150 uint32_t a = float32_val(a_);
151 #if SNAN_BIT_IS_ONE
152 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
153 #else
154 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
155 #endif
158 /*----------------------------------------------------------------------------
159 | Returns 1 if the single-precision floating-point value `a' is a signaling
160 | NaN; otherwise returns 0.
161 *----------------------------------------------------------------------------*/
163 int float32_is_signaling_nan( float32 a_ )
165 uint32_t a = float32_val(a_);
166 #if SNAN_BIT_IS_ONE
167 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
168 #else
169 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
170 #endif
173 /*----------------------------------------------------------------------------
174 | Returns a quiet NaN if the single-precision floating point value `a' is a
175 | signaling NaN; otherwise returns `a'.
176 *----------------------------------------------------------------------------*/
178 float32 float32_maybe_silence_nan( float32 a_ )
180 if (float32_is_signaling_nan(a_)) {
181 #if SNAN_BIT_IS_ONE
182 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
183 return float32_default_nan;
184 # else
185 # error Rules for silencing a signaling NaN are target-specific
186 # endif
187 #else
188 bits32 a = float32_val(a_);
189 a |= (1 << 22);
190 return make_float32(a);
191 #endif
193 return a_;
196 /*----------------------------------------------------------------------------
197 | Returns the result of converting the single-precision floating-point NaN
198 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
199 | exception is raised.
200 *----------------------------------------------------------------------------*/
202 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
204 commonNaNT z;
206 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
207 z.sign = float32_val(a)>>31;
208 z.low = 0;
209 z.high = ( (bits64) float32_val(a) )<<41;
210 return z;
213 /*----------------------------------------------------------------------------
214 | Returns the result of converting the canonical NaN `a' to the single-
215 | precision floating-point format.
216 *----------------------------------------------------------------------------*/
218 static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
220 bits32 mantissa = a.high>>41;
222 if ( STATUS(default_nan_mode) ) {
223 return float32_default_nan;
226 if ( mantissa )
227 return make_float32(
228 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
229 else
230 return float32_default_nan;
233 /*----------------------------------------------------------------------------
234 | Select which NaN to propagate for a two-input operation.
235 | IEEE754 doesn't specify all the details of this, so the
236 | algorithm is target-specific.
237 | The routine is passed various bits of information about the
238 | two NaNs and should return 0 to select NaN a and 1 for NaN b.
239 | Note that signalling NaNs are always squashed to quiet NaNs
240 | by the caller, by calling floatXX_maybe_silence_nan() before
241 | returning them.
243 | aIsLargerSignificand is only valid if both a and b are NaNs
244 | of some kind, and is true if a has the larger significand,
245 | or if both a and b have the same significand but a is
246 | positive but b is negative. It is only needed for the x87
247 | tie-break rule.
248 *----------------------------------------------------------------------------*/
250 #if defined(TARGET_ARM)
251 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
252 flag aIsLargerSignificand)
254 /* ARM mandated NaN propagation rules: take the first of:
255 * 1. A if it is signaling
256 * 2. B if it is signaling
257 * 3. A (quiet)
258 * 4. B (quiet)
259 * A signaling NaN is always quietened before returning it.
261 if (aIsSNaN) {
262 return 0;
263 } else if (bIsSNaN) {
264 return 1;
265 } else if (aIsQNaN) {
266 return 0;
267 } else {
268 return 1;
271 #elif defined(TARGET_MIPS)
272 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
273 flag aIsLargerSignificand)
275 /* According to MIPS specifications, if one of the two operands is
276 * a sNaN, a new qNaN has to be generated. This is done in
277 * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
278 * says: "When possible, this QNaN result is one of the operand QNaN
279 * values." In practice it seems that most implementations choose
280 * the first operand if both operands are qNaN. In short this gives
281 * the following rules:
282 * 1. A if it is signaling
283 * 2. B if it is signaling
284 * 3. A (quiet)
285 * 4. B (quiet)
286 * A signaling NaN is always silenced before returning it.
288 if (aIsSNaN) {
289 return 0;
290 } else if (bIsSNaN) {
291 return 1;
292 } else if (aIsQNaN) {
293 return 0;
294 } else {
295 return 1;
298 #elif defined(TARGET_PPC)
299 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
300 flag aIsLargerSignificand)
302 /* PowerPC propagation rules:
303 * 1. A if it sNaN or qNaN
304 * 2. B if it sNaN or qNaN
305 * A signaling NaN is always silenced before returning it.
307 if (aIsSNaN || aIsQNaN) {
308 return 0;
309 } else {
310 return 1;
313 #else
314 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
315 flag aIsLargerSignificand)
317 /* This implements x87 NaN propagation rules:
318 * SNaN + QNaN => return the QNaN
319 * two SNaNs => return the one with the larger significand, silenced
320 * two QNaNs => return the one with the larger significand
321 * SNaN and a non-NaN => return the SNaN, silenced
322 * QNaN and a non-NaN => return the QNaN
324 * If we get down to comparing significands and they are the same,
325 * return the NaN with the positive sign bit (if any).
327 if (aIsSNaN) {
328 if (bIsSNaN) {
329 return aIsLargerSignificand ? 0 : 1;
331 return bIsQNaN ? 1 : 0;
333 else if (aIsQNaN) {
334 if (bIsSNaN || !bIsQNaN)
335 return 0;
336 else {
337 return aIsLargerSignificand ? 0 : 1;
339 } else {
340 return 1;
343 #endif
345 /*----------------------------------------------------------------------------
346 | Takes two single-precision floating-point values `a' and `b', one of which
347 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
348 | signaling NaN, the invalid exception is raised.
349 *----------------------------------------------------------------------------*/
351 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
353 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
354 flag aIsLargerSignificand;
355 bits32 av, bv;
357 aIsQuietNaN = float32_is_quiet_nan( a );
358 aIsSignalingNaN = float32_is_signaling_nan( a );
359 bIsQuietNaN = float32_is_quiet_nan( b );
360 bIsSignalingNaN = float32_is_signaling_nan( b );
361 av = float32_val(a);
362 bv = float32_val(b);
364 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
366 if ( STATUS(default_nan_mode) )
367 return float32_default_nan;
369 if ((bits32)(av<<1) < (bits32)(bv<<1)) {
370 aIsLargerSignificand = 0;
371 } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
372 aIsLargerSignificand = 1;
373 } else {
374 aIsLargerSignificand = (av < bv) ? 1 : 0;
377 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
378 aIsLargerSignificand)) {
379 return float32_maybe_silence_nan(b);
380 } else {
381 return float32_maybe_silence_nan(a);
385 /*----------------------------------------------------------------------------
386 | Returns 1 if the double-precision floating-point value `a' is a quiet
387 | NaN; otherwise returns 0.
388 *----------------------------------------------------------------------------*/
390 int float64_is_quiet_nan( float64 a_ )
392 bits64 a = float64_val(a_);
393 #if SNAN_BIT_IS_ONE
394 return
395 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
396 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
397 #else
398 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
399 #endif
402 /*----------------------------------------------------------------------------
403 | Returns 1 if the double-precision floating-point value `a' is a signaling
404 | NaN; otherwise returns 0.
405 *----------------------------------------------------------------------------*/
407 int float64_is_signaling_nan( float64 a_ )
409 bits64 a = float64_val(a_);
410 #if SNAN_BIT_IS_ONE
411 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
412 #else
413 return
414 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
415 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
416 #endif
419 /*----------------------------------------------------------------------------
420 | Returns a quiet NaN if the double-precision floating point value `a' is a
421 | signaling NaN; otherwise returns `a'.
422 *----------------------------------------------------------------------------*/
424 float64 float64_maybe_silence_nan( float64 a_ )
426 if (float64_is_signaling_nan(a_)) {
427 #if SNAN_BIT_IS_ONE
428 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
429 return float64_default_nan;
430 # else
431 # error Rules for silencing a signaling NaN are target-specific
432 # endif
433 #else
434 bits64 a = float64_val(a_);
435 a |= LIT64( 0x0008000000000000 );
436 return make_float64(a);
437 #endif
439 return a_;
442 /*----------------------------------------------------------------------------
443 | Returns the result of converting the double-precision floating-point NaN
444 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
445 | exception is raised.
446 *----------------------------------------------------------------------------*/
448 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
450 commonNaNT z;
452 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
453 z.sign = float64_val(a)>>63;
454 z.low = 0;
455 z.high = float64_val(a)<<12;
456 return z;
459 /*----------------------------------------------------------------------------
460 | Returns the result of converting the canonical NaN `a' to the double-
461 | precision floating-point format.
462 *----------------------------------------------------------------------------*/
464 static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
466 bits64 mantissa = a.high>>12;
468 if ( STATUS(default_nan_mode) ) {
469 return float64_default_nan;
472 if ( mantissa )
473 return make_float64(
474 ( ( (bits64) a.sign )<<63 )
475 | LIT64( 0x7FF0000000000000 )
476 | ( a.high>>12 ));
477 else
478 return float64_default_nan;
481 /*----------------------------------------------------------------------------
482 | Takes two double-precision floating-point values `a' and `b', one of which
483 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
484 | signaling NaN, the invalid exception is raised.
485 *----------------------------------------------------------------------------*/
487 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
489 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
490 flag aIsLargerSignificand;
491 bits64 av, bv;
493 aIsQuietNaN = float64_is_quiet_nan( a );
494 aIsSignalingNaN = float64_is_signaling_nan( a );
495 bIsQuietNaN = float64_is_quiet_nan( b );
496 bIsSignalingNaN = float64_is_signaling_nan( b );
497 av = float64_val(a);
498 bv = float64_val(b);
500 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
502 if ( STATUS(default_nan_mode) )
503 return float64_default_nan;
505 if ((bits64)(av<<1) < (bits64)(bv<<1)) {
506 aIsLargerSignificand = 0;
507 } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
508 aIsLargerSignificand = 1;
509 } else {
510 aIsLargerSignificand = (av < bv) ? 1 : 0;
513 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
514 aIsLargerSignificand)) {
515 return float64_maybe_silence_nan(b);
516 } else {
517 return float64_maybe_silence_nan(a);
521 #ifdef FLOATX80
523 /*----------------------------------------------------------------------------
524 | Returns 1 if the extended double-precision floating-point value `a' is a
525 | quiet NaN; otherwise returns 0. This slightly differs from the same
526 | function for other types as floatx80 has an explicit bit.
527 *----------------------------------------------------------------------------*/
529 int floatx80_is_quiet_nan( floatx80 a )
531 #if SNAN_BIT_IS_ONE
532 bits64 aLow;
534 aLow = a.low & ~ LIT64( 0x4000000000000000 );
535 return
536 ( ( a.high & 0x7FFF ) == 0x7FFF )
537 && (bits64) ( aLow<<1 )
538 && ( a.low == aLow );
539 #else
540 return ( ( a.high & 0x7FFF ) == 0x7FFF )
541 && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
542 #endif
545 /*----------------------------------------------------------------------------
546 | Returns 1 if the extended double-precision floating-point value `a' is a
547 | signaling NaN; otherwise returns 0. This slightly differs from the same
548 | function for other types as floatx80 has an explicit bit.
549 *----------------------------------------------------------------------------*/
551 int floatx80_is_signaling_nan( floatx80 a )
553 #if SNAN_BIT_IS_ONE
554 return ( ( a.high & 0x7FFF ) == 0x7FFF )
555 && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
556 #else
557 bits64 aLow;
559 aLow = a.low & ~ LIT64( 0x4000000000000000 );
560 return
561 ( ( a.high & 0x7FFF ) == 0x7FFF )
562 && (bits64) ( aLow<<1 )
563 && ( a.low == aLow );
564 #endif
567 /*----------------------------------------------------------------------------
568 | Returns a quiet NaN if the extended double-precision floating point value
569 | `a' is a signaling NaN; otherwise returns `a'.
570 *----------------------------------------------------------------------------*/
572 floatx80 floatx80_maybe_silence_nan( floatx80 a )
574 if (floatx80_is_signaling_nan(a)) {
575 #if SNAN_BIT_IS_ONE
576 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
577 a.low = floatx80_default_nan_low;
578 a.high = floatx80_default_nan_high;
579 # else
580 # error Rules for silencing a signaling NaN are target-specific
581 # endif
582 #else
583 a.low |= LIT64( 0xC000000000000000 );
584 return a;
585 #endif
587 return a;
590 /*----------------------------------------------------------------------------
591 | Returns the result of converting the extended double-precision floating-
592 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
593 | invalid exception is raised.
594 *----------------------------------------------------------------------------*/
596 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
598 commonNaNT z;
600 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
601 z.sign = a.high>>15;
602 z.low = 0;
603 z.high = a.low;
604 return z;
607 /*----------------------------------------------------------------------------
608 | Returns the result of converting the canonical NaN `a' to the extended
609 | double-precision floating-point format.
610 *----------------------------------------------------------------------------*/
612 static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
614 floatx80 z;
616 if ( STATUS(default_nan_mode) ) {
617 z.low = floatx80_default_nan_low;
618 z.high = floatx80_default_nan_high;
619 return z;
622 if (a.high)
623 z.low = a.high;
624 else
625 z.low = floatx80_default_nan_low;
626 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
627 return z;
630 /*----------------------------------------------------------------------------
631 | Takes two extended double-precision floating-point values `a' and `b', one
632 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
633 | `b' is a signaling NaN, the invalid exception is raised.
634 *----------------------------------------------------------------------------*/
636 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
638 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
639 flag aIsLargerSignificand;
641 aIsQuietNaN = floatx80_is_quiet_nan( a );
642 aIsSignalingNaN = floatx80_is_signaling_nan( a );
643 bIsQuietNaN = floatx80_is_quiet_nan( b );
644 bIsSignalingNaN = floatx80_is_signaling_nan( b );
646 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
648 if ( STATUS(default_nan_mode) ) {
649 a.low = floatx80_default_nan_low;
650 a.high = floatx80_default_nan_high;
651 return a;
654 if (a.low < b.low) {
655 aIsLargerSignificand = 0;
656 } else if (b.low < a.low) {
657 aIsLargerSignificand = 1;
658 } else {
659 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
662 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
663 aIsLargerSignificand)) {
664 return floatx80_maybe_silence_nan(b);
665 } else {
666 return floatx80_maybe_silence_nan(a);
670 #endif
672 #ifdef FLOAT128
674 /*----------------------------------------------------------------------------
675 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
676 | NaN; otherwise returns 0.
677 *----------------------------------------------------------------------------*/
679 int float128_is_quiet_nan( float128 a )
681 #if SNAN_BIT_IS_ONE
682 return
683 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
684 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
685 #else
686 return
687 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
688 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
689 #endif
692 /*----------------------------------------------------------------------------
693 | Returns 1 if the quadruple-precision floating-point value `a' is a
694 | signaling NaN; otherwise returns 0.
695 *----------------------------------------------------------------------------*/
697 int float128_is_signaling_nan( float128 a )
699 #if SNAN_BIT_IS_ONE
700 return
701 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
702 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
703 #else
704 return
705 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
706 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
707 #endif
710 /*----------------------------------------------------------------------------
711 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
712 | a signaling NaN; otherwise returns `a'.
713 *----------------------------------------------------------------------------*/
715 float128 float128_maybe_silence_nan( float128 a )
717 if (float128_is_signaling_nan(a)) {
718 #if SNAN_BIT_IS_ONE
719 # if defined(TARGET_MIPS) || defined(TARGET_SH4)
720 a.low = float128_default_nan_low;
721 a.high = float128_default_nan_high;
722 # else
723 # error Rules for silencing a signaling NaN are target-specific
724 # endif
725 #else
726 a.high |= LIT64( 0x0000800000000000 );
727 return a;
728 #endif
730 return a;
733 /*----------------------------------------------------------------------------
734 | Returns the result of converting the quadruple-precision floating-point NaN
735 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
736 | exception is raised.
737 *----------------------------------------------------------------------------*/
739 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
741 commonNaNT z;
743 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
744 z.sign = a.high>>63;
745 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
746 return z;
749 /*----------------------------------------------------------------------------
750 | Returns the result of converting the canonical NaN `a' to the quadruple-
751 | precision floating-point format.
752 *----------------------------------------------------------------------------*/
754 static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
756 float128 z;
758 if ( STATUS(default_nan_mode) ) {
759 z.low = float128_default_nan_low;
760 z.high = float128_default_nan_high;
761 return z;
764 shift128Right( a.high, a.low, 16, &z.high, &z.low );
765 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
766 return z;
769 /*----------------------------------------------------------------------------
770 | Takes two quadruple-precision floating-point values `a' and `b', one of
771 | which is a NaN, and returns the appropriate NaN result. If either `a' or
772 | `b' is a signaling NaN, the invalid exception is raised.
773 *----------------------------------------------------------------------------*/
775 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
777 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
778 flag aIsLargerSignificand;
780 aIsQuietNaN = float128_is_quiet_nan( a );
781 aIsSignalingNaN = float128_is_signaling_nan( a );
782 bIsQuietNaN = float128_is_quiet_nan( b );
783 bIsSignalingNaN = float128_is_signaling_nan( b );
785 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
787 if ( STATUS(default_nan_mode) ) {
788 a.low = float128_default_nan_low;
789 a.high = float128_default_nan_high;
790 return a;
793 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
794 aIsLargerSignificand = 0;
795 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
796 aIsLargerSignificand = 1;
797 } else {
798 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
801 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
802 aIsLargerSignificand)) {
803 return float128_maybe_silence_nan(b);
804 } else {
805 return float128_maybe_silence_nan(a);
809 #endif