Add strict checking mode for softfp code.
[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 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     return make_float32(
129         ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ) );
130 }
131
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 *----------------------------------------------------------------------------*/
137
138 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
139 {
140     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
141     bits32 av, bv, res;
142
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;
160     }
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;
172         }
173     }
174     else {
175         res = bv;
176     }
177     return make_float32(res);
178 }
179
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
188
189 /*----------------------------------------------------------------------------
190 | Returns 1 if the double-precision floating-point value `a' is a quiet
191 | NaN; otherwise returns 0.
192 *----------------------------------------------------------------------------*/
193
194 int float64_is_nan( float64 a_ )
195 {
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
204 }
205
206 /*----------------------------------------------------------------------------
207 | Returns 1 if the double-precision floating-point value `a' is a signaling
208 | NaN; otherwise returns 0.
209 *----------------------------------------------------------------------------*/
210
211 int float64_is_signaling_nan( float64 a_ )
212 {
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
221 }
222
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 *----------------------------------------------------------------------------*/
228
229 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
230 {
231     commonNaNT z;
232
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;
238 }
239
240 /*----------------------------------------------------------------------------
241 | Returns the result of converting the canonical NaN `a' to the double-
242 | precision floating-point format.
243 *----------------------------------------------------------------------------*/
244
245 static float64 commonNaNToFloat64( commonNaNT a )
246 {
247     return make_float64(
248           ( ( (bits64) a.sign )<<63 )
249         | LIT64( 0x7FF8000000000000 )
250         | ( a.high>>12 ));
251 }
252
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 *----------------------------------------------------------------------------*/
258
259 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
260 {
261     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
262     bits64 av, bv, res;
263
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;
281     }
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;
293         }
294     }
295     else {
296         res = bv;
297     }
298     return make_float64(res);
299 }
300
301 #ifdef FLOATX80
302
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
315
316 /*----------------------------------------------------------------------------
317 | Returns 1 if the extended double-precision floating-point value `a' is a
318 | quiet NaN; otherwise returns 0.
319 *----------------------------------------------------------------------------*/
320
321 int floatx80_is_nan( floatx80 a )
322 {
323 #if SNAN_BIT_IS_ONE
324     bits64 aLow;
325
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
334 }
335
336 /*----------------------------------------------------------------------------
337 | Returns 1 if the extended double-precision floating-point value `a' is a
338 | signaling NaN; otherwise returns 0.
339 *----------------------------------------------------------------------------*/
340
341 int floatx80_is_signaling_nan( floatx80 a )
342 {
343 #if SNAN_BIT_IS_ONE
344     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
345 #else
346     bits64 aLow;
347
348     aLow = a.low & ~ LIT64( 0x4000000000000000 );
349     return
350            ( ( a.high & 0x7FFF ) == 0x7FFF )
351         && (bits64) ( aLow<<1 )
352         && ( a.low == aLow );
353 #endif
354 }
355
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 *----------------------------------------------------------------------------*/
361
362 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
363 {
364     commonNaNT z;
365
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;
371 }
372
373 /*----------------------------------------------------------------------------
374 | Returns the result of converting the canonical NaN `a' to the extended
375 | double-precision floating-point format.
376 *----------------------------------------------------------------------------*/
377
378 static floatx80 commonNaNToFloatx80( commonNaNT a )
379 {
380     floatx80 z;
381
382     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
383     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
384     return z;
385 }
386
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 *----------------------------------------------------------------------------*/
392
393 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
394 {
395     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
396
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;
412     }
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;
419     }
420     else {
421         return b;
422     }
423 }
424
425 #endif
426
427 #ifdef FLOAT128
428
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
440
441 /*----------------------------------------------------------------------------
442 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
443 | NaN; otherwise returns 0.
444 *----------------------------------------------------------------------------*/
445
446 int float128_is_nan( float128 a )
447 {
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
457 }
458
459 /*----------------------------------------------------------------------------
460 | Returns 1 if the quadruple-precision floating-point value `a' is a
461 | signaling NaN; otherwise returns 0.
462 *----------------------------------------------------------------------------*/
463
464 int float128_is_signaling_nan( float128 a )
465 {
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
475 }
476
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 *----------------------------------------------------------------------------*/
482
483 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
484 {
485     commonNaNT z;
486
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;
491 }
492
493 /*----------------------------------------------------------------------------
494 | Returns the result of converting the canonical NaN `a' to the quadruple-
495 | precision floating-point format.
496 *----------------------------------------------------------------------------*/
497
498 static float128 commonNaNToFloat128( commonNaNT a )
499 {
500     float128 z;
501
502     shift128Right( a.high, a.low, 16, &z.high, &z.low );
503     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
504     return z;
505 }
506
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 *----------------------------------------------------------------------------*/
512
513 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
514 {
515     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
516
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;
532     }
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;
539     }
540     else {
541         return b;
542     }
543 }
544
545 #endif