Hi Peter,

On 17/2/25 13:50, Peter Maydell wrote:

(1) floatx80 behaviours

Two QEMU targets implement floatx80: x86 and m68k. (PPC also has one
use in the xsrqpxp round-to-80-bit-precision operation, and the
Linux-user NWFPE emulation nominally supports it, but these are
minor.) x86 and m68k disagree about some of the corner cases of
floatx80 where the value has the explicit Integer bit wrongly set.  At
the moment the fpu code defaults to "floatx80 behaves like x86", with
TARGET_M68K ifdefs to get the other option.

The first six patches in this series remove those ifdefs, replacing
them with a floatx80_behaviour field in float_status which can have
various flags set to select the individual behaviours. The default is
"like x86", which allows us to set these only for m68k and not worry
about the minor "technically makes some use of floatx80" cases.


Peter Maydell (10):
   fpu: Make targets specify floatx80 default Inf at runtime
   target/m68k: Avoid using floatx80_infinity global const
   target/i386: Avoid using floatx80_infinity global const

Could you add a preparatory patch passing float_status argument
here? This eases the following patch review.

-- >8 --
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index afae3906024..3c83d703baf 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -999 +999 @@ static inline floatx80 floatx80_chs(floatx80 a)
-static inline bool floatx80_is_infinity(floatx80 a)
+static inline bool floatx80_is_infinity(floatx80 a, float_status *status)
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 741af09f908..3b79bc049d1 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -1395,3 +1395,4 @@ void helper_fpatan(CPUX86State *env)
         /* Pass this zero through.  */
- } else if (((floatx80_is_infinity(ST0) && !floatx80_is_infinity(ST1)) ||
+    } else if (((floatx80_is_infinity(ST0, &env->fp_status) &&
+                 !floatx80_is_infinity(ST1, &env->fp_status)) ||
                  arg0_exp - arg1_exp >= 80) &&
@@ -1444,4 +1445,4 @@ void helper_fpatan(CPUX86State *env)
             rsig1 = pi_sig_low;
-        } else if (floatx80_is_infinity(ST1)) {
-            if (floatx80_is_infinity(ST0)) {
+        } else if (floatx80_is_infinity(ST1, &env->fp_status)) {
+            if (floatx80_is_infinity(ST0, &env->fp_status)) {
                 if (arg0_sign) {
@@ -1464,3 +1465,4 @@ void helper_fpatan(CPUX86State *env)
             rsig1 = pi_2_sig_low;
- } else if (floatx80_is_infinity(ST0) || arg0_exp - arg1_exp >= 80) {
+        } else if (floatx80_is_infinity(ST0, &env->fp_status) ||
+                   arg0_exp - arg1_exp >= 80) {
             /* ST0 is negative.  */
@@ -1831,3 +1833,3 @@ void helper_fxtract(CPUX86State *env)
         ST0 = ST1;
-    } else if (floatx80_is_infinity(ST0)) {
+    } else if (floatx80_is_infinity(ST0, &env->fp_status)) {
         fpush(env);
@@ -2175,3 +2177,3 @@ void helper_fyl2x(CPUX86State *env)
         ST1 = floatx80_default_nan(&env->fp_status);
-    } else if (floatx80_is_infinity(ST1)) {
+    } else if (floatx80_is_infinity(ST1, &env->fp_status)) {
         FloatRelation cmp = floatx80_compare(ST0, floatx80_one,
@@ -2190,3 +2192,3 @@ void helper_fyl2x(CPUX86State *env)
         }
-    } else if (floatx80_is_infinity(ST0)) {
+    } else if (floatx80_is_infinity(ST0, &env->fp_status)) {
         if (floatx80_is_zero(ST1)) {
@@ -2343,3 +2345,3 @@ void helper_fscale(CPUX86State *env)
         }
-    } else if (floatx80_is_infinity(ST1) &&
+    } else if (floatx80_is_infinity(ST1, &env->fp_status) &&
                !floatx80_invalid_encoding(ST0) &&
@@ -2347,3 +2349,3 @@ void helper_fscale(CPUX86State *env)
         if (floatx80_is_neg(ST1)) {
-            if (floatx80_is_infinity(ST0)) {
+            if (floatx80_is_infinity(ST0, &env->fp_status)) {
                 float_raise(float_flag_invalid, &env->fp_status);
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 339b73ad7dc..eb1cb8c6872 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -458 +458 @@ void HELPER(ftst)(CPUM68KState *env, FPReg *val)
-    } else if (floatx80_is_infinity(val->d)) {
+    } else if (floatx80_is_infinity(val->d, &env->fp_status)) {
---

   fpu: Make targets specify whether floatx80 Inf can have Int bit clear

Ditto here:

-- >8 --
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 07259c59303..1c8f3cbb78d 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -1084 +1084 @@ static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b,
-static inline bool floatx80_invalid_encoding(floatx80 a)
+static inline bool floatx80_invalid_encoding(floatx80 a, float_status *s)
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index b12ad2b42a9..2a20ae871eb 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1813 +1813 @@ static bool floatx80_unpack_canonical(FloatParts128 *p, floatx80 f,
-    if (unlikely(floatx80_invalid_encoding(f))) {
+    if (unlikely(floatx80_invalid_encoding(f, s))) {
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 3b79bc049d1..4858ae9a5fb 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -1143,3 +1143,3 @@ void helper_f2xm1(CPUX86State *env)

-    if (floatx80_invalid_encoding(ST0)) {
+    if (floatx80_invalid_encoding(ST0, &env->fp_status)) {
         float_raise(float_flag_invalid, &env->fp_status);
@@ -1385,4 +1385,4 @@ void helper_fpatan(CPUX86State *env)
         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);
@@ -1821,3 +1821,3 @@ void helper_fxtract(CPUX86State *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);
@@ -1872,3 +1872,4 @@ static void helper_fprem_common(CPUX86State *env, bool mod)
         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, &quotient, &env->fp_status);
@@ -2068,4 +2069,4 @@ void helper_fyl2xp1(CPUX86State *env)
         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);
@@ -2166,4 +2167,4 @@ void helper_fyl2x(CPUX86State *env)
         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);
@@ -2333,3 +2334,4 @@ 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);
@@ -2346,3 +2348,3 @@ void helper_fscale(CPUX86State *env)
     } 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)) {
---

   fpu: Make floatx80 invalid encoding settable at runtime
   fpu: Move m68k_denormal fmt flag into floatx80_behaviour
   fpu: Always decide no_signaling_nans() at runtime
   fpu: Always decide snan_bit_is_one() at runtime
   fpu: Don't compile-time disable hardfloat for PPC targets
   fpu: Build only once

Thanks,

Phil.

Reply via email to