1 /* $NetBSD: softfloat-specialize,v 1.6 2011/03/06 10:27:37 martin Exp $ */
4 /* This is a derivative work. */
7 ===============================================================================
9 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
10 Arithmetic Package, Release 2a.
12 Written by John R. Hauser. This work was made possible in part by the
13 International Computer Science Institute, located at Suite 600, 1947 Center
14 Street, Berkeley, California 94704. Funding was partially provided by the
15 National Science Foundation under grant MIP-9311980. The original version
16 of this code was written as part of a project to build a fixed-point vector
17 processor in collaboration with the University of California at Berkeley,
18 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
19 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
20 arithmetic/SoftFloat.html'.
22 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
23 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
24 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
25 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
26 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
28 Derivative works are acceptable, even for commercial purposes, so long as
29 (1) they include prominent notice that the work is derivative, and (2) they
30 include prominent notice akin to these four paragraphs for those parts of
31 this code that are retained.
33 ===============================================================================
41 -------------------------------------------------------------------------------
42 Underflow tininess-detection mode, statically initialized to default value.
43 (The declaration in `softfloat.h' must match the `int8' type here.)
44 -------------------------------------------------------------------------------
46 #ifdef SOFTFLOAT_FOR_GCC
50 int8 float_detect_tininess = float_tininess_before_rounding;
52 int8 float_detect_tininess = float_tininess_after_rounding;
56 -------------------------------------------------------------------------------
57 Raises the exceptions specified by `flags'. Floating-point traps can be
58 defined here if desired. It is currently not possible for such a trap to
59 substitute a result value. If traps are not implemented, this routine
60 should be simply `float_exception_flags |= flags;'.
61 -------------------------------------------------------------------------------
63 #ifdef SOFTFLOAT_FOR_GCC
64 #define float_exception_mask __softfloat_float_exception_mask
66 int float_exception_mask = 0;
67 void float_raise( int flags )
70 float_exception_flags |= flags;
72 if ( flags & float_exception_mask ) {
75 memset(&info, 0, sizeof info);
76 info.si_signo = SIGFPE;
77 info.si_pid = getpid();
78 info.si_uid = geteuid();
79 if (flags & float_flag_underflow)
80 info.si_code = FPE_FLTUND;
81 else if (flags & float_flag_overflow)
82 info.si_code = FPE_FLTOVF;
83 else if (flags & float_flag_divbyzero)
84 info.si_code = FPE_FLTDIV;
85 else if (flags & float_flag_invalid)
86 info.si_code = FPE_FLTINV;
87 else if (flags & float_flag_inexact)
88 info.si_code = FPE_FLTRES;
89 sigqueueinfo(getpid(), &info);
95 #undef float_exception_mask
98 -------------------------------------------------------------------------------
99 Internal canonical NaN format.
100 -------------------------------------------------------------------------------
108 -------------------------------------------------------------------------------
109 The pattern for a default generated single-precision NaN.
110 -------------------------------------------------------------------------------
112 #define float32_default_nan 0xFFFFFFFF
115 -------------------------------------------------------------------------------
116 Returns 1 if the single-precision floating-point value `a' is a NaN;
118 -------------------------------------------------------------------------------
120 #ifdef SOFTFLOAT_FOR_GCC
123 flag float32_is_nan( float32 a )
126 return ( 0xFF000000 < (bits32) ( a<<1 ) );
131 -------------------------------------------------------------------------------
132 Returns 1 if the single-precision floating-point value `a' is a signaling
133 NaN; otherwise returns 0.
134 -------------------------------------------------------------------------------
136 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
137 !defined(SOFTFLOAT_M68K_FOR_GCC)
140 flag float32_is_signaling_nan( float32 a )
143 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
148 -------------------------------------------------------------------------------
149 Returns the result of converting the single-precision floating-point NaN
150 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
152 -------------------------------------------------------------------------------
154 static commonNaNT float32ToCommonNaN( float32 a )
158 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
161 z.high = ( (bits64) a )<<41;
167 -------------------------------------------------------------------------------
168 Returns the result of converting the canonical NaN `a' to the single-
169 precision floating-point format.
170 -------------------------------------------------------------------------------
172 static float32 commonNaNToFloat32( commonNaNT a )
175 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
180 -------------------------------------------------------------------------------
181 Takes two single-precision floating-point values `a' and `b', one of which
182 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
183 signaling NaN, the invalid exception is raised.
184 -------------------------------------------------------------------------------
186 static float32 propagateFloat32NaN( float32 a, float32 b )
188 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
190 aIsNaN = float32_is_nan( a );
191 aIsSignalingNaN = float32_is_signaling_nan( a );
192 bIsNaN = float32_is_nan( b );
193 bIsSignalingNaN = float32_is_signaling_nan( b );
196 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
198 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
207 -------------------------------------------------------------------------------
208 The pattern for a default generated double-precision NaN.
209 -------------------------------------------------------------------------------
211 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
214 -------------------------------------------------------------------------------
215 Returns 1 if the double-precision floating-point value `a' is a NaN;
217 -------------------------------------------------------------------------------
219 #ifdef SOFTFLOAT_FOR_GCC
222 flag float64_is_nan( float64 a )
225 return ( LIT64( 0xFFE0000000000000 ) <
226 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
231 -------------------------------------------------------------------------------
232 Returns 1 if the double-precision floating-point value `a' is a signaling
233 NaN; otherwise returns 0.
234 -------------------------------------------------------------------------------
236 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
237 !defined(SOFTFLOATM68K_FOR_GCC)
240 flag float64_is_signaling_nan( float64 a )
244 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
245 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
250 -------------------------------------------------------------------------------
251 Returns the result of converting the double-precision floating-point NaN
252 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
254 -------------------------------------------------------------------------------
256 static commonNaNT float64ToCommonNaN( float64 a )
260 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
261 z.sign = FLOAT64_DEMANGLE(a)>>63;
263 z.high = FLOAT64_DEMANGLE(a)<<12;
269 -------------------------------------------------------------------------------
270 Returns the result of converting the canonical NaN `a' to the double-
271 precision floating-point format.
272 -------------------------------------------------------------------------------
274 static float64 commonNaNToFloat64( commonNaNT a )
277 return FLOAT64_MANGLE(
278 ( ( (bits64) a.sign )<<63 )
279 | LIT64( 0x7FF8000000000000 )
285 -------------------------------------------------------------------------------
286 Takes two double-precision floating-point values `a' and `b', one of which
287 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
288 signaling NaN, the invalid exception is raised.
289 -------------------------------------------------------------------------------
291 static float64 propagateFloat64NaN( float64 a, float64 b )
293 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
295 aIsNaN = float64_is_nan( a );
296 aIsSignalingNaN = float64_is_signaling_nan( a );
297 bIsNaN = float64_is_nan( b );
298 bIsSignalingNaN = float64_is_signaling_nan( b );
299 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
300 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
301 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
303 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
314 -------------------------------------------------------------------------------
315 The pattern for a default generated extended double-precision NaN. The
316 `high' and `low' values hold the most- and least-significant bits,
318 -------------------------------------------------------------------------------
320 #define floatx80_default_nan_high 0xFFFF
321 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
324 -------------------------------------------------------------------------------
325 Returns 1 if the extended double-precision floating-point value `a' is a
326 NaN; otherwise returns 0.
327 -------------------------------------------------------------------------------
329 flag floatx80_is_nan( floatx80 a )
332 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
337 -------------------------------------------------------------------------------
338 Returns 1 if the extended double-precision floating-point value `a' is a
339 signaling NaN; otherwise returns 0.
340 -------------------------------------------------------------------------------
342 flag floatx80_is_signaling_nan( floatx80 a )
346 aLow = a.low & ~ LIT64( 0x4000000000000000 );
348 ( ( a.high & 0x7FFF ) == 0x7FFF )
349 && (bits64) ( aLow<<1 )
350 && ( a.low == aLow );
355 -------------------------------------------------------------------------------
356 Returns the result of converting the extended double-precision floating-
357 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
358 invalid exception is raised.
359 -------------------------------------------------------------------------------
361 static commonNaNT floatx80ToCommonNaN( floatx80 a )
365 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
374 -------------------------------------------------------------------------------
375 Returns the result of converting the canonical NaN `a' to the extended
376 double-precision floating-point format.
377 -------------------------------------------------------------------------------
379 static floatx80 commonNaNToFloatx80( commonNaNT a )
383 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
384 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
390 -------------------------------------------------------------------------------
391 Takes two extended double-precision floating-point values `a' and `b', one
392 of which is a NaN, and returns the appropriate NaN result. If either `a' or
393 `b' is a signaling NaN, the invalid exception is raised.
394 -------------------------------------------------------------------------------
396 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
398 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
400 aIsNaN = floatx80_is_nan( a );
401 aIsSignalingNaN = floatx80_is_signaling_nan( a );
402 bIsNaN = floatx80_is_nan( b );
403 bIsSignalingNaN = floatx80_is_signaling_nan( b );
404 a.low |= LIT64( 0xC000000000000000 );
405 b.low |= LIT64( 0xC000000000000000 );
406 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
408 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
421 -------------------------------------------------------------------------------
422 The pattern for a default generated quadruple-precision NaN. The `high' and
423 `low' values hold the most- and least-significant bits, respectively.
424 -------------------------------------------------------------------------------
426 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
427 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
430 -------------------------------------------------------------------------------
431 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
433 -------------------------------------------------------------------------------
435 flag float128_is_nan( float128 a )
439 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
440 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
445 -------------------------------------------------------------------------------
446 Returns 1 if the quadruple-precision floating-point value `a' is a
447 signaling NaN; otherwise returns 0.
448 -------------------------------------------------------------------------------
450 flag float128_is_signaling_nan( float128 a )
454 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
455 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
460 -------------------------------------------------------------------------------
461 Returns the result of converting the quadruple-precision floating-point NaN
462 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
464 -------------------------------------------------------------------------------
466 static commonNaNT float128ToCommonNaN( float128 a )
470 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
472 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
478 -------------------------------------------------------------------------------
479 Returns the result of converting the canonical NaN `a' to the quadruple-
480 precision floating-point format.
481 -------------------------------------------------------------------------------
483 static float128 commonNaNToFloat128( commonNaNT a )
487 shift128Right( a.high, a.low, 16, &z.high, &z.low );
488 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
494 -------------------------------------------------------------------------------
495 Takes two quadruple-precision floating-point values `a' and `b', one of
496 which is a NaN, and returns the appropriate NaN result. If either `a' or
497 `b' is a signaling NaN, the invalid exception is raised.
498 -------------------------------------------------------------------------------
500 static float128 propagateFloat128NaN( float128 a, float128 b )
502 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
504 aIsNaN = float128_is_nan( a );
505 aIsSignalingNaN = float128_is_signaling_nan( a );
506 bIsNaN = float128_is_nan( b );
507 bIsSignalingNaN = float128_is_signaling_nan( b );
508 a.high |= LIT64( 0x0000800000000000 );
509 b.high |= LIT64( 0x0000800000000000 );
510 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
512 return ( aIsSignalingNaN & bIsNaN ) ? b : a;