From: Aurelien Jarno <aurelien@aurel32.net>
To: qemu-devel@nongnu.org
Cc: Aurelien Jarno <aurelien@aurel32.net>
Subject: [Qemu-devel] [PATCH v2 07/20] softfloat: fix float*_scalnb() corner cases
Date: Wed, 20 Apr 2011 12:11:56 +0200 [thread overview]
Message-ID: <1303294329-22634-8-git-send-email-aurelien@aurel32.net> (raw)
In-Reply-To: <1303294329-22634-1-git-send-email-aurelien@aurel32.net>
float*_scalnb() were not taking into account all cases. This patch fixes
some corner cases:
- NaN values in input were not properly propagated and the invalid flag
not correctly raised. Use propagateFloat*NaN() for that.
- NaN or infinite values in input of floatx80_scalnb() were not correctly
detected due to a typo.
- The sum of exponent and n could overflow, leading to strange results.
Additionally having int16 defined to int make that happening for a very
small range of values. Fix that by saturating n to the maximum exponent
range, and using an explicit wider type if needed.
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
---
fpu/softfloat.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 42 insertions(+), 5 deletions(-)
v1 -> v2: fix condition for float32
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 4368069..baba1dc 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -6333,7 +6333,7 @@ MINMAX(64, 0x7ff)
float32 float32_scalbn( float32 a, int n STATUS_PARAM )
{
flag aSign;
- int16 aExp;
+ int16_t aExp;
uint32_t aSig;
a = float32_squash_input_denormal(a STATUS_VAR);
@@ -6342,6 +6342,9 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
aSign = extractFloat32Sign( a );
if ( aExp == 0xFF ) {
+ if ( aSig ) {
+ return propagateFloat32NaN( a, a STATUS_VAR );
+ }
return a;
}
if ( aExp != 0 )
@@ -6349,6 +6352,12 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
else if ( aSig == 0 )
return a;
+ if (n > 0x200) {
+ n = 0x200;
+ } else if (n < -0x200) {
+ n = -0x200;
+ }
+
aExp += n - 1;
aSig <<= 7;
return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
@@ -6357,7 +6366,7 @@ float32 float32_scalbn( float32 a, int n STATUS_PARAM )
float64 float64_scalbn( float64 a, int n STATUS_PARAM )
{
flag aSign;
- int16 aExp;
+ int16_t aExp;
uint64_t aSig;
a = float64_squash_input_denormal(a STATUS_VAR);
@@ -6366,6 +6375,9 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
aSign = extractFloat64Sign( a );
if ( aExp == 0x7FF ) {
+ if ( aSig ) {
+ return propagateFloat64NaN( a, a STATUS_VAR );
+ }
return a;
}
if ( aExp != 0 )
@@ -6373,6 +6385,12 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
else if ( aSig == 0 )
return a;
+ if (n > 0x1000) {
+ n = 0x1000;
+ } else if (n < -0x1000) {
+ n = -0x1000;
+ }
+
aExp += n - 1;
aSig <<= 10;
return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
@@ -6382,19 +6400,29 @@ float64 float64_scalbn( float64 a, int n STATUS_PARAM )
floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
{
flag aSign;
- int16 aExp;
+ int32_t aExp;
uint64_t aSig;
aSig = extractFloatx80Frac( a );
aExp = extractFloatx80Exp( a );
aSign = extractFloatx80Sign( a );
- if ( aExp == 0x7FF ) {
+ if ( aExp == 0x7FFF ) {
+ if ( aSig<<1 ) {
+ return propagateFloatx80NaN( a, a STATUS_VAR );
+ }
return a;
}
+
if (aExp == 0 && aSig == 0)
return a;
+ if (n > 0x10000) {
+ n = 0x10000;
+ } else if (n < -0x10000) {
+ n = -0x10000;
+ }
+
aExp += n;
return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
aSign, aExp, aSig, 0 STATUS_VAR );
@@ -6405,7 +6433,7 @@ floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
float128 float128_scalbn( float128 a, int n STATUS_PARAM )
{
flag aSign;
- int32 aExp;
+ int32_t aExp;
uint64_t aSig0, aSig1;
aSig1 = extractFloat128Frac1( a );
@@ -6413,6 +6441,9 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
aExp = extractFloat128Exp( a );
aSign = extractFloat128Sign( a );
if ( aExp == 0x7FFF ) {
+ if ( aSig0 | aSig1 ) {
+ return propagateFloat128NaN( a, a STATUS_VAR );
+ }
return a;
}
if ( aExp != 0 )
@@ -6420,6 +6451,12 @@ float128 float128_scalbn( float128 a, int n STATUS_PARAM )
else if ( aSig0 == 0 && aSig1 == 0 )
return a;
+ if (n > 0x10000) {
+ n = 0x10000;
+ } else if (n < -0x10000) {
+ n = -0x10000;
+ }
+
aExp += n - 1;
return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
STATUS_VAR );
--
1.7.2.3
next prev parent reply other threads:[~2011-04-20 10:12 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-04-20 10:11 [Qemu-devel] [PATCH v2 00/20] *** SUBJECT HERE *** Aurelien Jarno
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 01/20] softfloat: fix floatx80 handling of NaN Aurelien Jarno
2011-04-20 10:35 ` Peter Maydell
2011-04-20 11:24 ` [Qemu-devel] [PATCH v3 " Aurelien Jarno
2011-04-20 11:28 ` Peter Maydell
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 02/20] softfloat: fix floatx80_is_infinity() Aurelien Jarno
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 03/20] softfloat: add floatx80 constants Aurelien Jarno
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 04/20] softfloat: add pi constants Aurelien Jarno
2011-04-20 10:40 ` Peter Maydell
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 05/20] softfloat-native: add a few constant values Aurelien Jarno
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 06/20] softfloat: add floatx80_compare*() functions Aurelien Jarno
2011-04-20 10:11 ` Aurelien Jarno [this message]
2011-04-20 10:40 ` [Qemu-devel] [PATCH v2 07/20] softfloat: fix float*_scalnb() corner cases Peter Maydell
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 08/20] softfloat-native: fix float*_scalbn() functions Aurelien Jarno
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 09/20] softfloat-native: add float*_is_any_nan() functions Aurelien Jarno
2011-04-20 10:11 ` [Qemu-devel] [PATCH v2 10/20] target-i386: fix helper_fscale() wrt softfloat Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 11/20] target-i386: fix helper_fbld_ST0() " Aurelien Jarno
2011-04-20 10:41 ` Peter Maydell
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 12/20] target-i386: fix helper_fxtract() " Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 13/20] target-i386: fix helper_fdiv() " Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 14/20] target-i386: fix helper_fsqrt() " Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 15/20] target-i386: replace approx_rsqrt and approx_rcp by softfloat ops Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 16/20] target-i386: add CPU86_LDouble <-> double conversion functions Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 17/20] target-i386: fix logarithmic and trigonometric helpers wrt softfloat Aurelien Jarno
2011-04-20 10:41 ` Peter Maydell
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 18/20] target-i386: fix helper_fprem() and helper_fprem1() " Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 19/20] target-i386: fix constants " Aurelien Jarno
2011-04-20 10:12 ` [Qemu-devel] [PATCH v2 20/20] target-i386: switch to softfloat Aurelien Jarno
2011-04-20 10:42 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1303294329-22634-8-git-send-email-aurelien@aurel32.net \
--to=aurelien@aurel32.net \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).