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_HPPA)
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_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65 #define float32_default_nan make_float32(0x7FC00000)
66 #elif defined(TARGET_HPPA)
67 #define float32_default_nan make_float32(0x7FA00000)
69 #define float32_default_nan make_float32(0x7FBFFFFF)
71 #define float32_default_nan make_float32(0xFFC00000)
74 /*----------------------------------------------------------------------------
75 | Returns 1 if the single-precision floating-point value `a' is a quiet
76 | NaN; otherwise returns 0.
77 *----------------------------------------------------------------------------*/
79 int float32_is_quiet_nan( float32 a_
)
81 uint32_t a
= float32_val(a_
);
83 return ( ( ( a
>>22 ) & 0x1FF ) == 0x1FE ) && ( a
& 0x003FFFFF );
85 return ( 0xFF800000 <= (bits32
) ( a
<<1 ) );
89 /*----------------------------------------------------------------------------
90 | Returns 1 if the single-precision floating-point value `a' is a signaling
91 | NaN; otherwise returns 0.
92 *----------------------------------------------------------------------------*/
94 int float32_is_signaling_nan( float32 a_
)
96 uint32_t a
= float32_val(a_
);
98 return ( 0xFF800000 <= (bits32
) ( a
<<1 ) );
100 return ( ( ( a
>>22 ) & 0x1FF ) == 0x1FE ) && ( a
& 0x003FFFFF );
104 /*----------------------------------------------------------------------------
105 | Returns a quiet NaN if the single-precision floating point value `a' is a
106 | signaling NaN; otherwise returns `a'.
107 *----------------------------------------------------------------------------*/
109 float32
float32_maybe_silence_nan( float32 a_
)
111 if (float32_is_signaling_nan(a_
)) {
112 uint32_t a
= float32_val(a_
);
118 return make_float32(a
);
123 /*----------------------------------------------------------------------------
124 | Returns the result of converting the single-precision floating-point NaN
125 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
126 | exception is raised.
127 *----------------------------------------------------------------------------*/
129 static commonNaNT
float32ToCommonNaN( float32 a STATUS_PARAM
)
133 if ( float32_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
134 z
.sign
= float32_val(a
)>>31;
136 z
.high
= ( (bits64
) float32_val(a
) )<<41;
140 /*----------------------------------------------------------------------------
141 | Returns the result of converting the canonical NaN `a' to the single-
142 | precision floating-point format.
143 *----------------------------------------------------------------------------*/
145 static float32
commonNaNToFloat32( commonNaNT a
)
147 bits32 mantissa
= a
.high
>>41;
150 ( ( (bits32
) a
.sign
)<<31 ) | 0x7F800000 | ( a
.high
>>41 ) );
152 return float32_default_nan
;
155 /*----------------------------------------------------------------------------
156 | Select which NaN to propagate for a two-input operation.
157 | IEEE754 doesn't specify all the details of this, so the
158 | algorithm is target-specific.
159 | The routine is passed various bits of information about the
160 | two NaNs and should return 0 to select NaN a and 1 for NaN b.
161 | Note that signalling NaNs are always squashed to quiet NaNs
162 | by the caller, by flipping the SNaN bit before returning them.
164 | aIsLargerSignificand is only valid if both a and b are NaNs
165 | of some kind, and is true if a has the larger significand,
166 | or if both a and b have the same significand but a is
167 | positive but b is negative. It is only needed for the x87
169 *----------------------------------------------------------------------------*/
171 #if defined(TARGET_ARM)
172 static int pickNaN(flag aIsQNaN
, flag aIsSNaN
, flag bIsQNaN
, flag bIsSNaN
,
173 flag aIsLargerSignificand
)
175 /* ARM mandated NaN propagation rules: take the first of:
176 * 1. A if it is signaling
177 * 2. B if it is signaling
180 * A signaling NaN is always quietened before returning it.
184 } else if (bIsSNaN
) {
186 } else if (aIsQNaN
) {
193 static int pickNaN(flag aIsQNaN
, flag aIsSNaN
, flag bIsQNaN
, flag bIsSNaN
,
194 flag aIsLargerSignificand
)
196 /* This implements x87 NaN propagation rules:
197 * SNaN + QNaN => return the QNaN
198 * two SNaNs => return the one with the larger significand, silenced
199 * two QNaNs => return the one with the larger significand
200 * SNaN and a non-NaN => return the SNaN, silenced
201 * QNaN and a non-NaN => return the QNaN
203 * If we get down to comparing significands and they are the same,
204 * return the NaN with the positive sign bit (if any).
208 return aIsLargerSignificand
? 0 : 1;
210 return bIsQNaN
? 1 : 0;
213 if (bIsSNaN
|| !bIsQNaN
)
216 return aIsLargerSignificand
? 0 : 1;
224 /*----------------------------------------------------------------------------
225 | Takes two single-precision floating-point values `a' and `b', one of which
226 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
227 | signaling NaN, the invalid exception is raised.
228 *----------------------------------------------------------------------------*/
230 static float32
propagateFloat32NaN( float32 a
, float32 b STATUS_PARAM
)
232 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
, aIsLargerSignificand
;
235 if ( STATUS(default_nan_mode
) )
236 return float32_default_nan
;
238 aIsNaN
= float32_is_quiet_nan( a
);
239 aIsSignalingNaN
= float32_is_signaling_nan( a
);
240 bIsNaN
= float32_is_quiet_nan( b
);
241 bIsSignalingNaN
= float32_is_signaling_nan( b
);
251 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
253 if ((bits32
)(av
<<1) < (bits32
)(bv
<<1)) {
254 aIsLargerSignificand
= 0;
255 } else if ((bits32
)(bv
<<1) < (bits32
)(av
<<1)) {
256 aIsLargerSignificand
= 1;
258 aIsLargerSignificand
= (av
< bv
) ? 1 : 0;
261 if (pickNaN(aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
,
262 aIsLargerSignificand
)) {
268 return make_float32(res
);
271 /*----------------------------------------------------------------------------
272 | The pattern for a default generated double-precision NaN.
273 *----------------------------------------------------------------------------*/
274 #if defined(TARGET_SPARC)
275 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
276 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
277 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
278 #elif defined(TARGET_HPPA)
279 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
280 #elif SNAN_BIT_IS_ONE
281 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
283 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
286 /*----------------------------------------------------------------------------
287 | Returns 1 if the double-precision floating-point value `a' is a quiet
288 | NaN; otherwise returns 0.
289 *----------------------------------------------------------------------------*/
291 int float64_is_quiet_nan( float64 a_
)
293 bits64 a
= float64_val(a_
);
296 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
297 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
299 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
303 /*----------------------------------------------------------------------------
304 | Returns 1 if the double-precision floating-point value `a' is a signaling
305 | NaN; otherwise returns 0.
306 *----------------------------------------------------------------------------*/
308 int float64_is_signaling_nan( float64 a_
)
310 bits64 a
= float64_val(a_
);
312 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
315 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
316 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
320 /*----------------------------------------------------------------------------
321 | Returns a quiet NaN if the double-precision floating point value `a' is a
322 | signaling NaN; otherwise returns `a'.
323 *----------------------------------------------------------------------------*/
325 float64
float64_maybe_silence_nan( float64 a_
)
327 if (float64_is_signaling_nan(a_
)) {
328 bits64 a
= float64_val(a_
);
330 a
&= ~LIT64( 0x0008000000000000 );
332 a
|= LIT64( 0x0008000000000000 );
334 return make_float64(a
);
339 /*----------------------------------------------------------------------------
340 | Returns the result of converting the double-precision floating-point NaN
341 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
342 | exception is raised.
343 *----------------------------------------------------------------------------*/
345 static commonNaNT
float64ToCommonNaN( float64 a STATUS_PARAM
)
349 if ( float64_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
350 z
.sign
= float64_val(a
)>>63;
352 z
.high
= float64_val(a
)<<12;
356 /*----------------------------------------------------------------------------
357 | Returns the result of converting the canonical NaN `a' to the double-
358 | precision floating-point format.
359 *----------------------------------------------------------------------------*/
361 static float64
commonNaNToFloat64( commonNaNT a
)
363 bits64 mantissa
= a
.high
>>12;
367 ( ( (bits64
) a
.sign
)<<63 )
368 | LIT64( 0x7FF0000000000000 )
371 return float64_default_nan
;
374 /*----------------------------------------------------------------------------
375 | Takes two double-precision floating-point values `a' and `b', one of which
376 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
377 | signaling NaN, the invalid exception is raised.
378 *----------------------------------------------------------------------------*/
380 static float64
propagateFloat64NaN( float64 a
, float64 b STATUS_PARAM
)
382 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
, aIsLargerSignificand
;
385 if ( STATUS(default_nan_mode
) )
386 return float64_default_nan
;
388 aIsNaN
= float64_is_quiet_nan( a
);
389 aIsSignalingNaN
= float64_is_signaling_nan( a
);
390 bIsNaN
= float64_is_quiet_nan( b
);
391 bIsSignalingNaN
= float64_is_signaling_nan( b
);
395 av
&= ~LIT64( 0x0008000000000000 );
396 bv
&= ~LIT64( 0x0008000000000000 );
398 av
|= LIT64( 0x0008000000000000 );
399 bv
|= LIT64( 0x0008000000000000 );
401 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
403 if ((bits64
)(av
<<1) < (bits64
)(bv
<<1)) {
404 aIsLargerSignificand
= 0;
405 } else if ((bits64
)(bv
<<1) < (bits64
)(av
<<1)) {
406 aIsLargerSignificand
= 1;
408 aIsLargerSignificand
= (av
< bv
) ? 1 : 0;
411 if (pickNaN(aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
,
412 aIsLargerSignificand
)) {
418 return make_float64(res
);
423 /*----------------------------------------------------------------------------
424 | The pattern for a default generated extended double-precision NaN. The
425 | `high' and `low' values hold the most- and least-significant bits,
427 *----------------------------------------------------------------------------*/
429 #define floatx80_default_nan_high 0x7FFF
430 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
432 #define floatx80_default_nan_high 0xFFFF
433 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
436 /*----------------------------------------------------------------------------
437 | Returns 1 if the extended double-precision floating-point value `a' is a
438 | quiet NaN; otherwise returns 0.
439 *----------------------------------------------------------------------------*/
441 int floatx80_is_quiet_nan( floatx80 a
)
446 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
448 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
449 && (bits64
) ( aLow
<<1 )
450 && ( a
.low
== aLow
);
452 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
456 /*----------------------------------------------------------------------------
457 | Returns 1 if the extended double-precision floating-point value `a' is a
458 | signaling NaN; otherwise returns 0.
459 *----------------------------------------------------------------------------*/
461 int floatx80_is_signaling_nan( floatx80 a
)
464 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
468 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
470 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
471 && (bits64
) ( aLow
<<1 )
472 && ( a
.low
== aLow
);
476 /*----------------------------------------------------------------------------
477 | Returns the result of converting the extended double-precision floating-
478 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
479 | invalid exception is raised.
480 *----------------------------------------------------------------------------*/
482 static commonNaNT
floatx80ToCommonNaN( floatx80 a STATUS_PARAM
)
486 if ( floatx80_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
493 /*----------------------------------------------------------------------------
494 | Returns the result of converting the canonical NaN `a' to the extended
495 | double-precision floating-point format.
496 *----------------------------------------------------------------------------*/
498 static floatx80
commonNaNToFloatx80( commonNaNT a
)
505 z
.low
= floatx80_default_nan_low
;
506 z
.high
= ( ( (bits16
) a
.sign
)<<15 ) | 0x7FFF;
510 /*----------------------------------------------------------------------------
511 | Takes two extended double-precision floating-point values `a' and `b', one
512 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
513 | `b' is a signaling NaN, the invalid exception is raised.
514 *----------------------------------------------------------------------------*/
516 static floatx80
propagateFloatx80NaN( floatx80 a
, floatx80 b STATUS_PARAM
)
518 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
, aIsLargerSignificand
;
520 if ( STATUS(default_nan_mode
) ) {
521 a
.low
= floatx80_default_nan_low
;
522 a
.high
= floatx80_default_nan_high
;
526 aIsNaN
= floatx80_is_quiet_nan( a
);
527 aIsSignalingNaN
= floatx80_is_signaling_nan( a
);
528 bIsNaN
= floatx80_is_quiet_nan( b
);
529 bIsSignalingNaN
= floatx80_is_signaling_nan( b
);
531 a
.low
&= ~LIT64( 0xC000000000000000 );
532 b
.low
&= ~LIT64( 0xC000000000000000 );
534 a
.low
|= LIT64( 0xC000000000000000 );
535 b
.low
|= LIT64( 0xC000000000000000 );
537 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
540 aIsLargerSignificand
= 0;
541 } else if (b
.low
< a
.low
) {
542 aIsLargerSignificand
= 1;
544 aIsLargerSignificand
= (a
.high
< b
.high
) ? 1 : 0;
547 if (pickNaN(aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
,
548 aIsLargerSignificand
)) {
559 /*----------------------------------------------------------------------------
560 | The pattern for a default generated quadruple-precision NaN. The `high' and
561 | `low' values hold the most- and least-significant bits, respectively.
562 *----------------------------------------------------------------------------*/
564 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
565 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
567 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
568 #define float128_default_nan_low LIT64( 0x0000000000000000 )
571 /*----------------------------------------------------------------------------
572 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
573 | NaN; otherwise returns 0.
574 *----------------------------------------------------------------------------*/
576 int float128_is_quiet_nan( float128 a
)
580 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
581 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
584 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
585 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
589 /*----------------------------------------------------------------------------
590 | Returns 1 if the quadruple-precision floating-point value `a' is a
591 | signaling NaN; otherwise returns 0.
592 *----------------------------------------------------------------------------*/
594 int float128_is_signaling_nan( float128 a
)
598 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
599 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
602 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
603 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
607 /*----------------------------------------------------------------------------
608 | Returns the result of converting the quadruple-precision floating-point NaN
609 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
610 | exception is raised.
611 *----------------------------------------------------------------------------*/
613 static commonNaNT
float128ToCommonNaN( float128 a STATUS_PARAM
)
617 if ( float128_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
619 shortShift128Left( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
623 /*----------------------------------------------------------------------------
624 | Returns the result of converting the canonical NaN `a' to the quadruple-
625 | precision floating-point format.
626 *----------------------------------------------------------------------------*/
628 static float128
commonNaNToFloat128( commonNaNT a
)
632 shift128Right( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
633 z
.high
|= ( ( (bits64
) a
.sign
)<<63 ) | LIT64( 0x7FFF000000000000 );
637 /*----------------------------------------------------------------------------
638 | Takes two quadruple-precision floating-point values `a' and `b', one of
639 | which is a NaN, and returns the appropriate NaN result. If either `a' or
640 | `b' is a signaling NaN, the invalid exception is raised.
641 *----------------------------------------------------------------------------*/
643 static float128
propagateFloat128NaN( float128 a
, float128 b STATUS_PARAM
)
645 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
, aIsLargerSignificand
;
647 if ( STATUS(default_nan_mode
) ) {
648 a
.low
= float128_default_nan_low
;
649 a
.high
= float128_default_nan_high
;
653 aIsNaN
= float128_is_quiet_nan( a
);
654 aIsSignalingNaN
= float128_is_signaling_nan( a
);
655 bIsNaN
= float128_is_quiet_nan( b
);
656 bIsSignalingNaN
= float128_is_signaling_nan( b
);
658 a
.high
&= ~LIT64( 0x0000800000000000 );
659 b
.high
&= ~LIT64( 0x0000800000000000 );
661 a
.high
|= LIT64( 0x0000800000000000 );
662 b
.high
|= LIT64( 0x0000800000000000 );
664 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
666 if (lt128(a
.high
<<1, a
.low
, b
.high
<<1, b
.low
)) {
667 aIsLargerSignificand
= 0;
668 } else if (lt128(b
.high
<<1, b
.low
, a
.high
<<1, a
.low
)) {
669 aIsLargerSignificand
= 1;
671 aIsLargerSignificand
= (a
.high
< b
.high
) ? 1 : 0;
674 if (pickNaN(aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
,
675 aIsLargerSignificand
)) {