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)
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 if ( STATUS(default_nan_mode
) )
148 return float32_default_nan
;
150 aIsNaN
= float32_is_nan( a
);
151 aIsSignalingNaN
= float32_is_signaling_nan( a
);
152 bIsNaN
= float32_is_nan( b
);
153 bIsSignalingNaN
= float32_is_signaling_nan( b
);
163 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
164 if ( aIsSignalingNaN
) {
165 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
166 res
= bIsNaN
? bv
: av
;
169 if ( bIsSignalingNaN
|| ! bIsNaN
)
172 returnLargerSignificand
:
173 if ( (bits32
) ( av
<<1 ) < (bits32
) ( bv
<<1 ) )
175 else if ( (bits32
) ( bv
<<1 ) < (bits32
) ( av
<<1 ) )
178 res
= ( av
< bv
) ? av
: bv
;
184 return make_float32(res
);
187 /*----------------------------------------------------------------------------
188 | The pattern for a default generated double-precision NaN.
189 *----------------------------------------------------------------------------*/
190 #if defined(TARGET_SPARC)
191 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
192 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
193 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
194 #elif defined(TARGET_HPPA)
195 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
196 #elif SNAN_BIT_IS_ONE
197 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
199 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
202 /*----------------------------------------------------------------------------
203 | Returns 1 if the double-precision floating-point value `a' is a quiet
204 | NaN; otherwise returns 0.
205 *----------------------------------------------------------------------------*/
207 int float64_is_nan( float64 a_
)
209 bits64 a
= float64_val(a_
);
212 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
213 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
215 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
219 /*----------------------------------------------------------------------------
220 | Returns 1 if the double-precision floating-point value `a' is a signaling
221 | NaN; otherwise returns 0.
222 *----------------------------------------------------------------------------*/
224 int float64_is_signaling_nan( float64 a_
)
226 bits64 a
= float64_val(a_
);
228 return ( LIT64( 0xFFF0000000000000 ) <= (bits64
) ( a
<<1 ) );
231 ( ( ( a
>>51 ) & 0xFFF ) == 0xFFE )
232 && ( a
& LIT64( 0x0007FFFFFFFFFFFF ) );
236 /*----------------------------------------------------------------------------
237 | Returns the result of converting the double-precision floating-point NaN
238 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
239 | exception is raised.
240 *----------------------------------------------------------------------------*/
242 static commonNaNT
float64ToCommonNaN( float64 a STATUS_PARAM
)
246 if ( float64_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
247 z
.sign
= float64_val(a
)>>63;
249 z
.high
= float64_val(a
)<<12;
253 /*----------------------------------------------------------------------------
254 | Returns the result of converting the canonical NaN `a' to the double-
255 | precision floating-point format.
256 *----------------------------------------------------------------------------*/
258 static float64
commonNaNToFloat64( commonNaNT a
)
260 bits64 mantissa
= a
.high
>>12;
264 ( ( (bits64
) a
.sign
)<<63 )
265 | LIT64( 0x7FF0000000000000 )
268 return float64_default_nan
;
271 /*----------------------------------------------------------------------------
272 | Takes two double-precision floating-point values `a' and `b', one of which
273 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
274 | signaling NaN, the invalid exception is raised.
275 *----------------------------------------------------------------------------*/
277 static float64
propagateFloat64NaN( float64 a
, float64 b STATUS_PARAM
)
279 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
282 if ( STATUS(default_nan_mode
) )
283 return float64_default_nan
;
285 aIsNaN
= float64_is_nan( a
);
286 aIsSignalingNaN
= float64_is_signaling_nan( a
);
287 bIsNaN
= float64_is_nan( b
);
288 bIsSignalingNaN
= float64_is_signaling_nan( b
);
292 av
&= ~LIT64( 0x0008000000000000 );
293 bv
&= ~LIT64( 0x0008000000000000 );
295 av
|= LIT64( 0x0008000000000000 );
296 bv
|= LIT64( 0x0008000000000000 );
298 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
299 if ( aIsSignalingNaN
) {
300 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
301 res
= bIsNaN
? bv
: av
;
304 if ( bIsSignalingNaN
|| ! bIsNaN
)
307 returnLargerSignificand
:
308 if ( (bits64
) ( av
<<1 ) < (bits64
) ( bv
<<1 ) )
310 else if ( (bits64
) ( bv
<<1 ) < (bits64
) ( av
<<1 ) )
313 res
= ( av
< bv
) ? av
: bv
;
319 return make_float64(res
);
324 /*----------------------------------------------------------------------------
325 | The pattern for a default generated extended double-precision NaN. The
326 | `high' and `low' values hold the most- and least-significant bits,
328 *----------------------------------------------------------------------------*/
330 #define floatx80_default_nan_high 0x7FFF
331 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
333 #define floatx80_default_nan_high 0xFFFF
334 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
337 /*----------------------------------------------------------------------------
338 | Returns 1 if the extended double-precision floating-point value `a' is a
339 | quiet NaN; otherwise returns 0.
340 *----------------------------------------------------------------------------*/
342 int floatx80_is_nan( floatx80 a
)
347 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
349 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
350 && (bits64
) ( aLow
<<1 )
351 && ( a
.low
== aLow
);
353 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
357 /*----------------------------------------------------------------------------
358 | Returns 1 if the extended double-precision floating-point value `a' is a
359 | signaling NaN; otherwise returns 0.
360 *----------------------------------------------------------------------------*/
362 int floatx80_is_signaling_nan( floatx80 a
)
365 return ( ( a
.high
& 0x7FFF ) == 0x7FFF ) && (bits64
) ( a
.low
<<1 );
369 aLow
= a
.low
& ~ LIT64( 0x4000000000000000 );
371 ( ( a
.high
& 0x7FFF ) == 0x7FFF )
372 && (bits64
) ( aLow
<<1 )
373 && ( a
.low
== aLow
);
377 /*----------------------------------------------------------------------------
378 | Returns the result of converting the extended double-precision floating-
379 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
380 | invalid exception is raised.
381 *----------------------------------------------------------------------------*/
383 static commonNaNT
floatx80ToCommonNaN( floatx80 a STATUS_PARAM
)
387 if ( floatx80_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
394 /*----------------------------------------------------------------------------
395 | Returns the result of converting the canonical NaN `a' to the extended
396 | double-precision floating-point format.
397 *----------------------------------------------------------------------------*/
399 static floatx80
commonNaNToFloatx80( commonNaNT a
)
406 z
.low
= floatx80_default_nan_low
;
407 z
.high
= ( ( (bits16
) a
.sign
)<<15 ) | 0x7FFF;
411 /*----------------------------------------------------------------------------
412 | Takes two extended double-precision floating-point values `a' and `b', one
413 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
414 | `b' is a signaling NaN, the invalid exception is raised.
415 *----------------------------------------------------------------------------*/
417 static floatx80
propagateFloatx80NaN( floatx80 a
, floatx80 b STATUS_PARAM
)
419 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
421 if ( STATUS(default_nan_mode
) ) {
422 a
.low
= floatx80_default_nan_low
;
423 a
.high
= floatx80_default_nan_high
;
427 aIsNaN
= floatx80_is_nan( a
);
428 aIsSignalingNaN
= floatx80_is_signaling_nan( a
);
429 bIsNaN
= floatx80_is_nan( b
);
430 bIsSignalingNaN
= floatx80_is_signaling_nan( b
);
432 a
.low
&= ~LIT64( 0xC000000000000000 );
433 b
.low
&= ~LIT64( 0xC000000000000000 );
435 a
.low
|= LIT64( 0xC000000000000000 );
436 b
.low
|= LIT64( 0xC000000000000000 );
438 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
439 if ( aIsSignalingNaN
) {
440 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
441 return bIsNaN
? b
: a
;
444 if ( bIsSignalingNaN
|| ! bIsNaN
) return a
;
445 returnLargerSignificand
:
446 if ( a
.low
< b
.low
) return b
;
447 if ( b
.low
< a
.low
) return a
;
448 return ( a
.high
< b
.high
) ? a
: b
;
459 /*----------------------------------------------------------------------------
460 | The pattern for a default generated quadruple-precision NaN. The `high' and
461 | `low' values hold the most- and least-significant bits, respectively.
462 *----------------------------------------------------------------------------*/
464 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
465 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
467 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
468 #define float128_default_nan_low LIT64( 0x0000000000000000 )
471 /*----------------------------------------------------------------------------
472 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
473 | NaN; otherwise returns 0.
474 *----------------------------------------------------------------------------*/
476 int float128_is_nan( float128 a
)
480 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
481 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
484 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
485 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
489 /*----------------------------------------------------------------------------
490 | Returns 1 if the quadruple-precision floating-point value `a' is a
491 | signaling NaN; otherwise returns 0.
492 *----------------------------------------------------------------------------*/
494 int float128_is_signaling_nan( float128 a
)
498 ( LIT64( 0xFFFE000000000000 ) <= (bits64
) ( a
.high
<<1 ) )
499 && ( a
.low
|| ( a
.high
& LIT64( 0x0000FFFFFFFFFFFF ) ) );
502 ( ( ( a
.high
>>47 ) & 0xFFFF ) == 0xFFFE )
503 && ( a
.low
|| ( a
.high
& LIT64( 0x00007FFFFFFFFFFF ) ) );
507 /*----------------------------------------------------------------------------
508 | Returns the result of converting the quadruple-precision floating-point NaN
509 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
510 | exception is raised.
511 *----------------------------------------------------------------------------*/
513 static commonNaNT
float128ToCommonNaN( float128 a STATUS_PARAM
)
517 if ( float128_is_signaling_nan( a
) ) float_raise( float_flag_invalid STATUS_VAR
);
519 shortShift128Left( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
523 /*----------------------------------------------------------------------------
524 | Returns the result of converting the canonical NaN `a' to the quadruple-
525 | precision floating-point format.
526 *----------------------------------------------------------------------------*/
528 static float128
commonNaNToFloat128( commonNaNT a
)
532 shift128Right( a
.high
, a
.low
, 16, &z
.high
, &z
.low
);
533 z
.high
|= ( ( (bits64
) a
.sign
)<<63 ) | LIT64( 0x7FFF000000000000 );
537 /*----------------------------------------------------------------------------
538 | Takes two quadruple-precision floating-point values `a' and `b', one of
539 | which is a NaN, and returns the appropriate NaN result. If either `a' or
540 | `b' is a signaling NaN, the invalid exception is raised.
541 *----------------------------------------------------------------------------*/
543 static float128
propagateFloat128NaN( float128 a
, float128 b STATUS_PARAM
)
545 flag aIsNaN
, aIsSignalingNaN
, bIsNaN
, bIsSignalingNaN
;
547 if ( STATUS(default_nan_mode
) ) {
548 a
.low
= float128_default_nan_low
;
549 a
.high
= float128_default_nan_high
;
553 aIsNaN
= float128_is_nan( a
);
554 aIsSignalingNaN
= float128_is_signaling_nan( a
);
555 bIsNaN
= float128_is_nan( b
);
556 bIsSignalingNaN
= float128_is_signaling_nan( b
);
558 a
.high
&= ~LIT64( 0x0000800000000000 );
559 b
.high
&= ~LIT64( 0x0000800000000000 );
561 a
.high
|= LIT64( 0x0000800000000000 );
562 b
.high
|= LIT64( 0x0000800000000000 );
564 if ( aIsSignalingNaN
| bIsSignalingNaN
) float_raise( float_flag_invalid STATUS_VAR
);
565 if ( aIsSignalingNaN
) {
566 if ( bIsSignalingNaN
) goto returnLargerSignificand
;
567 return bIsNaN
? b
: a
;
570 if ( bIsSignalingNaN
|| ! bIsNaN
) return a
;
571 returnLargerSignificand
:
572 if ( lt128( a
.high
<<1, a
.low
, b
.high
<<1, b
.low
) ) return b
;
573 if ( lt128( b
.high
<<1, b
.low
, a
.high
<<1, a
.low
) ) return a
;
574 return ( a
.high
< b
.high
) ? a
: b
;