Commit 5a6932d51d1b34b68b3f10fc5ac65598bece88c0
1 parent
7863667f
Fix NaN handling for MIPS and HPPA.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3655 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
68 additions
and
40 deletions
fpu/softfloat-specialize.h
@@ -30,6 +30,12 @@ these four paragraphs for those parts of this code that are retained. | @@ -30,6 +30,12 @@ these four paragraphs for those parts of this code that are retained. | ||
30 | 30 | ||
31 | =============================================================================*/ | 31 | =============================================================================*/ |
32 | 32 | ||
33 | +#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | ||
34 | +#define SNAN_BIT_IS_ONE 1 | ||
35 | +#else | ||
36 | +#define SNAN_BIT_IS_ONE 0 | ||
37 | +#endif | ||
38 | + | ||
33 | /*---------------------------------------------------------------------------- | 39 | /*---------------------------------------------------------------------------- |
34 | | Underflow tininess-detection mode, statically initialized to default value. | 40 | | Underflow tininess-detection mode, statically initialized to default value. |
35 | | (The declaration in `softfloat.h' must match the `int8' type here.) | 41 | | (The declaration in `softfloat.h' must match the `int8' type here.) |
@@ -45,9 +51,7 @@ int8 float_detect_tininess = float_tininess_after_rounding; | @@ -45,9 +51,7 @@ int8 float_detect_tininess = float_tininess_after_rounding; | ||
45 | 51 | ||
46 | void float_raise( int8 flags STATUS_PARAM ) | 52 | void float_raise( int8 flags STATUS_PARAM ) |
47 | { | 53 | { |
48 | - | ||
49 | STATUS(float_exception_flags) |= flags; | 54 | STATUS(float_exception_flags) |= flags; |
50 | - | ||
51 | } | 55 | } |
52 | 56 | ||
53 | /*---------------------------------------------------------------------------- | 57 | /*---------------------------------------------------------------------------- |
@@ -61,20 +65,20 @@ typedef struct { | @@ -61,20 +65,20 @@ typedef struct { | ||
61 | /*---------------------------------------------------------------------------- | 65 | /*---------------------------------------------------------------------------- |
62 | | The pattern for a default generated single-precision NaN. | 66 | | The pattern for a default generated single-precision NaN. |
63 | *----------------------------------------------------------------------------*/ | 67 | *----------------------------------------------------------------------------*/ |
64 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | ||
65 | -#define float32_default_nan 0xFF800000 | 68 | +#if SNAN_BIT_IS_ONE |
69 | +#define float32_default_nan 0x7FBFFFFF | ||
66 | #else | 70 | #else |
67 | #define float32_default_nan 0xFFC00000 | 71 | #define float32_default_nan 0xFFC00000 |
68 | #endif | 72 | #endif |
69 | 73 | ||
70 | /*---------------------------------------------------------------------------- | 74 | /*---------------------------------------------------------------------------- |
71 | -| Returns 1 if the single-precision floating-point value `a' is a NaN; | ||
72 | -| otherwise returns 0. | 75 | +| Returns 1 if the single-precision floating-point value `a' is a quiet |
76 | +| NaN; otherwise returns 0. | ||
73 | *----------------------------------------------------------------------------*/ | 77 | *----------------------------------------------------------------------------*/ |
74 | 78 | ||
75 | int float32_is_nan( float32 a ) | 79 | int float32_is_nan( float32 a ) |
76 | { | 80 | { |
77 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | 81 | +#if SNAN_BIT_IS_ONE |
78 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); | 82 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); |
79 | #else | 83 | #else |
80 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); | 84 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); |
@@ -88,7 +92,7 @@ int float32_is_nan( float32 a ) | @@ -88,7 +92,7 @@ int float32_is_nan( float32 a ) | ||
88 | 92 | ||
89 | int float32_is_signaling_nan( float32 a ) | 93 | int float32_is_signaling_nan( float32 a ) |
90 | { | 94 | { |
91 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | 95 | +#if SNAN_BIT_IS_ONE |
92 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); | 96 | return ( 0xFF800000 <= (bits32) ( a<<1 ) ); |
93 | #else | 97 | #else |
94 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); | 98 | return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF ); |
@@ -110,7 +114,6 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | @@ -110,7 +114,6 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | ||
110 | z.low = 0; | 114 | z.low = 0; |
111 | z.high = ( (bits64) a )<<41; | 115 | z.high = ( (bits64) a )<<41; |
112 | return z; | 116 | return z; |
113 | - | ||
114 | } | 117 | } |
115 | 118 | ||
116 | /*---------------------------------------------------------------------------- | 119 | /*---------------------------------------------------------------------------- |
@@ -120,9 +123,7 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | @@ -120,9 +123,7 @@ static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM ) | ||
120 | 123 | ||
121 | static float32 commonNaNToFloat32( commonNaNT a ) | 124 | static float32 commonNaNToFloat32( commonNaNT a ) |
122 | { | 125 | { |
123 | - | ||
124 | return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); | 126 | return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 ); |
125 | - | ||
126 | } | 127 | } |
127 | 128 | ||
128 | /*---------------------------------------------------------------------------- | 129 | /*---------------------------------------------------------------------------- |
@@ -139,7 +140,7 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | @@ -139,7 +140,7 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | ||
139 | aIsSignalingNaN = float32_is_signaling_nan( a ); | 140 | aIsSignalingNaN = float32_is_signaling_nan( a ); |
140 | bIsNaN = float32_is_nan( b ); | 141 | bIsNaN = float32_is_nan( b ); |
141 | bIsSignalingNaN = float32_is_signaling_nan( b ); | 142 | bIsSignalingNaN = float32_is_signaling_nan( b ); |
142 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | 143 | +#if SNAN_BIT_IS_ONE |
143 | a &= ~0x00400000; | 144 | a &= ~0x00400000; |
144 | b &= ~0x00400000; | 145 | b &= ~0x00400000; |
145 | #else | 146 | #else |
@@ -161,26 +162,25 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | @@ -161,26 +162,25 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | ||
161 | else { | 162 | else { |
162 | return b; | 163 | return b; |
163 | } | 164 | } |
164 | - | ||
165 | } | 165 | } |
166 | 166 | ||
167 | /*---------------------------------------------------------------------------- | 167 | /*---------------------------------------------------------------------------- |
168 | | The pattern for a default generated double-precision NaN. | 168 | | The pattern for a default generated double-precision NaN. |
169 | *----------------------------------------------------------------------------*/ | 169 | *----------------------------------------------------------------------------*/ |
170 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | ||
171 | -#define float64_default_nan LIT64( 0xFFF0000000000000 ) | 170 | +#if SNAN_BIT_IS_ONE |
171 | +#define float64_default_nan LIT64( 0x7FF7FFFFFFFFFFFF ) | ||
172 | #else | 172 | #else |
173 | #define float64_default_nan LIT64( 0xFFF8000000000000 ) | 173 | #define float64_default_nan LIT64( 0xFFF8000000000000 ) |
174 | #endif | 174 | #endif |
175 | 175 | ||
176 | /*---------------------------------------------------------------------------- | 176 | /*---------------------------------------------------------------------------- |
177 | -| Returns 1 if the double-precision floating-point value `a' is a NaN; | ||
178 | -| otherwise returns 0. | 177 | +| Returns 1 if the double-precision floating-point value `a' is a quiet |
178 | +| NaN; otherwise returns 0. | ||
179 | *----------------------------------------------------------------------------*/ | 179 | *----------------------------------------------------------------------------*/ |
180 | 180 | ||
181 | int float64_is_nan( float64 a ) | 181 | int float64_is_nan( float64 a ) |
182 | { | 182 | { |
183 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | 183 | +#if SNAN_BIT_IS_ONE |
184 | return | 184 | return |
185 | ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) | 185 | ( ( ( a>>51 ) & 0xFFF ) == 0xFFE ) |
186 | && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); | 186 | && ( a & LIT64( 0x0007FFFFFFFFFFFF ) ); |
@@ -196,7 +196,7 @@ int float64_is_nan( float64 a ) | @@ -196,7 +196,7 @@ int float64_is_nan( float64 a ) | ||
196 | 196 | ||
197 | int float64_is_signaling_nan( float64 a ) | 197 | int float64_is_signaling_nan( float64 a ) |
198 | { | 198 | { |
199 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | 199 | +#if SNAN_BIT_IS_ONE |
200 | return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); | 200 | return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) ); |
201 | #else | 201 | #else |
202 | return | 202 | return |
@@ -220,7 +220,6 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | @@ -220,7 +220,6 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | ||
220 | z.low = 0; | 220 | z.low = 0; |
221 | z.high = a<<12; | 221 | z.high = a<<12; |
222 | return z; | 222 | return z; |
223 | - | ||
224 | } | 223 | } |
225 | 224 | ||
226 | /*---------------------------------------------------------------------------- | 225 | /*---------------------------------------------------------------------------- |
@@ -230,12 +229,10 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | @@ -230,12 +229,10 @@ static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM) | ||
230 | 229 | ||
231 | static float64 commonNaNToFloat64( commonNaNT a ) | 230 | static float64 commonNaNToFloat64( commonNaNT a ) |
232 | { | 231 | { |
233 | - | ||
234 | return | 232 | return |
235 | ( ( (bits64) a.sign )<<63 ) | 233 | ( ( (bits64) a.sign )<<63 ) |
236 | | LIT64( 0x7FF8000000000000 ) | 234 | | LIT64( 0x7FF8000000000000 ) |
237 | | ( a.high>>12 ); | 235 | | ( a.high>>12 ); |
238 | - | ||
239 | } | 236 | } |
240 | 237 | ||
241 | /*---------------------------------------------------------------------------- | 238 | /*---------------------------------------------------------------------------- |
@@ -252,7 +249,7 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | @@ -252,7 +249,7 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | ||
252 | aIsSignalingNaN = float64_is_signaling_nan( a ); | 249 | aIsSignalingNaN = float64_is_signaling_nan( a ); |
253 | bIsNaN = float64_is_nan( b ); | 250 | bIsNaN = float64_is_nan( b ); |
254 | bIsSignalingNaN = float64_is_signaling_nan( b ); | 251 | bIsSignalingNaN = float64_is_signaling_nan( b ); |
255 | -#if defined(TARGET_MIPS) || defined(TARGET_HPPA) | 252 | +#if SNAN_BIT_IS_ONE |
256 | a &= ~LIT64( 0x0008000000000000 ); | 253 | a &= ~LIT64( 0x0008000000000000 ); |
257 | b &= ~LIT64( 0x0008000000000000 ); | 254 | b &= ~LIT64( 0x0008000000000000 ); |
258 | #else | 255 | #else |
@@ -274,7 +271,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | @@ -274,7 +271,6 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | ||
274 | else { | 271 | else { |
275 | return b; | 272 | return b; |
276 | } | 273 | } |
277 | - | ||
278 | } | 274 | } |
279 | 275 | ||
280 | #ifdef FLOATX80 | 276 | #ifdef FLOATX80 |
@@ -284,19 +280,32 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | @@ -284,19 +280,32 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | ||
284 | | `high' and `low' values hold the most- and least-significant bits, | 280 | | `high' and `low' values hold the most- and least-significant bits, |
285 | | respectively. | 281 | | respectively. |
286 | *----------------------------------------------------------------------------*/ | 282 | *----------------------------------------------------------------------------*/ |
283 | +#if SNAN_BIT_IS_ONE | ||
284 | +#define floatx80_default_nan_high 0x7FFF | ||
285 | +#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF ) | ||
286 | +#else | ||
287 | #define floatx80_default_nan_high 0xFFFF | 287 | #define floatx80_default_nan_high 0xFFFF |
288 | #define floatx80_default_nan_low LIT64( 0xC000000000000000 ) | 288 | #define floatx80_default_nan_low LIT64( 0xC000000000000000 ) |
289 | +#endif | ||
289 | 290 | ||
290 | /*---------------------------------------------------------------------------- | 291 | /*---------------------------------------------------------------------------- |
291 | | Returns 1 if the extended double-precision floating-point value `a' is a | 292 | | Returns 1 if the extended double-precision floating-point value `a' is a |
292 | -| NaN; otherwise returns 0. | 293 | +| quiet NaN; otherwise returns 0. |
293 | *----------------------------------------------------------------------------*/ | 294 | *----------------------------------------------------------------------------*/ |
294 | 295 | ||
295 | int floatx80_is_nan( floatx80 a ) | 296 | int floatx80_is_nan( floatx80 a ) |
296 | { | 297 | { |
298 | +#if SNAN_BIT_IS_ONE | ||
299 | + bits64 aLow; | ||
297 | 300 | ||
301 | + aLow = a.low & ~ LIT64( 0x4000000000000000 ); | ||
302 | + return | ||
303 | + ( ( a.high & 0x7FFF ) == 0x7FFF ) | ||
304 | + && (bits64) ( aLow<<1 ) | ||
305 | + && ( a.low == aLow ); | ||
306 | +#else | ||
298 | return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); | 307 | return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); |
299 | - | 308 | +#endif |
300 | } | 309 | } |
301 | 310 | ||
302 | /*---------------------------------------------------------------------------- | 311 | /*---------------------------------------------------------------------------- |
@@ -306,6 +315,9 @@ int floatx80_is_nan( floatx80 a ) | @@ -306,6 +315,9 @@ int floatx80_is_nan( floatx80 a ) | ||
306 | 315 | ||
307 | int floatx80_is_signaling_nan( floatx80 a ) | 316 | int floatx80_is_signaling_nan( floatx80 a ) |
308 | { | 317 | { |
318 | +#if SNAN_BIT_IS_ONE | ||
319 | + return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 ); | ||
320 | +#else | ||
309 | bits64 aLow; | 321 | bits64 aLow; |
310 | 322 | ||
311 | aLow = a.low & ~ LIT64( 0x4000000000000000 ); | 323 | aLow = a.low & ~ LIT64( 0x4000000000000000 ); |
@@ -313,7 +325,7 @@ int floatx80_is_signaling_nan( floatx80 a ) | @@ -313,7 +325,7 @@ int floatx80_is_signaling_nan( floatx80 a ) | ||
313 | ( ( a.high & 0x7FFF ) == 0x7FFF ) | 325 | ( ( a.high & 0x7FFF ) == 0x7FFF ) |
314 | && (bits64) ( aLow<<1 ) | 326 | && (bits64) ( aLow<<1 ) |
315 | && ( a.low == aLow ); | 327 | && ( a.low == aLow ); |
316 | - | 328 | +#endif |
317 | } | 329 | } |
318 | 330 | ||
319 | /*---------------------------------------------------------------------------- | 331 | /*---------------------------------------------------------------------------- |
@@ -331,7 +343,6 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) | @@ -331,7 +343,6 @@ static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM) | ||
331 | z.low = 0; | 343 | z.low = 0; |
332 | z.high = a.low<<1; | 344 | z.high = a.low<<1; |
333 | return z; | 345 | return z; |
334 | - | ||
335 | } | 346 | } |
336 | 347 | ||
337 | /*---------------------------------------------------------------------------- | 348 | /*---------------------------------------------------------------------------- |
@@ -346,7 +357,6 @@ static floatx80 commonNaNToFloatx80( commonNaNT a ) | @@ -346,7 +357,6 @@ static floatx80 commonNaNToFloatx80( commonNaNT a ) | ||
346 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); | 357 | z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 ); |
347 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; | 358 | z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF; |
348 | return z; | 359 | return z; |
349 | - | ||
350 | } | 360 | } |
351 | 361 | ||
352 | /*---------------------------------------------------------------------------- | 362 | /*---------------------------------------------------------------------------- |
@@ -363,8 +373,13 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | @@ -363,8 +373,13 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | ||
363 | aIsSignalingNaN = floatx80_is_signaling_nan( a ); | 373 | aIsSignalingNaN = floatx80_is_signaling_nan( a ); |
364 | bIsNaN = floatx80_is_nan( b ); | 374 | bIsNaN = floatx80_is_nan( b ); |
365 | bIsSignalingNaN = floatx80_is_signaling_nan( b ); | 375 | bIsSignalingNaN = floatx80_is_signaling_nan( b ); |
376 | +#if SNAN_BIT_IS_ONE | ||
377 | + a.low &= ~LIT64( 0xC000000000000000 ); | ||
378 | + b.low &= ~LIT64( 0xC000000000000000 ); | ||
379 | +#else | ||
366 | a.low |= LIT64( 0xC000000000000000 ); | 380 | a.low |= LIT64( 0xC000000000000000 ); |
367 | b.low |= LIT64( 0xC000000000000000 ); | 381 | b.low |= LIT64( 0xC000000000000000 ); |
382 | +#endif | ||
368 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); | 383 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); |
369 | if ( aIsSignalingNaN ) { | 384 | if ( aIsSignalingNaN ) { |
370 | if ( bIsSignalingNaN ) goto returnLargerSignificand; | 385 | if ( bIsSignalingNaN ) goto returnLargerSignificand; |
@@ -380,7 +395,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | @@ -380,7 +395,6 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | ||
380 | else { | 395 | else { |
381 | return b; | 396 | return b; |
382 | } | 397 | } |
383 | - | ||
384 | } | 398 | } |
385 | 399 | ||
386 | #endif | 400 | #endif |
@@ -391,21 +405,30 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | @@ -391,21 +405,30 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | ||
391 | | The pattern for a default generated quadruple-precision NaN. The `high' and | 405 | | The pattern for a default generated quadruple-precision NaN. The `high' and |
392 | | `low' values hold the most- and least-significant bits, respectively. | 406 | | `low' values hold the most- and least-significant bits, respectively. |
393 | *----------------------------------------------------------------------------*/ | 407 | *----------------------------------------------------------------------------*/ |
408 | +#if SNAN_BIT_IS_ONE | ||
409 | +#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF ) | ||
410 | +#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF ) | ||
411 | +#else | ||
394 | #define float128_default_nan_high LIT64( 0xFFFF800000000000 ) | 412 | #define float128_default_nan_high LIT64( 0xFFFF800000000000 ) |
395 | #define float128_default_nan_low LIT64( 0x0000000000000000 ) | 413 | #define float128_default_nan_low LIT64( 0x0000000000000000 ) |
414 | +#endif | ||
396 | 415 | ||
397 | /*---------------------------------------------------------------------------- | 416 | /*---------------------------------------------------------------------------- |
398 | -| Returns 1 if the quadruple-precision floating-point value `a' is a NaN; | ||
399 | -| otherwise returns 0. | 417 | +| Returns 1 if the quadruple-precision floating-point value `a' is a quiet |
418 | +| NaN; otherwise returns 0. | ||
400 | *----------------------------------------------------------------------------*/ | 419 | *----------------------------------------------------------------------------*/ |
401 | 420 | ||
402 | int float128_is_nan( float128 a ) | 421 | int float128_is_nan( float128 a ) |
403 | { | 422 | { |
404 | - | 423 | +#if SNAN_BIT_IS_ONE |
424 | + return | ||
425 | + ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) | ||
426 | + && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); | ||
427 | +#else | ||
405 | return | 428 | return |
406 | ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) | 429 | ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) |
407 | && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); | 430 | && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); |
408 | - | 431 | +#endif |
409 | } | 432 | } |
410 | 433 | ||
411 | /*---------------------------------------------------------------------------- | 434 | /*---------------------------------------------------------------------------- |
@@ -415,11 +438,15 @@ int float128_is_nan( float128 a ) | @@ -415,11 +438,15 @@ int float128_is_nan( float128 a ) | ||
415 | 438 | ||
416 | int float128_is_signaling_nan( float128 a ) | 439 | int float128_is_signaling_nan( float128 a ) |
417 | { | 440 | { |
418 | - | 441 | +#if SNAN_BIT_IS_ONE |
442 | + return | ||
443 | + ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) ) | ||
444 | + && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) ); | ||
445 | +#else | ||
419 | return | 446 | return |
420 | ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) | 447 | ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE ) |
421 | && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); | 448 | && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) ); |
422 | - | 449 | +#endif |
423 | } | 450 | } |
424 | 451 | ||
425 | /*---------------------------------------------------------------------------- | 452 | /*---------------------------------------------------------------------------- |
@@ -436,7 +463,6 @@ static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM) | @@ -436,7 +463,6 @@ static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM) | ||
436 | z.sign = a.high>>63; | 463 | z.sign = a.high>>63; |
437 | shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); | 464 | shortShift128Left( a.high, a.low, 16, &z.high, &z.low ); |
438 | return z; | 465 | return z; |
439 | - | ||
440 | } | 466 | } |
441 | 467 | ||
442 | /*---------------------------------------------------------------------------- | 468 | /*---------------------------------------------------------------------------- |
@@ -451,7 +477,6 @@ static float128 commonNaNToFloat128( commonNaNT a ) | @@ -451,7 +477,6 @@ static float128 commonNaNToFloat128( commonNaNT a ) | ||
451 | shift128Right( a.high, a.low, 16, &z.high, &z.low ); | 477 | shift128Right( a.high, a.low, 16, &z.high, &z.low ); |
452 | z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); | 478 | z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 ); |
453 | return z; | 479 | return z; |
454 | - | ||
455 | } | 480 | } |
456 | 481 | ||
457 | /*---------------------------------------------------------------------------- | 482 | /*---------------------------------------------------------------------------- |
@@ -468,8 +493,13 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) | @@ -468,8 +493,13 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) | ||
468 | aIsSignalingNaN = float128_is_signaling_nan( a ); | 493 | aIsSignalingNaN = float128_is_signaling_nan( a ); |
469 | bIsNaN = float128_is_nan( b ); | 494 | bIsNaN = float128_is_nan( b ); |
470 | bIsSignalingNaN = float128_is_signaling_nan( b ); | 495 | bIsSignalingNaN = float128_is_signaling_nan( b ); |
496 | +#if SNAN_BIT_IS_ONE | ||
497 | + a.high &= ~LIT64( 0x0000800000000000 ); | ||
498 | + b.high &= ~LIT64( 0x0000800000000000 ); | ||
499 | +#else | ||
471 | a.high |= LIT64( 0x0000800000000000 ); | 500 | a.high |= LIT64( 0x0000800000000000 ); |
472 | b.high |= LIT64( 0x0000800000000000 ); | 501 | b.high |= LIT64( 0x0000800000000000 ); |
502 | +#endif | ||
473 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); | 503 | if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR); |
474 | if ( aIsSignalingNaN ) { | 504 | if ( aIsSignalingNaN ) { |
475 | if ( bIsSignalingNaN ) goto returnLargerSignificand; | 505 | if ( bIsSignalingNaN ) goto returnLargerSignificand; |
@@ -485,8 +515,6 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) | @@ -485,8 +515,6 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) | ||
485 | else { | 515 | else { |
486 | return b; | 516 | return b; |
487 | } | 517 | } |
488 | - | ||
489 | } | 518 | } |
490 | 519 | ||
491 | #endif | 520 | #endif |
492 | - |