1 /* $NetBSD: softfloat-specialize,v 1.3 2002/05/12 13:12:45 bjh21 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 ===============================================================================
39 -------------------------------------------------------------------------------
40 Underflow tininess-detection mode, statically initialized to default value.
41 (The declaration in `softfloat.h' must match the `int8' type here.)
42 -------------------------------------------------------------------------------
44 #ifdef SOFTFLOAT_FOR_GCC
48 int8 float_detect_tininess = float_tininess_before_rounding;
50 int8 float_detect_tininess = float_tininess_after_rounding;
54 -------------------------------------------------------------------------------
55 Raises the exceptions specified by `flags'. Floating-point traps can be
56 defined here if desired. It is currently not possible for such a trap to
57 substitute a result value. If traps are not implemented, this routine
58 should be simply `float_exception_flags |= flags;'.
59 -------------------------------------------------------------------------------
61 fp_except float_exception_mask = 0;
62 void float_raise( fp_except flags )
65 float_exception_flags |= flags;
67 if ( flags & float_exception_mask ) {
73 -------------------------------------------------------------------------------
74 Internal canonical NaN format.
75 -------------------------------------------------------------------------------
83 -------------------------------------------------------------------------------
84 The pattern for a default generated single-precision NaN.
85 -------------------------------------------------------------------------------
87 #define float32_default_nan 0xFFFFFFFF
90 -------------------------------------------------------------------------------
91 Returns 1 if the single-precision floating-point value `a' is a NaN;
93 -------------------------------------------------------------------------------
95 #ifdef SOFTFLOAT_FOR_GCC
98 flag float32_is_nan( float32 a )
101 return ( 0xFF000000 < (bits32) ( a<<1 ) );
106 -------------------------------------------------------------------------------
107 Returns 1 if the single-precision floating-point value `a' is a signaling
108 NaN; otherwise returns 0.
109 -------------------------------------------------------------------------------
111 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
114 flag float32_is_signaling_nan( float32 a )
117 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
122 -------------------------------------------------------------------------------
123 Returns the result of converting the single-precision floating-point NaN
124 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
126 -------------------------------------------------------------------------------
128 static commonNaNT float32ToCommonNaN( float32 a )
132 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
135 z.high = ( (bits64) a )<<41;
141 -------------------------------------------------------------------------------
142 Returns the result of converting the canonical NaN `a' to the single-
143 precision floating-point format.
144 -------------------------------------------------------------------------------
146 static float32 commonNaNToFloat32( commonNaNT a )
149 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
154 -------------------------------------------------------------------------------
155 Takes two single-precision floating-point values `a' and `b', one of which
156 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
157 signaling NaN, the invalid exception is raised.
158 -------------------------------------------------------------------------------
160 static float32 propagateFloat32NaN( float32 a, float32 b )
162 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
164 aIsNaN = float32_is_nan( a );
165 aIsSignalingNaN = float32_is_signaling_nan( a );
166 bIsNaN = float32_is_nan( b );
167 bIsSignalingNaN = float32_is_signaling_nan( b );
170 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
172 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
181 -------------------------------------------------------------------------------
182 The pattern for a default generated double-precision NaN.
183 -------------------------------------------------------------------------------
185 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
188 -------------------------------------------------------------------------------
189 Returns 1 if the double-precision floating-point value `a' is a NaN;
191 -------------------------------------------------------------------------------
193 #ifdef SOFTFLOAT_FOR_GCC
196 flag float64_is_nan( float64 a )
199 return ( LIT64( 0xFFE0000000000000 ) <
200 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
205 -------------------------------------------------------------------------------
206 Returns 1 if the double-precision floating-point value `a' is a signaling
207 NaN; otherwise returns 0.
208 -------------------------------------------------------------------------------
210 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
213 flag float64_is_signaling_nan( float64 a )
217 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
218 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
223 -------------------------------------------------------------------------------
224 Returns the result of converting the double-precision floating-point NaN
225 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
227 -------------------------------------------------------------------------------
229 static commonNaNT float64ToCommonNaN( float64 a )
233 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
234 z.sign = FLOAT64_DEMANGLE(a)>>63;
236 z.high = FLOAT64_DEMANGLE(a)<<12;
242 -------------------------------------------------------------------------------
243 Returns the result of converting the canonical NaN `a' to the double-
244 precision floating-point format.
245 -------------------------------------------------------------------------------
247 static float64 commonNaNToFloat64( commonNaNT a )
250 return FLOAT64_MANGLE(
251 ( ( (bits64) a.sign )<<63 )
252 | LIT64( 0x7FF8000000000000 )
258 -------------------------------------------------------------------------------
259 Takes two double-precision floating-point values `a' and `b', one of which
260 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
261 signaling NaN, the invalid exception is raised.
262 -------------------------------------------------------------------------------
264 static float64 propagateFloat64NaN( float64 a, float64 b )
266 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
268 aIsNaN = float64_is_nan( a );
269 aIsSignalingNaN = float64_is_signaling_nan( a );
270 bIsNaN = float64_is_nan( b );
271 bIsSignalingNaN = float64_is_signaling_nan( b );
272 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
273 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
274 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
276 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
287 -------------------------------------------------------------------------------
288 The pattern for a default generated extended double-precision NaN. The
289 `high' and `low' values hold the most- and least-significant bits,
291 -------------------------------------------------------------------------------
293 #define floatx80_default_nan_high 0xFFFF
294 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
297 -------------------------------------------------------------------------------
298 Returns 1 if the extended double-precision floating-point value `a' is a
299 NaN; otherwise returns 0.
300 -------------------------------------------------------------------------------
302 flag floatx80_is_nan( floatx80 a )
305 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
310 -------------------------------------------------------------------------------
311 Returns 1 if the extended double-precision floating-point value `a' is a
312 signaling NaN; otherwise returns 0.
313 -------------------------------------------------------------------------------
315 flag floatx80_is_signaling_nan( floatx80 a )
319 aLow = a.low & ~ LIT64( 0x4000000000000000 );
321 ( ( a.high & 0x7FFF ) == 0x7FFF )
322 && (bits64) ( aLow<<1 )
323 && ( a.low == aLow );
328 -------------------------------------------------------------------------------
329 Returns the result of converting the extended double-precision floating-
330 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
331 invalid exception is raised.
332 -------------------------------------------------------------------------------
334 static commonNaNT floatx80ToCommonNaN( floatx80 a )
338 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
347 -------------------------------------------------------------------------------
348 Returns the result of converting the canonical NaN `a' to the extended
349 double-precision floating-point format.
350 -------------------------------------------------------------------------------
352 static floatx80 commonNaNToFloatx80( commonNaNT a )
356 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
357 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
363 -------------------------------------------------------------------------------
364 Takes two extended double-precision floating-point values `a' and `b', one
365 of which is a NaN, and returns the appropriate NaN result. If either `a' or
366 `b' is a signaling NaN, the invalid exception is raised.
367 -------------------------------------------------------------------------------
369 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
371 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
373 aIsNaN = floatx80_is_nan( a );
374 aIsSignalingNaN = floatx80_is_signaling_nan( a );
375 bIsNaN = floatx80_is_nan( b );
376 bIsSignalingNaN = floatx80_is_signaling_nan( b );
377 a.low |= LIT64( 0xC000000000000000 );
378 b.low |= LIT64( 0xC000000000000000 );
379 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
381 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
394 -------------------------------------------------------------------------------
395 The pattern for a default generated quadruple-precision NaN. The `high' and
396 `low' values hold the most- and least-significant bits, respectively.
397 -------------------------------------------------------------------------------
399 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
400 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
403 -------------------------------------------------------------------------------
404 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
406 -------------------------------------------------------------------------------
408 flag float128_is_nan( float128 a )
412 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
413 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
418 -------------------------------------------------------------------------------
419 Returns 1 if the quadruple-precision floating-point value `a' is a
420 signaling NaN; otherwise returns 0.
421 -------------------------------------------------------------------------------
423 flag float128_is_signaling_nan( float128 a )
427 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
428 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
433 -------------------------------------------------------------------------------
434 Returns the result of converting the quadruple-precision floating-point NaN
435 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
437 -------------------------------------------------------------------------------
439 static commonNaNT float128ToCommonNaN( float128 a )
443 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
445 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
451 -------------------------------------------------------------------------------
452 Returns the result of converting the canonical NaN `a' to the quadruple-
453 precision floating-point format.
454 -------------------------------------------------------------------------------
456 static float128 commonNaNToFloat128( commonNaNT a )
460 shift128Right( a.high, a.low, 16, &z.high, &z.low );
461 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
467 -------------------------------------------------------------------------------
468 Takes two quadruple-precision floating-point values `a' and `b', one of
469 which is a NaN, and returns the appropriate NaN result. If either `a' or
470 `b' is a signaling NaN, the invalid exception is raised.
471 -------------------------------------------------------------------------------
473 static float128 propagateFloat128NaN( float128 a, float128 b )
475 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
477 aIsNaN = float128_is_nan( a );
478 aIsSignalingNaN = float128_is_signaling_nan( a );
479 bIsNaN = float128_is_nan( b );
480 bIsSignalingNaN = float128_is_signaling_nan( b );
481 a.high |= LIT64( 0x0000800000000000 );
482 b.high |= LIT64( 0x0000800000000000 );
483 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
485 return ( aIsSignalingNaN & bIsNaN ) ? b : a;