Add strict checking mode for softfp code.
[qemu/mini2440.git] / fpu / softfloat-specialize.h
blob18c6dd52d0c368a0cf828d5939181ca217e63cbd
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 | Underflow tininess-detection mode, statically initialized to default value.
41 | (The declaration in `softfloat.h' must match the `int8' type here.)
42 *----------------------------------------------------------------------------*/
43 int8 float_detect_tininess = float_tininess_after_rounding;
45 /*----------------------------------------------------------------------------
46 | Raises the exceptions specified by `flags'. Floating-point traps can be
47 | defined here if desired. It is currently not possible for such a trap
48 | to substitute a result value. If traps are not implemented, this routine
49 | should be simply `float_exception_flags |= flags;'.
50 *----------------------------------------------------------------------------*/
52 void float_raise( int8 flags STATUS_PARAM )
54 STATUS(float_exception_flags) |= flags;
57 /*----------------------------------------------------------------------------
58 | Internal canonical NaN format.
59 *----------------------------------------------------------------------------*/
60 typedef struct {
61 flag sign;
62 bits64 high, low;
63 } commonNaNT;
65 /*----------------------------------------------------------------------------
66 | The pattern for a default generated single-precision NaN.
67 *----------------------------------------------------------------------------*/
68 #if 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 return make_float32(
129 ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ) );
132 /*----------------------------------------------------------------------------
133 | Takes two single-precision floating-point values `a' and `b', one of which
134 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
135 | signaling NaN, the invalid exception is raised.
136 *----------------------------------------------------------------------------*/
138 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
140 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
141 bits32 av, bv, res;
143 aIsNaN = float32_is_nan( a );
144 aIsSignalingNaN = float32_is_signaling_nan( a );
145 bIsNaN = float32_is_nan( b );
146 bIsSignalingNaN = float32_is_signaling_nan( b );
147 av = float32_val(a);
148 bv = float32_val(b);
149 #if SNAN_BIT_IS_ONE
150 av &= ~0x00400000;
151 bv &= ~0x00400000;
152 #else
153 av |= 0x00400000;
154 bv |= 0x00400000;
155 #endif
156 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
157 if ( aIsSignalingNaN ) {
158 if ( bIsSignalingNaN ) goto returnLargerSignificand;
159 res = bIsNaN ? bv : av;
161 else if ( aIsNaN ) {
162 if ( bIsSignalingNaN | ! bIsNaN )
163 res = av;
164 else {
165 returnLargerSignificand:
166 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
167 res = bv;
168 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
169 res = av;
170 else
171 res = ( av < bv ) ? av : bv;
174 else {
175 res = bv;
177 return make_float32(res);
180 /*----------------------------------------------------------------------------
181 | The pattern for a default generated double-precision NaN.
182 *----------------------------------------------------------------------------*/
183 #if SNAN_BIT_IS_ONE
184 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
185 #else
186 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
187 #endif
189 /*----------------------------------------------------------------------------
190 | Returns 1 if the double-precision floating-point value `a' is a quiet
191 | NaN; otherwise returns 0.
192 *----------------------------------------------------------------------------*/
194 int float64_is_nan( float64 a_ )
196 bits64 a = float64_val(a_);
197 #if SNAN_BIT_IS_ONE
198 return
199 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
200 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
201 #else
202 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
203 #endif
206 /*----------------------------------------------------------------------------
207 | Returns 1 if the double-precision floating-point value `a' is a signaling
208 | NaN; otherwise returns 0.
209 *----------------------------------------------------------------------------*/
211 int float64_is_signaling_nan( float64 a_ )
213 bits64 a = float64_val(a_);
214 #if SNAN_BIT_IS_ONE
215 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
216 #else
217 return
218 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
219 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
220 #endif
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
226 | exception is raised.
227 *----------------------------------------------------------------------------*/
229 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
231 commonNaNT z;
233 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
234 z.sign = float64_val(a)>>63;
235 z.low = 0;
236 z.high = float64_val(a)<<12;
237 return z;
240 /*----------------------------------------------------------------------------
241 | Returns the result of converting the canonical NaN `a' to the double-
242 | precision floating-point format.
243 *----------------------------------------------------------------------------*/
245 static float64 commonNaNToFloat64( commonNaNT a )
247 return make_float64(
248 ( ( (bits64) a.sign )<<63 )
249 | LIT64( 0x7FF8000000000000 )
250 | ( a.high>>12 ));
253 /*----------------------------------------------------------------------------
254 | Takes two double-precision floating-point values `a' and `b', one of which
255 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
256 | signaling NaN, the invalid exception is raised.
257 *----------------------------------------------------------------------------*/
259 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
261 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
262 bits64 av, bv, res;
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 av = float64_val(a);
269 bv = float64_val(b);
270 #if SNAN_BIT_IS_ONE
271 av &= ~LIT64( 0x0008000000000000 );
272 bv &= ~LIT64( 0x0008000000000000 );
273 #else
274 av |= LIT64( 0x0008000000000000 );
275 bv |= LIT64( 0x0008000000000000 );
276 #endif
277 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
278 if ( aIsSignalingNaN ) {
279 if ( bIsSignalingNaN ) goto returnLargerSignificand;
280 res = bIsNaN ? bv : av;
282 else if ( aIsNaN ) {
283 if ( bIsSignalingNaN | ! bIsNaN )
284 res = av;
285 else {
286 returnLargerSignificand:
287 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
288 res = bv;
289 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
290 res = av;
291 else
292 res = ( av < bv ) ? av : bv;
295 else {
296 res = bv;
298 return make_float64(res);
301 #ifdef FLOATX80
303 /*----------------------------------------------------------------------------
304 | The pattern for a default generated extended double-precision NaN. The
305 | `high' and `low' values hold the most- and least-significant bits,
306 | respectively.
307 *----------------------------------------------------------------------------*/
308 #if SNAN_BIT_IS_ONE
309 #define floatx80_default_nan_high 0x7FFF
310 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
311 #else
312 #define floatx80_default_nan_high 0xFFFF
313 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
314 #endif
316 /*----------------------------------------------------------------------------
317 | Returns 1 if the extended double-precision floating-point value `a' is a
318 | quiet NaN; otherwise returns 0.
319 *----------------------------------------------------------------------------*/
321 int floatx80_is_nan( floatx80 a )
323 #if SNAN_BIT_IS_ONE
324 bits64 aLow;
326 aLow = a.low & ~ LIT64( 0x4000000000000000 );
327 return
328 ( ( a.high & 0x7FFF ) == 0x7FFF )
329 && (bits64) ( aLow<<1 )
330 && ( a.low == aLow );
331 #else
332 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
333 #endif
336 /*----------------------------------------------------------------------------
337 | Returns 1 if the extended double-precision floating-point value `a' is a
338 | signaling NaN; otherwise returns 0.
339 *----------------------------------------------------------------------------*/
341 int floatx80_is_signaling_nan( floatx80 a )
343 #if SNAN_BIT_IS_ONE
344 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
345 #else
346 bits64 aLow;
348 aLow = a.low & ~ LIT64( 0x4000000000000000 );
349 return
350 ( ( a.high & 0x7FFF ) == 0x7FFF )
351 && (bits64) ( aLow<<1 )
352 && ( a.low == aLow );
353 #endif
356 /*----------------------------------------------------------------------------
357 | Returns the result of converting the extended double-precision floating-
358 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
359 | invalid exception is raised.
360 *----------------------------------------------------------------------------*/
362 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
364 commonNaNT z;
366 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
367 z.sign = a.high>>15;
368 z.low = 0;
369 z.high = a.low<<1;
370 return z;
373 /*----------------------------------------------------------------------------
374 | Returns the result of converting the canonical NaN `a' to the extended
375 | double-precision floating-point format.
376 *----------------------------------------------------------------------------*/
378 static floatx80 commonNaNToFloatx80( commonNaNT a )
380 floatx80 z;
382 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
383 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
384 return z;
387 /*----------------------------------------------------------------------------
388 | Takes two extended double-precision floating-point values `a' and `b', one
389 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
390 | `b' is a signaling NaN, the invalid exception is raised.
391 *----------------------------------------------------------------------------*/
393 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
395 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
397 aIsNaN = floatx80_is_nan( a );
398 aIsSignalingNaN = floatx80_is_signaling_nan( a );
399 bIsNaN = floatx80_is_nan( b );
400 bIsSignalingNaN = floatx80_is_signaling_nan( b );
401 #if SNAN_BIT_IS_ONE
402 a.low &= ~LIT64( 0xC000000000000000 );
403 b.low &= ~LIT64( 0xC000000000000000 );
404 #else
405 a.low |= LIT64( 0xC000000000000000 );
406 b.low |= LIT64( 0xC000000000000000 );
407 #endif
408 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
409 if ( aIsSignalingNaN ) {
410 if ( bIsSignalingNaN ) goto returnLargerSignificand;
411 return bIsNaN ? b : a;
413 else if ( aIsNaN ) {
414 if ( bIsSignalingNaN | ! bIsNaN ) return a;
415 returnLargerSignificand:
416 if ( a.low < b.low ) return b;
417 if ( b.low < a.low ) return a;
418 return ( a.high < b.high ) ? a : b;
420 else {
421 return b;
425 #endif
427 #ifdef FLOAT128
429 /*----------------------------------------------------------------------------
430 | The pattern for a default generated quadruple-precision NaN. The `high' and
431 | `low' values hold the most- and least-significant bits, respectively.
432 *----------------------------------------------------------------------------*/
433 #if SNAN_BIT_IS_ONE
434 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
435 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
436 #else
437 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
438 #define float128_default_nan_low LIT64( 0x0000000000000000 )
439 #endif
441 /*----------------------------------------------------------------------------
442 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
443 | NaN; otherwise returns 0.
444 *----------------------------------------------------------------------------*/
446 int float128_is_nan( float128 a )
448 #if SNAN_BIT_IS_ONE
449 return
450 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
451 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
452 #else
453 return
454 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
455 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
456 #endif
459 /*----------------------------------------------------------------------------
460 | Returns 1 if the quadruple-precision floating-point value `a' is a
461 | signaling NaN; otherwise returns 0.
462 *----------------------------------------------------------------------------*/
464 int float128_is_signaling_nan( float128 a )
466 #if SNAN_BIT_IS_ONE
467 return
468 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
469 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
470 #else
471 return
472 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
473 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
474 #endif
477 /*----------------------------------------------------------------------------
478 | Returns the result of converting the quadruple-precision floating-point NaN
479 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
480 | exception is raised.
481 *----------------------------------------------------------------------------*/
483 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
485 commonNaNT z;
487 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
488 z.sign = a.high>>63;
489 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
490 return z;
493 /*----------------------------------------------------------------------------
494 | Returns the result of converting the canonical NaN `a' to the quadruple-
495 | precision floating-point format.
496 *----------------------------------------------------------------------------*/
498 static float128 commonNaNToFloat128( commonNaNT a )
500 float128 z;
502 shift128Right( a.high, a.low, 16, &z.high, &z.low );
503 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
504 return z;
507 /*----------------------------------------------------------------------------
508 | Takes two quadruple-precision floating-point values `a' and `b', one of
509 | which is a NaN, and returns the appropriate NaN result. If either `a' or
510 | `b' is a signaling NaN, the invalid exception is raised.
511 *----------------------------------------------------------------------------*/
513 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
515 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
517 aIsNaN = float128_is_nan( a );
518 aIsSignalingNaN = float128_is_signaling_nan( a );
519 bIsNaN = float128_is_nan( b );
520 bIsSignalingNaN = float128_is_signaling_nan( b );
521 #if SNAN_BIT_IS_ONE
522 a.high &= ~LIT64( 0x0000800000000000 );
523 b.high &= ~LIT64( 0x0000800000000000 );
524 #else
525 a.high |= LIT64( 0x0000800000000000 );
526 b.high |= LIT64( 0x0000800000000000 );
527 #endif
528 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
529 if ( aIsSignalingNaN ) {
530 if ( bIsSignalingNaN ) goto returnLargerSignificand;
531 return bIsNaN ? b : a;
533 else if ( aIsNaN ) {
534 if ( bIsSignalingNaN | ! bIsNaN ) return a;
535 returnLargerSignificand:
536 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
537 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
538 return ( a.high < b.high ) ? a : b;
540 else {
541 return b;
545 #endif