From: Thiemo Seufer <ths@networkno.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH, RFC] Fix softfloat NaN handling
Date: Wed, 9 May 2007 14:20:48 +0100 [thread overview]
Message-ID: <20070509132047.GA29921@networkno.de> (raw)
Hello All,
The relevant IEEE standards don't define if a set or a clear bit is
used to distinguish between QNaN and SNaN. MIPS, and apparently
PA RISC, made a different choice than the rest of the industry.
The appended patch accounts for this, it fixes a number of failures
on MIPS, none of those appears to be covered by e.g. classic paranoia.
It also changes some things for the other architectures, that's why
I ask for comments:
- float32_is_nan tests now for <=, since the set MSB of the mantissa
is enough to make it a proper QNaN.
- float64_is_nan has the same change, plus a changed bitmask which
is consistent to the QNaN definition.
Thiemo
Index: qemu-cvs/fpu/softfloat-specialize.h
===================================================================
--- qemu-cvs.orig/fpu/softfloat-specialize.h
+++ qemu-cvs/fpu/softfloat-specialize.h
@@ -61,7 +61,11 @@
/*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+#define float32_default_nan 0xFF800000
+#else
#define float32_default_nan 0xFFC00000
+#endif
/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a NaN;
@@ -70,9 +74,11 @@
int float32_is_nan( float32 a )
{
-
- return ( 0xFF000000 < (bits32) ( a<<1 ) );
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+ return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
+#else
+ return ( 0xFF800000 <= (bits32) ( a<<1 ) );
+#endif
}
/*----------------------------------------------------------------------------
@@ -82,9 +88,11 @@
int float32_is_signaling_nan( float32 a )
{
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+ return ( 0xFF800000 <= (bits32) ( a<<1 ) );
+#else
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
-
+#endif
}
/*----------------------------------------------------------------------------
@@ -131,8 +139,13 @@
aIsSignalingNaN = float32_is_signaling_nan( a );
bIsNaN = float32_is_nan( b );
bIsSignalingNaN = float32_is_signaling_nan( b );
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+ a &= ~0x00400000;
+ b &= ~0x00400000;
+#else
a |= 0x00400000;
b |= 0x00400000;
+#endif
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
if ( aIsSignalingNaN ) {
if ( bIsSignalingNaN ) goto returnLargerSignificand;
@@ -154,7 +167,11 @@
/*----------------------------------------------------------------------------
| The pattern for a default generated double-precision NaN.
*----------------------------------------------------------------------------*/
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+#define float64_default_nan LIT64( 0xFFF0000000000000 )
+#else
#define float64_default_nan LIT64( 0xFFF8000000000000 )
+#endif
/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a NaN;
@@ -163,9 +180,13 @@
int float64_is_nan( float64 a )
{
-
- return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+ return
+ ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
+ && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
+#else
+ return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
+#endif
}
/*----------------------------------------------------------------------------
@@ -175,11 +196,13 @@
int float64_is_signaling_nan( float64 a )
{
-
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+ return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
+#else
return
( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
&& ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
-
+#endif
}
/*----------------------------------------------------------------------------
@@ -229,8 +252,13 @@
aIsSignalingNaN = float64_is_signaling_nan( a );
bIsNaN = float64_is_nan( b );
bIsSignalingNaN = float64_is_signaling_nan( b );
+#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
+ a &= ~LIT64( 0x0008000000000000 );
+ b &= ~LIT64( 0x0008000000000000 );
+#else
a |= LIT64( 0x0008000000000000 );
b |= LIT64( 0x0008000000000000 );
+#endif
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
if ( aIsSignalingNaN ) {
if ( bIsSignalingNaN ) goto returnLargerSignificand;
next reply other threads:[~2007-05-09 13:28 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-05-09 13:20 Thiemo Seufer [this message]
2007-05-09 15:17 ` [Qemu-devel] [PATCH, RFC] Fix softfloat NaN handling Blue Swirl
2007-05-09 15:26 ` Thiemo Seufer
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=20070509132047.GA29921@networkno.de \
--to=ths@networkno.de \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.