s390x/tcg: Fix FP CONVERT TO (LOGICAL) FIXED NaN handling
In case we encounter a NaN, we have to return the smallest possible number, corresponding to either 0 or the maximum negative number. This seems to differ from IEEE handling as implemented in softfloat, whereby we return the biggest possible number. While at it, use float32_to_uint64() in the CLGEB handler. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Hildenbrand <david@redhat.com> Message-Id: <20210608092337.12221-2-david@redhat.com> Signed-off-by: Cornelia Huck <cohuck@redhat.com>
This commit is contained in:
parent
3fb3b122ac
commit
0a3be7be73
@ -509,6 +509,9 @@ uint64_t HELPER(cgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float32_is_any_nan(v2)) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -520,6 +523,9 @@ uint64_t HELPER(cgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float64_is_any_nan(v2)) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -532,6 +538,9 @@ uint64_t HELPER(cgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float128_is_any_nan(v2)) {
|
||||
return INT64_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -543,6 +552,9 @@ uint64_t HELPER(cfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float32_is_any_nan(v2)) {
|
||||
return INT32_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -554,6 +566,9 @@ uint64_t HELPER(cfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float64_is_any_nan(v2)) {
|
||||
return INT32_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -566,6 +581,9 @@ uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float128_is_any_nan(v2)) {
|
||||
return INT32_MIN;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -573,12 +591,12 @@ uint64_t HELPER(cfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
uint64_t HELPER(clgeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
{
|
||||
int old_mode = s390_swap_bfp_rounding_mode(env, round_from_m34(m34));
|
||||
uint64_t ret;
|
||||
|
||||
v2 = float32_to_float64(v2, &env->fpu_status);
|
||||
ret = float64_to_uint64(v2, &env->fpu_status);
|
||||
uint64_t ret = float32_to_uint64(v2, &env->fpu_status);
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float32_is_any_nan(v2)) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -590,6 +608,9 @@ uint64_t HELPER(clgdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float64_is_any_nan(v2)) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -601,6 +622,9 @@ uint64_t HELPER(clgxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float128_is_any_nan(make_float128(h, l))) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -612,6 +636,9 @@ uint64_t HELPER(clfeb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float32_is_any_nan(v2)) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -623,6 +650,9 @@ uint64_t HELPER(clfdb)(CPUS390XState *env, uint64_t v2, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float64_is_any_nan(v2)) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -634,6 +664,9 @@ uint64_t HELPER(clfxb)(CPUS390XState *env, uint64_t h, uint64_t l, uint32_t m34)
|
||||
|
||||
s390_restore_bfp_rounding_mode(env, old_mode);
|
||||
handle_exceptions(env, xxc_from_m34(m34), GETPC());
|
||||
if (float128_is_any_nan(make_float128(h, l))) {
|
||||
return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -326,7 +326,9 @@ void HELPER(gvec_vcdlg64s)(void *v1, const void *v2, CPUS390XState *env,
|
||||
|
||||
static uint64_t vcgd64(uint64_t a, float_status *s)
|
||||
{
|
||||
return float64_to_int64(a, s);
|
||||
const uint64_t tmp = float64_to_int64(a, s);
|
||||
|
||||
return float64_is_any_nan(a) ? INT64_MIN : tmp;
|
||||
}
|
||||
|
||||
void HELPER(gvec_vcgd64)(void *v1, const void *v2, CPUS390XState *env,
|
||||
@ -349,7 +351,9 @@ void HELPER(gvec_vcgd64s)(void *v1, const void *v2, CPUS390XState *env,
|
||||
|
||||
static uint64_t vclgd64(uint64_t a, float_status *s)
|
||||
{
|
||||
return float64_to_uint64(a, s);
|
||||
const uint64_t tmp = float64_to_uint64(a, s);
|
||||
|
||||
return float64_is_any_nan(a) ? 0 : tmp;
|
||||
}
|
||||
|
||||
void HELPER(gvec_vclgd64)(void *v1, const void *v2, CPUS390XState *env,
|
||||
|
Loading…
Reference in New Issue
Block a user