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)
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 the result of converting the single-precision floating-point NaN
106 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
107 | exception is raised.
108 *----------------------------------------------------------------------------*/
110 static commonNaNT
float32ToCommonNaN( float32 a STATUS_PARAM
)
114 if ( float32_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
115 z
.sign
= float32_val(a
)>>31;
117 z
.high
= ( (bits64
) float32_val(a
) )<<41;
121 /*----------------------------------------------------------------------------
122 | Returns the result of converting the canonical NaN `a' to the single-
123 | precision floating-point format.
124 *----------------------------------------------------------------------------*/
126 static float32
commonNaNToFloat32( commonNaNT a
)
128 bits32 mantissa
= a
.high
>>41;
131 ( ( (bits32
) a
.sign
)<<31 ) | 0x7F800000 | ( a
.high
>>41 ) );
133 return float32_default_nan
;
136 /*----------------------------------------------------------------------------
137 | Takes two single-precision floating-point values `a' and `b', one of which
138 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
139 | signaling NaN, the invalid exception is raised.
140 *----------------------------------------------------------------------------*/
142 static float32
propagateFloat32NaN( float32 a
, float32 b STATUS_PARAM
)
144 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
147 aIsNaN
= float32_is_nan( a
);
148 aIsSignalingNaN
= float32_is_signaling_nan( a
);
149 bIsNaN
= float32_is_nan( b
);
150 bIsSignalingNaN
= float32_is_signaling_nan( b
);
160 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
161 if ( aIsSignalingNaN
) {
162 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
163 res
= bIsNaN
? bv
: av
;
166 if ( bIsSignalingNaN
| ! bIsNaN
)
169 returnLargerSignificand
:
170 if ( (bits32
) ( av
<<1 ) < (bits32
) ( bv
<<1 ) )
172 else if ( (bits32
) ( bv
<<1 ) < (bits32
) ( av
<<1 ) )
175 res
= ( av
< bv
) ? av
: bv
;
181 return make_float32(res
);
184 /*----------------------------------------------------------------------------
185 | The pattern for a default generated double-precision NaN.
186 *----------------------------------------------------------------------------*/
187 #if defined(TARGET_SPARC)
188 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
189 #elif defined(TARGET_POWERPC)
190 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
191 #elif defined(TARGET_HPPA)
192 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
193 #elif SNAN_BIT_IS_ONE
194 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
196 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
199 /*----------------------------------------------------------------------------
200 | Returns 1 if the double-precision floating-point value `a' is a quiet
201 | NaN; otherwise returns 0.
202 *----------------------------------------------------------------------------*/
204 int float64_is_nan( float64 a_
)
206 bits64 a
= float64_val(a_
);
209 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
210 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
212 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
216 /*----------------------------------------------------------------------------
217 | Returns 1 if the double-precision floating-point value `a' is a signaling
218 | NaN; otherwise returns 0.
219 *----------------------------------------------------------------------------*/
221 int float64_is_signaling_nan( float64 a_
)
223 bits64 a
= float64_val(a_
);
225 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
228 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
229 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
233 /*----------------------------------------------------------------------------
234 | Returns the result of converting the double-precision floating-point NaN
235 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
236 | exception is raised.
237 *----------------------------------------------------------------------------*/
239 static commonNaNT
float64ToCommonNaN( float64 a STATUS_PARAM
)
243 if ( float64_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
244 z
.sign
= float64_val(a
)>>63;
246 z
.high
= float64_val(a
)<<12;
250 /*----------------------------------------------------------------------------
251 | Returns the result of converting the canonical NaN `a' to the double-
252 | precision floating-point format.
253 *----------------------------------------------------------------------------*/
255 static float64
commonNaNToFloat64( commonNaNT a
)
257 bits64 mantissa
= a
.high
>>12;
261 ( ( (bits64
) a
.sign
)<<63 )
262 | LIT64( 0x7FF0000000000000 )
265 return float64_default_nan
;
268 /*----------------------------------------------------------------------------
269 | Takes two double-precision floating-point values `a' and `b', one of which
270 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
271 | signaling NaN, the invalid exception is raised.
272 *----------------------------------------------------------------------------*/
274 static float64
propagateFloat64NaN( float64 a
, float64 b STATUS_PARAM
)
276 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
279 aIsNaN
= float64_is_nan( a
);
280 aIsSignalingNaN
= float64_is_signaling_nan( a
);
281 bIsNaN
= float64_is_nan( b
);
282 bIsSignalingNaN
= float64_is_signaling_nan( b
);
286 av
&= ~LIT64( 0x0008000000000000 );
287 bv
&= ~LIT64( 0x0008000000000000 );
289 av
|= LIT64( 0x0008000000000000 );
290 bv
|= LIT64( 0x0008000000000000 );
292 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
293 if ( aIsSignalingNaN
) {
294 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
295 res
= bIsNaN
? bv
: av
;
298 if ( bIsSignalingNaN
| ! bIsNaN
)
301 returnLargerSignificand
:
302 if ( (bits64
) ( av
<<1 ) < (bits64
) ( bv
<<1 ) )
304 else if ( (bits64
) ( bv
<<1 ) < (bits64
) ( av
<<1 ) )
307 res
= ( av
< bv
) ? av
: bv
;
313 return make_float64(res
);
318 /*----------------------------------------------------------------------------
319 | The pattern for a default generated extended double-precision NaN. The
320 | `high' and `low' values hold the most- and least-significant bits,
322 *----------------------------------------------------------------------------*/
324 #define floatx80_default_nan_high 0x7FFF
325 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
327 #define floatx80_default_nan_high 0xFFFF
328 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
331 /*----------------------------------------------------------------------------
332 | Returns 1 if the extended double-precision floating-point value `a' is a
333 | quiet NaN; otherwise returns 0.
334 *----------------------------------------------------------------------------*/
336 int floatx80_is_nan( floatx80 a
)
341 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
343 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
344 && (bits64
) ( aLow
<<1 )
345 && ( a
.low
== aLow
);
347 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
351 /*----------------------------------------------------------------------------
352 | Returns 1 if the extended double-precision floating-point value `a' is a
353 | signaling NaN; otherwise returns 0.
354 *----------------------------------------------------------------------------*/
356 int floatx80_is_signaling_nan( floatx80 a
)
359 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
363 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
365 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
366 && (bits64
) ( aLow
<<1 )
367 && ( a
.low
== aLow
);
371 /*----------------------------------------------------------------------------
372 | Returns the result of converting the extended double-precision floating-
373 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
374 | invalid exception is raised.
375 *----------------------------------------------------------------------------*/
377 static commonNaNT
floatx80ToCommonNaN( floatx80 a STATUS_PARAM
)
381 if ( floatx80_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
388 /*----------------------------------------------------------------------------
389 | Returns the result of converting the canonical NaN `a' to the extended
390 | double-precision floating-point format.
391 *----------------------------------------------------------------------------*/
393 static floatx80
commonNaNToFloatx80( commonNaNT a
)
400 z
.low
= floatx80_default_nan_low
;
401 z
.high
= ( ( (bits16
) a
.sign
)<<15 ) | 0x7FFF;
405 /*----------------------------------------------------------------------------
406 | Takes two extended double-precision floating-point values `a' and `b', one
407 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
408 | `b' is a signaling NaN, the invalid exception is raised.
409 *----------------------------------------------------------------------------*/
411 static floatx80
propagateFloatx80NaN( floatx80 a
, floatx80 b STATUS_PARAM
)
413 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
415 aIsNaN
= floatx80_is_nan( a
);
416 aIsSignalingNaN
= floatx80_is_signaling_nan( a
);
417 bIsNaN
= floatx80_is_nan( b
);
418 bIsSignalingNaN
= floatx80_is_signaling_nan( b
);
420 a
.low
&= ~LIT64( 0xC000000000000000 );
421 b
.low
&= ~LIT64( 0xC000000000000000 );
423 a
.low
|= LIT64( 0xC000000000000000 );
424 b
.low
|= LIT64( 0xC000000000000000 );
426 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
427 if ( aIsSignalingNaN
) {
428 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
429 return bIsNaN
? b
: a
;
432 if ( bIsSignalingNaN
| ! bIsNaN
) return a
;
433 returnLargerSignificand
:
434 if ( a
.low
< b
.low
) return b
;
435 if ( b
.low
< a
.low
) return a
;
436 return ( a
.high
< b
.high
) ? a
: b
;
447 /*----------------------------------------------------------------------------
448 | The pattern for a default generated quadruple-precision NaN. The `high' and
449 | `low' values hold the most- and least-significant bits, respectively.
450 *----------------------------------------------------------------------------*/
452 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
453 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
455 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
456 #define float128_default_nan_low LIT64( 0x0000000000000000 )
459 /*----------------------------------------------------------------------------
460 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
461 | NaN; otherwise returns 0.
462 *----------------------------------------------------------------------------*/
464 int float128_is_nan( float128 a
)
468 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
469 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
472 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
473 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
477 /*----------------------------------------------------------------------------
478 | Returns 1 if the quadruple-precision floating-point value `a' is a
479 | signaling NaN; otherwise returns 0.
480 *----------------------------------------------------------------------------*/
482 int float128_is_signaling_nan( float128 a
)
486 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
487 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
490 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
491 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
495 /*----------------------------------------------------------------------------
496 | Returns the result of converting the quadruple-precision floating-point NaN
497 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
498 | exception is raised.
499 *----------------------------------------------------------------------------*/
501 static commonNaNT
float128ToCommonNaN( float128 a STATUS_PARAM
)
505 if ( float128_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
507 shortShift128Left( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
511 /*----------------------------------------------------------------------------
512 | Returns the result of converting the canonical NaN `a' to the quadruple-
513 | precision floating-point format.
514 *----------------------------------------------------------------------------*/
516 static float128
commonNaNToFloat128( commonNaNT a
)
520 shift128Right( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
521 z
.high
|= ( ( (bits64
) a
.sign
)<<63 ) | LIT64( 0x7FFF000000000000 );
525 /*----------------------------------------------------------------------------
526 | Takes two quadruple-precision floating-point values `a' and `b', one of
527 | which is a NaN, and returns the appropriate NaN result. If either `a' or
528 | `b' is a signaling NaN, the invalid exception is raised.
529 *----------------------------------------------------------------------------*/
531 static float128
propagateFloat128NaN( float128 a
, float128 b STATUS_PARAM
)
533 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
535 aIsNaN
= float128_is_nan( a
);
536 aIsSignalingNaN
= float128_is_signaling_nan( a
);
537 bIsNaN
= float128_is_nan( b
);
538 bIsSignalingNaN
= float128_is_signaling_nan( b
);
540 a
.high
&= ~LIT64( 0x0000800000000000 );
541 b
.high
&= ~LIT64( 0x0000800000000000 );
543 a
.high
|= LIT64( 0x0000800000000000 );
544 b
.high
|= LIT64( 0x0000800000000000 );
546 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
547 if ( aIsSignalingNaN
) {
548 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
549 return bIsNaN
? b
: a
;
552 if ( bIsSignalingNaN
| ! bIsNaN
) return a
;
553 returnLargerSignificand
:
554 if ( lt128( a
.high
<<1, a
.low
, b
.high
<<1, b
.low
) ) return b
;
555 if ( lt128( b
.high
<<1, b
.low
, a
.high
<<1, a
.low
) ) return a
;
556 return ( a
.high
< b
.high
) ? a
: b
;