proll update: IDE HDD/CD support (Blue Swirl)
[qemu/qemu_0_9_1_stable.git] / fpu / softfloat-specialize.h
blobd430f58a719cd074e92b984e65150036c955c29f
2 /*============================================================================
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2b.
7 Written by John R. Hauser. This work was made possible in part by the
8 International Computer Science Institute, located at Suite 600, 1947 Center
9 Street, Berkeley, California 94704. Funding was partially provided by the
10 National Science Foundation under grant MIP-9311980. The original version
11 of this code was written as part of a project to build a fixed-point vector
12 processor in collaboration with the University of California at Berkeley,
13 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
14 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15 arithmetic/SoftFloat.html'.
17 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
18 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19 RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
26 Derivative works are acceptable, even for commercial purposes, so long as
27 (1) the source code for the derivative work includes prominent notice that
28 the work is derivative, and (2) the source code includes prominent notice with
29 these four paragraphs for those parts of this code that are retained.
31 =============================================================================*/
33 /*----------------------------------------------------------------------------
34 | Underflow tininess-detection mode, statically initialized to default value.
35 | (The declaration in `softfloat.h' must match the `int8' type here.)
36 *----------------------------------------------------------------------------*/
37 int8 float_detect_tininess = float_tininess_after_rounding;
39 /*----------------------------------------------------------------------------
40 | Raises the exceptions specified by `flags'. Floating-point traps can be
41 | defined here if desired. It is currently not possible for such a trap
42 | to substitute a result value. If traps are not implemented, this routine
43 | should be simply `float_exception_flags |= flags;'.
44 *----------------------------------------------------------------------------*/
46 void float_raise( int8 flags STATUS_PARAM )
49 STATUS(float_exception_flags) |= flags;
53 /*----------------------------------------------------------------------------
54 | Internal canonical NaN format.
55 *----------------------------------------------------------------------------*/
56 typedef struct {
57 flag sign;
58 bits64 high, low;
59 } commonNaNT;
61 /*----------------------------------------------------------------------------
62 | The pattern for a default generated single-precision NaN.
63 *----------------------------------------------------------------------------*/
64 #define float32_default_nan 0xFFC00000
66 /*----------------------------------------------------------------------------
67 | Returns 1 if the single-precision floating-point value `a' is a NaN;
68 | otherwise returns 0.
69 *----------------------------------------------------------------------------*/
71 flag float32_is_nan( float32 a )
74 return ( 0xFF000000 < (bits32) ( a<<1 ) );
78 /*----------------------------------------------------------------------------
79 | Returns 1 if the single-precision floating-point value `a' is a signaling
80 | NaN; otherwise returns 0.
81 *----------------------------------------------------------------------------*/
83 flag float32_is_signaling_nan( float32 a )
86 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
90 /*----------------------------------------------------------------------------
91 | Returns the result of converting the single-precision floating-point NaN
92 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
93 | exception is raised.
94 *----------------------------------------------------------------------------*/
96 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
98 commonNaNT z;
100 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
101 z.sign = a>>31;
102 z.low = 0;
103 z.high = ( (bits64) a )<<41;
104 return z;
108 /*----------------------------------------------------------------------------
109 | Returns the result of converting the canonical NaN `a' to the single-
110 | precision floating-point format.
111 *----------------------------------------------------------------------------*/
113 static float32 commonNaNToFloat32( commonNaNT a )
116 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
120 /*----------------------------------------------------------------------------
121 | Takes two single-precision floating-point values `a' and `b', one of which
122 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
123 | signaling NaN, the invalid exception is raised.
124 *----------------------------------------------------------------------------*/
126 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
128 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
130 aIsNaN = float32_is_nan( a );
131 aIsSignalingNaN = float32_is_signaling_nan( a );
132 bIsNaN = float32_is_nan( b );
133 bIsSignalingNaN = float32_is_signaling_nan( b );
134 a |= 0x00400000;
135 b |= 0x00400000;
136 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
137 if ( aIsSignalingNaN ) {
138 if ( bIsSignalingNaN ) goto returnLargerSignificand;
139 return bIsNaN ? b : a;
141 else if ( aIsNaN ) {
142 if ( bIsSignalingNaN | ! bIsNaN ) return a;
143 returnLargerSignificand:
144 if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
145 if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
146 return ( a < b ) ? a : b;
148 else {
149 return b;
154 /*----------------------------------------------------------------------------
155 | The pattern for a default generated double-precision NaN.
156 *----------------------------------------------------------------------------*/
157 #define float64_default_nan LIT64( 0xFFF8000000000000 )
159 /*----------------------------------------------------------------------------
160 | Returns 1 if the double-precision floating-point value `a' is a NaN;
161 | otherwise returns 0.
162 *----------------------------------------------------------------------------*/
164 flag float64_is_nan( float64 a )
167 return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
171 /*----------------------------------------------------------------------------
172 | Returns 1 if the double-precision floating-point value `a' is a signaling
173 | NaN; otherwise returns 0.
174 *----------------------------------------------------------------------------*/
176 flag float64_is_signaling_nan( float64 a )
179 return
180 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
181 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
185 /*----------------------------------------------------------------------------
186 | Returns the result of converting the double-precision floating-point NaN
187 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
188 | exception is raised.
189 *----------------------------------------------------------------------------*/
191 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
193 commonNaNT z;
195 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
196 z.sign = a>>63;
197 z.low = 0;
198 z.high = a<<12;
199 return z;
203 /*----------------------------------------------------------------------------
204 | Returns the result of converting the canonical NaN `a' to the double-
205 | precision floating-point format.
206 *----------------------------------------------------------------------------*/
208 static float64 commonNaNToFloat64( commonNaNT a )
211 return
212 ( ( (bits64) a.sign )<<63 )
213 | LIT64( 0x7FF8000000000000 )
214 | ( a.high>>12 );
218 /*----------------------------------------------------------------------------
219 | Takes two double-precision floating-point values `a' and `b', one of which
220 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
221 | signaling NaN, the invalid exception is raised.
222 *----------------------------------------------------------------------------*/
224 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
226 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
228 aIsNaN = float64_is_nan( a );
229 aIsSignalingNaN = float64_is_signaling_nan( a );
230 bIsNaN = float64_is_nan( b );
231 bIsSignalingNaN = float64_is_signaling_nan( b );
232 a |= LIT64( 0x0008000000000000 );
233 b |= LIT64( 0x0008000000000000 );
234 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
235 if ( aIsSignalingNaN ) {
236 if ( bIsSignalingNaN ) goto returnLargerSignificand;
237 return bIsNaN ? b : a;
239 else if ( aIsNaN ) {
240 if ( bIsSignalingNaN | ! bIsNaN ) return a;
241 returnLargerSignificand:
242 if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
243 if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
244 return ( a < b ) ? a : b;
246 else {
247 return b;
252 #ifdef FLOATX80
254 /*----------------------------------------------------------------------------
255 | The pattern for a default generated extended double-precision NaN. The
256 | `high' and `low' values hold the most- and least-significant bits,
257 | respectively.
258 *----------------------------------------------------------------------------*/
259 #define floatx80_default_nan_high 0xFFFF
260 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
262 /*----------------------------------------------------------------------------
263 | Returns 1 if the extended double-precision floating-point value `a' is a
264 | NaN; otherwise returns 0.
265 *----------------------------------------------------------------------------*/
267 flag floatx80_is_nan( floatx80 a )
270 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
274 /*----------------------------------------------------------------------------
275 | Returns 1 if the extended double-precision floating-point value `a' is a
276 | signaling NaN; otherwise returns 0.
277 *----------------------------------------------------------------------------*/
279 flag floatx80_is_signaling_nan( floatx80 a )
281 bits64 aLow;
283 aLow = a.low & ~ LIT64( 0x4000000000000000 );
284 return
285 ( ( a.high & 0x7FFF ) == 0x7FFF )
286 && (bits64) ( aLow<<1 )
287 && ( a.low == aLow );
291 /*----------------------------------------------------------------------------
292 | Returns the result of converting the extended double-precision floating-
293 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
294 | invalid exception is raised.
295 *----------------------------------------------------------------------------*/
297 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
299 commonNaNT z;
301 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
302 z.sign = a.high>>15;
303 z.low = 0;
304 z.high = a.low<<1;
305 return z;
309 /*----------------------------------------------------------------------------
310 | Returns the result of converting the canonical NaN `a' to the extended
311 | double-precision floating-point format.
312 *----------------------------------------------------------------------------*/
314 static floatx80 commonNaNToFloatx80( commonNaNT a )
316 floatx80 z;
318 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
319 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
320 return z;
324 /*----------------------------------------------------------------------------
325 | Takes two extended double-precision floating-point values `a' and `b', one
326 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
327 | `b' is a signaling NaN, the invalid exception is raised.
328 *----------------------------------------------------------------------------*/
330 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
332 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
334 aIsNaN = floatx80_is_nan( a );
335 aIsSignalingNaN = floatx80_is_signaling_nan( a );
336 bIsNaN = floatx80_is_nan( b );
337 bIsSignalingNaN = floatx80_is_signaling_nan( b );
338 a.low |= LIT64( 0xC000000000000000 );
339 b.low |= LIT64( 0xC000000000000000 );
340 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
341 if ( aIsSignalingNaN ) {
342 if ( bIsSignalingNaN ) goto returnLargerSignificand;
343 return bIsNaN ? b : a;
345 else if ( aIsNaN ) {
346 if ( bIsSignalingNaN | ! bIsNaN ) return a;
347 returnLargerSignificand:
348 if ( a.low < b.low ) return b;
349 if ( b.low < a.low ) return a;
350 return ( a.high < b.high ) ? a : b;
352 else {
353 return b;
358 #endif
360 #ifdef FLOAT128
362 /*----------------------------------------------------------------------------
363 | The pattern for a default generated quadruple-precision NaN. The `high' and
364 | `low' values hold the most- and least-significant bits, respectively.
365 *----------------------------------------------------------------------------*/
366 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
367 #define float128_default_nan_low LIT64( 0x0000000000000000 )
369 /*----------------------------------------------------------------------------
370 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
371 | otherwise returns 0.
372 *----------------------------------------------------------------------------*/
374 flag float128_is_nan( float128 a )
377 return
378 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
379 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
383 /*----------------------------------------------------------------------------
384 | Returns 1 if the quadruple-precision floating-point value `a' is a
385 | signaling NaN; otherwise returns 0.
386 *----------------------------------------------------------------------------*/
388 flag float128_is_signaling_nan( float128 a )
391 return
392 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
393 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
397 /*----------------------------------------------------------------------------
398 | Returns the result of converting the quadruple-precision floating-point NaN
399 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
400 | exception is raised.
401 *----------------------------------------------------------------------------*/
403 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
405 commonNaNT z;
407 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
408 z.sign = a.high>>63;
409 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
410 return z;
414 /*----------------------------------------------------------------------------
415 | Returns the result of converting the canonical NaN `a' to the quadruple-
416 | precision floating-point format.
417 *----------------------------------------------------------------------------*/
419 static float128 commonNaNToFloat128( commonNaNT a )
421 float128 z;
423 shift128Right( a.high, a.low, 16, &z.high, &z.low );
424 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
425 return z;
429 /*----------------------------------------------------------------------------
430 | Takes two quadruple-precision floating-point values `a' and `b', one of
431 | which is a NaN, and returns the appropriate NaN result. If either `a' or
432 | `b' is a signaling NaN, the invalid exception is raised.
433 *----------------------------------------------------------------------------*/
435 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
437 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
439 aIsNaN = float128_is_nan( a );
440 aIsSignalingNaN = float128_is_signaling_nan( a );
441 bIsNaN = float128_is_nan( b );
442 bIsSignalingNaN = float128_is_signaling_nan( b );
443 a.high |= LIT64( 0x0000800000000000 );
444 b.high |= LIT64( 0x0000800000000000 );
445 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
446 if ( aIsSignalingNaN ) {
447 if ( bIsSignalingNaN ) goto returnLargerSignificand;
448 return bIsNaN ? b : a;
450 else if ( aIsNaN ) {
451 if ( bIsSignalingNaN | ! bIsNaN ) return a;
452 returnLargerSignificand:
453 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
454 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
455 return ( a.high < b.high ) ? a : b;
457 else {
458 return b;
463 #endif