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 ===============================================================================
40 -------------------------------------------------------------------------------
41 Underflow tininess-detection mode, statically initialized to default value.
42 (The declaration in `softfloat.h' must match the `int8' type here.)
43 -------------------------------------------------------------------------------
45 #ifdef SOFTFLOAT_FOR_GCC
48 int8 float_detect_tininess = float_tininess_after_rounding;
51 -------------------------------------------------------------------------------
52 Raises the exceptions specified by `flags'. Floating-point traps can be
53 defined here if desired. It is currently not possible for such a trap to
54 substitute a result value. If traps are not implemented, this routine
55 should be simply `float_exception_flags |= flags;'.
56 -------------------------------------------------------------------------------
58 #ifdef SOFTFLOAT_FOR_GCC
59 #ifndef set_float_exception_mask
60 #define float_exception_mask _softfloat_float_exception_mask
63 #ifndef set_float_exception_mask
64 fp_except float_exception_mask = 0;
67 float_raise( fp_except flags )
70 #if 0 // Don't raise exceptions
72 fp_except mask = float_exception_mask;
74 #ifdef set_float_exception_mask
75 flags |= set_float_exception_flags(flags, 0);
77 float_exception_flags |= flags;
78 flags = float_exception_flags;
83 memset(&info, 0, sizeof info);
84 info.si_signo = SIGFPE;
85 info.si_pid = getpid();
86 info.si_uid = geteuid();
87 if (flags & float_flag_underflow)
88 info.si_code = FPE_FLTUND;
89 else if (flags & float_flag_overflow)
90 info.si_code = FPE_FLTOVF;
91 else if (flags & float_flag_divbyzero)
92 info.si_code = FPE_FLTDIV;
93 else if (flags & float_flag_invalid)
94 info.si_code = FPE_FLTINV;
95 else if (flags & float_flag_inexact)
96 info.si_code = FPE_FLTRES;
97 sigqueueinfo(getpid(), &info);
99 #else // Don't raise exceptions
100 float_exception_flags |= flags;
101 #endif // Don't raise exceptions
103 #undef float_exception_mask
106 -------------------------------------------------------------------------------
107 Internal canonical NaN format.
108 -------------------------------------------------------------------------------
116 -------------------------------------------------------------------------------
117 The pattern for a default generated single-precision NaN.
118 -------------------------------------------------------------------------------
120 #define float32_default_nan 0xFFFFFFFF
123 -------------------------------------------------------------------------------
124 Returns 1 if the single-precision floating-point value `a' is a NaN;
126 -------------------------------------------------------------------------------
128 #ifdef SOFTFLOAT_FOR_GCC
131 flag float32_is_nan( float32 a )
134 return ( (bits32)0xFF000000 < (bits32) ( a<<1 ) );
139 -------------------------------------------------------------------------------
140 Returns 1 if the single-precision floating-point value `a' is a signaling
141 NaN; otherwise returns 0.
142 -------------------------------------------------------------------------------
144 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
145 !defined(SOFTFLOAT_M68K_FOR_GCC)
148 flag float32_is_signaling_nan( float32 a )
151 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
156 -------------------------------------------------------------------------------
157 Returns the result of converting the single-precision floating-point NaN
158 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
160 -------------------------------------------------------------------------------
162 static commonNaNT float32ToCommonNaN( float32 a )
166 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
169 z.high = ( (bits64) a )<<41;
175 -------------------------------------------------------------------------------
176 Returns the result of converting the canonical NaN `a' to the single-
177 precision floating-point format.
178 -------------------------------------------------------------------------------
180 static float32 commonNaNToFloat32( commonNaNT a )
183 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | (bits32)( a.high>>41 );
188 -------------------------------------------------------------------------------
189 Takes two single-precision floating-point values `a' and `b', one of which
190 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
191 signaling NaN, the invalid exception is raised.
192 -------------------------------------------------------------------------------
194 static float32 propagateFloat32NaN( float32 a, float32 b )
196 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
198 aIsNaN = float32_is_nan( a );
199 aIsSignalingNaN = float32_is_signaling_nan( a );
200 bIsNaN = float32_is_nan( b );
201 bIsSignalingNaN = float32_is_signaling_nan( b );
204 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
206 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
215 -------------------------------------------------------------------------------
216 The pattern for a default generated double-precision NaN.
217 -------------------------------------------------------------------------------
219 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
222 -------------------------------------------------------------------------------
223 Returns 1 if the double-precision floating-point value `a' is a NaN;
225 -------------------------------------------------------------------------------
227 #ifdef SOFTFLOAT_FOR_GCC
230 flag float64_is_nan( float64 a )
233 return ( (bits64)LIT64( 0xFFE0000000000000 ) <
234 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
239 -------------------------------------------------------------------------------
240 Returns 1 if the double-precision floating-point value `a' is a signaling
241 NaN; otherwise returns 0.
242 -------------------------------------------------------------------------------
244 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
245 !defined(SOFTFLOATM68K_FOR_GCC)
248 flag float64_is_signaling_nan( float64 a )
252 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
253 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
258 -------------------------------------------------------------------------------
259 Returns the result of converting the double-precision floating-point NaN
260 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
262 -------------------------------------------------------------------------------
264 static commonNaNT float64ToCommonNaN( float64 a )
268 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
269 z.sign = (flag)(FLOAT64_DEMANGLE(a)>>63);
271 z.high = FLOAT64_DEMANGLE(a)<<12;
277 -------------------------------------------------------------------------------
278 Returns the result of converting the canonical NaN `a' to the double-
279 precision floating-point format.
280 -------------------------------------------------------------------------------
282 static float64 commonNaNToFloat64( commonNaNT a )
285 return FLOAT64_MANGLE(
286 ( ( (bits64) a.sign )<<63 )
287 | LIT64( 0x7FF8000000000000 )
293 -------------------------------------------------------------------------------
294 Takes two double-precision floating-point values `a' and `b', one of which
295 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
296 signaling NaN, the invalid exception is raised.
297 -------------------------------------------------------------------------------
299 static float64 propagateFloat64NaN( float64 a, float64 b )
301 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
303 aIsNaN = float64_is_nan( a );
304 aIsSignalingNaN = float64_is_signaling_nan( a );
305 bIsNaN = float64_is_nan( b );
306 bIsSignalingNaN = float64_is_signaling_nan( b );
307 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
308 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
309 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
311 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
322 -------------------------------------------------------------------------------
323 The pattern for a default generated extended double-precision NaN. The
324 `high' and `low' values hold the most- and least-significant bits,
326 -------------------------------------------------------------------------------
328 #define floatx80_default_nan_high 0xFFFF
329 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
332 -------------------------------------------------------------------------------
333 Returns 1 if the extended double-precision floating-point value `a' is a
334 NaN; otherwise returns 0.
335 -------------------------------------------------------------------------------
337 flag floatx80_is_nan( floatx80 a )
340 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
345 -------------------------------------------------------------------------------
346 Returns 1 if the extended double-precision floating-point value `a' is a
347 signaling NaN; otherwise returns 0.
348 -------------------------------------------------------------------------------
350 flag floatx80_is_signaling_nan( floatx80 a )
354 aLow = a.low & ~ LIT64( 0x4000000000000000 );
356 ( ( a.high & 0x7FFF ) == 0x7FFF )
357 && (bits64) ( aLow<<1 )
358 && ( a.low == aLow );
363 -------------------------------------------------------------------------------
364 Returns the result of converting the extended double-precision floating-
365 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
366 invalid exception is raised.
367 -------------------------------------------------------------------------------
369 static commonNaNT floatx80ToCommonNaN( floatx80 a )
373 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
382 -------------------------------------------------------------------------------
383 Returns the result of converting the canonical NaN `a' to the extended
384 double-precision floating-point format.
385 -------------------------------------------------------------------------------
387 static floatx80 commonNaNToFloatx80( commonNaNT a )
391 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
392 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
398 -------------------------------------------------------------------------------
399 Takes two extended double-precision floating-point values `a' and `b', one
400 of which is a NaN, and returns the appropriate NaN result. If either `a' or
401 `b' is a signaling NaN, the invalid exception is raised.
402 -------------------------------------------------------------------------------
404 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
406 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
408 aIsNaN = floatx80_is_nan( a );
409 aIsSignalingNaN = floatx80_is_signaling_nan( a );
410 bIsNaN = floatx80_is_nan( b );
411 bIsSignalingNaN = floatx80_is_signaling_nan( b );
412 a.low |= LIT64( 0xC000000000000000 );
413 b.low |= LIT64( 0xC000000000000000 );
414 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
416 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
429 -------------------------------------------------------------------------------
430 The pattern for a default generated quadruple-precision NaN. The `high' and
431 `low' values hold the most- and least-significant bits, respectively.
432 -------------------------------------------------------------------------------
434 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
435 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
438 -------------------------------------------------------------------------------
439 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
441 -------------------------------------------------------------------------------
443 flag float128_is_nan( float128 a )
447 ( (bits64)LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
448 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
453 -------------------------------------------------------------------------------
454 Returns 1 if the quadruple-precision floating-point value `a' is a
455 signaling NaN; otherwise returns 0.
456 -------------------------------------------------------------------------------
458 flag float128_is_signaling_nan( float128 a )
462 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
463 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
468 -------------------------------------------------------------------------------
469 Returns the result of converting the quadruple-precision floating-point NaN
470 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
472 -------------------------------------------------------------------------------
474 static commonNaNT float128ToCommonNaN( float128 a )
478 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
479 z.sign = (flag)(a.high>>63);
480 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
486 -------------------------------------------------------------------------------
487 Returns the result of converting the canonical NaN `a' to the quadruple-
488 precision floating-point format.
489 -------------------------------------------------------------------------------
491 static float128 commonNaNToFloat128( commonNaNT a )
495 shift128Right( a.high, a.low, 16, &z.high, &z.low );
496 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
502 -------------------------------------------------------------------------------
503 Takes two quadruple-precision floating-point values `a' and `b', one of
504 which is a NaN, and returns the appropriate NaN result. If either `a' or
505 `b' is a signaling NaN, the invalid exception is raised.
506 -------------------------------------------------------------------------------
508 static float128 propagateFloat128NaN( float128 a, float128 b )
510 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
512 aIsNaN = float128_is_nan( a );
513 aIsSignalingNaN = float128_is_signaling_nan( a );
514 bIsNaN = float128_is_nan( b );
515 bIsSignalingNaN = float128_is_signaling_nan( b );
516 a.high |= LIT64( 0x0000800000000000 );
517 b.high |= LIT64( 0x0000800000000000 );
518 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
520 return ( aIsSignalingNaN & bIsNaN ) ? b : a;