Commit b645bb48850fea8db017026897827f0ab42fbdea

Authored by ths
1 parent 5a1e8ffb

Fix softfloat NaN handling.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2805 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 38 additions and 10 deletions
fpu/softfloat-specialize.h
@@ -61,7 +61,11 @@ typedef struct { @@ -61,7 +61,11 @@ typedef struct {
61 /*---------------------------------------------------------------------------- 61 /*----------------------------------------------------------------------------
62 | The pattern for a default generated single-precision NaN. 62 | The pattern for a default generated single-precision NaN.
63 *----------------------------------------------------------------------------*/ 63 *----------------------------------------------------------------------------*/
  64 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  65 +#define float32_default_nan 0xFF800000
  66 +#else
64 #define float32_default_nan 0xFFC00000 67 #define float32_default_nan 0xFFC00000
  68 +#endif
65 69
66 /*---------------------------------------------------------------------------- 70 /*----------------------------------------------------------------------------
67 | Returns 1 if the single-precision floating-point value `a' is a NaN; 71 | Returns 1 if the single-precision floating-point value `a' is a NaN;
@@ -70,9 +74,11 @@ typedef struct { @@ -70,9 +74,11 @@ typedef struct {
70 74
71 int float32_is_nan( float32 a ) 75 int float32_is_nan( float32 a )
72 { 76 {
73 -  
74 - return ( 0xFF000000 < (bits32) ( a<<1 ) );  
75 - 77 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  78 + return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
  79 +#else
  80 + return ( 0xFF800000 <= (bits32) ( a<<1 ) );
  81 +#endif
76 } 82 }
77 83
78 /*---------------------------------------------------------------------------- 84 /*----------------------------------------------------------------------------
@@ -82,9 +88,11 @@ int float32_is_nan( float32 a ) @@ -82,9 +88,11 @@ int float32_is_nan( float32 a )
82 88
83 int float32_is_signaling_nan( float32 a ) 89 int float32_is_signaling_nan( float32 a )
84 { 90 {
85 - 91 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  92 + return ( 0xFF800000 <= (bits32) ( a<<1 ) );
  93 +#else
86 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); 94 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
87 - 95 +#endif
88 } 96 }
89 97
90 /*---------------------------------------------------------------------------- 98 /*----------------------------------------------------------------------------
@@ -131,8 +139,13 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) @@ -131,8 +139,13 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
131 aIsSignalingNaN = float32_is_signaling_nan( a ); 139 aIsSignalingNaN = float32_is_signaling_nan( a );
132 bIsNaN = float32_is_nan( b ); 140 bIsNaN = float32_is_nan( b );
133 bIsSignalingNaN = float32_is_signaling_nan( b ); 141 bIsSignalingNaN = float32_is_signaling_nan( b );
  142 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  143 + a &= ~0x00400000;
  144 + b &= ~0x00400000;
  145 +#else
134 a |= 0x00400000; 146 a |= 0x00400000;
135 b |= 0x00400000; 147 b |= 0x00400000;
  148 +#endif
136 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 149 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
137 if ( aIsSignalingNaN ) { 150 if ( aIsSignalingNaN ) {
138 if ( bIsSignalingNaN ) goto returnLargerSignificand; 151 if ( bIsSignalingNaN ) goto returnLargerSignificand;
@@ -154,7 +167,11 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) @@ -154,7 +167,11 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
154 /*---------------------------------------------------------------------------- 167 /*----------------------------------------------------------------------------
155 | The pattern for a default generated double-precision NaN. 168 | The pattern for a default generated double-precision NaN.
156 *----------------------------------------------------------------------------*/ 169 *----------------------------------------------------------------------------*/
  170 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  171 +#define float64_default_nan LIT64( 0xFFF0000000000000 )
  172 +#else
157 #define float64_default_nan LIT64( 0xFFF8000000000000 ) 173 #define float64_default_nan LIT64( 0xFFF8000000000000 )
  174 +#endif
158 175
159 /*---------------------------------------------------------------------------- 176 /*----------------------------------------------------------------------------
160 | Returns 1 if the double-precision floating-point value `a' is a NaN; 177 | Returns 1 if the double-precision floating-point value `a' is a NaN;
@@ -163,9 +180,13 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) @@ -163,9 +180,13 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
163 180
164 int float64_is_nan( float64 a ) 181 int float64_is_nan( float64 a )
165 { 182 {
166 -  
167 - return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );  
168 - 183 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  184 + return
  185 + ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
  186 + && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
  187 +#else
  188 + return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
  189 +#endif
169 } 190 }
170 191
171 /*---------------------------------------------------------------------------- 192 /*----------------------------------------------------------------------------
@@ -175,11 +196,13 @@ int float64_is_nan( float64 a ) @@ -175,11 +196,13 @@ int float64_is_nan( float64 a )
175 196
176 int float64_is_signaling_nan( float64 a ) 197 int float64_is_signaling_nan( float64 a )
177 { 198 {
178 - 199 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  200 + return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
  201 +#else
179 return 202 return
180 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) 203 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
181 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); 204 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
182 - 205 +#endif
183 } 206 }
184 207
185 /*---------------------------------------------------------------------------- 208 /*----------------------------------------------------------------------------
@@ -229,8 +252,13 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) @@ -229,8 +252,13 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
229 aIsSignalingNaN = float64_is_signaling_nan( a ); 252 aIsSignalingNaN = float64_is_signaling_nan( a );
230 bIsNaN = float64_is_nan( b ); 253 bIsNaN = float64_is_nan( b );
231 bIsSignalingNaN = float64_is_signaling_nan( b ); 254 bIsSignalingNaN = float64_is_signaling_nan( b );
  255 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  256 + a &= ~LIT64( 0x0008000000000000 );
  257 + b &= ~LIT64( 0x0008000000000000 );
  258 +#else
232 a |= LIT64( 0x0008000000000000 ); 259 a |= LIT64( 0x0008000000000000 );
233 b |= LIT64( 0x0008000000000000 ); 260 b |= LIT64( 0x0008000000000000 );
  261 +#endif
234 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); 262 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
235 if ( aIsSignalingNaN ) { 263 if ( aIsSignalingNaN ) {
236 if ( bIsSignalingNaN ) goto returnLargerSignificand; 264 if ( bIsSignalingNaN ) goto returnLargerSignificand;