summaryrefslogtreecommitdiff
path: root/fpu
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-12-19 12:59:28 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-12-19 12:59:28 +0000
commit69397542d6e5372703f29aa99ba07aa15e787fe0 (patch)
tree2780ad787b4a0433d4e2af58b4b9c0e0878c91b3 /fpu
parent731abc0d2284b957fdf77e76ef34eff1bd0a5bc1 (diff)
downloadqemu-69397542d6e5372703f29aa99ba07aa15e787fe0.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.c37
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