aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2025-02-24 11:15:17 +0000
committerPeter Maydell <peter.maydell@linaro.org>2025-02-25 15:32:57 +0000
commit44eb32a9835fe2feb19503e93476eee602daee0b (patch)
tree6615fb3fc6eef6579ccb25afed9df78d149620d0
parent9ea6d1f141426a7da91f1c7ba3d693472f0550a4 (diff)
downloadqemu-44eb32a9835fe2feb19503e93476eee602daee0b.zip
qemu-44eb32a9835fe2feb19503e93476eee602daee0b.tar.gz
qemu-44eb32a9835fe2feb19503e93476eee602daee0b.tar.bz2
fpu: Make targets specify whether floatx80 Inf can have Int bit clear
In Intel terminology, a floatx80 Infinity with the explicit integer bit clear is a "pseudo-infinity"; for x86 these are not valid infinity values. m68k is looser and does not care whether the Integer bit is set or clear in an infinity. Move this setting to runtime rather than using an ifdef in floatx80_is_infinity(). Since this was the last use of the floatx80_infinity global constant, we remove it and its definition here. 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-6-peter.maydell@linaro.org Message-id: 20250217125055.160887-5-peter.maydell@linaro.org
-rw-r--r--fpu/softfloat-specialize.c.inc10
-rw-r--r--include/fpu/softfloat-types.h5
-rw-r--r--include/fpu/softfloat.h18
-rw-r--r--target/m68k/cpu.c4
4 files changed, 19 insertions, 18 deletions
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index 73789e9..8327f72 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -237,16 +237,6 @@ floatx80 floatx80_default_inf(bool zSign, float_status *status)
return packFloatx80(zSign, 0x7fff, z ? 0 : (1ULL << 63));
}
-#define floatx80_infinity_high 0x7FFF
-#if defined(TARGET_M68K)
-#define floatx80_infinity_low UINT64_C(0x0000000000000000)
-#else
-#define floatx80_infinity_low UINT64_C(0x8000000000000000)
-#endif
-
-const floatx80 floatx80_infinity
- = make_floatx80_init(floatx80_infinity_high, floatx80_infinity_low);
-
/*----------------------------------------------------------------------------
| Returns 1 if the half-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index dd22ecd..e1732be 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -330,6 +330,11 @@ typedef enum __attribute__((__packed__)) {
typedef enum __attribute__((__packed__)) {
/* In the default Infinity value, is the Integer bit 0 ? */
floatx80_default_inf_int_bit_is_zero = 1,
+ /*
+ * Are Pseudo-infinities (Inf with the Integer bit zero) valid?
+ * If so, floatx80_is_infinity() will return true for them.
+ */
+ floatx80_pseudo_inf_valid = 2,
} FloatX80Behaviour;
/*
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 3c83d70..07259c5 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -960,7 +960,6 @@ float128 floatx80_to_float128(floatx80, float_status *status);
/*----------------------------------------------------------------------------
| The pattern for an extended double-precision inf.
*----------------------------------------------------------------------------*/
-extern const floatx80 floatx80_infinity;
floatx80 floatx80_default_inf(bool zSign, float_status *status);
/*----------------------------------------------------------------------------
@@ -998,12 +997,17 @@ static inline floatx80 floatx80_chs(floatx80 a)
static inline bool floatx80_is_infinity(floatx80 a, float_status *status)
{
-#if defined(TARGET_M68K)
- return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1);
-#else
- return (a.high & 0x7fff) == floatx80_infinity.high &&
- a.low == floatx80_infinity.low;
-#endif
+ /*
+ * It's target-specific whether the Integer bit is permitted
+ * to be 0 in a valid Infinity value. (x86 says no, m68k says yes).
+ */
+ bool intbit = a.low >> 63;
+
+ if (!intbit &&
+ !(status->floatx80_behaviour & floatx80_pseudo_inf_valid)) {
+ return false;
+ }
+ return (a.high & 0x7fff) == 0x7fff && !(a.low << 1);
}
static inline bool floatx80_is_neg(floatx80 a)
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index df66e8b..56b23de 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -110,8 +110,10 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
/*
* m68k-specific floatx80 behaviour:
* * default Infinity values have a zero Integer bit
+ * * input Infinities may have the Integer bit either 0 or 1
*/
- set_floatx80_behaviour(floatx80_default_inf_int_bit_is_zero,
+ set_floatx80_behaviour(floatx80_default_inf_int_bit_is_zero |
+ floatx80_pseudo_inf_valid,
&env->fp_status);
nan = floatx80_default_nan(&env->fp_status);