diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-19 12:59:28 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-19 12:59:28 +0000 |
commit | c5c519f29236e5c218238e7e26b376edfe8d05b3 (patch) | |
tree | 2780ad787b4a0433d4e2af58b4b9c0e0878c91b3 /fpu | |
parent | 3dcd4a7f96b42c66f2f54881e7eded2ec9d0f2c2 (diff) | |
download | qemu-c5c519f29236e5c218238e7e26b376edfe8d05b3.tar.gz qemu-c5c519f29236e5c218238e7e26b376edfe8d05b3.tar.bz2 qemu-c5c519f29236e5c218238e7e26b376edfe8d05b3.zip |
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
Diffstat (limited to 'fpu')
-rw-r--r-- | fpu/softfloat.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 3988bd1099..e66a5d46c8 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -5479,8 +5479,14 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM ) if ( aExp == 0xFF ) { return a; } - aExp += n; - return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); + if ( aExp != 0 ) + aSig |= 0x00800000; + else if ( aSig == 0 ) + return a; + + aExp += n - 1; + aSig <<= 7; + return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); } float64 float64_scalbn( float64 a, int n STATUS_PARAM ) @@ -5496,8 +5502,14 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM ) if ( aExp == 0x7FF ) { return a; } - aExp += n; - return roundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); + if ( aExp != 0 ) + aSig |= LIT64( 0x0010000000000000 ); + else if ( aSig == 0 ) + return a; + + aExp += n - 1; + aSig <<= 10; + return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR ); } #ifdef FLOATX80 @@ -5514,9 +5526,12 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM ) if ( aExp == 0x7FF ) { return a; } + if (aExp == 0 && aSig == 0) + return a; + aExp += n; - return roundAndPackFloatx80( STATUS(floatx80_rounding_precision), - aSign, aExp, aSig, 0 STATUS_VAR ); + return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision), + aSign, aExp, aSig, 0 STATUS_VAR ); } #endif @@ -5534,8 +5549,14 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM ) if ( aExp == 0x7FFF ) { return a; } - aExp += n; - return roundAndPackFloat128( aSign, aExp, aSig0, aSig1, 0 STATUS_VAR ); + if ( aExp != 0 ) + aSig0 |= LIT64( 0x0001000000000000 ); + else if ( aSig0 == 0 && aSig1 == 0 ) + return a; + + aExp += n - 1; + return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1 + STATUS_VAR ); } #endif |