1 /* $NetBSD: softfloat-specialize,v 1.6 2011/03/06 10:27:37 martin 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
49 int8 float_detect_tininess = float_tininess_before_rounding;
51 int8 float_detect_tininess = float_tininess_after_rounding;
55 -------------------------------------------------------------------------------
56 Raises the exceptions specified by `flags'. Floating-point traps can be
57 defined here if desired. It is currently not possible for such a trap to
58 substitute a result value. If traps are not implemented, this routine
59 should be simply `float_exception_flags |= flags;'.
60 -------------------------------------------------------------------------------
62 #ifdef SOFTFLOAT_FOR_GCC
63 #define float_exception_mask __softfloat_float_exception_mask
65 int float_exception_mask = 0;
66 void float_raise( int flags )
69 float_exception_flags |= flags;
71 if ( flags & float_exception_mask ) {
74 memset(&info, 0, sizeof info);
75 info.si_signo = SIGFPE;
76 info.si_pid = getpid();
77 info.si_uid = geteuid();
78 if (flags & float_flag_underflow)
79 info.si_code = FPE_FLTUND;
80 else if (flags & float_flag_overflow)
81 info.si_code = FPE_FLTOVF;
82 else if (flags & float_flag_divbyzero)
83 info.si_code = FPE_FLTDIV;
84 else if (flags & float_flag_invalid)
85 info.si_code = FPE_FLTINV;
86 else if (flags & float_flag_inexact)
87 info.si_code = FPE_FLTRES;
88 sigqueueinfo(getpid(), &info);
94 #undef float_exception_mask
97 -------------------------------------------------------------------------------
98 Internal canonical NaN format.
99 -------------------------------------------------------------------------------
107 -------------------------------------------------------------------------------
108 The pattern for a default generated single-precision NaN.
109 -------------------------------------------------------------------------------
111 #define float32_default_nan 0xFFFFFFFF
114 -------------------------------------------------------------------------------
115 Returns 1 if the single-precision floating-point value `a' is a NaN;
117 -------------------------------------------------------------------------------
119 #ifdef SOFTFLOAT_FOR_GCC
122 flag float32_is_nan( float32 a )
125 return ( 0xFF000000 < (bits32) ( a<<1 ) );
130 -------------------------------------------------------------------------------
131 Returns 1 if the single-precision floating-point value `a' is a signaling
132 NaN; otherwise returns 0.
133 -------------------------------------------------------------------------------
135 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
136 !defined(SOFTFLOAT_M68K_FOR_GCC)
139 flag float32_is_signaling_nan( float32 a )
142 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
147 -------------------------------------------------------------------------------
148 Returns the result of converting the single-precision floating-point NaN
149 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
151 -------------------------------------------------------------------------------
153 static commonNaNT float32ToCommonNaN( float32 a )
157 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
160 z.high = ( (bits64) a )<<41;
166 -------------------------------------------------------------------------------
167 Returns the result of converting the canonical NaN `a' to the single-
168 precision floating-point format.
169 -------------------------------------------------------------------------------
171 static float32 commonNaNToFloat32( commonNaNT a )
174 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
179 -------------------------------------------------------------------------------
180 Takes two single-precision floating-point values `a' and `b', one of which
181 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
182 signaling NaN, the invalid exception is raised.
183 -------------------------------------------------------------------------------
185 static float32 propagateFloat32NaN( float32 a, float32 b )
187 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
189 aIsNaN = float32_is_nan( a );
190 aIsSignalingNaN = float32_is_signaling_nan( a );
191 bIsNaN = float32_is_nan( b );
192 bIsSignalingNaN = float32_is_signaling_nan( b );
195 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
197 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
206 -------------------------------------------------------------------------------
207 The pattern for a default generated double-precision NaN.
208 -------------------------------------------------------------------------------
210 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
213 -------------------------------------------------------------------------------
214 Returns 1 if the double-precision floating-point value `a' is a NaN;
216 -------------------------------------------------------------------------------
218 #ifdef SOFTFLOAT_FOR_GCC
221 flag float64_is_nan( float64 a )
224 return ( LIT64( 0xFFE0000000000000 ) <
225 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
230 -------------------------------------------------------------------------------
231 Returns 1 if the double-precision floating-point value `a' is a signaling
232 NaN; otherwise returns 0.
233 -------------------------------------------------------------------------------
235 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
236 !defined(SOFTFLOATM68K_FOR_GCC)
239 flag float64_is_signaling_nan( float64 a )
243 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
244 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
249 -------------------------------------------------------------------------------
250 Returns the result of converting the double-precision floating-point NaN
251 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
253 -------------------------------------------------------------------------------
255 static commonNaNT float64ToCommonNaN( float64 a )
259 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
260 z.sign = FLOAT64_DEMANGLE(a)>>63;
262 z.high = FLOAT64_DEMANGLE(a)<<12;
268 -------------------------------------------------------------------------------
269 Returns the result of converting the canonical NaN `a' to the double-
270 precision floating-point format.
271 -------------------------------------------------------------------------------
273 static float64 commonNaNToFloat64( commonNaNT a )
276 return FLOAT64_MANGLE(
277 ( ( (bits64) a.sign )<<63 )
278 | LIT64( 0x7FF8000000000000 )
284 -------------------------------------------------------------------------------
285 Takes two double-precision floating-point values `a' and `b', one of which
286 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
287 signaling NaN, the invalid exception is raised.
288 -------------------------------------------------------------------------------
290 static float64 propagateFloat64NaN( float64 a, float64 b )
292 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
294 aIsNaN = float64_is_nan( a );
295 aIsSignalingNaN = float64_is_signaling_nan( a );
296 bIsNaN = float64_is_nan( b );
297 bIsSignalingNaN = float64_is_signaling_nan( b );
298 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
299 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
300 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
302 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
313 -------------------------------------------------------------------------------
314 The pattern for a default generated extended double-precision NaN. The
315 `high' and `low' values hold the most- and least-significant bits,
317 -------------------------------------------------------------------------------
319 #define floatx80_default_nan_high 0xFFFF
320 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
323 -------------------------------------------------------------------------------
324 Returns 1 if the extended double-precision floating-point value `a' is a
325 NaN; otherwise returns 0.
326 -------------------------------------------------------------------------------
328 flag floatx80_is_nan( floatx80 a )
331 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
336 -------------------------------------------------------------------------------
337 Returns 1 if the extended double-precision floating-point value `a' is a
338 signaling NaN; otherwise returns 0.
339 -------------------------------------------------------------------------------
341 flag floatx80_is_signaling_nan( floatx80 a )
345 aLow = a.low & ~ LIT64( 0x4000000000000000 );
347 ( ( a.high & 0x7FFF ) == 0x7FFF )
348 && (bits64) ( aLow<<1 )
349 && ( a.low == aLow );
354 -------------------------------------------------------------------------------
355 Returns the result of converting the extended double-precision floating-
356 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
357 invalid exception is raised.
358 -------------------------------------------------------------------------------
360 static commonNaNT floatx80ToCommonNaN( floatx80 a )
364 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
373 -------------------------------------------------------------------------------
374 Returns the result of converting the canonical NaN `a' to the extended
375 double-precision floating-point format.
376 -------------------------------------------------------------------------------
378 static floatx80 commonNaNToFloatx80( commonNaNT a )
382 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
383 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
389 -------------------------------------------------------------------------------
390 Takes two extended double-precision floating-point values `a' and `b', one
391 of which is a NaN, and returns the appropriate NaN result. If either `a' or
392 `b' is a signaling NaN, the invalid exception is raised.
393 -------------------------------------------------------------------------------
395 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
397 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
399 aIsNaN = floatx80_is_nan( a );
400 aIsSignalingNaN = floatx80_is_signaling_nan( a );
401 bIsNaN = floatx80_is_nan( b );
402 bIsSignalingNaN = floatx80_is_signaling_nan( b );
403 a.low |= LIT64( 0xC000000000000000 );
404 b.low |= LIT64( 0xC000000000000000 );
405 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
407 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
420 -------------------------------------------------------------------------------
421 The pattern for a default generated quadruple-precision NaN. The `high' and
422 `low' values hold the most- and least-significant bits, respectively.
423 -------------------------------------------------------------------------------
425 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
426 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
429 -------------------------------------------------------------------------------
430 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
432 -------------------------------------------------------------------------------
434 flag float128_is_nan( float128 a )
438 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
439 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
444 -------------------------------------------------------------------------------
445 Returns 1 if the quadruple-precision floating-point value `a' is a
446 signaling NaN; otherwise returns 0.
447 -------------------------------------------------------------------------------
449 flag float128_is_signaling_nan( float128 a )
453 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
454 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
459 -------------------------------------------------------------------------------
460 Returns the result of converting the quadruple-precision floating-point NaN
461 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
463 -------------------------------------------------------------------------------
465 static commonNaNT float128ToCommonNaN( float128 a )
469 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
471 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
477 -------------------------------------------------------------------------------
478 Returns the result of converting the canonical NaN `a' to the quadruple-
479 precision floating-point format.
480 -------------------------------------------------------------------------------
482 static float128 commonNaNToFloat128( commonNaNT a )
486 shift128Right( a.high, a.low, 16, &z.high, &z.low );
487 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
493 -------------------------------------------------------------------------------
494 Takes two quadruple-precision floating-point values `a' and `b', one of
495 which is a NaN, and returns the appropriate NaN result. If either `a' or
496 `b' is a signaling NaN, the invalid exception is raised.
497 -------------------------------------------------------------------------------
499 static float128 propagateFloat128NaN( float128 a, float128 b )
501 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
503 aIsNaN = float128_is_nan( a );
504 aIsSignalingNaN = float128_is_signaling_nan( a );
505 bIsNaN = float128_is_nan( b );
506 bIsSignalingNaN = float128_is_signaling_nan( b );
507 a.high |= LIT64( 0x0000800000000000 );
508 b.high |= LIT64( 0x0000800000000000 );
509 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
511 return ( aIsSignalingNaN & bIsNaN ) ? b : a;