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 | ... | ... |