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,6 +144,9 @@ static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM) | ||
144 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; | 144 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
145 | bits32 av, bv, res; | 145 | bits32 av, bv, res; |
146 | 146 | ||
147 | + if ( STATUS(default_nan_mode) ) | ||
148 | + return float32_default_nan; | ||
149 | + | ||
147 | aIsNaN = float32_is_nan( a ); | 150 | aIsNaN = float32_is_nan( a ); |
148 | aIsSignalingNaN = float32_is_signaling_nan( a ); | 151 | aIsSignalingNaN = float32_is_signaling_nan( a ); |
149 | bIsNaN = float32_is_nan( b ); | 152 | bIsNaN = float32_is_nan( b ); |
@@ -276,6 +279,9 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | @@ -276,6 +279,9 @@ static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM) | ||
276 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; | 279 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; |
277 | bits64 av, bv, res; | 280 | bits64 av, bv, res; |
278 | 281 | ||
282 | + if ( STATUS(default_nan_mode) ) | ||
283 | + return float64_default_nan; | ||
284 | + | ||
279 | aIsNaN = float64_is_nan( a ); | 285 | aIsNaN = float64_is_nan( a ); |
280 | aIsSignalingNaN = float64_is_signaling_nan( a ); | 286 | aIsSignalingNaN = float64_is_signaling_nan( a ); |
281 | bIsNaN = float64_is_nan( b ); | 287 | bIsNaN = float64_is_nan( b ); |
@@ -412,6 +418,12 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | @@ -412,6 +418,12 @@ static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM) | ||
412 | { | 418 | { |
413 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; | 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 | aIsNaN = floatx80_is_nan( a ); | 427 | aIsNaN = floatx80_is_nan( a ); |
416 | aIsSignalingNaN = floatx80_is_signaling_nan( a ); | 428 | aIsSignalingNaN = floatx80_is_signaling_nan( a ); |
417 | bIsNaN = floatx80_is_nan( b ); | 429 | bIsNaN = floatx80_is_nan( b ); |
@@ -532,6 +544,12 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) | @@ -532,6 +544,12 @@ static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM) | ||
532 | { | 544 | { |
533 | flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN; | 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 | aIsNaN = float128_is_nan( a ); | 553 | aIsNaN = float128_is_nan( a ); |
536 | aIsSignalingNaN = float128_is_signaling_nan( a ); | 554 | aIsSignalingNaN = float128_is_signaling_nan( a ); |
537 | bIsNaN = float128_is_nan( b ); | 555 | bIsNaN = float128_is_nan( b ); |
fpu/softfloat.h
@@ -190,10 +190,15 @@ typedef struct float_status { | @@ -190,10 +190,15 @@ typedef struct float_status { | ||
190 | #ifdef FLOATX80 | 190 | #ifdef FLOATX80 |
191 | signed char floatx80_rounding_precision; | 191 | signed char floatx80_rounding_precision; |
192 | #endif | 192 | #endif |
193 | + flag default_nan_mode; | ||
193 | } float_status; | 194 | } float_status; |
194 | 195 | ||
195 | void set_float_rounding_mode(int val STATUS_PARAM); | 196 | void set_float_rounding_mode(int val STATUS_PARAM); |
196 | void set_float_exception_flags(int val STATUS_PARAM); | 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 | INLINE int get_float_exception_flags(float_status *status) | 202 | INLINE int get_float_exception_flags(float_status *status) |
198 | { | 203 | { |
199 | return STATUS(float_exception_flags); | 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,6 +2334,8 @@ void HELPER(vfp_set_fpscr)(CPUState *env, uint32_t val) | ||
2334 | } | 2334 | } |
2335 | set_float_rounding_mode(i, &env->vfp.fp_status); | 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 | i = vfp_exceptbits_to_host((val >> 8) & 0x1f); | 2340 | i = vfp_exceptbits_to_host((val >> 8) & 0x1f); |
2339 | set_float_exception_flags(i, &env->vfp.fp_status); | 2341 | set_float_exception_flags(i, &env->vfp.fp_status); |