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 | 5479 | if ( aExp == 0xFF ) { |
| 5480 | 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 | 5492 | float64 float64_scalbn( float64 a, int n STATUS_PARAM ) |
| ... | ... | @@ -5496,8 +5502,14 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM ) |
| 5496 | 5502 | if ( aExp == 0x7FF ) { |
| 5497 | 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 | 5515 | #ifdef FLOATX80 |
| ... | ... | @@ -5514,9 +5526,12 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) |
| 5514 | 5526 | if ( aExp == 0x7FF ) { |
| 5515 | 5527 | return a; |
| 5516 | 5528 | } |
| 5529 | + if (aExp == 0 && aSig == 0) | |
| 5530 | + return a; | |
| 5531 | + | |
| 5517 | 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 | 5536 | #endif |
| 5522 | 5537 | |
| ... | ... | @@ -5534,8 +5549,14 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM ) |
| 5534 | 5549 | if ( aExp == 0x7FFF ) { |
| 5535 | 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 | 5562 | #endif | ... | ... |