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 61 /*----------------------------------------------------------------------------
62 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 67 #define float32_default_nan 0xFFC00000
  68 +#endif
65 69  
66 70 /*----------------------------------------------------------------------------
67 71 | Returns 1 if the single-precision floating-point value `a' is a NaN;
... ... @@ -70,9 +74,11 @@ typedef struct {
70 74  
71 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 88  
83 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 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 139 aIsSignalingNaN = float32_is_signaling_nan( a );
132 140 bIsNaN = float32_is_nan( b );
133 141 bIsSignalingNaN = float32_is_signaling_nan( b );
  142 +#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
  143 + a &= ~0x00400000;
  144 + b &= ~0x00400000;
  145 +#else
134 146 a |= 0x00400000;
135 147 b |= 0x00400000;
  148 +#endif
136 149 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
137 150 if ( aIsSignalingNaN ) {
138 151 if ( bIsSignalingNaN ) goto returnLargerSignificand;
... ... @@ -154,7 +167,11 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
154 167 /*----------------------------------------------------------------------------
155 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 173 #define float64_default_nan LIT64( 0xFFF8000000000000 )
  174 +#endif
158 175  
159 176 /*----------------------------------------------------------------------------
160 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 180  
164 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 196  
176 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 202 return
180 203 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
181 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 252 aIsSignalingNaN = float64_is_signaling_nan( a );
230 253 bIsNaN = float64_is_nan( b );
231 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 259 a |= LIT64( 0x0008000000000000 );
233 260 b |= LIT64( 0x0008000000000000 );
  261 +#endif
234 262 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
235 263 if ( aIsSignalingNaN ) {
236 264 if ( bIsSignalingNaN ) goto returnLargerSignificand;
... ...