Fix preprocessor guard condition
[qemu/mini2440.git] / fpu / softfloat-specialize.h
blob93fe06ec0b0fb32bdedfc2d9ba6e14f2e0ff83df
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 defined(TARGET_SPARC)
69 #define float32_default_nan make_float32(0x7FFFFFFF)
70 #elif defined(TARGET_POWERPC)
71 #define float32_default_nan make_float32(0x7FC00000)
72 #elif defined(TARGET_HPPA)
73 #define float32_default_nan make_float32(0x7FA00000)
74 #elif SNAN_BIT_IS_ONE
75 #define float32_default_nan make_float32(0x7FBFFFFF)
76 #else
77 #define float32_default_nan make_float32(0xFFC00000)
78 #endif
80 /*----------------------------------------------------------------------------
81 | Returns 1 if the single-precision floating-point value `a' is a quiet
82 | NaN; otherwise returns 0.
83 *----------------------------------------------------------------------------*/
85 int float32_is_nan( float32 a_ )
87 uint32_t a = float32_val(a_);
88 #if SNAN_BIT_IS_ONE
89 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
90 #else
91 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
92 #endif
95 /*----------------------------------------------------------------------------
96 | Returns 1 if the single-precision floating-point value `a' is a signaling
97 | NaN; otherwise returns 0.
98 *----------------------------------------------------------------------------*/
100 int float32_is_signaling_nan( float32 a_ )
102 uint32_t a = float32_val(a_);
103 #if SNAN_BIT_IS_ONE
104 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
105 #else
106 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
107 #endif
110 /*----------------------------------------------------------------------------
111 | Returns the result of converting the single-precision floating-point NaN
112 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
113 | exception is raised.
114 *----------------------------------------------------------------------------*/
116 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
118 commonNaNT z;
120 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
121 z.sign = float32_val(a)>>31;
122 z.low = 0;
123 z.high = ( (bits64) float32_val(a) )<<41;
124 return z;
127 /*----------------------------------------------------------------------------
128 | Returns the result of converting the canonical NaN `a' to the single-
129 | precision floating-point format.
130 *----------------------------------------------------------------------------*/
132 static float32 commonNaNToFloat32( commonNaNT a )
134 bits32 mantissa = a.high>>41;
135 if ( mantissa )
136 return make_float32(
137 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
138 else
139 return float32_default_nan;
142 /*----------------------------------------------------------------------------
143 | Takes two single-precision floating-point values `a' and `b', one of which
144 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
145 | signaling NaN, the invalid exception is raised.
146 *----------------------------------------------------------------------------*/
148 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
150 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
151 bits32 av, bv, res;
153 aIsNaN = float32_is_nan( a );
154 aIsSignalingNaN = float32_is_signaling_nan( a );
155 bIsNaN = float32_is_nan( b );
156 bIsSignalingNaN = float32_is_signaling_nan( b );
157 av = float32_val(a);
158 bv = float32_val(b);
159 #if SNAN_BIT_IS_ONE
160 av &= ~0x00400000;
161 bv &= ~0x00400000;
162 #else
163 av |= 0x00400000;
164 bv |= 0x00400000;
165 #endif
166 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
167 if ( aIsSignalingNaN ) {
168 if ( bIsSignalingNaN ) goto returnLargerSignificand;
169 res = bIsNaN ? bv : av;
171 else if ( aIsNaN ) {
172 if ( bIsSignalingNaN | ! bIsNaN )
173 res = av;
174 else {
175 returnLargerSignificand:
176 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
177 res = bv;
178 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
179 res = av;
180 else
181 res = ( av < bv ) ? av : bv;
184 else {
185 res = bv;
187 return make_float32(res);
190 /*----------------------------------------------------------------------------
191 | The pattern for a default generated double-precision NaN.
192 *----------------------------------------------------------------------------*/
193 #if defined(TARGET_SPARC)
194 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
195 #elif defined(TARGET_POWERPC)
196 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
197 #elif defined(TARGET_HPPA)
198 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
199 #elif SNAN_BIT_IS_ONE
200 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
201 #else
202 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
203 #endif
205 /*----------------------------------------------------------------------------
206 | Returns 1 if the double-precision floating-point value `a' is a quiet
207 | NaN; otherwise returns 0.
208 *----------------------------------------------------------------------------*/
210 int float64_is_nan( float64 a_ )
212 bits64 a = float64_val(a_);
213 #if SNAN_BIT_IS_ONE
214 return
215 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
216 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
217 #else
218 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
219 #endif
222 /*----------------------------------------------------------------------------
223 | Returns 1 if the double-precision floating-point value `a' is a signaling
224 | NaN; otherwise returns 0.
225 *----------------------------------------------------------------------------*/
227 int float64_is_signaling_nan( float64 a_ )
229 bits64 a = float64_val(a_);
230 #if SNAN_BIT_IS_ONE
231 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
232 #else
233 return
234 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
235 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
236 #endif
239 /*----------------------------------------------------------------------------
240 | Returns the result of converting the double-precision floating-point NaN
241 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
242 | exception is raised.
243 *----------------------------------------------------------------------------*/
245 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
247 commonNaNT z;
249 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
250 z.sign = float64_val(a)>>63;
251 z.low = 0;
252 z.high = float64_val(a)<<12;
253 return z;
256 /*----------------------------------------------------------------------------
257 | Returns the result of converting the canonical NaN `a' to the double-
258 | precision floating-point format.
259 *----------------------------------------------------------------------------*/
261 static float64 commonNaNToFloat64( commonNaNT a )
263 bits64 mantissa = a.high>>12;
265 if ( mantissa )
266 return make_float64(
267 ( ( (bits64) a.sign )<<63 )
268 | LIT64( 0x7FF0000000000000 )
269 | ( a.high>>12 ));
270 else
271 return float64_default_nan;
274 /*----------------------------------------------------------------------------
275 | Takes two double-precision floating-point values `a' and `b', one of which
276 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
277 | signaling NaN, the invalid exception is raised.
278 *----------------------------------------------------------------------------*/
280 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
282 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
283 bits64 av, bv, res;
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 aIsNaN = floatx80_is_nan( a );
422 aIsSignalingNaN = floatx80_is_signaling_nan( a );
423 bIsNaN = floatx80_is_nan( b );
424 bIsSignalingNaN = floatx80_is_signaling_nan( b );
425 #if SNAN_BIT_IS_ONE
426 a.low &= ~LIT64( 0xC000000000000000 );
427 b.low &= ~LIT64( 0xC000000000000000 );
428 #else
429 a.low |= LIT64( 0xC000000000000000 );
430 b.low |= LIT64( 0xC000000000000000 );
431 #endif
432 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
433 if ( aIsSignalingNaN ) {
434 if ( bIsSignalingNaN ) goto returnLargerSignificand;
435 return bIsNaN ? b : a;
437 else if ( aIsNaN ) {
438 if ( bIsSignalingNaN | ! bIsNaN ) return a;
439 returnLargerSignificand:
440 if ( a.low < b.low ) return b;
441 if ( b.low < a.low ) return a;
442 return ( a.high < b.high ) ? a : b;
444 else {
445 return b;
449 #endif
451 #ifdef FLOAT128
453 /*----------------------------------------------------------------------------
454 | The pattern for a default generated quadruple-precision NaN. The `high' and
455 | `low' values hold the most- and least-significant bits, respectively.
456 *----------------------------------------------------------------------------*/
457 #if SNAN_BIT_IS_ONE
458 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
459 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
460 #else
461 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
462 #define float128_default_nan_low LIT64( 0x0000000000000000 )
463 #endif
465 /*----------------------------------------------------------------------------
466 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
467 | NaN; otherwise returns 0.
468 *----------------------------------------------------------------------------*/
470 int float128_is_nan( float128 a )
472 #if SNAN_BIT_IS_ONE
473 return
474 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
475 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
476 #else
477 return
478 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
479 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
480 #endif
483 /*----------------------------------------------------------------------------
484 | Returns 1 if the quadruple-precision floating-point value `a' is a
485 | signaling NaN; otherwise returns 0.
486 *----------------------------------------------------------------------------*/
488 int float128_is_signaling_nan( float128 a )
490 #if SNAN_BIT_IS_ONE
491 return
492 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
493 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
494 #else
495 return
496 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
497 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
498 #endif
501 /*----------------------------------------------------------------------------
502 | Returns the result of converting the quadruple-precision floating-point NaN
503 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
504 | exception is raised.
505 *----------------------------------------------------------------------------*/
507 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
509 commonNaNT z;
511 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
512 z.sign = a.high>>63;
513 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
514 return z;
517 /*----------------------------------------------------------------------------
518 | Returns the result of converting the canonical NaN `a' to the quadruple-
519 | precision floating-point format.
520 *----------------------------------------------------------------------------*/
522 static float128 commonNaNToFloat128( commonNaNT a )
524 float128 z;
526 shift128Right( a.high, a.low, 16, &z.high, &z.low );
527 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
528 return z;
531 /*----------------------------------------------------------------------------
532 | Takes two quadruple-precision floating-point values `a' and `b', one of
533 | which is a NaN, and returns the appropriate NaN result. If either `a' or
534 | `b' is a signaling NaN, the invalid exception is raised.
535 *----------------------------------------------------------------------------*/
537 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
539 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
541 aIsNaN = float128_is_nan( a );
542 aIsSignalingNaN = float128_is_signaling_nan( a );
543 bIsNaN = float128_is_nan( b );
544 bIsSignalingNaN = float128_is_signaling_nan( b );
545 #if SNAN_BIT_IS_ONE
546 a.high &= ~LIT64( 0x0000800000000000 );
547 b.high &= ~LIT64( 0x0000800000000000 );
548 #else
549 a.high |= LIT64( 0x0000800000000000 );
550 b.high |= LIT64( 0x0000800000000000 );
551 #endif
552 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
553 if ( aIsSignalingNaN ) {
554 if ( bIsSignalingNaN ) goto returnLargerSignificand;
555 return bIsNaN ? b : a;
557 else if ( aIsNaN ) {
558 if ( bIsSignalingNaN | ! bIsNaN ) return a;
559 returnLargerSignificand:
560 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
561 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
562 return ( a.high < b.high ) ? a : b;
564 else {
565 return b;
569 #endif