Assortment of soft-float fixes, by Aurelien Jarno.
[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 | 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;
44
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 *----------------------------------------------------------------------------*/
51
52 void float_raise( int8 flags STATUS_PARAM )
53 {
54     STATUS(float_exception_flags) |= flags;
55 }
56
57 /*----------------------------------------------------------------------------
58 | Internal canonical NaN format.
59 *----------------------------------------------------------------------------*/
60 typedef struct {
61     flag sign;
62     bits64 high, low;
63 } commonNaNT;
64
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
79
80 /*----------------------------------------------------------------------------
81 | Returns 1 if the single-precision floating-point value `a' is a quiet
82 | NaN; otherwise returns 0.
83 *----------------------------------------------------------------------------*/
84
85 int float32_is_nan( float32 a_ )
86 {
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
93 }
94
95 /*----------------------------------------------------------------------------
96 | Returns 1 if the single-precision floating-point value `a' is a signaling
97 | NaN; otherwise returns 0.
98 *----------------------------------------------------------------------------*/
99
100 int float32_is_signaling_nan( float32 a_ )
101 {
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
108 }
109
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 *----------------------------------------------------------------------------*/
115
116 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
117 {
118     commonNaNT z;
119
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;
125 }
126
127 /*----------------------------------------------------------------------------
128 | Returns the result of converting the canonical NaN `a' to the single-
129 | precision floating-point format.
130 *----------------------------------------------------------------------------*/
131
132 static float32 commonNaNToFloat32( commonNaNT a )
133 {
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;
140 }
141
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 *----------------------------------------------------------------------------*/
147
148 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
149 {
150     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
151     bits32 av, bv, res;
152
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;
170     }
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;
182         }
183     }
184     else {
185         res = bv;
186     }
187     return make_float32(res);
188 }
189
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
204
205 /*----------------------------------------------------------------------------
206 | Returns 1 if the double-precision floating-point value `a' is a quiet
207 | NaN; otherwise returns 0.
208 *----------------------------------------------------------------------------*/
209
210 int float64_is_nan( float64 a_ )
211 {
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
220 }
221
222 /*----------------------------------------------------------------------------
223 | Returns 1 if the double-precision floating-point value `a' is a signaling
224 | NaN; otherwise returns 0.
225 *----------------------------------------------------------------------------*/
226
227 int float64_is_signaling_nan( float64 a_ )
228 {
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
237 }
238
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 *----------------------------------------------------------------------------*/
244
245 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
246 {
247     commonNaNT z;
248
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;
254 }
255
256 /*----------------------------------------------------------------------------
257 | Returns the result of converting the canonical NaN `a' to the double-
258 | precision floating-point format.
259 *----------------------------------------------------------------------------*/
260
261 static float64 commonNaNToFloat64( commonNaNT a )
262 {
263     bits64 mantissa = a.high>>12;
264
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;
272 }
273
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 *----------------------------------------------------------------------------*/
279
280 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
281 {
282     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
283     bits64 av, bv, res;
284
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;
302     }
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;
314         }
315     }
316     else {
317         res = bv;
318     }
319     return make_float64(res);
320 }
321
322 #ifdef FLOATX80
323
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
336
337 /*----------------------------------------------------------------------------
338 | Returns 1 if the extended double-precision floating-point value `a' is a
339 | quiet NaN; otherwise returns 0.
340 *----------------------------------------------------------------------------*/
341
342 int floatx80_is_nan( floatx80 a )
343 {
344 #if SNAN_BIT_IS_ONE
345     bits64 aLow;
346
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
355 }
356
357 /*----------------------------------------------------------------------------
358 | Returns 1 if the extended double-precision floating-point value `a' is a
359 | signaling NaN; otherwise returns 0.
360 *----------------------------------------------------------------------------*/
361
362 int floatx80_is_signaling_nan( floatx80 a )
363 {
364 #if SNAN_BIT_IS_ONE
365     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
366 #else
367     bits64 aLow;
368
369     aLow = a.low & ~ LIT64( 0x4000000000000000 );
370     return
371            ( ( a.high & 0x7FFF ) == 0x7FFF )
372         && (bits64) ( aLow<<1 )
373         && ( a.low == aLow );
374 #endif
375 }
376
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 *----------------------------------------------------------------------------*/
382
383 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
384 {
385     commonNaNT z;
386
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;
392 }
393
394 /*----------------------------------------------------------------------------
395 | Returns the result of converting the canonical NaN `a' to the extended
396 | double-precision floating-point format.
397 *----------------------------------------------------------------------------*/
398
399 static floatx80 commonNaNToFloatx80( commonNaNT a )
400 {
401     floatx80 z;
402
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;
409 }
410
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 *----------------------------------------------------------------------------*/
416
417 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
418 {
419     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
420
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;
436     }
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;
443     }
444     else {
445         return b;
446     }
447 }
448
449 #endif
450
451 #ifdef FLOAT128
452
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
464
465 /*----------------------------------------------------------------------------
466 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
467 | NaN; otherwise returns 0.
468 *----------------------------------------------------------------------------*/
469
470 int float128_is_nan( float128 a )
471 {
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
481 }
482
483 /*----------------------------------------------------------------------------
484 | Returns 1 if the quadruple-precision floating-point value `a' is a
485 | signaling NaN; otherwise returns 0.
486 *----------------------------------------------------------------------------*/
487
488 int float128_is_signaling_nan( float128 a )
489 {
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
499 }
500
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 *----------------------------------------------------------------------------*/
506
507 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
508 {
509     commonNaNT z;
510
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;
515 }
516
517 /*----------------------------------------------------------------------------
518 | Returns the result of converting the canonical NaN `a' to the quadruple-
519 | precision floating-point format.
520 *----------------------------------------------------------------------------*/
521
522 static float128 commonNaNToFloat128( commonNaNT a )
523 {
524     float128 z;
525
526     shift128Right( a.high, a.low, 16, &z.high, &z.low );
527     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
528     return z;
529 }
530
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 *----------------------------------------------------------------------------*/
536
537 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
538 {
539     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
540
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;
556     }
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;
563     }
564     else {
565         return b;
566     }
567 }
568
569 #endif