Commit 5a6932d51d1b34b68b3f10fc5ac65598bece88c0

Authored by ths
1 parent 7863667f

Fix NaN handling for MIPS and HPPA.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3655 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 68 additions and 40 deletions
fpu/softfloat-specialize.h
... ... @@ -30,6 +30,12 @@ these four paragraphs for those parts of this code that are retained.
30 30  
31 31 =============================================================================*/
32 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 +
33 39 /*----------------------------------------------------------------------------
34 40 | Underflow tininess-detection mode, statically initialized to default value.
35 41 | (The declaration in `softfloat.h' must match the `int8' type here.)
... ... @@ -45,9 +51,7 @@ int8 float_detect_tininess = float_tininess_after_rounding;
45 51  
46 52 void float_raise( int8 flags STATUS_PARAM )
47 53 {
48   -
49 54 STATUS(float_exception_flags) |= flags;
50   -
51 55 }
52 56  
53 57 /*----------------------------------------------------------------------------
... ... @@ -61,20 +65,20 @@ typedef struct {
61 65 /*----------------------------------------------------------------------------
62 66 | The pattern for a default generated single-precision NaN.
63 67 *----------------------------------------------------------------------------*/
64   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
65   -#define float32_default_nan 0xFF800000
  68 +#if SNAN_BIT_IS_ONE
  69 +#define float32_default_nan 0x7FBFFFFF
66 70 #else
67 71 #define float32_default_nan 0xFFC00000
68 72 #endif
69 73  
70 74 /*----------------------------------------------------------------------------
71   -| Returns 1 if the single-precision floating-point value `a' is a NaN;
72   -| otherwise returns 0.
  75 +| Returns 1 if the single-precision floating-point value `a' is a quiet
  76 +| NaN; otherwise returns 0.
73 77 *----------------------------------------------------------------------------*/
74 78  
75 79 int float32_is_nan( float32 a )
76 80 {
77   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  81 +#if SNAN_BIT_IS_ONE
78 82 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
79 83 #else
80 84 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
... ... @@ -88,7 +92,7 @@ int float32_is_nan( float32 a )
88 92  
89 93 int float32_is_signaling_nan( float32 a )
90 94 {
91   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  95 +#if SNAN_BIT_IS_ONE
92 96 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
93 97 #else
94 98 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
... ... @@ -110,7 +114,6 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
110 114 z.low = 0;
111 115 z.high = ( (bits64) a )<<41;
112 116 return z;
113   -
114 117 }
115 118  
116 119 /*----------------------------------------------------------------------------
... ... @@ -120,9 +123,7 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
120 123  
121 124 static float32 commonNaNToFloat32( commonNaNT a )
122 125 {
123   -
124 126 return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
125   -
126 127 }
127 128  
128 129 /*----------------------------------------------------------------------------
... ... @@ -139,7 +140,7 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
139 140 aIsSignalingNaN = float32_is_signaling_nan( a );
140 141 bIsNaN = float32_is_nan( b );
141 142 bIsSignalingNaN = float32_is_signaling_nan( b );
142   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  143 +#if SNAN_BIT_IS_ONE
143 144 a &= ~0x00400000;
144 145 b &= ~0x00400000;
145 146 #else
... ... @@ -161,26 +162,25 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
161 162 else {
162 163 return b;
163 164 }
164   -
165 165 }
166 166  
167 167 /*----------------------------------------------------------------------------
168 168 | The pattern for a default generated double-precision NaN.
169 169 *----------------------------------------------------------------------------*/
170   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
171   -#define float64_default_nan LIT64( 0xFFF0000000000000 )
  170 +#if SNAN_BIT_IS_ONE
  171 +#define float64_default_nan LIT64( 0x7FF7FFFFFFFFFFFF )
172 172 #else
173 173 #define float64_default_nan LIT64( 0xFFF8000000000000 )
174 174 #endif
175 175  
176 176 /*----------------------------------------------------------------------------
177   -| Returns 1 if the double-precision floating-point value `a' is a NaN;
178   -| otherwise returns 0.
  177 +| Returns 1 if the double-precision floating-point value `a' is a quiet
  178 +| NaN; otherwise returns 0.
179 179 *----------------------------------------------------------------------------*/
180 180  
181 181 int float64_is_nan( float64 a )
182 182 {
183   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  183 +#if SNAN_BIT_IS_ONE
184 184 return
185 185 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
186 186 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
... ... @@ -196,7 +196,7 @@ int float64_is_nan( float64 a )
196 196  
197 197 int float64_is_signaling_nan( float64 a )
198 198 {
199   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  199 +#if SNAN_BIT_IS_ONE
200 200 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
201 201 #else
202 202 return
... ... @@ -220,7 +220,6 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
220 220 z.low = 0;
221 221 z.high = a<<12;
222 222 return z;
223   -
224 223 }
225 224  
226 225 /*----------------------------------------------------------------------------
... ... @@ -230,12 +229,10 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
230 229  
231 230 static float64 commonNaNToFloat64( commonNaNT a )
232 231 {
233   -
234 232 return
235 233 ( ( (bits64) a.sign )<<63 )
236 234 | LIT64( 0x7FF8000000000000 )
237 235 | ( a.high>>12 );
238   -
239 236 }
240 237  
241 238 /*----------------------------------------------------------------------------
... ... @@ -252,7 +249,7 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
252 249 aIsSignalingNaN = float64_is_signaling_nan( a );
253 250 bIsNaN = float64_is_nan( b );
254 251 bIsSignalingNaN = float64_is_signaling_nan( b );
255   -#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  252 +#if SNAN_BIT_IS_ONE
256 253 a &= ~LIT64( 0x0008000000000000 );
257 254 b &= ~LIT64( 0x0008000000000000 );
258 255 #else
... ... @@ -274,7 +271,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
274 271 else {
275 272 return b;
276 273 }
277   -
278 274 }
279 275  
280 276 #ifdef FLOATX80
... ... @@ -284,19 +280,32 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
284 280 | `high' and `low' values hold the most- and least-significant bits,
285 281 | respectively.
286 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 287 #define floatx80_default_nan_high 0xFFFF
288 288 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
  289 +#endif
289 290  
290 291 /*----------------------------------------------------------------------------
291 292 | Returns 1 if the extended double-precision floating-point value `a' is a
292   -| NaN; otherwise returns 0.
  293 +| quiet NaN; otherwise returns 0.
293 294 *----------------------------------------------------------------------------*/
294 295  
295 296 int floatx80_is_nan( floatx80 a )
296 297 {
  298 +#if SNAN_BIT_IS_ONE
  299 + bits64 aLow;
297 300  
  301 + aLow = a.low & ~ LIT64( 0x4000000000000000 );
  302 + return
  303 + ( ( a.high & 0x7FFF ) == 0x7FFF )
  304 + && (bits64) ( aLow<<1 )
  305 + && ( a.low == aLow );
  306 +#else
298 307 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
299   -
  308 +#endif
300 309 }
301 310  
302 311 /*----------------------------------------------------------------------------
... ... @@ -306,6 +315,9 @@ int floatx80_is_nan( floatx80 a )
306 315  
307 316 int floatx80_is_signaling_nan( floatx80 a )
308 317 {
  318 +#if SNAN_BIT_IS_ONE
  319 + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
  320 +#else
309 321 bits64 aLow;
310 322  
311 323 aLow = a.low & ~ LIT64( 0x4000000000000000 );
... ... @@ -313,7 +325,7 @@ int floatx80_is_signaling_nan( floatx80 a )
313 325 ( ( a.high & 0x7FFF ) == 0x7FFF )
314 326 && (bits64) ( aLow<<1 )
315 327 && ( a.low == aLow );
316   -
  328 +#endif
317 329 }
318 330  
319 331 /*----------------------------------------------------------------------------
... ... @@ -331,7 +343,6 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
331 343 z.low = 0;
332 344 z.high = a.low<<1;
333 345 return z;
334   -
335 346 }
336 347  
337 348 /*----------------------------------------------------------------------------
... ... @@ -346,7 +357,6 @@ static floatx80 commonNaNToFloatx80( commonNaNT a )
346 357 z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
347 358 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
348 359 return z;
349   -
350 360 }
351 361  
352 362 /*----------------------------------------------------------------------------
... ... @@ -363,8 +373,13 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
363 373 aIsSignalingNaN = floatx80_is_signaling_nan( a );
364 374 bIsNaN = floatx80_is_nan( b );
365 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
366 380 a.low |= LIT64( 0xC000000000000000 );
367 381 b.low |= LIT64( 0xC000000000000000 );
  382 +#endif
368 383 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
369 384 if ( aIsSignalingNaN ) {
370 385 if ( bIsSignalingNaN ) goto returnLargerSignificand;
... ... @@ -380,7 +395,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
380 395 else {
381 396 return b;
382 397 }
383   -
384 398 }
385 399  
386 400 #endif
... ... @@ -391,21 +405,30 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
391 405 | The pattern for a default generated quadruple-precision NaN. The `high' and
392 406 | `low' values hold the most- and least-significant bits, respectively.
393 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
394 412 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
395 413 #define float128_default_nan_low LIT64( 0x0000000000000000 )
  414 +#endif
396 415  
397 416 /*----------------------------------------------------------------------------
398   -| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
399   -| otherwise returns 0.
  417 +| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
  418 +| NaN; otherwise returns 0.
400 419 *----------------------------------------------------------------------------*/
401 420  
402 421 int float128_is_nan( float128 a )
403 422 {
404   -
  423 +#if SNAN_BIT_IS_ONE
  424 + return
  425 + ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
  426 + && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
  427 +#else
405 428 return
406 429 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
407 430 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
408   -
  431 +#endif
409 432 }
410 433  
411 434 /*----------------------------------------------------------------------------
... ... @@ -415,11 +438,15 @@ int float128_is_nan( float128 a )
415 438  
416 439 int float128_is_signaling_nan( float128 a )
417 440 {
418   -
  441 +#if SNAN_BIT_IS_ONE
  442 + return
  443 + ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
  444 + && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
  445 +#else
419 446 return
420 447 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
421 448 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
422   -
  449 +#endif
423 450 }
424 451  
425 452 /*----------------------------------------------------------------------------
... ... @@ -436,7 +463,6 @@ static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
436 463 z.sign = a.high>>63;
437 464 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
438 465 return z;
439   -
440 466 }
441 467  
442 468 /*----------------------------------------------------------------------------
... ... @@ -451,7 +477,6 @@ static float128 commonNaNToFloat128( commonNaNT a )
451 477 shift128Right( a.high, a.low, 16, &z.high, &z.low );
452 478 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
453 479 return z;
454   -
455 480 }
456 481  
457 482 /*----------------------------------------------------------------------------
... ... @@ -468,8 +493,13 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
468 493 aIsSignalingNaN = float128_is_signaling_nan( a );
469 494 bIsNaN = float128_is_nan( b );
470 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
471 500 a.high |= LIT64( 0x0000800000000000 );
472 501 b.high |= LIT64( 0x0000800000000000 );
  502 +#endif
473 503 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
474 504 if ( aIsSignalingNaN ) {
475 505 if ( bIsSignalingNaN ) goto returnLargerSignificand;
... ... @@ -485,8 +515,6 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
485 515 else {
486 516 return b;
487 517 }
488   -
489 518 }
490 519  
491 520 #endif
492   -
... ...