Preliminary AIX support
[qemu] / fpu / softfloat-specialize.h
1
2 /*============================================================================
3
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2b.
6
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'.
16
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.
25
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.
30
31 =============================================================================*/
32
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
38
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 *----------------------------------------------------------------------------*/
45
46 void float_raise( int8 flags STATUS_PARAM )
47 {
48     STATUS(float_exception_flags) |= flags;
49 }
50
51 /*----------------------------------------------------------------------------
52 | Internal canonical NaN format.
53 *----------------------------------------------------------------------------*/
54 typedef struct {
55     flag sign;
56     bits64 high, low;
57 } commonNaNT;
58
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)
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
73
74 /*----------------------------------------------------------------------------
75 | Returns 1 if the single-precision floating-point value `a' is a quiet
76 | NaN; otherwise returns 0.
77 *----------------------------------------------------------------------------*/
78
79 int float32_is_nan( float32 a_ )
80 {
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
87 }
88
89 /*----------------------------------------------------------------------------
90 | Returns 1 if the single-precision floating-point value `a' is a signaling
91 | NaN; otherwise returns 0.
92 *----------------------------------------------------------------------------*/
93
94 int float32_is_signaling_nan( float32 a_ )
95 {
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
102 }
103
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 *----------------------------------------------------------------------------*/
109
110 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
111 {
112     commonNaNT z;
113
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;
119 }
120
121 /*----------------------------------------------------------------------------
122 | Returns the result of converting the canonical NaN `a' to the single-
123 | precision floating-point format.
124 *----------------------------------------------------------------------------*/
125
126 static float32 commonNaNToFloat32( commonNaNT a )
127 {
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;
134 }
135
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 *----------------------------------------------------------------------------*/
141
142 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
143 {
144     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
145     bits32 av, bv, res;
146
147     aIsNaN = float32_is_nan( a );
148     aIsSignalingNaN = float32_is_signaling_nan( a );
149     bIsNaN = float32_is_nan( b );
150     bIsSignalingNaN = float32_is_signaling_nan( b );
151     av = float32_val(a);
152     bv = float32_val(b);
153 #if SNAN_BIT_IS_ONE
154     av &= ~0x00400000;
155     bv &= ~0x00400000;
156 #else
157     av |= 0x00400000;
158     bv |= 0x00400000;
159 #endif
160     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
161     if ( aIsSignalingNaN ) {
162         if ( bIsSignalingNaN ) goto returnLargerSignificand;
163         res = bIsNaN ? bv : av;
164     }
165     else if ( aIsNaN ) {
166         if ( bIsSignalingNaN | ! bIsNaN )
167             res = av;
168         else {
169  returnLargerSignificand:
170             if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
171                 res = bv;
172             else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
173                 res = av;
174             else
175                 res = ( av < bv ) ? av : bv;
176         }
177     }
178     else {
179         res = bv;
180     }
181     return make_float32(res);
182 }
183
184 /*----------------------------------------------------------------------------
185 | The pattern for a default generated double-precision NaN.
186 *----------------------------------------------------------------------------*/
187 #if defined(TARGET_SPARC)
188 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
189 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM)
190 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
191 #elif defined(TARGET_HPPA)
192 #define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
193 #elif SNAN_BIT_IS_ONE
194 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
195 #else
196 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
197 #endif
198
199 /*----------------------------------------------------------------------------
200 | Returns 1 if the double-precision floating-point value `a' is a quiet
201 | NaN; otherwise returns 0.
202 *----------------------------------------------------------------------------*/
203
204 int float64_is_nan( float64 a_ )
205 {
206     bits64 a = float64_val(a_);
207 #if SNAN_BIT_IS_ONE
208     return
209            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
210         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
211 #else
212     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
213 #endif
214 }
215
216 /*----------------------------------------------------------------------------
217 | Returns 1 if the double-precision floating-point value `a' is a signaling
218 | NaN; otherwise returns 0.
219 *----------------------------------------------------------------------------*/
220
221 int float64_is_signaling_nan( float64 a_ )
222 {
223     bits64 a = float64_val(a_);
224 #if SNAN_BIT_IS_ONE
225     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
226 #else
227     return
228            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
229         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
230 #endif
231 }
232
233 /*----------------------------------------------------------------------------
234 | Returns the result of converting the double-precision floating-point NaN
235 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
236 | exception is raised.
237 *----------------------------------------------------------------------------*/
238
239 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
240 {
241     commonNaNT z;
242
243     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
244     z.sign = float64_val(a)>>63;
245     z.low = 0;
246     z.high = float64_val(a)<<12;
247     return z;
248 }
249
250 /*----------------------------------------------------------------------------
251 | Returns the result of converting the canonical NaN `a' to the double-
252 | precision floating-point format.
253 *----------------------------------------------------------------------------*/
254
255 static float64 commonNaNToFloat64( commonNaNT a )
256 {
257     bits64 mantissa = a.high>>12;
258
259     if ( mantissa )
260         return make_float64(
261               ( ( (bits64) a.sign )<<63 )
262             | LIT64( 0x7FF0000000000000 )
263             | ( a.high>>12 ));
264     else
265         return float64_default_nan;
266 }
267
268 /*----------------------------------------------------------------------------
269 | Takes two double-precision floating-point values `a' and `b', one of which
270 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
271 | signaling NaN, the invalid exception is raised.
272 *----------------------------------------------------------------------------*/
273
274 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
275 {
276     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
277     bits64 av, bv, res;
278
279     aIsNaN = float64_is_nan( a );
280     aIsSignalingNaN = float64_is_signaling_nan( a );
281     bIsNaN = float64_is_nan( b );
282     bIsSignalingNaN = float64_is_signaling_nan( b );
283     av = float64_val(a);
284     bv = float64_val(b);
285 #if SNAN_BIT_IS_ONE
286     av &= ~LIT64( 0x0008000000000000 );
287     bv &= ~LIT64( 0x0008000000000000 );
288 #else
289     av |= LIT64( 0x0008000000000000 );
290     bv |= LIT64( 0x0008000000000000 );
291 #endif
292     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
293     if ( aIsSignalingNaN ) {
294         if ( bIsSignalingNaN ) goto returnLargerSignificand;
295         res = bIsNaN ? bv : av;
296     }
297     else if ( aIsNaN ) {
298         if ( bIsSignalingNaN | ! bIsNaN )
299             res = av;
300         else {
301  returnLargerSignificand:
302             if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
303                 res = bv;
304             else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
305                 res = av;
306             else
307                 res = ( av < bv ) ? av : bv;
308         }
309     }
310     else {
311         res = bv;
312     }
313     return make_float64(res);
314 }
315
316 #ifdef FLOATX80
317
318 /*----------------------------------------------------------------------------
319 | The pattern for a default generated extended double-precision NaN.  The
320 | `high' and `low' values hold the most- and least-significant bits,
321 | respectively.
322 *----------------------------------------------------------------------------*/
323 #if SNAN_BIT_IS_ONE
324 #define floatx80_default_nan_high 0x7FFF
325 #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
326 #else
327 #define floatx80_default_nan_high 0xFFFF
328 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
329 #endif
330
331 /*----------------------------------------------------------------------------
332 | Returns 1 if the extended double-precision floating-point value `a' is a
333 | quiet NaN; otherwise returns 0.
334 *----------------------------------------------------------------------------*/
335
336 int floatx80_is_nan( floatx80 a )
337 {
338 #if SNAN_BIT_IS_ONE
339     bits64 aLow;
340
341     aLow = a.low & ~ LIT64( 0x4000000000000000 );
342     return
343            ( ( a.high & 0x7FFF ) == 0x7FFF )
344         && (bits64) ( aLow<<1 )
345         && ( a.low == aLow );
346 #else
347     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
348 #endif
349 }
350
351 /*----------------------------------------------------------------------------
352 | Returns 1 if the extended double-precision floating-point value `a' is a
353 | signaling NaN; otherwise returns 0.
354 *----------------------------------------------------------------------------*/
355
356 int floatx80_is_signaling_nan( floatx80 a )
357 {
358 #if SNAN_BIT_IS_ONE
359     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
360 #else
361     bits64 aLow;
362
363     aLow = a.low & ~ LIT64( 0x4000000000000000 );
364     return
365            ( ( a.high & 0x7FFF ) == 0x7FFF )
366         && (bits64) ( aLow<<1 )
367         && ( a.low == aLow );
368 #endif
369 }
370
371 /*----------------------------------------------------------------------------
372 | Returns the result of converting the extended double-precision floating-
373 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
374 | invalid exception is raised.
375 *----------------------------------------------------------------------------*/
376
377 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
378 {
379     commonNaNT z;
380
381     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
382     z.sign = a.high>>15;
383     z.low = 0;
384     z.high = a.low;
385     return z;
386 }
387
388 /*----------------------------------------------------------------------------
389 | Returns the result of converting the canonical NaN `a' to the extended
390 | double-precision floating-point format.
391 *----------------------------------------------------------------------------*/
392
393 static floatx80 commonNaNToFloatx80( commonNaNT a )
394 {
395     floatx80 z;
396
397     if (a.high)
398         z.low = a.high;
399     else
400         z.low = floatx80_default_nan_low;
401     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
402     return z;
403 }
404
405 /*----------------------------------------------------------------------------
406 | Takes two extended double-precision floating-point values `a' and `b', one
407 | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
408 | `b' is a signaling NaN, the invalid exception is raised.
409 *----------------------------------------------------------------------------*/
410
411 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
412 {
413     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
414
415     aIsNaN = floatx80_is_nan( a );
416     aIsSignalingNaN = floatx80_is_signaling_nan( a );
417     bIsNaN = floatx80_is_nan( b );
418     bIsSignalingNaN = floatx80_is_signaling_nan( b );
419 #if SNAN_BIT_IS_ONE
420     a.low &= ~LIT64( 0xC000000000000000 );
421     b.low &= ~LIT64( 0xC000000000000000 );
422 #else
423     a.low |= LIT64( 0xC000000000000000 );
424     b.low |= LIT64( 0xC000000000000000 );
425 #endif
426     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
427     if ( aIsSignalingNaN ) {
428         if ( bIsSignalingNaN ) goto returnLargerSignificand;
429         return bIsNaN ? b : a;
430     }
431     else if ( aIsNaN ) {
432         if ( bIsSignalingNaN | ! bIsNaN ) return a;
433  returnLargerSignificand:
434         if ( a.low < b.low ) return b;
435         if ( b.low < a.low ) return a;
436         return ( a.high < b.high ) ? a : b;
437     }
438     else {
439         return b;
440     }
441 }
442
443 #endif
444
445 #ifdef FLOAT128
446
447 /*----------------------------------------------------------------------------
448 | The pattern for a default generated quadruple-precision NaN.  The `high' and
449 | `low' values hold the most- and least-significant bits, respectively.
450 *----------------------------------------------------------------------------*/
451 #if SNAN_BIT_IS_ONE
452 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
453 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
454 #else
455 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
456 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
457 #endif
458
459 /*----------------------------------------------------------------------------
460 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
461 | NaN; otherwise returns 0.
462 *----------------------------------------------------------------------------*/
463
464 int float128_is_nan( float128 a )
465 {
466 #if SNAN_BIT_IS_ONE
467     return
468            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
469         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
470 #else
471     return
472            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
473         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
474 #endif
475 }
476
477 /*----------------------------------------------------------------------------
478 | Returns 1 if the quadruple-precision floating-point value `a' is a
479 | signaling NaN; otherwise returns 0.
480 *----------------------------------------------------------------------------*/
481
482 int float128_is_signaling_nan( float128 a )
483 {
484 #if SNAN_BIT_IS_ONE
485     return
486            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
487         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
488 #else
489     return
490            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
491         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
492 #endif
493 }
494
495 /*----------------------------------------------------------------------------
496 | Returns the result of converting the quadruple-precision floating-point NaN
497 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
498 | exception is raised.
499 *----------------------------------------------------------------------------*/
500
501 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
502 {
503     commonNaNT z;
504
505     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
506     z.sign = a.high>>63;
507     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
508     return z;
509 }
510
511 /*----------------------------------------------------------------------------
512 | Returns the result of converting the canonical NaN `a' to the quadruple-
513 | precision floating-point format.
514 *----------------------------------------------------------------------------*/
515
516 static float128 commonNaNToFloat128( commonNaNT a )
517 {
518     float128 z;
519
520     shift128Right( a.high, a.low, 16, &z.high, &z.low );
521     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
522     return z;
523 }
524
525 /*----------------------------------------------------------------------------
526 | Takes two quadruple-precision floating-point values `a' and `b', one of
527 | which is a NaN, and returns the appropriate NaN result.  If either `a' or
528 | `b' is a signaling NaN, the invalid exception is raised.
529 *----------------------------------------------------------------------------*/
530
531 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
532 {
533     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
534
535     aIsNaN = float128_is_nan( a );
536     aIsSignalingNaN = float128_is_signaling_nan( a );
537     bIsNaN = float128_is_nan( b );
538     bIsSignalingNaN = float128_is_signaling_nan( b );
539 #if SNAN_BIT_IS_ONE
540     a.high &= ~LIT64( 0x0000800000000000 );
541     b.high &= ~LIT64( 0x0000800000000000 );
542 #else
543     a.high |= LIT64( 0x0000800000000000 );
544     b.high |= LIT64( 0x0000800000000000 );
545 #endif
546     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
547     if ( aIsSignalingNaN ) {
548         if ( bIsSignalingNaN ) goto returnLargerSignificand;
549         return bIsNaN ? b : a;
550     }
551     else if ( aIsNaN ) {
552         if ( bIsSignalingNaN | ! bIsNaN ) return a;
553  returnLargerSignificand:
554         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
555         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
556         return ( a.high < b.high ) ? a : b;
557     }
558     else {
559         return b;
560     }
561 }
562
563 #endif