1 /* $NetBSD: softfloat-specialize,v 1.3 2002/05/12 13:12:45 bjh21 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 ===============================================================================
38 -------------------------------------------------------------------------------
39 Underflow tininess-detection mode, statically initialized to default value.
40 (The declaration in `softfloat.h' must match the `int8' type here.)
41 -------------------------------------------------------------------------------
43 #ifdef SOFTFLOAT_FOR_GCC
46 int8 float_detect_tininess = float_tininess_after_rounding;
49 -------------------------------------------------------------------------------
50 Raises the exceptions specified by `flags'. Floating-point traps can be
51 defined here if desired. It is currently not possible for such a trap to
52 substitute a result value. If traps are not implemented, this routine
53 should be simply `float_exception_flags |= flags;'.
54 -------------------------------------------------------------------------------
56 fp_except float_exception_mask = 0;
57 void float_raise( fp_except flags )
60 float_exception_flags |= flags;
62 if ( flags & float_exception_mask ) {
68 -------------------------------------------------------------------------------
69 Internal canonical NaN format.
70 -------------------------------------------------------------------------------
78 -------------------------------------------------------------------------------
79 The pattern for a default generated single-precision NaN.
80 -------------------------------------------------------------------------------
82 #define float32_default_nan 0xFFFFFFFF
85 -------------------------------------------------------------------------------
86 Returns 1 if the single-precision floating-point value `a' is a NaN;
88 -------------------------------------------------------------------------------
90 #ifdef SOFTFLOAT_FOR_GCC
93 flag float32_is_nan( float32 a )
96 return ( 0xFF000000 < (bits32) ( a<<1 ) );
101 -------------------------------------------------------------------------------
102 Returns 1 if the single-precision floating-point value `a' is a signaling
103 NaN; otherwise returns 0.
104 -------------------------------------------------------------------------------
106 #if defined(SOFTFLOAT_FOR_GCC) && !defined(SOFTFLOATSPARC64_FOR_GCC) && \
107 !defined(SOFTFLOAT_M68K_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) && \
207 !defined(SOFTFLOATM68K_FOR_GCC)
210 flag float64_is_signaling_nan( float64 a )
214 ( ( ( FLOAT64_DEMANGLE(a)>>51 ) & 0xFFF ) == 0xFFE )
215 && ( FLOAT64_DEMANGLE(a) & LIT64( 0x0007FFFFFFFFFFFF ) );
220 -------------------------------------------------------------------------------
221 Returns the result of converting the double-precision floating-point NaN
222 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
224 -------------------------------------------------------------------------------
226 static commonNaNT float64ToCommonNaN( float64 a )
230 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
231 z.sign = FLOAT64_DEMANGLE(a)>>63;
233 z.high = FLOAT64_DEMANGLE(a)<<12;
239 -------------------------------------------------------------------------------
240 Returns the result of converting the canonical NaN `a' to the double-
241 precision floating-point format.
242 -------------------------------------------------------------------------------
244 static float64 commonNaNToFloat64( commonNaNT a )
247 return FLOAT64_MANGLE(
248 ( ( (bits64) a.sign )<<63 )
249 | LIT64( 0x7FF8000000000000 )
255 -------------------------------------------------------------------------------
256 Takes two double-precision floating-point values `a' and `b', one of which
257 is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
258 signaling NaN, the invalid exception is raised.
259 -------------------------------------------------------------------------------
261 static float64 propagateFloat64NaN( float64 a, float64 b )
263 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
265 aIsNaN = float64_is_nan( a );
266 aIsSignalingNaN = float64_is_signaling_nan( a );
267 bIsNaN = float64_is_nan( b );
268 bIsSignalingNaN = float64_is_signaling_nan( b );
269 a |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
270 b |= FLOAT64_MANGLE(LIT64( 0x0008000000000000 ));
271 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
273 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
284 -------------------------------------------------------------------------------
285 The pattern for a default generated extended double-precision NaN. The
286 `high' and `low' values hold the most- and least-significant bits,
288 -------------------------------------------------------------------------------
290 #define floatx80_default_nan_high 0xFFFF
291 #define floatx80_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
294 -------------------------------------------------------------------------------
295 Returns 1 if the extended double-precision floating-point value `a' is a
296 NaN; otherwise returns 0.
297 -------------------------------------------------------------------------------
299 flag floatx80_is_nan( floatx80 a )
302 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
307 -------------------------------------------------------------------------------
308 Returns 1 if the extended double-precision floating-point value `a' is a
309 signaling NaN; otherwise returns 0.
310 -------------------------------------------------------------------------------
312 flag floatx80_is_signaling_nan( floatx80 a )
316 aLow = a.low & ~ LIT64( 0x4000000000000000 );
318 ( ( a.high & 0x7FFF ) == 0x7FFF )
319 && (bits64) ( aLow<<1 )
320 && ( a.low == aLow );
325 -------------------------------------------------------------------------------
326 Returns the result of converting the extended double-precision floating-
327 point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
328 invalid exception is raised.
329 -------------------------------------------------------------------------------
331 static commonNaNT floatx80ToCommonNaN( floatx80 a )
335 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
344 -------------------------------------------------------------------------------
345 Returns the result of converting the canonical NaN `a' to the extended
346 double-precision floating-point format.
347 -------------------------------------------------------------------------------
349 static floatx80 commonNaNToFloatx80( commonNaNT a )
353 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
354 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
360 -------------------------------------------------------------------------------
361 Takes two extended double-precision floating-point values `a' and `b', one
362 of which is a NaN, and returns the appropriate NaN result. If either `a' or
363 `b' is a signaling NaN, the invalid exception is raised.
364 -------------------------------------------------------------------------------
366 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
368 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
370 aIsNaN = floatx80_is_nan( a );
371 aIsSignalingNaN = floatx80_is_signaling_nan( a );
372 bIsNaN = floatx80_is_nan( b );
373 bIsSignalingNaN = floatx80_is_signaling_nan( b );
374 a.low |= LIT64( 0xC000000000000000 );
375 b.low |= LIT64( 0xC000000000000000 );
376 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
378 return ( aIsSignalingNaN & bIsNaN ) ? b : a;
391 -------------------------------------------------------------------------------
392 The pattern for a default generated quadruple-precision NaN. The `high' and
393 `low' values hold the most- and least-significant bits, respectively.
394 -------------------------------------------------------------------------------
396 #define float128_default_nan_high LIT64( 0xFFFFFFFFFFFFFFFF )
397 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
400 -------------------------------------------------------------------------------
401 Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
403 -------------------------------------------------------------------------------
405 flag float128_is_nan( float128 a )
409 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
410 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
415 -------------------------------------------------------------------------------
416 Returns 1 if the quadruple-precision floating-point value `a' is a
417 signaling NaN; otherwise returns 0.
418 -------------------------------------------------------------------------------
420 flag float128_is_signaling_nan( float128 a )
424 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
425 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
430 -------------------------------------------------------------------------------
431 Returns the result of converting the quadruple-precision floating-point NaN
432 `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
434 -------------------------------------------------------------------------------
436 static commonNaNT float128ToCommonNaN( float128 a )
440 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
442 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
448 -------------------------------------------------------------------------------
449 Returns the result of converting the canonical NaN `a' to the quadruple-
450 precision floating-point format.
451 -------------------------------------------------------------------------------
453 static float128 commonNaNToFloat128( commonNaNT a )
457 shift128Right( a.high, a.low, 16, &z.high, &z.low );
458 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
464 -------------------------------------------------------------------------------
465 Takes two quadruple-precision floating-point values `a' and `b', one of
466 which is a NaN, and returns the appropriate NaN result. If either `a' or
467 `b' is a signaling NaN, the invalid exception is raised.
468 -------------------------------------------------------------------------------
470 static float128 propagateFloat128NaN( float128 a, float128 b )
472 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
474 aIsNaN = float128_is_nan( a );
475 aIsSignalingNaN = float128_is_signaling_nan( a );
476 bIsNaN = float128_is_nan( b );
477 bIsSignalingNaN = float128_is_signaling_nan( b );
478 a.high |= LIT64( 0x0000800000000000 );
479 b.high |= LIT64( 0x0000800000000000 );
480 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
482 return ( aIsSignalingNaN & bIsNaN ) ? b : a;