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
47 int8 float_detect_tininess = float_tininess_after_rounding;
50 -------------------------------------------------------------------------------
51 Raises the exceptions specified by `flags'. Floating-point traps can be
52 defined here if desired. It is currently not possible for such a trap to
53 substitute a result value. If traps are not implemented, this routine
54 should be simply `float_exception_flags |= flags;'.
55 -------------------------------------------------------------------------------
57 fp_except float_exception_mask = 0;
58 void float_raise( fp_except flags )
61 float_exception_flags |= flags;
63 if ( flags & float_exception_mask ) {
69 -------------------------------------------------------------------------------
70 Internal canonical NaN format.
71 -------------------------------------------------------------------------------
79 -------------------------------------------------------------------------------
80 The pattern for a default generated single-precision NaN.
81 -------------------------------------------------------------------------------
83 #define float32_default_nan 0xFFFFFFFF
86 -------------------------------------------------------------------------------
87 Returns 1 if the single-precision floating-point value `a' is a NaN;
89 -------------------------------------------------------------------------------
91 #ifdef SOFTFLOAT_FOR_GCC
94 flag float32_is_nan( float32 a )
97 return ( 0xFF000000 < (bits32) ( a<<1 ) );
102 -------------------------------------------------------------------------------
103 Returns 1 if the single-precision floating-point value `a' is a signaling
104 NaN; otherwise returns 0.
105 -------------------------------------------------------------------------------
107 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
110 flag float32_is_signaling_nan( float32 a )
113 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
118 -------------------------------------------------------------------------------
119 Returns the result of converting the single-precision floating-point NaN
120 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
122 -------------------------------------------------------------------------------
124 static commonNaNT float32ToCommonNaN( float32 a )
128 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
131 z.high = ( (bits64) a )<<41;
137 -------------------------------------------------------------------------------
138 Returns the result of converting the canonical NaN `a' to the single-
139 precision floating-point format.
140 -------------------------------------------------------------------------------
142 static float32 commonNaNToFloat32( commonNaNT a )
145 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
150 -------------------------------------------------------------------------------
151 Takes two single-precision floating-point values `a' and `b', one of which
152 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
153 signaling NaN, the invalid exception is raised.
154 -------------------------------------------------------------------------------
156 static float32 propagateFloat32NaN( float32 a, float32 b )
158 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
160 aIsNaN = float32_is_nan( a );
161 aIsSignalingNaN = float32_is_signaling_nan( a );
162 bIsNaN = float32_is_nan( b );
163 bIsSignalingNaN = float32_is_signaling_nan( b );
166 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
168 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
177 -------------------------------------------------------------------------------
178 The pattern for a default generated double-precision NaN.
179 -------------------------------------------------------------------------------
181 #define float64_default_nan LIT64( 0xFFFFFFFFFFFFFFFF )
184 -------------------------------------------------------------------------------
185 Returns 1 if the double-precision floating-point value `a' is a NaN;
187 -------------------------------------------------------------------------------
189 #ifdef SOFTFLOAT_FOR_GCC
192 flag float64_is_nan( float64 a )
195 return ( LIT64( 0xFFE0000000000000 ) <
196 (bits64) ( FLOAT64_DEMANGLE(a)<<1 ) );
201 -------------------------------------------------------------------------------
202 Returns 1 if the double-precision floating-point value `a' is a signaling
203 NaN; otherwise returns 0.
204 -------------------------------------------------------------------------------
206 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC)
209 flag float64_is_signaling_nan( float64 a )
213 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
214 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
219 -------------------------------------------------------------------------------
220 Returns the result of converting the double-precision floating-point NaN
221 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
223 -------------------------------------------------------------------------------
225 static commonNaNT float64ToCommonNaN( float64 a )
229 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
230 z.sign = FLOAT64_DEMANGLE(a)>>63;
232 z.high = FLOAT64_DEMANGLE(a)<<12;
238 -------------------------------------------------------------------------------
239 Returns the result of converting the canonical NaN `a' to the double-
240 precision floating-point format.
241 -------------------------------------------------------------------------------
243 static float64 commonNaNToFloat64( commonNaNT a )
246 return FLOAT64_MANGLE(
247 ( ( (bits64) a.sign )<<63 )
248 | LIT64( 0x7FF8000000000000 )
254 -------------------------------------------------------------------------------
255 Takes two double-precision floating-point values `a' and `b', one of which
256 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
257 signaling NaN, the invalid exception is raised.
258 -------------------------------------------------------------------------------
260 static float64 propagateFloat64NaN( float64 a, float64 b )
262 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
264 aIsNaN = float64_is_nan( a );
265 aIsSignalingNaN = float64_is_signaling_nan( a );
266 bIsNaN = float64_is_nan( b );
267 bIsSignalingNaN = float64_is_signaling_nan( b );
268 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
269 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
270 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
272 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
283 -------------------------------------------------------------------------------
284 The pattern for a default generated extended double-precision NaN. The
285 `high' and `low' values hold the most- and least-significant bits,
287 -------------------------------------------------------------------------------
289 #define floatx80_default_nan_high 0xFFFF
290 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
293 -------------------------------------------------------------------------------
294 Returns 1 if the extended double-precision floating-point value `a' is a
295 NaN; otherwise returns 0.
296 -------------------------------------------------------------------------------
298 flag floatx80_is_nan( floatx80 a )
301 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
306 -------------------------------------------------------------------------------
307 Returns 1 if the extended double-precision floating-point value `a' is a
308 signaling NaN; otherwise returns 0.
309 -------------------------------------------------------------------------------
311 flag floatx80_is_signaling_nan( floatx80 a )
315 aLow = a.low & ~ LIT64( 0x4000000000000000 );
317 ( ( a.high & 0x7FFF ) == 0x7FFF )
318 && (bits64) ( aLow<<1 )
319 && ( a.low == aLow );
324 -------------------------------------------------------------------------------
325 Returns the result of converting the extended double-precision floating-
326 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
327 invalid exception is raised.
328 -------------------------------------------------------------------------------
330 static commonNaNT floatx80ToCommonNaN( floatx80 a )
334 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
343 -------------------------------------------------------------------------------
344 Returns the result of converting the canonical NaN `a' to the extended
345 double-precision floating-point format.
346 -------------------------------------------------------------------------------
348 static floatx80 commonNaNToFloatx80( commonNaNT a )
352 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
353 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
359 -------------------------------------------------------------------------------
360 Takes two extended double-precision floating-point values `a' and `b', one
361 of which is a NaN, and returns the appropriate NaN result. If either `a' or
362 `b' is a signaling NaN, the invalid exception is raised.
363 -------------------------------------------------------------------------------
365 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
367 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
369 aIsNaN = floatx80_is_nan( a );
370 aIsSignalingNaN = floatx80_is_signaling_nan( a );
371 bIsNaN = floatx80_is_nan( b );
372 bIsSignalingNaN = floatx80_is_signaling_nan( b );
373 a.low |= LIT64( 0xC000000000000000 );
374 b.low |= LIT64( 0xC000000000000000 );
375 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
377 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
390 -------------------------------------------------------------------------------
391 The pattern for a default generated quadruple-precision NaN. The `high' and
392 `low' values hold the most- and least-significant bits, respectively.
393 -------------------------------------------------------------------------------
395 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
396 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
399 -------------------------------------------------------------------------------
400 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
402 -------------------------------------------------------------------------------
404 flag float128_is_nan( float128 a )
408 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
409 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
414 -------------------------------------------------------------------------------
415 Returns 1 if the quadruple-precision floating-point value `a' is a
416 signaling NaN; otherwise returns 0.
417 -------------------------------------------------------------------------------
419 flag float128_is_signaling_nan( float128 a )
423 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
424 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
429 -------------------------------------------------------------------------------
430 Returns the result of converting the quadruple-precision floating-point NaN
431 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
433 -------------------------------------------------------------------------------
435 static commonNaNT float128ToCommonNaN( float128 a )
439 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
441 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
447 -------------------------------------------------------------------------------
448 Returns the result of converting the canonical NaN `a' to the quadruple-
449 precision floating-point format.
450 -------------------------------------------------------------------------------
452 static float128 commonNaNToFloat128( commonNaNT a )
456 shift128Right( a.high, a.low, 16, &z.high, &z.low );
457 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
463 -------------------------------------------------------------------------------
464 Takes two quadruple-precision floating-point values `a' and `b', one of
465 which is a NaN, and returns the appropriate NaN result. If either `a' or
466 `b' is a signaling NaN, the invalid exception is raised.
467 -------------------------------------------------------------------------------
469 static float128 propagateFloat128NaN( float128 a, float128 b )
471 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
473 aIsNaN = float128_is_nan( a );
474 aIsSignalingNaN = float128_is_signaling_nan( a );
475 bIsNaN = float128_is_nan( b );
476 bIsSignalingNaN = float128_is_signaling_nan( b );
477 a.high |= LIT64( 0x0000800000000000 );
478 b.high |= LIT64( 0x0000800000000000 );
479 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
481 return ( aIsSignalingNaN & bIsNaN ) ? b : a;