Commit 5c7908ed23256a6c1aababa8d3b7515db76a590c
1 parent
a49ea279
Implement default-NaN mode.
Signed-off-by: Paul Brook <paul@codesourcery.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6106 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
25 additions
and
0 deletions
fpu/softfloat-specialize.h
| ... | ... | @@ -144,6 +144,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) |
| 144 | 144 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
| 145 | 145 | bits32 av, bv, res; |
| 146 | 146 | |
| 147 | + if ( STATUS(default_nan_mode) ) | |
| 148 | + return float32_default_nan; | |
| 149 | + | |
| 147 | 150 | aIsNaN = float32_is_nan( a ); |
| 148 | 151 | aIsSignalingNaN = float32_is_signaling_nan( a ); |
| 149 | 152 | bIsNaN = float32_is_nan( b ); |
| ... | ... | @@ -276,6 +279,9 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) |
| 276 | 279 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
| 277 | 280 | bits64 av, bv, res; |
| 278 | 281 | |
| 282 | + if ( STATUS(default_nan_mode) ) | |
| 283 | + return float64_default_nan; | |
| 284 | + | |
| 279 | 285 | aIsNaN = float64_is_nan( a ); |
| 280 | 286 | aIsSignalingNaN = float64_is_signaling_nan( a ); |
| 281 | 287 | bIsNaN = float64_is_nan( b ); |
| ... | ... | @@ -412,6 +418,12 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) |
| 412 | 418 | { |
| 413 | 419 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
| 414 | 420 | |
| 421 | + if ( STATUS(default_nan_mode) ) { | |
| 422 | + a.low = floatx80_default_nan_low; | |
| 423 | + a.high = floatx80_default_nan_high; | |
| 424 | + return a; | |
| 425 | + } | |
| 426 | + | |
| 415 | 427 | aIsNaN = floatx80_is_nan( a ); |
| 416 | 428 | aIsSignalingNaN = floatx80_is_signaling_nan( a ); |
| 417 | 429 | bIsNaN = floatx80_is_nan( b ); |
| ... | ... | @@ -532,6 +544,12 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) |
| 532 | 544 | { |
| 533 | 545 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
| 534 | 546 | |
| 547 | + if ( STATUS(default_nan_mode) ) { | |
| 548 | + a.low = float128_default_nan_low; | |
| 549 | + a.high = float128_default_nan_high; | |
| 550 | + return a; | |
| 551 | + } | |
| 552 | + | |
| 535 | 553 | aIsNaN = float128_is_nan( a ); |
| 536 | 554 | aIsSignalingNaN = float128_is_signaling_nan( a ); |
| 537 | 555 | bIsNaN = float128_is_nan( b ); | ... | ... |
fpu/softfloat.h
| ... | ... | @@ -190,10 +190,15 @@ typedef struct float_status { |
| 190 | 190 | #ifdef FLOATX80 |
| 191 | 191 | signed char floatx80_rounding_precision; |
| 192 | 192 | #endif |
| 193 | + flag default_nan_mode; | |
| 193 | 194 | } float_status; |
| 194 | 195 | |
| 195 | 196 | void set_float_rounding_mode(int val STATUS_PARAM); |
| 196 | 197 | void set_float_exception_flags(int val STATUS_PARAM); |
| 198 | +INLINE void set_default_nan_mode(flag val STATUS_PARAM) | |
| 199 | +{ | |
| 200 | + STATUS(default_nan_mode) = val; | |
| 201 | +} | |
| 197 | 202 | INLINE int get_float_exception_flags(float_status *status) |
| 198 | 203 | { |
| 199 | 204 | return STATUS(float_exception_flags); | ... | ... |
target-arm/helper.c
| ... | ... | @@ -2334,6 +2334,8 @@ void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val) |
| 2334 | 2334 | } |
| 2335 | 2335 | set_float_rounding_mode(i, &env->vfp.fp_status); |
| 2336 | 2336 | } |
| 2337 | + if (changed & (1 << 25)) | |
| 2338 | + set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status); | |
| 2337 | 2339 | |
| 2338 | 2340 | i = vfp_exceptbits_to_host((val >> 8) & 0x1f); |
| 2339 | 2341 | set_float_exception_flags(i, &env->vfp.fp_status); | ... | ... |