]> git.proxmox.com Git - qemu.git/blob - fpu/softfloat-specialize.h
Fix NaN handling for MIPS and HPPA.
[qemu.git] / 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 0x7FBFFFFF
70 #else
71 #define float32_default_nan 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 #if SNAN_BIT_IS_ONE
82 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
83 #else
84 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
85 #endif
86 }
87
88 /*----------------------------------------------------------------------------
89 | Returns 1 if the single-precision floating-point value `a' is a signaling
90 | NaN; otherwise returns 0.
91 *----------------------------------------------------------------------------*/
92
93 int float32_is_signaling_nan( float32 a )
94 {
95 #if SNAN_BIT_IS_ONE
96 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
97 #else
98 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99 #endif
100 }
101
102 /*----------------------------------------------------------------------------
103 | Returns the result of converting the single-precision floating-point NaN
104 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
105 | exception is raised.
106 *----------------------------------------------------------------------------*/
107
108 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
109 {
110 commonNaNT z;
111
112 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
113 z.sign = a>>31;
114 z.low = 0;
115 z.high = ( (bits64) a )<<41;
116 return z;
117 }
118
119 /*----------------------------------------------------------------------------
120 | Returns the result of converting the canonical NaN `a' to the single-
121 | precision floating-point format.
122 *----------------------------------------------------------------------------*/
123
124 static float32 commonNaNToFloat32( commonNaNT a )
125 {
126 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
127 }
128
129 /*----------------------------------------------------------------------------
130 | Takes two single-precision floating-point values `a' and `b', one of which
131 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
132 | signaling NaN, the invalid exception is raised.
133 *----------------------------------------------------------------------------*/
134
135 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
136 {
137 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
138
139 aIsNaN = float32_is_nan( a );
140 aIsSignalingNaN = float32_is_signaling_nan( a );
141 bIsNaN = float32_is_nan( b );
142 bIsSignalingNaN = float32_is_signaling_nan( b );
143 #if SNAN_BIT_IS_ONE
144 a &= ~0x00400000;
145 b &= ~0x00400000;
146 #else
147 a |= 0x00400000;
148 b |= 0x00400000;
149 #endif
150 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
151 if ( aIsSignalingNaN ) {
152 if ( bIsSignalingNaN ) goto returnLargerSignificand;
153 return bIsNaN ? b : a;
154 }
155 else if ( aIsNaN ) {
156 if ( bIsSignalingNaN | ! bIsNaN ) return a;
157 returnLargerSignificand:
158 if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
159 if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
160 return ( a < b ) ? a : b;
161 }
162 else {
163 return b;
164 }
165 }
166
167 /*----------------------------------------------------------------------------
168 | The pattern for a default generated double-precision NaN.
169 *----------------------------------------------------------------------------*/
170 #if SNAN_BIT_IS_ONE
171 #define float64_default_nan LIT64( 0x7FF7FFFFFFFFFFFF )
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 quiet
178 | NaN; otherwise returns 0.
179 *----------------------------------------------------------------------------*/
180
181 int float64_is_nan( float64 a )
182 {
183 #if SNAN_BIT_IS_ONE
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 SNAN_BIT_IS_ONE
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 | Returns the result of converting the canonical NaN `a' to the double-
227 | precision floating-point format.
228 *----------------------------------------------------------------------------*/
229
230 static float64 commonNaNToFloat64( commonNaNT a )
231 {
232 return
233 ( ( (bits64) a.sign )<<63 )
234 | LIT64( 0x7FF8000000000000 )
235 | ( a.high>>12 );
236 }
237
238 /*----------------------------------------------------------------------------
239 | Takes two double-precision floating-point values `a' and `b', one of which
240 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
241 | signaling NaN, the invalid exception is raised.
242 *----------------------------------------------------------------------------*/
243
244 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
245 {
246 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
247
248 aIsNaN = float64_is_nan( a );
249 aIsSignalingNaN = float64_is_signaling_nan( a );
250 bIsNaN = float64_is_nan( b );
251 bIsSignalingNaN = float64_is_signaling_nan( b );
252 #if SNAN_BIT_IS_ONE
253 a &= ~LIT64( 0x0008000000000000 );
254 b &= ~LIT64( 0x0008000000000000 );
255 #else
256 a |= LIT64( 0x0008000000000000 );
257 b |= LIT64( 0x0008000000000000 );
258 #endif
259 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
260 if ( aIsSignalingNaN ) {
261 if ( bIsSignalingNaN ) goto returnLargerSignificand;
262 return bIsNaN ? b : a;
263 }
264 else if ( aIsNaN ) {
265 if ( bIsSignalingNaN | ! bIsNaN ) return a;
266 returnLargerSignificand:
267 if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
268 if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
269 return ( a < b ) ? a : b;
270 }
271 else {
272 return b;
273 }
274 }
275
276 #ifdef FLOATX80
277
278 /*----------------------------------------------------------------------------
279 | The pattern for a default generated extended double-precision NaN. The
280 | `high' and `low' values hold the most- and least-significant bits,
281 | respectively.
282 *----------------------------------------------------------------------------*/
283 #if SNAN_BIT_IS_ONE
284 #define floatx80_default_nan_high 0x7FFF
285 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
286 #else
287 #define floatx80_default_nan_high 0xFFFF
288 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
289 #endif
290
291 /*----------------------------------------------------------------------------
292 | Returns 1 if the extended double-precision floating-point value `a' is a
293 | quiet NaN; otherwise returns 0.
294 *----------------------------------------------------------------------------*/
295
296 int floatx80_is_nan( floatx80 a )
297 {
298 #if SNAN_BIT_IS_ONE
299 bits64 aLow;
300
301 aLow = a.low & ~ LIT64( 0x4000000000000000 );
302 return
303 ( ( a.high & 0x7FFF ) == 0x7FFF )
304 && (bits64) ( aLow<<1 )
305 && ( a.low == aLow );
306 #else
307 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
308 #endif
309 }
310
311 /*----------------------------------------------------------------------------
312 | Returns 1 if the extended double-precision floating-point value `a' is a
313 | signaling NaN; otherwise returns 0.
314 *----------------------------------------------------------------------------*/
315
316 int floatx80_is_signaling_nan( floatx80 a )
317 {
318 #if SNAN_BIT_IS_ONE
319 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
320 #else
321 bits64 aLow;
322
323 aLow = a.low & ~ LIT64( 0x4000000000000000 );
324 return
325 ( ( a.high & 0x7FFF ) == 0x7FFF )
326 && (bits64) ( aLow<<1 )
327 && ( a.low == aLow );
328 #endif
329 }
330
331 /*----------------------------------------------------------------------------
332 | Returns the result of converting the extended double-precision floating-
333 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
334 | invalid exception is raised.
335 *----------------------------------------------------------------------------*/
336
337 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
338 {
339 commonNaNT z;
340
341 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
342 z.sign = a.high>>15;
343 z.low = 0;
344 z.high = a.low<<1;
345 return z;
346 }
347
348 /*----------------------------------------------------------------------------
349 | Returns the result of converting the canonical NaN `a' to the extended
350 | double-precision floating-point format.
351 *----------------------------------------------------------------------------*/
352
353 static floatx80 commonNaNToFloatx80( commonNaNT a )
354 {
355 floatx80 z;
356
357 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
358 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
359 return z;
360 }
361
362 /*----------------------------------------------------------------------------
363 | Takes two extended double-precision floating-point values `a' and `b', one
364 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
365 | `b' is a signaling NaN, the invalid exception is raised.
366 *----------------------------------------------------------------------------*/
367
368 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
369 {
370 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
371
372 aIsNaN = floatx80_is_nan( a );
373 aIsSignalingNaN = floatx80_is_signaling_nan( a );
374 bIsNaN = floatx80_is_nan( b );
375 bIsSignalingNaN = floatx80_is_signaling_nan( b );
376 #if SNAN_BIT_IS_ONE
377 a.low &= ~LIT64( 0xC000000000000000 );
378 b.low &= ~LIT64( 0xC000000000000000 );
379 #else
380 a.low |= LIT64( 0xC000000000000000 );
381 b.low |= LIT64( 0xC000000000000000 );
382 #endif
383 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
384 if ( aIsSignalingNaN ) {
385 if ( bIsSignalingNaN ) goto returnLargerSignificand;
386 return bIsNaN ? b : a;
387 }
388 else if ( aIsNaN ) {
389 if ( bIsSignalingNaN | ! bIsNaN ) return a;
390 returnLargerSignificand:
391 if ( a.low < b.low ) return b;
392 if ( b.low < a.low ) return a;
393 return ( a.high < b.high ) ? a : b;
394 }
395 else {
396 return b;
397 }
398 }
399
400 #endif
401
402 #ifdef FLOAT128
403
404 /*----------------------------------------------------------------------------
405 | The pattern for a default generated quadruple-precision NaN. The `high' and
406 | `low' values hold the most- and least-significant bits, respectively.
407 *----------------------------------------------------------------------------*/
408 #if SNAN_BIT_IS_ONE
409 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
410 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
411 #else
412 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
413 #define float128_default_nan_low LIT64( 0x0000000000000000 )
414 #endif
415
416 /*----------------------------------------------------------------------------
417 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
418 | NaN; otherwise returns 0.
419 *----------------------------------------------------------------------------*/
420
421 int float128_is_nan( float128 a )
422 {
423 #if SNAN_BIT_IS_ONE
424 return
425 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
426 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
427 #else
428 return
429 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
430 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
431 #endif
432 }
433
434 /*----------------------------------------------------------------------------
435 | Returns 1 if the quadruple-precision floating-point value `a' is a
436 | signaling NaN; otherwise returns 0.
437 *----------------------------------------------------------------------------*/
438
439 int float128_is_signaling_nan( float128 a )
440 {
441 #if SNAN_BIT_IS_ONE
442 return
443 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
444 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
445 #else
446 return
447 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
448 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
449 #endif
450 }
451
452 /*----------------------------------------------------------------------------
453 | Returns the result of converting the quadruple-precision floating-point NaN
454 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
455 | exception is raised.
456 *----------------------------------------------------------------------------*/
457
458 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
459 {
460 commonNaNT z;
461
462 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
463 z.sign = a.high>>63;
464 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
465 return z;
466 }
467
468 /*----------------------------------------------------------------------------
469 | Returns the result of converting the canonical NaN `a' to the quadruple-
470 | precision floating-point format.
471 *----------------------------------------------------------------------------*/
472
473 static float128 commonNaNToFloat128( commonNaNT a )
474 {
475 float128 z;
476
477 shift128Right( a.high, a.low, 16, &z.high, &z.low );
478 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
479 return z;
480 }
481
482 /*----------------------------------------------------------------------------
483 | Takes two quadruple-precision floating-point values `a' and `b', one of
484 | which is a NaN, and returns the appropriate NaN result. If either `a' or
485 | `b' is a signaling NaN, the invalid exception is raised.
486 *----------------------------------------------------------------------------*/
487
488 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
489 {
490 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
491
492 aIsNaN = float128_is_nan( a );
493 aIsSignalingNaN = float128_is_signaling_nan( a );
494 bIsNaN = float128_is_nan( b );
495 bIsSignalingNaN = float128_is_signaling_nan( b );
496 #if SNAN_BIT_IS_ONE
497 a.high &= ~LIT64( 0x0000800000000000 );
498 b.high &= ~LIT64( 0x0000800000000000 );
499 #else
500 a.high |= LIT64( 0x0000800000000000 );
501 b.high |= LIT64( 0x0000800000000000 );
502 #endif
503 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
504 if ( aIsSignalingNaN ) {
505 if ( bIsSignalingNaN ) goto returnLargerSignificand;
506 return bIsNaN ? b : a;
507 }
508 else if ( aIsNaN ) {
509 if ( bIsSignalingNaN | ! bIsNaN ) return a;
510 returnLargerSignificand:
511 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
512 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
513 return ( a.high < b.high ) ? a : b;
514 }
515 else {
516 return b;
517 }
518 }
519
520 #endif