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