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_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 | Takes two single-precision floating-point values `a' and `b', one of which
157 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
158 | signaling NaN, the invalid exception is raised.
159 *----------------------------------------------------------------------------*/
161 static float32
propagateFloat32NaN( float32 a
, float32 b STATUS_PARAM
)
163 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
166 if ( STATUS(default_nan_mode
) )
167 return float32_default_nan
;
169 aIsNaN
= float32_is_nan( a
);
170 aIsSignalingNaN
= float32_is_signaling_nan( a
);
171 bIsNaN
= float32_is_nan( b
);
172 bIsSignalingNaN
= float32_is_signaling_nan( b
);
182 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
183 if ( aIsSignalingNaN
) {
184 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
185 res
= bIsNaN
? bv
: av
;
188 if ( bIsSignalingNaN
|| ! bIsNaN
)
191 returnLargerSignificand
:
192 if ( (bits32
) ( av
<<1 ) < (bits32
) ( bv
<<1 ) )
194 else if ( (bits32
) ( bv
<<1 ) < (bits32
) ( av
<<1 ) )
197 res
= ( av
< bv
) ? av
: bv
;
203 return make_float32(res
);
206 /*----------------------------------------------------------------------------
207 | The pattern for a default generated double-precision NaN.
208 *----------------------------------------------------------------------------*/
209 #if defined(TARGET_SPARC)
210 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
211 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
212 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
213 #elif defined(TARGET_HPPA)
214 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
215 #elif SNAN_BIT_IS_ONE
216 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
218 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
221 /*----------------------------------------------------------------------------
222 | Returns 1 if the double-precision floating-point value `a' is a quiet
223 | NaN; otherwise returns 0.
224 *----------------------------------------------------------------------------*/
226 int float64_is_nan( float64 a_
)
228 bits64 a
= float64_val(a_
);
231 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
232 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
234 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
238 /*----------------------------------------------------------------------------
239 | Returns 1 if the double-precision floating-point value `a' is a signaling
240 | NaN; otherwise returns 0.
241 *----------------------------------------------------------------------------*/
243 int float64_is_signaling_nan( float64 a_
)
245 bits64 a
= float64_val(a_
);
247 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
250 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
251 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
255 /*----------------------------------------------------------------------------
256 | Returns a quiet NaN if the double-precision floating point value `a' is a
257 | signaling NaN; otherwise returns `a'.
258 *----------------------------------------------------------------------------*/
260 float64
float64_maybe_silence_nan( float64 a_
)
262 if (float64_is_signaling_nan(a_
)) {
263 bits64 a
= float64_val(a_
);
265 a
&= ~LIT64( 0x0008000000000000 );
267 a
|= LIT64( 0x0008000000000000 );
269 return make_float64(a
);
274 /*----------------------------------------------------------------------------
275 | Returns the result of converting the double-precision floating-point NaN
276 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
277 | exception is raised.
278 *----------------------------------------------------------------------------*/
280 static commonNaNT
float64ToCommonNaN( float64 a STATUS_PARAM
)
284 if ( float64_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
285 z
.sign
= float64_val(a
)>>63;
287 z
.high
= float64_val(a
)<<12;
291 /*----------------------------------------------------------------------------
292 | Returns the result of converting the canonical NaN `a' to the double-
293 | precision floating-point format.
294 *----------------------------------------------------------------------------*/
296 static float64
commonNaNToFloat64( commonNaNT a
)
298 bits64 mantissa
= a
.high
>>12;
302 ( ( (bits64
) a
.sign
)<<63 )
303 | LIT64( 0x7FF0000000000000 )
306 return float64_default_nan
;
309 /*----------------------------------------------------------------------------
310 | Takes two double-precision floating-point values `a' and `b', one of which
311 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
312 | signaling NaN, the invalid exception is raised.
313 *----------------------------------------------------------------------------*/
315 static float64
propagateFloat64NaN( float64 a
, float64 b STATUS_PARAM
)
317 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
320 if ( STATUS(default_nan_mode
) )
321 return float64_default_nan
;
323 aIsNaN
= float64_is_nan( a
);
324 aIsSignalingNaN
= float64_is_signaling_nan( a
);
325 bIsNaN
= float64_is_nan( b
);
326 bIsSignalingNaN
= float64_is_signaling_nan( b
);
330 av
&= ~LIT64( 0x0008000000000000 );
331 bv
&= ~LIT64( 0x0008000000000000 );
333 av
|= LIT64( 0x0008000000000000 );
334 bv
|= LIT64( 0x0008000000000000 );
336 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
337 if ( aIsSignalingNaN
) {
338 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
339 res
= bIsNaN
? bv
: av
;
342 if ( bIsSignalingNaN
|| ! bIsNaN
)
345 returnLargerSignificand
:
346 if ( (bits64
) ( av
<<1 ) < (bits64
) ( bv
<<1 ) )
348 else if ( (bits64
) ( bv
<<1 ) < (bits64
) ( av
<<1 ) )
351 res
= ( av
< bv
) ? av
: bv
;
357 return make_float64(res
);
362 /*----------------------------------------------------------------------------
363 | The pattern for a default generated extended double-precision NaN. The
364 | `high' and `low' values hold the most- and least-significant bits,
366 *----------------------------------------------------------------------------*/
368 #define floatx80_default_nan_high 0x7FFF
369 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
371 #define floatx80_default_nan_high 0xFFFF
372 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
375 /*----------------------------------------------------------------------------
376 | Returns 1 if the extended double-precision floating-point value `a' is a
377 | quiet NaN; otherwise returns 0.
378 *----------------------------------------------------------------------------*/
380 int floatx80_is_nan( floatx80 a
)
385 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
387 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
388 && (bits64
) ( aLow
<<1 )
389 && ( a
.low
== aLow
);
391 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
395 /*----------------------------------------------------------------------------
396 | Returns 1 if the extended double-precision floating-point value `a' is a
397 | signaling NaN; otherwise returns 0.
398 *----------------------------------------------------------------------------*/
400 int floatx80_is_signaling_nan( floatx80 a
)
403 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
407 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
409 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
410 && (bits64
) ( aLow
<<1 )
411 && ( a
.low
== aLow
);
415 /*----------------------------------------------------------------------------
416 | Returns the result of converting the extended double-precision floating-
417 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
418 | invalid exception is raised.
419 *----------------------------------------------------------------------------*/
421 static commonNaNT
floatx80ToCommonNaN( floatx80 a STATUS_PARAM
)
425 if ( floatx80_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
432 /*----------------------------------------------------------------------------
433 | Returns the result of converting the canonical NaN `a' to the extended
434 | double-precision floating-point format.
435 *----------------------------------------------------------------------------*/
437 static floatx80
commonNaNToFloatx80( commonNaNT a
)
444 z
.low
= floatx80_default_nan_low
;
445 z
.high
= ( ( (bits16
) a
.sign
)<<15 ) | 0x7FFF;
449 /*----------------------------------------------------------------------------
450 | Takes two extended double-precision floating-point values `a' and `b', one
451 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
452 | `b' is a signaling NaN, the invalid exception is raised.
453 *----------------------------------------------------------------------------*/
455 static floatx80
propagateFloatx80NaN( floatx80 a
, floatx80 b STATUS_PARAM
)
457 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
459 if ( STATUS(default_nan_mode
) ) {
460 a
.low
= floatx80_default_nan_low
;
461 a
.high
= floatx80_default_nan_high
;
465 aIsNaN
= floatx80_is_nan( a
);
466 aIsSignalingNaN
= floatx80_is_signaling_nan( a
);
467 bIsNaN
= floatx80_is_nan( b
);
468 bIsSignalingNaN
= floatx80_is_signaling_nan( b
);
470 a
.low
&= ~LIT64( 0xC000000000000000 );
471 b
.low
&= ~LIT64( 0xC000000000000000 );
473 a
.low
|= LIT64( 0xC000000000000000 );
474 b
.low
|= LIT64( 0xC000000000000000 );
476 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
477 if ( aIsSignalingNaN
) {
478 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
479 return bIsNaN
? b
: a
;
482 if ( bIsSignalingNaN
|| ! bIsNaN
) return a
;
483 returnLargerSignificand
:
484 if ( a
.low
< b
.low
) return b
;
485 if ( b
.low
< a
.low
) return a
;
486 return ( a
.high
< b
.high
) ? a
: b
;
497 /*----------------------------------------------------------------------------
498 | The pattern for a default generated quadruple-precision NaN. The `high' and
499 | `low' values hold the most- and least-significant bits, respectively.
500 *----------------------------------------------------------------------------*/
502 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
503 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
505 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
506 #define float128_default_nan_low LIT64( 0x0000000000000000 )
509 /*----------------------------------------------------------------------------
510 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
511 | NaN; otherwise returns 0.
512 *----------------------------------------------------------------------------*/
514 int float128_is_nan( float128 a
)
518 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
519 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
522 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
523 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
527 /*----------------------------------------------------------------------------
528 | Returns 1 if the quadruple-precision floating-point value `a' is a
529 | signaling NaN; otherwise returns 0.
530 *----------------------------------------------------------------------------*/
532 int float128_is_signaling_nan( float128 a
)
536 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
537 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
540 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
541 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
545 /*----------------------------------------------------------------------------
546 | Returns the result of converting the quadruple-precision floating-point NaN
547 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
548 | exception is raised.
549 *----------------------------------------------------------------------------*/
551 static commonNaNT
float128ToCommonNaN( float128 a STATUS_PARAM
)
555 if ( float128_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
557 shortShift128Left( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
561 /*----------------------------------------------------------------------------
562 | Returns the result of converting the canonical NaN `a' to the quadruple-
563 | precision floating-point format.
564 *----------------------------------------------------------------------------*/
566 static float128
commonNaNToFloat128( commonNaNT a
)
570 shift128Right( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
571 z
.high
|= ( ( (bits64
) a
.sign
)<<63 ) | LIT64( 0x7FFF000000000000 );
575 /*----------------------------------------------------------------------------
576 | Takes two quadruple-precision floating-point values `a' and `b', one of
577 | which is a NaN, and returns the appropriate NaN result. If either `a' or
578 | `b' is a signaling NaN, the invalid exception is raised.
579 *----------------------------------------------------------------------------*/
581 static float128
propagateFloat128NaN( float128 a
, float128 b STATUS_PARAM
)
583 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
585 if ( STATUS(default_nan_mode
) ) {
586 a
.low
= float128_default_nan_low
;
587 a
.high
= float128_default_nan_high
;
591 aIsNaN
= float128_is_nan( a
);
592 aIsSignalingNaN
= float128_is_signaling_nan( a
);
593 bIsNaN
= float128_is_nan( b
);
594 bIsSignalingNaN
= float128_is_signaling_nan( b
);
596 a
.high
&= ~LIT64( 0x0000800000000000 );
597 b
.high
&= ~LIT64( 0x0000800000000000 );
599 a
.high
|= LIT64( 0x0000800000000000 );
600 b
.high
|= LIT64( 0x0000800000000000 );
602 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
603 if ( aIsSignalingNaN
) {
604 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
605 return bIsNaN
? b
: a
;
608 if ( bIsSignalingNaN
|| ! bIsNaN
) return a
;
609 returnLargerSignificand
:
610 if ( lt128( a
.high
<<1, a
.low
, b
.high
<<1, b
.low
) ) return b
;
611 if ( lt128( b
.high
<<1, b
.low
, a
.high
<<1, a
.low
) ) return a
;
612 return ( a
.high
< b
.high
) ? a
: b
;