Fix softfloat NaN handling.
[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 /*----------------------------------------------------------------------------
34 | Underflow tininess-detection mode, statically initialized to default value.
35 | (The declaration in `softfloat.h' must match the `int8' type here.)
36 *----------------------------------------------------------------------------*/
37 int8 float_detect_tininess = float_tininess_after_rounding;
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
49     STATUS(float_exception_flags) |= flags;
50
51 }
52
53 /*----------------------------------------------------------------------------
54 | Internal canonical NaN format.
55 *----------------------------------------------------------------------------*/
56 typedef struct {
57     flag sign;
58     bits64 high, low;
59 } commonNaNT;
60
61 /*----------------------------------------------------------------------------
62 | The pattern for a default generated single-precision NaN.
63 *----------------------------------------------------------------------------*/
64 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
65 #define float32_default_nan 0xFF800000
66 #else
67 #define float32_default_nan 0xFFC00000
68 #endif
69
70 /*----------------------------------------------------------------------------
71 | Returns 1 if the single-precision floating-point value `a' is a NaN;
72 | otherwise returns 0.
73 *----------------------------------------------------------------------------*/
74
75 int float32_is_nan( float32 a )
76 {
77 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
78     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
79 #else
80     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
81 #endif
82 }
83
84 /*----------------------------------------------------------------------------
85 | Returns 1 if the single-precision floating-point value `a' is a signaling
86 | NaN; otherwise returns 0.
87 *----------------------------------------------------------------------------*/
88
89 int float32_is_signaling_nan( float32 a )
90 {
91 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
92     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
93 #else
94     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
95 #endif
96 }
97
98 /*----------------------------------------------------------------------------
99 | Returns the result of converting the single-precision floating-point NaN
100 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
101 | exception is raised.
102 *----------------------------------------------------------------------------*/
103
104 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
105 {
106     commonNaNT z;
107
108     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
109     z.sign = a>>31;
110     z.low = 0;
111     z.high = ( (bits64) a )<<41;
112     return z;
113
114 }
115
116 /*----------------------------------------------------------------------------
117 | Returns the result of converting the canonical NaN `a' to the single-
118 | precision floating-point format.
119 *----------------------------------------------------------------------------*/
120
121 static float32 commonNaNToFloat32( commonNaNT a )
122 {
123
124     return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
125
126 }
127
128 /*----------------------------------------------------------------------------
129 | Takes two single-precision floating-point values `a' and `b', one of which
130 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
131 | signaling NaN, the invalid exception is raised.
132 *----------------------------------------------------------------------------*/
133
134 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
135 {
136     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
137
138     aIsNaN = float32_is_nan( a );
139     aIsSignalingNaN = float32_is_signaling_nan( a );
140     bIsNaN = float32_is_nan( b );
141     bIsSignalingNaN = float32_is_signaling_nan( b );
142 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
143     a &= ~0x00400000;
144     b &= ~0x00400000;
145 #else
146     a |= 0x00400000;
147     b |= 0x00400000;
148 #endif
149     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
150     if ( aIsSignalingNaN ) {
151         if ( bIsSignalingNaN ) goto returnLargerSignificand;
152         return bIsNaN ? b : a;
153     }
154     else if ( aIsNaN ) {
155         if ( bIsSignalingNaN | ! bIsNaN ) return a;
156  returnLargerSignificand:
157         if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
158         if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
159         return ( a < b ) ? a : b;
160     }
161     else {
162         return b;
163     }
164
165 }
166
167 /*----------------------------------------------------------------------------
168 | The pattern for a default generated double-precision NaN.
169 *----------------------------------------------------------------------------*/
170 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
171 #define float64_default_nan LIT64( 0xFFF0000000000000 )
172 #else
173 #define float64_default_nan LIT64( 0xFFF8000000000000 )
174 #endif
175
176 /*----------------------------------------------------------------------------
177 | Returns 1 if the double-precision floating-point value `a' is a NaN;
178 | otherwise returns 0.
179 *----------------------------------------------------------------------------*/
180
181 int float64_is_nan( float64 a )
182 {
183 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
184     return
185            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
186         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
187 #else
188     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
189 #endif
190 }
191
192 /*----------------------------------------------------------------------------
193 | Returns 1 if the double-precision floating-point value `a' is a signaling
194 | NaN; otherwise returns 0.
195 *----------------------------------------------------------------------------*/
196
197 int float64_is_signaling_nan( float64 a )
198 {
199 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
200     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
201 #else
202     return
203            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
204         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
205 #endif
206 }
207
208 /*----------------------------------------------------------------------------
209 | Returns the result of converting the double-precision floating-point NaN
210 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
211 | exception is raised.
212 *----------------------------------------------------------------------------*/
213
214 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
215 {
216     commonNaNT z;
217
218     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
219     z.sign = a>>63;
220     z.low = 0;
221     z.high = a<<12;
222     return z;
223
224 }
225
226 /*----------------------------------------------------------------------------
227 | Returns the result of converting the canonical NaN `a' to the double-
228 | precision floating-point format.
229 *----------------------------------------------------------------------------*/
230
231 static float64 commonNaNToFloat64( commonNaNT a )
232 {
233
234     return
235           ( ( (bits64) a.sign )<<63 )
236         | LIT64( 0x7FF8000000000000 )
237         | ( a.high>>12 );
238
239 }
240
241 /*----------------------------------------------------------------------------
242 | Takes two double-precision floating-point values `a' and `b', one of which
243 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
244 | signaling NaN, the invalid exception is raised.
245 *----------------------------------------------------------------------------*/
246
247 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
248 {
249     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
250
251     aIsNaN = float64_is_nan( a );
252     aIsSignalingNaN = float64_is_signaling_nan( a );
253     bIsNaN = float64_is_nan( b );
254     bIsSignalingNaN = float64_is_signaling_nan( b );
255 #if defined(TARGET_MIPS) || defined(TARGET_HPPA)
256     a &= ~LIT64( 0x0008000000000000 );
257     b &= ~LIT64( 0x0008000000000000 );
258 #else
259     a |= LIT64( 0x0008000000000000 );
260     b |= LIT64( 0x0008000000000000 );
261 #endif
262     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
263     if ( aIsSignalingNaN ) {
264         if ( bIsSignalingNaN ) goto returnLargerSignificand;
265         return bIsNaN ? b : a;
266     }
267     else if ( aIsNaN ) {
268         if ( bIsSignalingNaN | ! bIsNaN ) return a;
269  returnLargerSignificand:
270         if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
271         if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
272         return ( a < b ) ? a : b;
273     }
274     else {
275         return b;
276     }
277
278 }
279
280 #ifdef FLOATX80
281
282 /*----------------------------------------------------------------------------
283 | The pattern for a default generated extended double-precision NaN.  The
284 | `high' and `low' values hold the most- and least-significant bits,
285 | respectively.
286 *----------------------------------------------------------------------------*/
287 #define floatx80_default_nan_high 0xFFFF
288 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
289
290 /*----------------------------------------------------------------------------
291 | Returns 1 if the extended double-precision floating-point value `a' is a
292 | NaN; otherwise returns 0.
293 *----------------------------------------------------------------------------*/
294
295 int floatx80_is_nan( floatx80 a )
296 {
297
298     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
299
300 }
301
302 /*----------------------------------------------------------------------------
303 | Returns 1 if the extended double-precision floating-point value `a' is a
304 | signaling NaN; otherwise returns 0.
305 *----------------------------------------------------------------------------*/
306
307 int floatx80_is_signaling_nan( floatx80 a )
308 {
309     bits64 aLow;
310
311     aLow = a.low & ~ LIT64( 0x4000000000000000 );
312     return
313            ( ( a.high & 0x7FFF ) == 0x7FFF )
314         && (bits64) ( aLow<<1 )
315         && ( a.low == aLow );
316
317 }
318
319 /*----------------------------------------------------------------------------
320 | Returns the result of converting the extended double-precision floating-
321 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
322 | invalid exception is raised.
323 *----------------------------------------------------------------------------*/
324
325 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
326 {
327     commonNaNT z;
328
329     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
330     z.sign = a.high>>15;
331     z.low = 0;
332     z.high = a.low<<1;
333     return z;
334
335 }
336
337 /*----------------------------------------------------------------------------
338 | Returns the result of converting the canonical NaN `a' to the extended
339 | double-precision floating-point format.
340 *----------------------------------------------------------------------------*/
341
342 static floatx80 commonNaNToFloatx80( commonNaNT a )
343 {
344     floatx80 z;
345
346     z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
347     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
348     return z;
349
350 }
351
352 /*----------------------------------------------------------------------------
353 | Takes two extended double-precision floating-point values `a' and `b', one
354 | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
355 | `b' is a signaling NaN, the invalid exception is raised.
356 *----------------------------------------------------------------------------*/
357
358 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
359 {
360     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
361
362     aIsNaN = floatx80_is_nan( a );
363     aIsSignalingNaN = floatx80_is_signaling_nan( a );
364     bIsNaN = floatx80_is_nan( b );
365     bIsSignalingNaN = floatx80_is_signaling_nan( b );
366     a.low |= LIT64( 0xC000000000000000 );
367     b.low |= LIT64( 0xC000000000000000 );
368     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
369     if ( aIsSignalingNaN ) {
370         if ( bIsSignalingNaN ) goto returnLargerSignificand;
371         return bIsNaN ? b : a;
372     }
373     else if ( aIsNaN ) {
374         if ( bIsSignalingNaN | ! bIsNaN ) return a;
375  returnLargerSignificand:
376         if ( a.low < b.low ) return b;
377         if ( b.low < a.low ) return a;
378         return ( a.high < b.high ) ? a : b;
379     }
380     else {
381         return b;
382     }
383
384 }
385
386 #endif
387
388 #ifdef FLOAT128
389
390 /*----------------------------------------------------------------------------
391 | The pattern for a default generated quadruple-precision NaN.  The `high' and
392 | `low' values hold the most- and least-significant bits, respectively.
393 *----------------------------------------------------------------------------*/
394 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
395 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
396
397 /*----------------------------------------------------------------------------
398 | Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
399 | otherwise returns 0.
400 *----------------------------------------------------------------------------*/
401
402 int float128_is_nan( float128 a )
403 {
404
405     return
406            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
407         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
408
409 }
410
411 /*----------------------------------------------------------------------------
412 | Returns 1 if the quadruple-precision floating-point value `a' is a
413 | signaling NaN; otherwise returns 0.
414 *----------------------------------------------------------------------------*/
415
416 int float128_is_signaling_nan( float128 a )
417 {
418
419     return
420            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
421         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
422
423 }
424
425 /*----------------------------------------------------------------------------
426 | Returns the result of converting the quadruple-precision floating-point NaN
427 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
428 | exception is raised.
429 *----------------------------------------------------------------------------*/
430
431 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
432 {
433     commonNaNT z;
434
435     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
436     z.sign = a.high>>63;
437     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
438     return z;
439
440 }
441
442 /*----------------------------------------------------------------------------
443 | Returns the result of converting the canonical NaN `a' to the quadruple-
444 | precision floating-point format.
445 *----------------------------------------------------------------------------*/
446
447 static float128 commonNaNToFloat128( commonNaNT a )
448 {
449     float128 z;
450
451     shift128Right( a.high, a.low, 16, &z.high, &z.low );
452     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
453     return z;
454
455 }
456
457 /*----------------------------------------------------------------------------
458 | Takes two quadruple-precision floating-point values `a' and `b', one of
459 | which is a NaN, and returns the appropriate NaN result.  If either `a' or
460 | `b' is a signaling NaN, the invalid exception is raised.
461 *----------------------------------------------------------------------------*/
462
463 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
464 {
465     flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
466
467     aIsNaN = float128_is_nan( a );
468     aIsSignalingNaN = float128_is_signaling_nan( a );
469     bIsNaN = float128_is_nan( b );
470     bIsSignalingNaN = float128_is_signaling_nan( b );
471     a.high |= LIT64( 0x0000800000000000 );
472     b.high |= LIT64( 0x0000800000000000 );
473     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
474     if ( aIsSignalingNaN ) {
475         if ( bIsSignalingNaN ) goto returnLargerSignificand;
476         return bIsNaN ? b : a;
477     }
478     else if ( aIsNaN ) {
479         if ( bIsSignalingNaN | ! bIsNaN ) return a;
480  returnLargerSignificand:
481         if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
482         if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
483         return ( a.high < b.high ) ? a : b;
484     }
485     else {
486         return b;
487     }
488
489 }
490
491 #endif
492