1 /* $NetBSD: softfloat-specialize,v 1.8 2013/01/10 08:16:10 matt Exp $ */
3 /* This is a derivative work. */
6 ===============================================================================
8 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
9 Arithmetic Package, Release 2a.
11 Written by John R. Hauser. This work was made possible in part by the
12 International Computer Science Institute, located at Suite 600, 1947 Center
13 Street, Berkeley, California 94704. Funding was partially provided by the
14 National Science Foundation under grant MIP-9311980. The original version
15 of this code was written as part of a project to build a fixed-point vector
16 processor in collaboration with the University of California at Berkeley,
17 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
18 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
19 arithmetic/SoftFloat.html'.
21 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
22 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
23 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
24 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
25 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
27 Derivative works are acceptable, even for commercial purposes, so long as
28 (1) they include prominent notice that the work is derivative, and (2) they
29 include prominent notice akin to these four paragraphs for those parts of
30 this code that are retained.
32 ===============================================================================
36 -------------------------------------------------------------------------------
37 Underflow tininess-detection mode, statically initialized to default value.
38 (The declaration in `softfloat.h' must match the `int8' type here.)
39 -------------------------------------------------------------------------------
41 #ifdef SOFTFLOAT_FOR_GCC
44 int8 float_detect_tininess = float_tininess_after_rounding;
47 -------------------------------------------------------------------------------
48 Raises the exceptions specified by `flags'. Floating-point traps can be
49 defined here if desired. It is currently not possible for such a trap to
50 substitute a result value. If traps are not implemented, this routine
51 should be simply `float_exception_flags |= flags;'.
52 -------------------------------------------------------------------------------
54 #ifdef SOFTFLOAT_FOR_GCC
55 #ifndef set_float_exception_mask
56 #define float_exception_mask _softfloat_float_exception_mask
59 #ifndef set_float_exception_mask
60 fp_except float_exception_mask = 0;
63 float_raise( fp_except flags )
66 #if 0 // Don't raise exceptions
68 fp_except mask = float_exception_mask;
70 #ifdef set_float_exception_mask
71 flags |= set_float_exception_flags(flags, 0);
73 float_exception_flags |= flags;
74 flags = float_exception_flags;
79 memset(&info, 0, sizeof info);
80 info.si_signo = SIGFPE;
81 info.si_pid = getpid();
82 info.si_uid = geteuid();
83 if (flags & float_flag_underflow)
84 info.si_code = FPE_FLTUND;
85 else if (flags & float_flag_overflow)
86 info.si_code = FPE_FLTOVF;
87 else if (flags & float_flag_divbyzero)
88 info.si_code = FPE_FLTDIV;
89 else if (flags & float_flag_invalid)
90 info.si_code = FPE_FLTINV;
91 else if (flags & float_flag_inexact)
92 info.si_code = FPE_FLTRES;
93 sigqueueinfo(getpid(), &info);
95 #else // Don't raise exceptions
96 float_exception_flags |= flags;
97 #endif // Don't raise exceptions
99 #undef float_exception_mask
102 -------------------------------------------------------------------------------
103 Internal canonical NaN format.
104 -------------------------------------------------------------------------------
112 -------------------------------------------------------------------------------
113 The pattern for a default generated single-precision NaN.
114 -------------------------------------------------------------------------------
116 #define float32_default_nan 0xFFFFFFFF
119 -------------------------------------------------------------------------------
120 Returns 1 if the single-precision floating-point value `a' is a NaN;
122 -------------------------------------------------------------------------------
124 #ifdef SOFTFLOAT_FOR_GCC
127 flag float32_is_nan( float32 a )
130 return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) );
135 -------------------------------------------------------------------------------
136 Returns 1 if the single-precision floating-point value `a' is a signaling
137 NaN; otherwise returns 0.
138 -------------------------------------------------------------------------------
140 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
141 !defined(SOFTFLOAT_M68K_FOR_GCC)
144 flag float32_is_signaling_nan( float32 a )
147 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
152 -------------------------------------------------------------------------------
153 Returns the result of converting the single-precision floating-point NaN
154 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
156 -------------------------------------------------------------------------------
158 static commonNaNT float32ToCommonNaN( float32 a )
162 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
165 z.high = ( (bits64) a )<<41;
171 -------------------------------------------------------------------------------
172 Returns the result of converting the canonical NaN `a' to the single-
173 precision floating-point format.
174 -------------------------------------------------------------------------------
176 static float32 commonNaNToFloat32( commonNaNT a )
179 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 );
184 -------------------------------------------------------------------------------
185 Takes two single-precision floating-point values `a' and `b', one of which
186 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
187 signaling NaN, the invalid exception is raised.
188 -------------------------------------------------------------------------------
190 static float32 propagateFloat32NaN( float32 a, float32 b )
192 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
194 aIsNaN = float32_is_nan( a );
195 aIsSignalingNaN = float32_is_signaling_nan( a );
196 bIsNaN = float32_is_nan( b );
197 bIsSignalingNaN = float32_is_signaling_nan( b );
200 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
202 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
211 -------------------------------------------------------------------------------
212 The pattern for a default generated double-precision NaN.
213 -------------------------------------------------------------------------------
215 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
218 -------------------------------------------------------------------------------
219 Returns 1 if the double-precision floating-point value `a' is a NaN;
221 -------------------------------------------------------------------------------
223 #ifdef SOFTFLOAT_FOR_GCC
226 flag float64_is_nan( float64 a )
229 return ( (bits64)LIT64( 0xFFE0000000000000 ) <
230 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
235 -------------------------------------------------------------------------------
236 Returns 1 if the double-precision floating-point value `a' is a signaling
237 NaN; otherwise returns 0.
238 -------------------------------------------------------------------------------
240 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
241 !defined(SOFTFLOATM68K_FOR_GCC)
244 flag float64_is_signaling_nan( float64 a )
248 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
249 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
254 -------------------------------------------------------------------------------
255 Returns the result of converting the double-precision floating-point NaN
256 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
258 -------------------------------------------------------------------------------
260 static commonNaNT float64ToCommonNaN( float64 a )
264 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
265 z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63);
267 z.high = FLOAT64_DEMANGLE(a)<<12;
273 -------------------------------------------------------------------------------
274 Returns the result of converting the canonical NaN `a' to the double-
275 precision floating-point format.
276 -------------------------------------------------------------------------------
278 static float64 commonNaNToFloat64( commonNaNT a )
281 return FLOAT64_MANGLE(
282 ( ( (bits64) a.sign )<<63 )
283 | LIT64( 0x7FF8000000000000 )
289 -------------------------------------------------------------------------------
290 Takes two double-precision floating-point values `a' and `b', one of which
291 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
292 signaling NaN, the invalid exception is raised.
293 -------------------------------------------------------------------------------
295 static float64 propagateFloat64NaN( float64 a, float64 b )
297 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
299 aIsNaN = float64_is_nan( a );
300 aIsSignalingNaN = float64_is_signaling_nan( a );
301 bIsNaN = float64_is_nan( b );
302 bIsSignalingNaN = float64_is_signaling_nan( b );
303 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
304 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
305 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
307 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
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 0xFFFF
325 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
328 -------------------------------------------------------------------------------
329 Returns 1 if the extended double-precision floating-point value `a' is a
330 NaN; otherwise returns 0.
331 -------------------------------------------------------------------------------
333 flag floatx80_is_nan( floatx80 a )
336 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
341 -------------------------------------------------------------------------------
342 Returns 1 if the extended double-precision floating-point value `a' is a
343 signaling NaN; otherwise returns 0.
344 -------------------------------------------------------------------------------
346 flag floatx80_is_signaling_nan( floatx80 a )
350 aLow = a.low & ~ LIT64( 0x4000000000000000 );
352 ( ( a.high & 0x7FFF ) == 0x7FFF )
353 && (bits64) ( aLow<<1 )
354 && ( a.low == aLow );
359 -------------------------------------------------------------------------------
360 Returns the result of converting the extended double-precision floating-
361 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
362 invalid exception is raised.
363 -------------------------------------------------------------------------------
365 static commonNaNT floatx80ToCommonNaN( floatx80 a )
369 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
378 -------------------------------------------------------------------------------
379 Returns the result of converting the canonical NaN `a' to the extended
380 double-precision floating-point format.
381 -------------------------------------------------------------------------------
383 static floatx80 commonNaNToFloatx80( commonNaNT a )
387 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
388 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
394 -------------------------------------------------------------------------------
395 Takes two extended double-precision floating-point values `a' and `b', one
396 of which is a NaN, and returns the appropriate NaN result. If either `a' or
397 `b' is a signaling NaN, the invalid exception is raised.
398 -------------------------------------------------------------------------------
400 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
402 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
404 aIsNaN = floatx80_is_nan( a );
405 aIsSignalingNaN = floatx80_is_signaling_nan( a );
406 bIsNaN = floatx80_is_nan( b );
407 bIsSignalingNaN = floatx80_is_signaling_nan( b );
408 a.low |= LIT64( 0xC000000000000000 );
409 b.low |= LIT64( 0xC000000000000000 );
410 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
412 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
425 -------------------------------------------------------------------------------
426 The pattern for a default generated quadruple-precision NaN. The `high' and
427 `low' values hold the most- and least-significant bits, respectively.
428 -------------------------------------------------------------------------------
430 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
431 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
434 -------------------------------------------------------------------------------
435 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
437 -------------------------------------------------------------------------------
439 flag float128_is_nan( float128 a )
443 ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
444 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
449 -------------------------------------------------------------------------------
450 Returns 1 if the quadruple-precision floating-point value `a' is a
451 signaling NaN; otherwise returns 0.
452 -------------------------------------------------------------------------------
454 flag float128_is_signaling_nan( float128 a )
458 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
459 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
464 -------------------------------------------------------------------------------
465 Returns the result of converting the quadruple-precision floating-point NaN
466 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
468 -------------------------------------------------------------------------------
470 static commonNaNT float128ToCommonNaN( float128 a )
474 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
475 z.sign = (flag)(a.high>>63);
476 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
482 -------------------------------------------------------------------------------
483 Returns the result of converting the canonical NaN `a' to the quadruple-
484 precision floating-point format.
485 -------------------------------------------------------------------------------
487 static float128 commonNaNToFloat128( commonNaNT a )
491 shift128Right( a.high, a.low, 16, &z.high, &z.low );
492 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
498 -------------------------------------------------------------------------------
499 Takes two quadruple-precision floating-point values `a' and `b', one of
500 which is a NaN, and returns the appropriate NaN result. If either `a' or
501 `b' is a signaling NaN, the invalid exception is raised.
502 -------------------------------------------------------------------------------
504 static float128 propagateFloat128NaN( float128 a, float128 b )
506 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
508 aIsNaN = float128_is_nan( a );
509 aIsSignalingNaN = float128_is_signaling_nan( a );
510 bIsNaN = float128_is_nan( b );
511 bIsSignalingNaN = float128_is_signaling_nan( b );
512 a.high |= LIT64( 0x0000800000000000 );
513 b.high |= LIT64( 0x0000800000000000 );
514 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
516 return ( aIsSignalingNaN & bIsNaN ) ? b : a;