Commit 69397542d6e5372703f29aa99ba07aa15e787fe0
1 parent
731abc0d
Correctly normalize values and handle zero inputs to scalbn functions.
Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6102 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
29 additions
and
8 deletions
fpu/softfloat.c
| @@ -5479,8 +5479,14 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) | @@ -5479,8 +5479,14 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) | ||
| 5479 | if ( aExp == 0xFF ) { | 5479 | if ( aExp == 0xFF ) { |
| 5480 | return a; | 5480 | return a; |
| 5481 | } | 5481 | } |
| 5482 | - aExp += n; | ||
| 5483 | - return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); | 5482 | + if ( aExp != 0 ) |
| 5483 | + aSig |= 0x00800000; | ||
| 5484 | + else if ( aSig == 0 ) | ||
| 5485 | + return a; | ||
| 5486 | + | ||
| 5487 | + aExp += n - 1; | ||
| 5488 | + aSig <<= 7; | ||
| 5489 | + return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); | ||
| 5484 | } | 5490 | } |
| 5485 | 5491 | ||
| 5486 | float64 float64_scalbn( float64 a, int n STATUS_PARAM ) | 5492 | float64 float64_scalbn( float64 a, int n STATUS_PARAM ) |
| @@ -5496,8 +5502,14 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM ) | @@ -5496,8 +5502,14 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM ) | ||
| 5496 | if ( aExp == 0x7FF ) { | 5502 | if ( aExp == 0x7FF ) { |
| 5497 | return a; | 5503 | return a; |
| 5498 | } | 5504 | } |
| 5499 | - aExp += n; | ||
| 5500 | - return roundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); | 5505 | + if ( aExp != 0 ) |
| 5506 | + aSig |= LIT64( 0x0010000000000000 ); | ||
| 5507 | + else if ( aSig == 0 ) | ||
| 5508 | + return a; | ||
| 5509 | + | ||
| 5510 | + aExp += n - 1; | ||
| 5511 | + aSig <<= 10; | ||
| 5512 | + return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); | ||
| 5501 | } | 5513 | } |
| 5502 | 5514 | ||
| 5503 | #ifdef FLOATX80 | 5515 | #ifdef FLOATX80 |
| @@ -5514,9 +5526,12 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) | @@ -5514,9 +5526,12 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) | ||
| 5514 | if ( aExp == 0x7FF ) { | 5526 | if ( aExp == 0x7FF ) { |
| 5515 | return a; | 5527 | return a; |
| 5516 | } | 5528 | } |
| 5529 | + if (aExp == 0 && aSig == 0) | ||
| 5530 | + return a; | ||
| 5531 | + | ||
| 5517 | aExp += n; | 5532 | aExp += n; |
| 5518 | - return roundAndPackFloatx80( STATUS(floatx80_rounding_precision), | ||
| 5519 | - aSign, aExp, aSig, 0 STATUS_VAR ); | 5533 | + return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision), |
| 5534 | + aSign, aExp, aSig, 0 STATUS_VAR ); | ||
| 5520 | } | 5535 | } |
| 5521 | #endif | 5536 | #endif |
| 5522 | 5537 | ||
| @@ -5534,8 +5549,14 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM ) | @@ -5534,8 +5549,14 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM ) | ||
| 5534 | if ( aExp == 0x7FFF ) { | 5549 | if ( aExp == 0x7FFF ) { |
| 5535 | return a; | 5550 | return a; |
| 5536 | } | 5551 | } |
| 5537 | - aExp += n; | ||
| 5538 | - return roundAndPackFloat128( aSign, aExp, aSig0, aSig1, 0 STATUS_VAR ); | 5552 | + if ( aExp != 0 ) |
| 5553 | + aSig0 |= LIT64( 0x0001000000000000 ); | ||
| 5554 | + else if ( aSig0 == 0 && aSig1 == 0 ) | ||
| 5555 | + return a; | ||
| 5556 | + | ||
| 5557 | + aExp += n - 1; | ||
| 5558 | + return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1 | ||
| 5559 | + STATUS_VAR ); | ||
| 5539 | 5560 | ||
| 5540 | } | 5561 | } |
| 5541 | #endif | 5562 | #endif |