QError: Don't abort on multiple faults
[qemu/kevin.git] / fpu / softfloat-specialize.h
blob8e6aceb55262758b22e83d2c4ca11b69ced5ce96
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 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
34 #define SNAN_BIT_IS_ONE 1
35 #else
36 #define SNAN_BIT_IS_ONE 0
37 #endif
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 )
48 STATUS(float_exception_flags) |= flags;
51 /*----------------------------------------------------------------------------
52 | Internal canonical NaN format.
53 *----------------------------------------------------------------------------*/
54 typedef struct {
55 flag sign;
56 bits64 high, low;
57 } commonNaNT;
59 /*----------------------------------------------------------------------------
60 | The pattern for a default generated single-precision NaN.
61 *----------------------------------------------------------------------------*/
62 #if defined(TARGET_SPARC)
63 #define float32_default_nan make_float32(0x7FFFFFFF)
64 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65 #define float32_default_nan make_float32(0x7FC00000)
66 #elif defined(TARGET_HPPA)
67 #define float32_default_nan make_float32(0x7FA00000)
68 #elif SNAN_BIT_IS_ONE
69 #define float32_default_nan make_float32(0x7FBFFFFF)
70 #else
71 #define float32_default_nan make_float32(0xFFC00000)
72 #endif
74 /*----------------------------------------------------------------------------
75 | Returns 1 if the single-precision floating-point value `a' is a quiet
76 | NaN; otherwise returns 0.
77 *----------------------------------------------------------------------------*/
79 int float32_is_nan( float32 a_ )
81 uint32_t a = float32_val(a_);
82 #if SNAN_BIT_IS_ONE
83 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
84 #else
85 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
86 #endif
89 /*----------------------------------------------------------------------------
90 | Returns 1 if the single-precision floating-point value `a' is a signaling
91 | NaN; otherwise returns 0.
92 *----------------------------------------------------------------------------*/
94 int float32_is_signaling_nan( float32 a_ )
96 uint32_t a = float32_val(a_);
97 #if SNAN_BIT_IS_ONE
98 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
99 #else
100 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
101 #endif
104 /*----------------------------------------------------------------------------
105 | Returns the result of converting the single-precision floating-point NaN
106 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
107 | exception is raised.
108 *----------------------------------------------------------------------------*/
110 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
112 commonNaNT z;
114 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
115 z.sign = float32_val(a)>>31;
116 z.low = 0;
117 z.high = ( (bits64) float32_val(a) )<<41;
118 return z;
121 /*----------------------------------------------------------------------------
122 | Returns the result of converting the canonical NaN `a' to the single-
123 | precision floating-point format.
124 *----------------------------------------------------------------------------*/
126 static float32 commonNaNToFloat32( commonNaNT a )
128 bits32 mantissa = a.high>>41;
129 if ( mantissa )
130 return make_float32(
131 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
132 else
133 return float32_default_nan;
136 /*----------------------------------------------------------------------------
137 | Takes two single-precision floating-point values `a' and `b', one of which
138 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
139 | signaling NaN, the invalid exception is raised.
140 *----------------------------------------------------------------------------*/
142 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
144 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
145 bits32 av, bv, res;
147 if ( STATUS(default_nan_mode) )
148 return float32_default_nan;
150 aIsNaN = float32_is_nan( a );
151 aIsSignalingNaN = float32_is_signaling_nan( a );
152 bIsNaN = float32_is_nan( b );
153 bIsSignalingNaN = float32_is_signaling_nan( b );
154 av = float32_val(a);
155 bv = float32_val(b);
156 #if SNAN_BIT_IS_ONE
157 av &= ~0x00400000;
158 bv &= ~0x00400000;
159 #else
160 av |= 0x00400000;
161 bv |= 0x00400000;
162 #endif
163 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
164 if ( aIsSignalingNaN ) {
165 if ( bIsSignalingNaN ) goto returnLargerSignificand;
166 res = bIsNaN ? bv : av;
168 else if ( aIsNaN ) {
169 if ( bIsSignalingNaN || ! bIsNaN )
170 res = av;
171 else {
172 returnLargerSignificand:
173 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
174 res = bv;
175 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
176 res = av;
177 else
178 res = ( av < bv ) ? av : bv;
181 else {
182 res = bv;
184 return make_float32(res);
187 /*----------------------------------------------------------------------------
188 | The pattern for a default generated double-precision NaN.
189 *----------------------------------------------------------------------------*/
190 #if defined(TARGET_SPARC)
191 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
192 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
193 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
194 #elif defined(TARGET_HPPA)
195 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
196 #elif SNAN_BIT_IS_ONE
197 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
198 #else
199 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
200 #endif
202 /*----------------------------------------------------------------------------
203 | Returns 1 if the double-precision floating-point value `a' is a quiet
204 | NaN; otherwise returns 0.
205 *----------------------------------------------------------------------------*/
207 int float64_is_nan( float64 a_ )
209 bits64 a = float64_val(a_);
210 #if SNAN_BIT_IS_ONE
211 return
212 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
213 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
214 #else
215 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
216 #endif
219 /*----------------------------------------------------------------------------
220 | Returns 1 if the double-precision floating-point value `a' is a signaling
221 | NaN; otherwise returns 0.
222 *----------------------------------------------------------------------------*/
224 int float64_is_signaling_nan( float64 a_ )
226 bits64 a = float64_val(a_);
227 #if SNAN_BIT_IS_ONE
228 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
229 #else
230 return
231 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233 #endif
236 /*----------------------------------------------------------------------------
237 | Returns the result of converting the double-precision floating-point NaN
238 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
239 | exception is raised.
240 *----------------------------------------------------------------------------*/
242 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
244 commonNaNT z;
246 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
247 z.sign = float64_val(a)>>63;
248 z.low = 0;
249 z.high = float64_val(a)<<12;
250 return z;
253 /*----------------------------------------------------------------------------
254 | Returns the result of converting the canonical NaN `a' to the double-
255 | precision floating-point format.
256 *----------------------------------------------------------------------------*/
258 static float64 commonNaNToFloat64( commonNaNT a )
260 bits64 mantissa = a.high>>12;
262 if ( mantissa )
263 return make_float64(
264 ( ( (bits64) a.sign )<<63 )
265 | LIT64( 0x7FF0000000000000 )
266 | ( a.high>>12 ));
267 else
268 return float64_default_nan;
271 /*----------------------------------------------------------------------------
272 | Takes two double-precision floating-point values `a' and `b', one of which
273 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
274 | signaling NaN, the invalid exception is raised.
275 *----------------------------------------------------------------------------*/
277 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
279 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
280 bits64 av, bv, res;
282 if ( STATUS(default_nan_mode) )
283 return float64_default_nan;
285 aIsNaN = float64_is_nan( a );
286 aIsSignalingNaN = float64_is_signaling_nan( a );
287 bIsNaN = float64_is_nan( b );
288 bIsSignalingNaN = float64_is_signaling_nan( b );
289 av = float64_val(a);
290 bv = float64_val(b);
291 #if SNAN_BIT_IS_ONE
292 av &= ~LIT64( 0x0008000000000000 );
293 bv &= ~LIT64( 0x0008000000000000 );
294 #else
295 av |= LIT64( 0x0008000000000000 );
296 bv |= LIT64( 0x0008000000000000 );
297 #endif
298 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
299 if ( aIsSignalingNaN ) {
300 if ( bIsSignalingNaN ) goto returnLargerSignificand;
301 res = bIsNaN ? bv : av;
303 else if ( aIsNaN ) {
304 if ( bIsSignalingNaN || ! bIsNaN )
305 res = av;
306 else {
307 returnLargerSignificand:
308 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
309 res = bv;
310 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
311 res = av;
312 else
313 res = ( av < bv ) ? av : bv;
316 else {
317 res = bv;
319 return make_float64(res);
322 #ifdef FLOATX80
324 /*----------------------------------------------------------------------------
325 | The pattern for a default generated extended double-precision NaN. The
326 | `high' and `low' values hold the most- and least-significant bits,
327 | respectively.
328 *----------------------------------------------------------------------------*/
329 #if SNAN_BIT_IS_ONE
330 #define floatx80_default_nan_high 0x7FFF
331 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
332 #else
333 #define floatx80_default_nan_high 0xFFFF
334 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
335 #endif
337 /*----------------------------------------------------------------------------
338 | Returns 1 if the extended double-precision floating-point value `a' is a
339 | quiet NaN; otherwise returns 0.
340 *----------------------------------------------------------------------------*/
342 int floatx80_is_nan( floatx80 a )
344 #if SNAN_BIT_IS_ONE
345 bits64 aLow;
347 aLow = a.low & ~ LIT64( 0x4000000000000000 );
348 return
349 ( ( a.high & 0x7FFF ) == 0x7FFF )
350 && (bits64) ( aLow<<1 )
351 && ( a.low == aLow );
352 #else
353 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
354 #endif
357 /*----------------------------------------------------------------------------
358 | Returns 1 if the extended double-precision floating-point value `a' is a
359 | signaling NaN; otherwise returns 0.
360 *----------------------------------------------------------------------------*/
362 int floatx80_is_signaling_nan( floatx80 a )
364 #if SNAN_BIT_IS_ONE
365 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
366 #else
367 bits64 aLow;
369 aLow = a.low & ~ LIT64( 0x4000000000000000 );
370 return
371 ( ( a.high & 0x7FFF ) == 0x7FFF )
372 && (bits64) ( aLow<<1 )
373 && ( a.low == aLow );
374 #endif
377 /*----------------------------------------------------------------------------
378 | Returns the result of converting the extended double-precision floating-
379 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
380 | invalid exception is raised.
381 *----------------------------------------------------------------------------*/
383 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
385 commonNaNT z;
387 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
388 z.sign = a.high>>15;
389 z.low = 0;
390 z.high = a.low;
391 return z;
394 /*----------------------------------------------------------------------------
395 | Returns the result of converting the canonical NaN `a' to the extended
396 | double-precision floating-point format.
397 *----------------------------------------------------------------------------*/
399 static floatx80 commonNaNToFloatx80( commonNaNT a )
401 floatx80 z;
403 if (a.high)
404 z.low = a.high;
405 else
406 z.low = floatx80_default_nan_low;
407 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
408 return z;
411 /*----------------------------------------------------------------------------
412 | Takes two extended double-precision floating-point values `a' and `b', one
413 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
414 | `b' is a signaling NaN, the invalid exception is raised.
415 *----------------------------------------------------------------------------*/
417 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
419 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
421 if ( STATUS(default_nan_mode) ) {
422 a.low = floatx80_default_nan_low;
423 a.high = floatx80_default_nan_high;
424 return a;
427 aIsNaN = floatx80_is_nan( a );
428 aIsSignalingNaN = floatx80_is_signaling_nan( a );
429 bIsNaN = floatx80_is_nan( b );
430 bIsSignalingNaN = floatx80_is_signaling_nan( b );
431 #if SNAN_BIT_IS_ONE
432 a.low &= ~LIT64( 0xC000000000000000 );
433 b.low &= ~LIT64( 0xC000000000000000 );
434 #else
435 a.low |= LIT64( 0xC000000000000000 );
436 b.low |= LIT64( 0xC000000000000000 );
437 #endif
438 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
439 if ( aIsSignalingNaN ) {
440 if ( bIsSignalingNaN ) goto returnLargerSignificand;
441 return bIsNaN ? b : a;
443 else if ( aIsNaN ) {
444 if ( bIsSignalingNaN || ! bIsNaN ) return a;
445 returnLargerSignificand:
446 if ( a.low < b.low ) return b;
447 if ( b.low < a.low ) return a;
448 return ( a.high < b.high ) ? a : b;
450 else {
451 return b;
455 #endif
457 #ifdef FLOAT128
459 /*----------------------------------------------------------------------------
460 | The pattern for a default generated quadruple-precision NaN. The `high' and
461 | `low' values hold the most- and least-significant bits, respectively.
462 *----------------------------------------------------------------------------*/
463 #if SNAN_BIT_IS_ONE
464 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
465 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
466 #else
467 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
468 #define float128_default_nan_low LIT64( 0x0000000000000000 )
469 #endif
471 /*----------------------------------------------------------------------------
472 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
473 | NaN; otherwise returns 0.
474 *----------------------------------------------------------------------------*/
476 int float128_is_nan( float128 a )
478 #if SNAN_BIT_IS_ONE
479 return
480 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
481 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
482 #else
483 return
484 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
485 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
486 #endif
489 /*----------------------------------------------------------------------------
490 | Returns 1 if the quadruple-precision floating-point value `a' is a
491 | signaling NaN; otherwise returns 0.
492 *----------------------------------------------------------------------------*/
494 int float128_is_signaling_nan( float128 a )
496 #if SNAN_BIT_IS_ONE
497 return
498 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
499 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
500 #else
501 return
502 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
503 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
504 #endif
507 /*----------------------------------------------------------------------------
508 | Returns the result of converting the quadruple-precision floating-point NaN
509 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
510 | exception is raised.
511 *----------------------------------------------------------------------------*/
513 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
515 commonNaNT z;
517 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
518 z.sign = a.high>>63;
519 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
520 return z;
523 /*----------------------------------------------------------------------------
524 | Returns the result of converting the canonical NaN `a' to the quadruple-
525 | precision floating-point format.
526 *----------------------------------------------------------------------------*/
528 static float128 commonNaNToFloat128( commonNaNT a )
530 float128 z;
532 shift128Right( a.high, a.low, 16, &z.high, &z.low );
533 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
534 return z;
537 /*----------------------------------------------------------------------------
538 | Takes two quadruple-precision floating-point values `a' and `b', one of
539 | which is a NaN, and returns the appropriate NaN result. If either `a' or
540 | `b' is a signaling NaN, the invalid exception is raised.
541 *----------------------------------------------------------------------------*/
543 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
545 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
547 if ( STATUS(default_nan_mode) ) {
548 a.low = float128_default_nan_low;
549 a.high = float128_default_nan_high;
550 return a;
553 aIsNaN = float128_is_nan( a );
554 aIsSignalingNaN = float128_is_signaling_nan( a );
555 bIsNaN = float128_is_nan( b );
556 bIsSignalingNaN = float128_is_signaling_nan( b );
557 #if SNAN_BIT_IS_ONE
558 a.high &= ~LIT64( 0x0000800000000000 );
559 b.high &= ~LIT64( 0x0000800000000000 );
560 #else
561 a.high |= LIT64( 0x0000800000000000 );
562 b.high |= LIT64( 0x0000800000000000 );
563 #endif
564 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
565 if ( aIsSignalingNaN ) {
566 if ( bIsSignalingNaN ) goto returnLargerSignificand;
567 return bIsNaN ? b : a;
569 else if ( aIsNaN ) {
570 if ( bIsSignalingNaN || ! bIsNaN ) return a;
571 returnLargerSignificand:
572 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
573 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
574 return ( a.high < b.high ) ? a : b;
576 else {
577 return b;
581 #endif