diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2025-02-24 11:15:18 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2025-02-25 15:32:57 +0000 |
commit | 765fe845ccb953b77b1b7e0557b13a7b760067b0 (patch) | |
tree | 073372bc44357cf852f1d5d896ed52ad72f5ae83 | |
parent | 44eb32a9835fe2feb19503e93476eee602daee0b (diff) | |
download | qemu-765fe845ccb953b77b1b7e0557b13a7b760067b0.zip qemu-765fe845ccb953b77b1b7e0557b13a7b760067b0.tar.gz qemu-765fe845ccb953b77b1b7e0557b13a7b760067b0.tar.bz2 |
fpu: Pass float_status to floatx80_invalid_encoding()
The definition of which floatx80 encodings are invalid is
target-specific. Currently we handle this with an ifdef, but we
would like to defer this decision to runtime. In preparation, pass a
float_status argument to floatx80_invalid_encoding().
We will change the implementation from ifdef to looking at
the status argument in the following commit.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20250224111524.1101196-7-peter.maydell@linaro.org
-rw-r--r-- | fpu/softfloat.c | 2 | ||||
-rw-r--r-- | include/fpu/softfloat.h | 2 | ||||
-rw-r--r-- | target/i386/tcg/fpu_helper.c | 24 |
3 files changed, 15 insertions, 13 deletions
diff --git a/fpu/softfloat.c b/fpu/softfloat.c index b12ad2b..2a20ae8 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1810,7 +1810,7 @@ static bool floatx80_unpack_canonical(FloatParts128 *p, floatx80 f, g_assert_not_reached(); } - if (unlikely(floatx80_invalid_encoding(f))) { + if (unlikely(floatx80_invalid_encoding(f, s))) { float_raise(float_flag_invalid, s); return false; } diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 07259c5..1c8f3cb 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -1081,7 +1081,7 @@ static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b, | pseudo-denormals, which must still be correctly handled as inputs even | if they are never generated as outputs. *----------------------------------------------------------------------------*/ -static inline bool floatx80_invalid_encoding(floatx80 a) +static inline bool floatx80_invalid_encoding(floatx80 a, float_status *s) { #if defined(TARGET_M68K) /*------------------------------------------------------------------------- diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c index 3b79bc0..4858ae9 100644 --- a/target/i386/tcg/fpu_helper.c +++ b/target/i386/tcg/fpu_helper.c @@ -1141,7 +1141,7 @@ void helper_f2xm1(CPUX86State *env) int32_t exp = extractFloatx80Exp(ST0); bool sign = extractFloatx80Sign(ST0); - if (floatx80_invalid_encoding(ST0)) { + if (floatx80_invalid_encoding(ST0, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST0 = floatx80_default_nan(&env->fp_status); } else if (floatx80_is_any_nan(ST0)) { @@ -1383,8 +1383,8 @@ void helper_fpatan(CPUX86State *env) } else if (floatx80_is_signaling_nan(ST1, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST1 = floatx80_silence_nan(ST1, &env->fp_status); - } else if (floatx80_invalid_encoding(ST0) || - floatx80_invalid_encoding(ST1)) { + } else if (floatx80_invalid_encoding(ST0, &env->fp_status) || + floatx80_invalid_encoding(ST1, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST1 = floatx80_default_nan(&env->fp_status); } else if (floatx80_is_any_nan(ST0)) { @@ -1819,7 +1819,7 @@ void helper_fxtract(CPUX86State *env) &env->fp_status); fpush(env); ST0 = temp.d; - } else if (floatx80_invalid_encoding(ST0)) { + } else if (floatx80_invalid_encoding(ST0, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST0 = floatx80_default_nan(&env->fp_status); fpush(env); @@ -1870,7 +1870,8 @@ static void helper_fprem_common(CPUX86State *env, bool mod) env->fpus &= ~0x4700; /* (C3,C2,C1,C0) <-- 0000 */ if (floatx80_is_zero(ST0) || floatx80_is_zero(ST1) || exp0 == 0x7fff || exp1 == 0x7fff || - floatx80_invalid_encoding(ST0) || floatx80_invalid_encoding(ST1)) { + floatx80_invalid_encoding(ST0, &env->fp_status) || + floatx80_invalid_encoding(ST1, &env->fp_status)) { ST0 = floatx80_modrem(ST0, ST1, mod, "ient, &env->fp_status); } else { if (exp0 == 0) { @@ -2066,8 +2067,8 @@ void helper_fyl2xp1(CPUX86State *env) } else if (floatx80_is_signaling_nan(ST1, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST1 = floatx80_silence_nan(ST1, &env->fp_status); - } else if (floatx80_invalid_encoding(ST0) || - floatx80_invalid_encoding(ST1)) { + } else if (floatx80_invalid_encoding(ST0, &env->fp_status) || + floatx80_invalid_encoding(ST1, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST1 = floatx80_default_nan(&env->fp_status); } else if (floatx80_is_any_nan(ST0)) { @@ -2164,8 +2165,8 @@ void helper_fyl2x(CPUX86State *env) } else if (floatx80_is_signaling_nan(ST1, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST1 = floatx80_silence_nan(ST1, &env->fp_status); - } else if (floatx80_invalid_encoding(ST0) || - floatx80_invalid_encoding(ST1)) { + } else if (floatx80_invalid_encoding(ST0, &env->fp_status) || + floatx80_invalid_encoding(ST1, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST1 = floatx80_default_nan(&env->fp_status); } else if (floatx80_is_any_nan(ST0)) { @@ -2331,7 +2332,8 @@ void helper_frndint(CPUX86State *env) void helper_fscale(CPUX86State *env) { uint8_t old_flags = save_exception_flags(env); - if (floatx80_invalid_encoding(ST1) || floatx80_invalid_encoding(ST0)) { + if (floatx80_invalid_encoding(ST1, &env->fp_status) || + floatx80_invalid_encoding(ST0, &env->fp_status)) { float_raise(float_flag_invalid, &env->fp_status); ST0 = floatx80_default_nan(&env->fp_status); } else if (floatx80_is_any_nan(ST1)) { @@ -2344,7 +2346,7 @@ void helper_fscale(CPUX86State *env) ST0 = floatx80_silence_nan(ST0, &env->fp_status); } } else if (floatx80_is_infinity(ST1, &env->fp_status) && - !floatx80_invalid_encoding(ST0) && + !floatx80_invalid_encoding(ST0, &env->fp_status) && !floatx80_is_any_nan(ST0)) { if (floatx80_is_neg(ST1)) { if (floatx80_is_infinity(ST0, &env->fp_status)) { |