From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HlmDl-0003ro-MS for qemu-devel@nongnu.org; Wed, 09 May 2007 09:28:45 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HlmDk-0003o8-C3 for qemu-devel@nongnu.org; Wed, 09 May 2007 09:28:45 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HlmDk-0003nj-7g for qemu-devel@nongnu.org; Wed, 09 May 2007 09:28:44 -0400 Received: from phoenix.bawue.net ([193.7.176.60] helo=mail.bawue.net) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Hlm6X-0001ss-4Z for qemu-devel@nongnu.org; Wed, 09 May 2007 09:21:17 -0400 Received: from lagash (intrt.mips-uk.com [194.74.144.130]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.bawue.net (Postfix) with ESMTP id 46DE884BB8 for ; Wed, 9 May 2007 15:19:53 +0200 (CEST) Received: from ths by lagash with local (Exim 4.67) (envelope-from ) id 1Hlm64-0005iw-4Z for qemu-devel@nongnu.org; Wed, 09 May 2007 14:20:48 +0100 Date: Wed, 9 May 2007 14:20:48 +0100 Message-ID: <20070509132047.GA29921@networkno.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline From: Thiemo Seufer Subject: [Qemu-devel] [PATCH, RFC] Fix softfloat NaN handling Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org 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;