Avoid a warning from OpenBSD linker
[qemu/ahci.git] / fpu / softfloat-specialize.h
blob07468786f91ec087719724ad665d2782d5fe1738
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 a quiet NaN if the single-precision floating point value `a' is a
106 | signaling NaN; otherwise returns `a'.
107 *----------------------------------------------------------------------------*/
109 float32 float32_maybe_silence_nan( float32 a_ )
111 if (float32_is_signaling_nan(a_)) {
112 uint32_t a = float32_val(a_);
113 #if SNAN_BIT_IS_ONE
114 a &= ~(1 << 22);
115 #else
116 a |= (1 << 22);
117 #endif
118 return make_float32(a);
120 return a_;
123 /*----------------------------------------------------------------------------
124 | Returns the result of converting the single-precision floating-point NaN
125 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
126 | exception is raised.
127 *----------------------------------------------------------------------------*/
129 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
131 commonNaNT z;
133 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
134 z.sign = float32_val(a)>>31;
135 z.low = 0;
136 z.high = ( (bits64) float32_val(a) )<<41;
137 return z;
140 /*----------------------------------------------------------------------------
141 | Returns the result of converting the canonical NaN `a' to the single-
142 | precision floating-point format.
143 *----------------------------------------------------------------------------*/
145 static float32 commonNaNToFloat32( commonNaNT a )
147 bits32 mantissa = a.high>>41;
148 if ( mantissa )
149 return make_float32(
150 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
151 else
152 return float32_default_nan;
155 /*----------------------------------------------------------------------------
156 | Takes two single-precision floating-point values `a' and `b', one of which
157 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
158 | signaling NaN, the invalid exception is raised.
159 *----------------------------------------------------------------------------*/
161 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
163 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
164 bits32 av, bv, res;
166 if ( STATUS(default_nan_mode) )
167 return float32_default_nan;
169 aIsNaN = float32_is_nan( a );
170 aIsSignalingNaN = float32_is_signaling_nan( a );
171 bIsNaN = float32_is_nan( b );
172 bIsSignalingNaN = float32_is_signaling_nan( b );
173 av = float32_val(a);
174 bv = float32_val(b);
175 #if SNAN_BIT_IS_ONE
176 av &= ~0x00400000;
177 bv &= ~0x00400000;
178 #else
179 av |= 0x00400000;
180 bv |= 0x00400000;
181 #endif
182 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
183 if ( aIsSignalingNaN ) {
184 if ( bIsSignalingNaN ) goto returnLargerSignificand;
185 res = bIsNaN ? bv : av;
187 else if ( aIsNaN ) {
188 if ( bIsSignalingNaN || ! bIsNaN )
189 res = av;
190 else {
191 returnLargerSignificand:
192 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
193 res = bv;
194 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
195 res = av;
196 else
197 res = ( av < bv ) ? av : bv;
200 else {
201 res = bv;
203 return make_float32(res);
206 /*----------------------------------------------------------------------------
207 | The pattern for a default generated double-precision NaN.
208 *----------------------------------------------------------------------------*/
209 #if defined(TARGET_SPARC)
210 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
211 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
212 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
213 #elif defined(TARGET_HPPA)
214 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
215 #elif SNAN_BIT_IS_ONE
216 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
217 #else
218 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
219 #endif
221 /*----------------------------------------------------------------------------
222 | Returns 1 if the double-precision floating-point value `a' is a quiet
223 | NaN; otherwise returns 0.
224 *----------------------------------------------------------------------------*/
226 int float64_is_nan( float64 a_ )
228 bits64 a = float64_val(a_);
229 #if SNAN_BIT_IS_ONE
230 return
231 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233 #else
234 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
235 #endif
238 /*----------------------------------------------------------------------------
239 | Returns 1 if the double-precision floating-point value `a' is a signaling
240 | NaN; otherwise returns 0.
241 *----------------------------------------------------------------------------*/
243 int float64_is_signaling_nan( float64 a_ )
245 bits64 a = float64_val(a_);
246 #if SNAN_BIT_IS_ONE
247 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
248 #else
249 return
250 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
251 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
252 #endif
255 /*----------------------------------------------------------------------------
256 | Returns a quiet NaN if the double-precision floating point value `a' is a
257 | signaling NaN; otherwise returns `a'.
258 *----------------------------------------------------------------------------*/
260 float64 float64_maybe_silence_nan( float64 a_ )
262 if (float64_is_signaling_nan(a_)) {
263 bits64 a = float64_val(a_);
264 #if SNAN_BIT_IS_ONE
265 a &= ~LIT64( 0x0008000000000000 );
266 #else
267 a |= LIT64( 0x0008000000000000 );
268 #endif
269 return make_float64(a);
271 return a_;
274 /*----------------------------------------------------------------------------
275 | Returns the result of converting the double-precision floating-point NaN
276 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
277 | exception is raised.
278 *----------------------------------------------------------------------------*/
280 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
282 commonNaNT z;
284 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
285 z.sign = float64_val(a)>>63;
286 z.low = 0;
287 z.high = float64_val(a)<<12;
288 return z;
291 /*----------------------------------------------------------------------------
292 | Returns the result of converting the canonical NaN `a' to the double-
293 | precision floating-point format.
294 *----------------------------------------------------------------------------*/
296 static float64 commonNaNToFloat64( commonNaNT a )
298 bits64 mantissa = a.high>>12;
300 if ( mantissa )
301 return make_float64(
302 ( ( (bits64) a.sign )<<63 )
303 | LIT64( 0x7FF0000000000000 )
304 | ( a.high>>12 ));
305 else
306 return float64_default_nan;
309 /*----------------------------------------------------------------------------
310 | Takes two double-precision floating-point values `a' and `b', one of which
311 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
312 | signaling NaN, the invalid exception is raised.
313 *----------------------------------------------------------------------------*/
315 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
317 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
318 bits64 av, bv, res;
320 if ( STATUS(default_nan_mode) )
321 return float64_default_nan;
323 aIsNaN = float64_is_nan( a );
324 aIsSignalingNaN = float64_is_signaling_nan( a );
325 bIsNaN = float64_is_nan( b );
326 bIsSignalingNaN = float64_is_signaling_nan( b );
327 av = float64_val(a);
328 bv = float64_val(b);
329 #if SNAN_BIT_IS_ONE
330 av &= ~LIT64( 0x0008000000000000 );
331 bv &= ~LIT64( 0x0008000000000000 );
332 #else
333 av |= LIT64( 0x0008000000000000 );
334 bv |= LIT64( 0x0008000000000000 );
335 #endif
336 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
337 if ( aIsSignalingNaN ) {
338 if ( bIsSignalingNaN ) goto returnLargerSignificand;
339 res = bIsNaN ? bv : av;
341 else if ( aIsNaN ) {
342 if ( bIsSignalingNaN || ! bIsNaN )
343 res = av;
344 else {
345 returnLargerSignificand:
346 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
347 res = bv;
348 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
349 res = av;
350 else
351 res = ( av < bv ) ? av : bv;
354 else {
355 res = bv;
357 return make_float64(res);
360 #ifdef FLOATX80
362 /*----------------------------------------------------------------------------
363 | The pattern for a default generated extended double-precision NaN. The
364 | `high' and `low' values hold the most- and least-significant bits,
365 | respectively.
366 *----------------------------------------------------------------------------*/
367 #if SNAN_BIT_IS_ONE
368 #define floatx80_default_nan_high 0x7FFF
369 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
370 #else
371 #define floatx80_default_nan_high 0xFFFF
372 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
373 #endif
375 /*----------------------------------------------------------------------------
376 | Returns 1 if the extended double-precision floating-point value `a' is a
377 | quiet NaN; otherwise returns 0.
378 *----------------------------------------------------------------------------*/
380 int floatx80_is_nan( floatx80 a )
382 #if SNAN_BIT_IS_ONE
383 bits64 aLow;
385 aLow = a.low & ~ LIT64( 0x4000000000000000 );
386 return
387 ( ( a.high & 0x7FFF ) == 0x7FFF )
388 && (bits64) ( aLow<<1 )
389 && ( a.low == aLow );
390 #else
391 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
392 #endif
395 /*----------------------------------------------------------------------------
396 | Returns 1 if the extended double-precision floating-point value `a' is a
397 | signaling NaN; otherwise returns 0.
398 *----------------------------------------------------------------------------*/
400 int floatx80_is_signaling_nan( floatx80 a )
402 #if SNAN_BIT_IS_ONE
403 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
404 #else
405 bits64 aLow;
407 aLow = a.low & ~ LIT64( 0x4000000000000000 );
408 return
409 ( ( a.high & 0x7FFF ) == 0x7FFF )
410 && (bits64) ( aLow<<1 )
411 && ( a.low == aLow );
412 #endif
415 /*----------------------------------------------------------------------------
416 | Returns the result of converting the extended double-precision floating-
417 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
418 | invalid exception is raised.
419 *----------------------------------------------------------------------------*/
421 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
423 commonNaNT z;
425 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
426 z.sign = a.high>>15;
427 z.low = 0;
428 z.high = a.low;
429 return z;
432 /*----------------------------------------------------------------------------
433 | Returns the result of converting the canonical NaN `a' to the extended
434 | double-precision floating-point format.
435 *----------------------------------------------------------------------------*/
437 static floatx80 commonNaNToFloatx80( commonNaNT a )
439 floatx80 z;
441 if (a.high)
442 z.low = a.high;
443 else
444 z.low = floatx80_default_nan_low;
445 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
446 return z;
449 /*----------------------------------------------------------------------------
450 | Takes two extended double-precision floating-point values `a' and `b', one
451 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
452 | `b' is a signaling NaN, the invalid exception is raised.
453 *----------------------------------------------------------------------------*/
455 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
457 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
459 if ( STATUS(default_nan_mode) ) {
460 a.low = floatx80_default_nan_low;
461 a.high = floatx80_default_nan_high;
462 return a;
465 aIsNaN = floatx80_is_nan( a );
466 aIsSignalingNaN = floatx80_is_signaling_nan( a );
467 bIsNaN = floatx80_is_nan( b );
468 bIsSignalingNaN = floatx80_is_signaling_nan( b );
469 #if SNAN_BIT_IS_ONE
470 a.low &= ~LIT64( 0xC000000000000000 );
471 b.low &= ~LIT64( 0xC000000000000000 );
472 #else
473 a.low |= LIT64( 0xC000000000000000 );
474 b.low |= LIT64( 0xC000000000000000 );
475 #endif
476 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
477 if ( aIsSignalingNaN ) {
478 if ( bIsSignalingNaN ) goto returnLargerSignificand;
479 return bIsNaN ? b : a;
481 else if ( aIsNaN ) {
482 if ( bIsSignalingNaN || ! bIsNaN ) return a;
483 returnLargerSignificand:
484 if ( a.low < b.low ) return b;
485 if ( b.low < a.low ) return a;
486 return ( a.high < b.high ) ? a : b;
488 else {
489 return b;
493 #endif
495 #ifdef FLOAT128
497 /*----------------------------------------------------------------------------
498 | The pattern for a default generated quadruple-precision NaN. The `high' and
499 | `low' values hold the most- and least-significant bits, respectively.
500 *----------------------------------------------------------------------------*/
501 #if SNAN_BIT_IS_ONE
502 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
503 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
504 #else
505 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
506 #define float128_default_nan_low LIT64( 0x0000000000000000 )
507 #endif
509 /*----------------------------------------------------------------------------
510 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
511 | NaN; otherwise returns 0.
512 *----------------------------------------------------------------------------*/
514 int float128_is_nan( float128 a )
516 #if SNAN_BIT_IS_ONE
517 return
518 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
519 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
520 #else
521 return
522 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
523 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
524 #endif
527 /*----------------------------------------------------------------------------
528 | Returns 1 if the quadruple-precision floating-point value `a' is a
529 | signaling NaN; otherwise returns 0.
530 *----------------------------------------------------------------------------*/
532 int float128_is_signaling_nan( float128 a )
534 #if SNAN_BIT_IS_ONE
535 return
536 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
537 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
538 #else
539 return
540 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
541 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
542 #endif
545 /*----------------------------------------------------------------------------
546 | Returns the result of converting the quadruple-precision floating-point NaN
547 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
548 | exception is raised.
549 *----------------------------------------------------------------------------*/
551 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
553 commonNaNT z;
555 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
556 z.sign = a.high>>63;
557 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
558 return z;
561 /*----------------------------------------------------------------------------
562 | Returns the result of converting the canonical NaN `a' to the quadruple-
563 | precision floating-point format.
564 *----------------------------------------------------------------------------*/
566 static float128 commonNaNToFloat128( commonNaNT a )
568 float128 z;
570 shift128Right( a.high, a.low, 16, &z.high, &z.low );
571 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
572 return z;
575 /*----------------------------------------------------------------------------
576 | Takes two quadruple-precision floating-point values `a' and `b', one of
577 | which is a NaN, and returns the appropriate NaN result. If either `a' or
578 | `b' is a signaling NaN, the invalid exception is raised.
579 *----------------------------------------------------------------------------*/
581 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
583 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
585 if ( STATUS(default_nan_mode) ) {
586 a.low = float128_default_nan_low;
587 a.high = float128_default_nan_high;
588 return a;
591 aIsNaN = float128_is_nan( a );
592 aIsSignalingNaN = float128_is_signaling_nan( a );
593 bIsNaN = float128_is_nan( b );
594 bIsSignalingNaN = float128_is_signaling_nan( b );
595 #if SNAN_BIT_IS_ONE
596 a.high &= ~LIT64( 0x0000800000000000 );
597 b.high &= ~LIT64( 0x0000800000000000 );
598 #else
599 a.high |= LIT64( 0x0000800000000000 );
600 b.high |= LIT64( 0x0000800000000000 );
601 #endif
602 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
603 if ( aIsSignalingNaN ) {
604 if ( bIsSignalingNaN ) goto returnLargerSignificand;
605 return bIsNaN ? b : a;
607 else if ( aIsNaN ) {
608 if ( bIsSignalingNaN || ! bIsNaN ) return a;
609 returnLargerSignificand:
610 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
611 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
612 return ( a.high < b.high ) ? a : b;
614 else {
615 return b;
619 #endif