Commit b645bb48850fea8db017026897827f0ab42fbdea
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; | ... | ... |