qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] softfloat: Improve denormal handling
@ 2021-05-27  4:13 Richard Henderson
  2021-05-27  4:13 ` [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal Richard Henderson
                   ` (11 more replies)
  0 siblings, 12 replies; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell

This attempts to fix the x86 denormal-exception flag, which is the
inverse of the existing float_flag_input_denormal flag.  I have not
created a new test case for this yet, fwiw.

While auditing all uses of float_flag_*_denormal, I found some errors
in target/rx and target/mips.

This is based on my current softfloat conversion for floatx80:
Based-on: <20210525150706.294968-1-richard.henderson@linaro.org>

The complete tree may be found at
https://gitlab.com/rth7680/qemu/-/commits/fpu-test-5


r~


Richard Henderson (11):
  softfloat: Rename float_flag_input_denormal to
    float_flag_iflush_denormal
  softfloat: Rename float_flag_output_denormal to
    float_flag_oflush_denormal
  softfloat: Introduce float_flag_inorm_denormal
  softfloat: Introduce float_flag_result_denormal
  target/i386: Use float_flag_inorm_denormal
  target/rx: Handle the FPSW.DN bit in helper_set_fpsw
  target/rx: Use FloatRoundMode in helper_set_fpsw
  target/rx: Fix setting of FPSW.CE
  target/mips: Drop inline markers from msa_helper.c
  target/mips: Do not check MSACSR_FS_MASK in update_msacsr
  target/mips: Drop denormal operand to update_msacsr

 include/fpu/softfloat-types.h |  18 +-
 fpu/softfloat.c               |  88 ++++------
 target/arm/sve_helper.c       |   6 +-
 target/arm/vfp_helper.c       |  12 +-
 target/i386/tcg/fpu_helper.c  |  18 +-
 target/mips/tcg/msa_helper.c  | 298 +++++++++++++++-------------------
 target/rx/op_helper.c         |  19 ++-
 target/tricore/fpu_helper.c   |   6 +-
 fpu/softfloat-parts.c.inc     |  13 +-
 9 files changed, 212 insertions(+), 266 deletions(-)

-- 
2.25.1



^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
@ 2021-05-27  4:13 ` Richard Henderson
  2021-06-07 15:16   ` Alex Bennée
  2021-06-19 15:08   ` Philippe Mathieu-Daudé
  2021-05-27  4:13 ` [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal Richard Henderson
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell

The new name emphasizes that the input denormal has been flushed to zero.

Patch created mechanically using:
  sed -i s,float_flag_input_denormal,float_flag_iflush_denormal,g \
    $(git grep -l float_flag_input_denormal)

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h |  2 +-
 fpu/softfloat.c               |  4 ++--
 target/arm/sve_helper.c       |  6 +++---
 target/arm/vfp_helper.c       | 10 +++++-----
 target/i386/tcg/fpu_helper.c  |  6 +++---
 target/mips/tcg/msa_helper.c  |  2 +-
 target/rx/op_helper.c         |  2 +-
 fpu/softfloat-parts.c.inc     |  2 +-
 8 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 1f83378c20..719b4d2531 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -148,7 +148,7 @@ enum {
     float_flag_overflow  =  8,
     float_flag_underflow = 16,
     float_flag_inexact   = 32,
-    float_flag_input_denormal = 64,
+    float_flag_iflush_denormal = 64,
     float_flag_output_denormal = 128
 };
 
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 79b2205070..fa3a691a5a 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -132,7 +132,7 @@ this code that are retained.
         if (unlikely(soft_t ## _is_denormal(*a))) {                     \
             *a = soft_t ## _set_sign(soft_t ## _zero,                   \
                                      soft_t ## _is_neg(*a));            \
-            float_raise(float_flag_input_denormal, s);                  \
+            float_raise(float_flag_iflush_denormal, s);                  \
         }                                                               \
     }
 
@@ -4441,7 +4441,7 @@ float128 float128_silence_nan(float128 a, float_status *status)
 static bool parts_squash_denormal(FloatParts64 p, float_status *status)
 {
     if (p.exp == 0 && p.frac != 0) {
-        float_raise(float_flag_input_denormal, status);
+        float_raise(float_flag_iflush_denormal, status);
         return true;
     }
 
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 40af3024df..16b055a34f 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -4774,7 +4774,7 @@ static int16_t do_float16_logb_as_int(float16 a, float_status *s)
                 return -15 - clz32(frac);
             }
             /* flush to zero */
-            float_raise(float_flag_input_denormal, s);
+            float_raise(float_flag_iflush_denormal, s);
         }
     } else if (unlikely(exp == 0x1f)) {
         if (frac == 0) {
@@ -4802,7 +4802,7 @@ static int32_t do_float32_logb_as_int(float32 a, float_status *s)
                 return -127 - clz32(frac);
             }
             /* flush to zero */
-            float_raise(float_flag_input_denormal, s);
+            float_raise(float_flag_iflush_denormal, s);
         }
     } else if (unlikely(exp == 0xff)) {
         if (frac == 0) {
@@ -4830,7 +4830,7 @@ static int64_t do_float64_logb_as_int(float64 a, float_status *s)
                 return -1023 - clz64(frac);
             }
             /* flush to zero */
-            float_raise(float_flag_input_denormal, s);
+            float_raise(float_flag_iflush_denormal, s);
         }
     } else if (unlikely(exp == 0x7ff)) {
         if (frac == 0) {
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index 01b9d8557f..0a43ccc6fa 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -52,7 +52,7 @@ static inline int vfp_exceptbits_from_host(int host_bits)
     if (host_bits & float_flag_inexact) {
         target_bits |= 0x10;
     }
-    if (host_bits & float_flag_input_denormal) {
+    if (host_bits & float_flag_iflush_denormal) {
         target_bits |= 0x80;
     }
     return target_bits;
@@ -79,7 +79,7 @@ static inline int vfp_exceptbits_to_host(int target_bits)
         host_bits |= float_flag_inexact;
     }
     if (target_bits & 0x80) {
-        host_bits |= float_flag_input_denormal;
+        host_bits |= float_flag_iflush_denormal;
     }
     return host_bits;
 }
@@ -92,9 +92,9 @@ static uint32_t vfp_get_fpscr_from_host(CPUARMState *env)
     i |= get_float_exception_flags(&env->vfp.standard_fp_status);
     /* FZ16 does not generate an input denormal exception.  */
     i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
-          & ~float_flag_input_denormal);
+          & ~float_flag_iflush_denormal);
     i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16)
-          & ~float_flag_input_denormal);
+          & ~float_flag_iflush_denormal);
     return vfp_exceptbits_from_host(i);
 }
 
@@ -1124,7 +1124,7 @@ uint64_t HELPER(fjcvtzs)(float64 value, void *vstatus)
         inexact = sign;
         if (frac != 0) {
             if (status->flush_inputs_to_zero) {
-                float_raise(float_flag_input_denormal, status);
+                float_raise(float_flag_iflush_denormal, status);
             } else {
                 float_raise(float_flag_inexact, status);
                 inexact = 1;
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 4e11965067..c402daf659 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -148,7 +148,7 @@ static void merge_exception_flags(CPUX86State *env, uint8_t old_flags)
                        (new_flags & float_flag_overflow ? FPUS_OE : 0) |
                        (new_flags & float_flag_underflow ? FPUS_UE : 0) |
                        (new_flags & float_flag_inexact ? FPUS_PE : 0) |
-                       (new_flags & float_flag_input_denormal ? FPUS_DE : 0)));
+                       (new_flags & float_flag_iflush_denormal ? FPUS_DE : 0)));
 }
 
 static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b)
@@ -1742,7 +1742,7 @@ void helper_fxtract(CPUX86State *env)
             int shift = clz64(temp.l.lower);
             temp.l.lower <<= shift;
             expdif = 1 - EXPBIAS - shift;
-            float_raise(float_flag_input_denormal, &env->fp_status);
+            float_raise(float_flag_iflush_denormal, &env->fp_status);
         } else {
             expdif = EXPD(temp) - EXPBIAS;
         }
@@ -2991,7 +2991,7 @@ void update_mxcsr_from_sse_status(CPUX86State *env)
     uint8_t flags = get_float_exception_flags(&env->sse_status);
     /*
      * The MXCSR denormal flag has opposite semantics to
-     * float_flag_input_denormal (the softfloat code sets that flag
+     * float_flag_iflush_denormal (the softfloat code sets that flag
      * only when flushing input denormals to zero, but SSE sets it
      * only when not flushing them to zero), so is not converted
      * here.
diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index 04af54f66d..992d348aa3 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -6230,7 +6230,7 @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
     enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
 
     /* Set Inexact (I) when flushing inputs to zero */
-    if ((ieee_exception_flags & float_flag_input_denormal) &&
+    if ((ieee_exception_flags & float_flag_iflush_denormal) &&
             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
         if (action & CLEAR_IS_INEXACT) {
             mips_exception_flags &= ~FP_INEXACT;
diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
index 4d315b4449..eb2c4a41fb 100644
--- a/target/rx/op_helper.c
+++ b/target/rx/op_helper.c
@@ -97,7 +97,7 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
         if (xcpt & float_flag_inexact) {
             SET_FPSW(X);
         }
-        if ((xcpt & (float_flag_input_denormal
+        if ((xcpt & (float_flag_iflush_denormal
                      | float_flag_output_denormal))
             && !FIELD_EX32(env->fpsw, FPSW, DN)) {
             env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1);
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 801aa86ff9..be29ba0aa3 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -112,7 +112,7 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
         if (likely(frac_eqz(p))) {
             p->cls = float_class_zero;
         } else if (status->flush_inputs_to_zero) {
-            float_raise(float_flag_input_denormal, status);
+            float_raise(float_flag_iflush_denormal, status);
             p->cls = float_class_zero;
             frac_clear(p);
         } else {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
  2021-05-27  4:13 ` [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal Richard Henderson
@ 2021-05-27  4:13 ` Richard Henderson
  2021-06-07 15:16   ` Alex Bennée
  2021-06-19 15:08   ` Philippe Mathieu-Daudé
  2021-05-27  4:13 ` [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal Richard Henderson
                   ` (9 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell

The new name emphasizes that the output denormal has been flushed to zero.

Patch created mechanically using:
  sed -i s,float_flag_output_denormal,float_flag_oflush_denormal,g \
    $(git grep -l float_flag_output_denormal)

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 2 +-
 fpu/softfloat.c               | 2 +-
 target/arm/vfp_helper.c       | 2 +-
 target/i386/tcg/fpu_helper.c  | 2 +-
 target/mips/tcg/msa_helper.c  | 2 +-
 target/rx/op_helper.c         | 2 +-
 target/tricore/fpu_helper.c   | 6 +++---
 fpu/softfloat-parts.c.inc     | 2 +-
 8 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 719b4d2531..e2d70ff556 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -149,7 +149,7 @@ enum {
     float_flag_underflow = 16,
     float_flag_inexact   = 32,
     float_flag_iflush_denormal = 64,
-    float_flag_output_denormal = 128
+    float_flag_oflush_denormal = 128
 };
 
 /*
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index fa3a691a5a..cb077cf111 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -4591,7 +4591,7 @@ floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign,
         }
         if ( zExp <= 0 ) {
             if (status->flush_to_zero) {
-                float_raise(float_flag_output_denormal, status);
+                float_raise(float_flag_oflush_denormal, status);
                 return packFloatx80(zSign, 0, 0);
             }
             isTiny = status->tininess_before_rounding
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
index 0a43ccc6fa..5864553718 100644
--- a/target/arm/vfp_helper.c
+++ b/target/arm/vfp_helper.c
@@ -46,7 +46,7 @@ static inline int vfp_exceptbits_from_host(int host_bits)
     if (host_bits & float_flag_overflow) {
         target_bits |= 4;
     }
-    if (host_bits & (float_flag_underflow | float_flag_output_denormal)) {
+    if (host_bits & (float_flag_underflow | float_flag_oflush_denormal)) {
         target_bits |= 8;
     }
     if (host_bits & float_flag_inexact) {
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index c402daf659..c9779a9fe0 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -3001,7 +3001,7 @@ void update_mxcsr_from_sse_status(CPUX86State *env)
                    (flags & float_flag_overflow ? FPUS_OE : 0) |
                    (flags & float_flag_underflow ? FPUS_UE : 0) |
                    (flags & float_flag_inexact ? FPUS_PE : 0) |
-                   (flags & float_flag_output_denormal ? FPUS_UE | FPUS_PE :
+                   (flags & float_flag_oflush_denormal ? FPUS_UE | FPUS_PE :
                     0));
 }
 
diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index 992d348aa3..51791f946b 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -6240,7 +6240,7 @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
     }
 
     /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
-    if ((ieee_exception_flags & float_flag_output_denormal) &&
+    if ((ieee_exception_flags & float_flag_oflush_denormal) &&
             (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
         mips_exception_flags |= FP_INEXACT;
         if (action & CLEAR_FS_UNDERFLOW) {
diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
index eb2c4a41fb..ef904eb5f9 100644
--- a/target/rx/op_helper.c
+++ b/target/rx/op_helper.c
@@ -98,7 +98,7 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
             SET_FPSW(X);
         }
         if ((xcpt & (float_flag_iflush_denormal
-                     | float_flag_output_denormal))
+                     | float_flag_oflush_denormal))
             && !FIELD_EX32(env->fpsw, FPSW, DN)) {
             env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1);
         }
diff --git a/target/tricore/fpu_helper.c b/target/tricore/fpu_helper.c
index cb7ee7dd35..7c826f9b7b 100644
--- a/target/tricore/fpu_helper.c
+++ b/target/tricore/fpu_helper.c
@@ -43,7 +43,7 @@ static inline uint8_t f_get_excp_flags(CPUTriCoreState *env)
            & (float_flag_invalid
               | float_flag_overflow
               | float_flag_underflow
-              | float_flag_output_denormal
+              | float_flag_oflush_denormal
               | float_flag_divbyzero
               | float_flag_inexact);
 }
@@ -99,7 +99,7 @@ static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
         some_excp = 1;
     }
 
-    if (flags & float_flag_underflow || flags & float_flag_output_denormal) {
+    if (flags & float_flag_underflow || flags & float_flag_oflush_denormal) {
         env->FPU_FU = 1 << 31;
         some_excp = 1;
     }
@@ -109,7 +109,7 @@ static void f_update_psw_flags(CPUTriCoreState *env, uint8_t flags)
         some_excp = 1;
     }
 
-    if (flags & float_flag_inexact || flags & float_flag_output_denormal) {
+    if (flags & float_flag_inexact || flags & float_flag_oflush_denormal) {
         env->PSW |= 1 << 26;
         some_excp = 1;
     }
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index be29ba0aa3..72e2b24539 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -227,7 +227,7 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
         }
         frac_shr(p, frac_shift);
     } else if (s->flush_to_zero) {
-        flags |= float_flag_output_denormal;
+        flags |= float_flag_oflush_denormal;
         p->cls = float_class_zero;
         exp = 0;
         frac_clear(p);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
  2021-05-27  4:13 ` [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal Richard Henderson
  2021-05-27  4:13 ` [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal Richard Henderson
@ 2021-05-27  4:13 ` Richard Henderson
  2021-05-28 17:41   ` Michael Morrell
  2021-06-07 15:35   ` Alex Bennée
  2021-05-27  4:13 ` [PATCH 04/11] softfloat: Introduce float_flag_result_denormal Richard Henderson
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell

Create a new exception flag for reporting input denormals that are not
flushed to zero, they are normalized and treated as normal numbers.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 15 ++++---
 fpu/softfloat.c               | 84 +++++++++++------------------------
 fpu/softfloat-parts.c.inc     |  1 +
 3 files changed, 36 insertions(+), 64 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index e2d70ff556..174100e50e 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -143,13 +143,14 @@ typedef enum __attribute__((__packed__)) {
  */
 
 enum {
-    float_flag_invalid   =  1,
-    float_flag_divbyzero =  4,
-    float_flag_overflow  =  8,
-    float_flag_underflow = 16,
-    float_flag_inexact   = 32,
-    float_flag_iflush_denormal = 64,
-    float_flag_oflush_denormal = 128
+    float_flag_invalid         = 0x0001,
+    float_flag_divbyzero       = 0x0002,
+    float_flag_overflow        = 0x0004,
+    float_flag_underflow       = 0x0008,
+    float_flag_inexact         = 0x0010,
+    float_flag_inorm_denormal  = 0x0020,  /* denormal input, normalized */
+    float_flag_iflush_denormal = 0x0040,  /* denormal input, flushed to zero */
+    float_flag_oflush_denormal = 0x0080,  /* denormal result, flushed to zero */
 };
 
 /*
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index cb077cf111..e54cdb274d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -126,61 +126,23 @@ this code that are retained.
  * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0 result
  * and the result is < the minimum normal.
  */
-#define GEN_INPUT_FLUSH__NOCHECK(name, soft_t)                          \
+
+#define GEN_INPUT_FLUSH(name, soft_t)                                   \
     static inline void name(soft_t *a, float_status *s)                 \
     {                                                                   \
         if (unlikely(soft_t ## _is_denormal(*a))) {                     \
-            *a = soft_t ## _set_sign(soft_t ## _zero,                   \
-                                     soft_t ## _is_neg(*a));            \
-            float_raise(float_flag_iflush_denormal, s);                  \
+            if (s->flush_inputs_to_zero) {                              \
+                *a = soft_t ## _set_sign(0, soft_t ## _is_neg(*a));     \
+                float_raise(float_flag_iflush_denormal, s);             \
+            } else {                                                    \
+                float_raise(float_flag_inorm_denormal, s);              \
+            }                                                           \
         }                                                               \
     }
 
-GEN_INPUT_FLUSH__NOCHECK(float32_input_flush__nocheck, float32)
-GEN_INPUT_FLUSH__NOCHECK(float64_input_flush__nocheck, float64)
-#undef GEN_INPUT_FLUSH__NOCHECK
-
-#define GEN_INPUT_FLUSH1(name, soft_t)                  \
-    static inline void name(soft_t *a, float_status *s) \
-    {                                                   \
-        if (likely(!s->flush_inputs_to_zero)) {         \
-            return;                                     \
-        }                                               \
-        soft_t ## _input_flush__nocheck(a, s);          \
-    }
-
-GEN_INPUT_FLUSH1(float32_input_flush1, float32)
-GEN_INPUT_FLUSH1(float64_input_flush1, float64)
-#undef GEN_INPUT_FLUSH1
-
-#define GEN_INPUT_FLUSH2(name, soft_t)                                  \
-    static inline void name(soft_t *a, soft_t *b, float_status *s)      \
-    {                                                                   \
-        if (likely(!s->flush_inputs_to_zero)) {                         \
-            return;                                                     \
-        }                                                               \
-        soft_t ## _input_flush__nocheck(a, s);                          \
-        soft_t ## _input_flush__nocheck(b, s);                          \
-    }
-
-GEN_INPUT_FLUSH2(float32_input_flush2, float32)
-GEN_INPUT_FLUSH2(float64_input_flush2, float64)
-#undef GEN_INPUT_FLUSH2
-
-#define GEN_INPUT_FLUSH3(name, soft_t)                                  \
-    static inline void name(soft_t *a, soft_t *b, soft_t *c, float_status *s) \
-    {                                                                   \
-        if (likely(!s->flush_inputs_to_zero)) {                         \
-            return;                                                     \
-        }                                                               \
-        soft_t ## _input_flush__nocheck(a, s);                          \
-        soft_t ## _input_flush__nocheck(b, s);                          \
-        soft_t ## _input_flush__nocheck(c, s);                          \
-    }
-
-GEN_INPUT_FLUSH3(float32_input_flush3, float32)
-GEN_INPUT_FLUSH3(float64_input_flush3, float64)
-#undef GEN_INPUT_FLUSH3
+GEN_INPUT_FLUSH(float32_input_flush, float32)
+GEN_INPUT_FLUSH(float64_input_flush, float64)
+#undef GEN_INPUT_FLUSH
 
 /*
  * Choose whether to use fpclassify or float32/64_* primitives in the generated
@@ -353,7 +315,8 @@ float32_gen2(float32 xa, float32 xb, float_status *s,
         goto soft;
     }
 
-    float32_input_flush2(&ua.s, &ub.s, s);
+    float32_input_flush(&ua.s, s);
+    float32_input_flush(&ub.s, s);
     if (unlikely(!pre(ua, ub))) {
         goto soft;
     }
@@ -384,7 +347,8 @@ float64_gen2(float64 xa, float64 xb, float_status *s,
         goto soft;
     }
 
-    float64_input_flush2(&ua.s, &ub.s, s);
+    float64_input_flush(&ua.s, s);
+    float64_input_flush(&ub.s, s);
     if (unlikely(!pre(ua, ub))) {
         goto soft;
     }
@@ -2161,7 +2125,9 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
         goto soft;
     }
 
-    float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
+    float32_input_flush(&ua.s, s);
+    float32_input_flush(&ub.s, s);
+    float32_input_flush(&uc.s, s);
     if (unlikely(!f32_is_zon3(ua, ub, uc))) {
         goto soft;
     }
@@ -2232,7 +2198,9 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
         goto soft;
     }
 
-    float64_input_flush3(&ua.s, &ub.s, &uc.s, s);
+    float64_input_flush(&ua.s, s);
+    float64_input_flush(&ub.s, s);
+    float64_input_flush(&uc.s, s);
     if (unlikely(!f64_is_zon3(ua, ub, uc))) {
         goto soft;
     }
@@ -3988,7 +3956,8 @@ float32_hs_compare(float32 xa, float32 xb, float_status *s, bool is_quiet)
         goto soft;
     }
 
-    float32_input_flush2(&ua.s, &ub.s, s);
+    float32_input_flush(&ua.s, s);
+    float32_input_flush(&ub.s, s);
     if (isgreaterequal(ua.h, ub.h)) {
         if (isgreater(ua.h, ub.h)) {
             return float_relation_greater;
@@ -4038,7 +4007,8 @@ float64_hs_compare(float64 xa, float64 xb, float_status *s, bool is_quiet)
         goto soft;
     }
 
-    float64_input_flush2(&ua.s, &ub.s, s);
+    float64_input_flush(&ua.s, s);
+    float64_input_flush(&ub.s, s);
     if (isgreaterequal(ua.h, ub.h)) {
         if (isgreater(ua.h, ub.h)) {
             return float_relation_greater;
@@ -4230,7 +4200,7 @@ float32 QEMU_FLATTEN float32_sqrt(float32 xa, float_status *s)
         goto soft;
     }
 
-    float32_input_flush1(&ua.s, s);
+    float32_input_flush(&ua.s, s);
     if (QEMU_HARDFLOAT_1F32_USE_FP) {
         if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
                        fpclassify(ua.h) == FP_ZERO) ||
@@ -4257,7 +4227,7 @@ float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s)
         goto soft;
     }
 
-    float64_input_flush1(&ua.s, s);
+    float64_input_flush(&ua.s, s);
     if (QEMU_HARDFLOAT_1F64_USE_FP) {
         if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
                        fpclassify(ua.h) == FP_ZERO) ||
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 72e2b24539..16d4425419 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -119,6 +119,7 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
             int shift = frac_normalize(p);
             p->cls = float_class_normal;
             p->exp = fmt->frac_shift - fmt->exp_bias - shift + 1;
+            float_raise(float_flag_inorm_denormal, status);
         }
     } else if (likely(p->exp < fmt->exp_max) || fmt->arm_althp) {
         p->cls = float_class_normal;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 04/11] softfloat: Introduce float_flag_result_denormal
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (2 preceding siblings ...)
  2021-05-27  4:13 ` [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal Richard Henderson
@ 2021-05-27  4:13 ` Richard Henderson
  2021-06-07 16:30   ` Alex Bennée
  2021-06-19 15:10   ` Philippe Mathieu-Daudé
  2021-05-27  4:13 ` [PATCH 05/11] target/i386: Use float_flag_inorm_denormal Richard Henderson
                   ` (7 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell

Create a new exception flag for reporting output denormals
that are not flushed to zero.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 3 ++-
 fpu/softfloat-parts.c.inc     | 8 ++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 174100e50e..83632aa09f 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -151,6 +151,7 @@ enum {
     float_flag_inorm_denormal  = 0x0020,  /* denormal input, normalized */
     float_flag_iflush_denormal = 0x0040,  /* denormal input, flushed to zero */
     float_flag_oflush_denormal = 0x0080,  /* denormal result, flushed to zero */
+    float_flag_result_denormal = 0x0100,  /* denormal result, not flushed */
 };
 
 /*
@@ -170,8 +171,8 @@ typedef enum __attribute__((__packed__)) {
  */
 
 typedef struct float_status {
+    uint16_t float_exception_flags;
     FloatRoundMode float_rounding_mode;
-    uint8_t     float_exception_flags;
     FloatX80RoundPrec floatx80_rounding_precision;
     bool tininess_before_rounding;
     /* should denormalised results go to zero and set the inexact flag? */
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 16d4425419..a21fcec3e5 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -276,8 +276,12 @@ static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s,
         if (is_tiny && (flags & float_flag_inexact)) {
             flags |= float_flag_underflow;
         }
-        if (exp == 0 && frac_eqz(p)) {
-            p->cls = float_class_zero;
+        if (exp == 0) {
+            if (frac_eqz(p)) {
+                p->cls = float_class_zero;
+            } else {
+                flags |= float_flag_result_denormal;
+            }
         }
     }
     p->exp = exp;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 05/11] target/i386: Use float_flag_inorm_denormal
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (3 preceding siblings ...)
  2021-05-27  4:13 ` [PATCH 04/11] softfloat: Introduce float_flag_result_denormal Richard Henderson
@ 2021-05-27  4:13 ` Richard Henderson
  2021-06-19 18:41   ` Richard Henderson
  2021-05-27  4:14 ` [PATCH 06/11] target/rx: Handle the FPSW.DN bit in helper_set_fpsw Richard Henderson
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:13 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell

The FSR and MXCSR DE flags have the semantics of the new flag.
We get to remove a big fixme in update_mxcsr_from_sse_status
vs float_flag_iflush_denormal.

Reported-by: Michael Morrell <mmorrell@tachyum.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/tcg/fpu_helper.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index c9779a9fe0..edc550de55 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -148,7 +148,7 @@ static void merge_exception_flags(CPUX86State *env, uint8_t old_flags)
                        (new_flags & float_flag_overflow ? FPUS_OE : 0) |
                        (new_flags & float_flag_underflow ? FPUS_UE : 0) |
                        (new_flags & float_flag_inexact ? FPUS_PE : 0) |
-                       (new_flags & float_flag_iflush_denormal ? FPUS_DE : 0)));
+                       (new_flags & float_flag_inorm_denormal ? FPUS_DE : 0)));
 }
 
 static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b)
@@ -1742,7 +1742,7 @@ void helper_fxtract(CPUX86State *env)
             int shift = clz64(temp.l.lower);
             temp.l.lower <<= shift;
             expdif = 1 - EXPBIAS - shift;
-            float_raise(float_flag_iflush_denormal, &env->fp_status);
+            float_raise(float_flag_inorm_denormal, &env->fp_status);
         } else {
             expdif = EXPD(temp) - EXPBIAS;
         }
@@ -2976,7 +2976,8 @@ void update_mxcsr_status(CPUX86State *env)
                               (mxcsr & FPUS_ZE ? float_flag_divbyzero : 0) |
                               (mxcsr & FPUS_OE ? float_flag_overflow : 0) |
                               (mxcsr & FPUS_UE ? float_flag_underflow : 0) |
-                              (mxcsr & FPUS_PE ? float_flag_inexact : 0),
+                              (mxcsr & FPUS_PE ? float_flag_inexact : 0) |
+                              (mxcsr & FPUS_DE ? float_flag_inorm_denormal : 0),
                               &env->sse_status);
 
     /* set denormals are zero */
@@ -2989,20 +2990,13 @@ void update_mxcsr_status(CPUX86State *env)
 void update_mxcsr_from_sse_status(CPUX86State *env)
 {
     uint8_t flags = get_float_exception_flags(&env->sse_status);
-    /*
-     * The MXCSR denormal flag has opposite semantics to
-     * float_flag_iflush_denormal (the softfloat code sets that flag
-     * only when flushing input denormals to zero, but SSE sets it
-     * only when not flushing them to zero), so is not converted
-     * here.
-     */
     env->mxcsr |= ((flags & float_flag_invalid ? FPUS_IE : 0) |
                    (flags & float_flag_divbyzero ? FPUS_ZE : 0) |
                    (flags & float_flag_overflow ? FPUS_OE : 0) |
                    (flags & float_flag_underflow ? FPUS_UE : 0) |
                    (flags & float_flag_inexact ? FPUS_PE : 0) |
-                   (flags & float_flag_oflush_denormal ? FPUS_UE | FPUS_PE :
-                    0));
+                   (flags & float_flag_inorm_denormal ? FPUS_DE : 0) |
+                   (flags & float_flag_oflush_denormal ? FPUS_UE | FPUS_PE : 0));
 }
 
 void helper_update_mxcsr(CPUX86State *env)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 06/11] target/rx: Handle the FPSW.DN bit in helper_set_fpsw
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (4 preceding siblings ...)
  2021-05-27  4:13 ` [PATCH 05/11] target/i386: Use float_flag_inorm_denormal Richard Henderson
@ 2021-05-27  4:14 ` Richard Henderson
  2021-05-28 15:34   ` Yoshinori Sato
  2021-05-27  4:14 ` [PATCH 07/11] target/rx: Use FloatRoundMode " Richard Henderson
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, mmorrell, Philippe Mathieu-Daudé, Yoshinori Sato

Both input and output denormals flush to zero when DN is set.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/rx/op_helper.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
index ef904eb5f9..2139def3b2 100644
--- a/target/rx/op_helper.c
+++ b/target/rx/op_helper.c
@@ -127,13 +127,20 @@ void helper_set_fpsw(CPURXState *env, uint32_t val)
         float_round_down,
     };
     uint32_t fpsw = env->fpsw;
+    bool dn;
+
     fpsw |= 0x7fffff03;
     val &= ~0x80000000;
     fpsw &= val;
     FIELD_DP32(fpsw, FPSW, FS, FIELD_EX32(fpsw, FPSW, FLAGS) != 0);
     env->fpsw = fpsw;
-    set_float_rounding_mode(roundmode[FIELD_EX32(env->fpsw, FPSW, RM)],
+
+    set_float_rounding_mode(roundmode[FIELD_EX32(fpsw, FPSW, RM)],
                             &env->fp_status);
+
+    dn = FIELD_EX32(env->fpsw, FPSW, DN);
+    set_flush_to_zero(dn, &env->fp_status);
+    set_flush_inputs_to_zero(dn, &env->fp_status);
 }
 
 #define FLOATOP(op, func)                                           \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 07/11] target/rx: Use FloatRoundMode in helper_set_fpsw
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (5 preceding siblings ...)
  2021-05-27  4:14 ` [PATCH 06/11] target/rx: Handle the FPSW.DN bit in helper_set_fpsw Richard Henderson
@ 2021-05-27  4:14 ` Richard Henderson
  2021-05-28 15:35   ` Yoshinori Sato
  2021-06-01  3:27   ` Philippe Mathieu-Daudé
  2021-05-27  4:14 ` [PATCH 08/11] target/rx: Fix setting of FPSW.CE Richard Henderson
                   ` (4 subsequent siblings)
  11 siblings, 2 replies; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, mmorrell, Philippe Mathieu-Daudé, Yoshinori Sato

Use the proper type for the roundmode array.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/rx/op_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
index 2139def3b2..b1772e9538 100644
--- a/target/rx/op_helper.c
+++ b/target/rx/op_helper.c
@@ -120,7 +120,7 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
 
 void helper_set_fpsw(CPURXState *env, uint32_t val)
 {
-    static const int roundmode[] = {
+    static const FloatRoundMode roundmode[] = {
         float_round_nearest_even,
         float_round_to_zero,
         float_round_up,
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 08/11] target/rx: Fix setting of FPSW.CE
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (6 preceding siblings ...)
  2021-05-27  4:14 ` [PATCH 07/11] target/rx: Use FloatRoundMode " Richard Henderson
@ 2021-05-27  4:14 ` Richard Henderson
  2021-05-28 15:35   ` Yoshinori Sato
  2021-05-27  4:14 ` [PATCH 09/11] target/mips: Drop inline markers from msa_helper.c Richard Henderson
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, mmorrell, Philippe Mathieu-Daudé, Yoshinori Sato

The existing check was completely wrong, confused about the
definition of the (previous) float_flag_{input,output}_denormal
flags, then making sure that DN, the flush-to-zero bit, was off.

Update for the introduction of float_flag_inorm_denormal and
float_flag_result_denormal, taking into account that DN now sets
the softfloat flush-to-zero bits.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/rx/op_helper.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
index b1772e9538..c2e4f9a5e3 100644
--- a/target/rx/op_helper.c
+++ b/target/rx/op_helper.c
@@ -97,9 +97,11 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
         if (xcpt & float_flag_inexact) {
             SET_FPSW(X);
         }
-        if ((xcpt & (float_flag_iflush_denormal
-                     | float_flag_oflush_denormal))
-            && !FIELD_EX32(env->fpsw, FPSW, DN)) {
+        /*
+         * If any input or output denormals, not flushed to zero, raise CE:
+         * unimplemented processing has been encountered.
+         */
+        if (xcpt & (float_flag_inorm_denormal | float_flag_result_denormal)) {
             env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1);
         }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 09/11] target/mips: Drop inline markers from msa_helper.c
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (7 preceding siblings ...)
  2021-05-27  4:14 ` [PATCH 08/11] target/rx: Fix setting of FPSW.CE Richard Henderson
@ 2021-05-27  4:14 ` Richard Henderson
  2021-06-01  3:27   ` Philippe Mathieu-Daudé
  2021-05-27  4:14 ` [PATCH 10/11] target/mips: Do not check MSACSR_FS_MASK in update_msacsr Richard Henderson
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell, Philippe Mathieu-Daudé

Some of these functions are quite large.
Let the compiler decide whether to inline.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/mips/tcg/msa_helper.c | 262 ++++++++++++++++-------------------
 1 file changed, 121 insertions(+), 141 deletions(-)

diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index 51791f946b..2f89abe166 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -68,7 +68,7 @@
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
+static int64_t msa_nlzc_df(uint32_t df, int64_t arg)
 {
     uint64_t x, y;
     int n, c;
@@ -89,7 +89,7 @@ static inline int64_t msa_nlzc_df(uint32_t df, int64_t arg)
     return n - x;
 }
 
-static inline int64_t msa_nloc_df(uint32_t df, int64_t arg)
+static int64_t msa_nloc_df(uint32_t df, int64_t arg)
 {
     return msa_nlzc_df(df, UNSIGNED((~arg), df));
 }
@@ -210,7 +210,7 @@ void helper_msa_nlzc_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
     pwd->d[1]  = msa_nlzc_df(DF_DOUBLE, pws->d[1]);
 }
 
-static inline int64_t msa_pcnt_df(uint32_t df, int64_t arg)
+static int64_t msa_pcnt_df(uint32_t df, int64_t arg)
 {
     uint64_t x;
 
@@ -307,8 +307,7 @@ void helper_msa_pcnt_d(CPUMIPSState *env, uint32_t wd, uint32_t ws)
 /* Data format bit position and unsigned values */
 #define BIT_POSITION(x, df) ((uint64_t)(x) % DF_BITS(df))
 
-static inline int64_t msa_binsl_df(uint32_t df,
-                                   int64_t dest, int64_t arg1, int64_t arg2)
+static int64_t msa_binsl_df(uint32_t df, int64_t dest, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_dest = UNSIGNED(dest, df);
@@ -388,8 +387,7 @@ void helper_msa_binsl_d(CPUMIPSState *env,
     pwd->d[1]  = msa_binsl_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_binsr_df(uint32_t df,
-                                   int64_t dest, int64_t arg1, int64_t arg2)
+static int64_t msa_binsr_df(uint32_t df, int64_t dest, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_dest = UNSIGNED(dest, df);
@@ -526,7 +524,7 @@ void helper_msa_bsel_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_bclr_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int32_t b_arg2 = BIT_POSITION(arg2, df);
     return UNSIGNED(arg1 & (~(1LL << b_arg2)), df);
@@ -594,7 +592,7 @@ void helper_msa_bclr_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
     pwd->d[1]  = msa_bclr_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_bneg_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int32_t b_arg2 = BIT_POSITION(arg2, df);
     return UNSIGNED(arg1 ^ (1LL << b_arg2), df);
@@ -662,8 +660,7 @@ void helper_msa_bneg_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
     pwd->d[1]  = msa_bneg_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_bset_df(uint32_t df, int64_t arg1,
-        int64_t arg2)
+static int64_t msa_bset_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int32_t b_arg2 = BIT_POSITION(arg2, df);
     return UNSIGNED(arg1 | (1LL << b_arg2), df);
@@ -809,7 +806,7 @@ void helper_msa_bset_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
  */
 
 
-static inline int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_add_a_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
@@ -883,7 +880,7 @@ void helper_msa_add_a_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_adds_a_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t max_int = (uint64_t)DF_MAX_INT(df);
     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
@@ -962,7 +959,7 @@ void helper_msa_adds_a_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_adds_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int64_t max_int = DF_MAX_INT(df);
     int64_t min_int = DF_MIN_INT(df);
@@ -1040,7 +1037,7 @@ void helper_msa_adds_s_d(CPUMIPSState *env,
 }
 
 
-static inline uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
+static uint64_t msa_adds_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
 {
     uint64_t max_uint = DF_MAX_UINT(df);
     uint64_t u_arg1 = UNSIGNED(arg1, df);
@@ -1115,7 +1112,7 @@ void helper_msa_adds_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_addv_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 + arg2;
 }
@@ -1200,7 +1197,7 @@ void helper_msa_addv_d(CPUMIPSState *env,
         ((((uint64_t)(a)) << (64 - DF_BITS(df))) >> (64 - DF_BITS(df) / 2))
 
 
-static inline int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_hadd_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return SIGNED_ODD(arg1, df) + SIGNED_EVEN(arg2, df);
 }
@@ -1247,7 +1244,7 @@ void helper_msa_hadd_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_hadd_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return UNSIGNED_ODD(arg1, df) + UNSIGNED_EVEN(arg2, df);
 }
@@ -1318,7 +1315,7 @@ void helper_msa_hadd_u_d(CPUMIPSState *env,
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_ave_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     /* signed shift */
     return (arg1 >> 1) + (arg2 >> 1) + (arg1 & arg2 & 1);
@@ -1390,7 +1387,7 @@ void helper_msa_ave_s_d(CPUMIPSState *env,
     pwd->d[1]  = msa_ave_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
+static uint64_t msa_ave_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -1464,7 +1461,7 @@ void helper_msa_ave_u_d(CPUMIPSState *env,
     pwd->d[1]  = msa_ave_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_aver_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     /* signed shift */
     return (arg1 >> 1) + (arg2 >> 1) + ((arg1 | arg2) & 1);
@@ -1536,7 +1533,7 @@ void helper_msa_aver_s_d(CPUMIPSState *env,
     pwd->d[1]  = msa_aver_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
+static uint64_t msa_aver_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -1639,12 +1636,12 @@ void helper_msa_aver_u_d(CPUMIPSState *env,
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_ceq_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 == arg2 ? -1 : 0;
 }
 
-static inline int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
+static int8_t msa_ceq_b(int8_t arg1, int8_t arg2)
 {
     return arg1 == arg2 ? -1 : 0;
 }
@@ -1673,7 +1670,7 @@ void helper_msa_ceq_b(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
     pwd->b[15] = msa_ceq_b(pws->b[15], pwt->b[15]);
 }
 
-static inline int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
+static int16_t msa_ceq_h(int16_t arg1, int16_t arg2)
 {
     return arg1 == arg2 ? -1 : 0;
 }
@@ -1694,7 +1691,7 @@ void helper_msa_ceq_h(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
     pwd->h[7]  = msa_ceq_h(pws->h[7],  pwt->h[7]);
 }
 
-static inline int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
+static int32_t msa_ceq_w(int32_t arg1, int32_t arg2)
 {
     return arg1 == arg2 ? -1 : 0;
 }
@@ -1711,7 +1708,7 @@ void helper_msa_ceq_w(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
     pwd->w[3]  = msa_ceq_w(pws->w[3],  pwt->w[3]);
 }
 
-static inline int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
+static int64_t msa_ceq_d(int64_t arg1, int64_t arg2)
 {
     return arg1 == arg2 ? -1 : 0;
 }
@@ -1726,7 +1723,7 @@ void helper_msa_ceq_d(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
     pwd->d[1]  = msa_ceq_d(pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_cle_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 <= arg2 ? -1 : 0;
 }
@@ -1797,7 +1794,7 @@ void helper_msa_cle_s_d(CPUMIPSState *env,
     pwd->d[1]  = msa_cle_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_cle_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -1870,12 +1867,12 @@ void helper_msa_cle_u_d(CPUMIPSState *env,
     pwd->d[1]  = msa_cle_u_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_clt_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 < arg2 ? -1 : 0;
 }
 
-static inline int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
+static int8_t msa_clt_s_b(int8_t arg1, int8_t arg2)
 {
     return arg1 < arg2 ? -1 : 0;
 }
@@ -1905,7 +1902,7 @@ void helper_msa_clt_s_b(CPUMIPSState *env,
     pwd->b[15] = msa_clt_s_b(pws->b[15], pwt->b[15]);
 }
 
-static inline int16_t msa_clt_s_h(int16_t arg1, int16_t arg2)
+static int16_t msa_clt_s_h(int16_t arg1, int16_t arg2)
 {
     return arg1 < arg2 ? -1 : 0;
 }
@@ -1927,7 +1924,7 @@ void helper_msa_clt_s_h(CPUMIPSState *env,
     pwd->h[7]  = msa_clt_s_h(pws->h[7],  pwt->h[7]);
 }
 
-static inline int32_t msa_clt_s_w(int32_t arg1, int32_t arg2)
+static int32_t msa_clt_s_w(int32_t arg1, int32_t arg2)
 {
     return arg1 < arg2 ? -1 : 0;
 }
@@ -1945,7 +1942,7 @@ void helper_msa_clt_s_w(CPUMIPSState *env,
     pwd->w[3]  = msa_clt_s_w(pws->w[3],  pwt->w[3]);
 }
 
-static inline int64_t msa_clt_s_d(int64_t arg1, int64_t arg2)
+static int64_t msa_clt_s_d(int64_t arg1, int64_t arg2)
 {
     return arg1 < arg2 ? -1 : 0;
 }
@@ -1961,7 +1958,7 @@ void helper_msa_clt_s_d(CPUMIPSState *env,
     pwd->d[1]  = msa_clt_s_d(pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_clt_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -2052,7 +2049,7 @@ void helper_msa_clt_u_d(CPUMIPSState *env,
  */
 
 
-static inline int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_div_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
         return DF_MIN_INT(df);
@@ -2127,7 +2124,7 @@ void helper_msa_div_s_d(CPUMIPSState *env,
     pwd->d[1]  = msa_div_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_div_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -2240,7 +2237,7 @@ void helper_msa_div_u_d(CPUMIPSState *env,
     } while (0)
 
 
-static inline int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_dotp_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int64_t even_arg1;
     int64_t even_arg2;
@@ -2293,7 +2290,7 @@ void helper_msa_dotp_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_dotp_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int64_t even_arg1;
     int64_t even_arg2;
@@ -2346,8 +2343,8 @@ void helper_msa_dotp_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
-                                     int64_t arg2)
+static int64_t msa_dpadd_s_df(uint32_t df, int64_t dest, int64_t arg1,
+                              int64_t arg2)
 {
     int64_t even_arg1;
     int64_t even_arg2;
@@ -2400,8 +2397,8 @@ void helper_msa_dpadd_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
-                                     int64_t arg2)
+static int64_t msa_dpadd_u_df(uint32_t df, int64_t dest, int64_t arg1,
+                              int64_t arg2)
 {
     int64_t even_arg1;
     int64_t even_arg2;
@@ -2454,8 +2451,8 @@ void helper_msa_dpadd_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
-                                     int64_t arg2)
+static int64_t msa_dpsub_s_df(uint32_t df, int64_t dest, int64_t arg1,
+                              int64_t arg2)
 {
     int64_t even_arg1;
     int64_t even_arg2;
@@ -2508,8 +2505,8 @@ void helper_msa_dpsub_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
-                                     int64_t arg2)
+static int64_t msa_dpsub_u_df(uint32_t df, int64_t dest, int64_t arg1,
+                              int64_t arg2)
 {
     int64_t even_arg1;
     int64_t even_arg2;
@@ -2594,7 +2591,7 @@ void helper_msa_dpsub_u_d(CPUMIPSState *env,
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_max_a_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
@@ -2668,7 +2665,7 @@ void helper_msa_max_a_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_max_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 > arg2 ? arg1 : arg2;
 }
@@ -2740,7 +2737,7 @@ void helper_msa_max_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_max_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -2814,7 +2811,7 @@ void helper_msa_max_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_min_a_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t abs_arg1 = arg1 >= 0 ? arg1 : -arg1;
     uint64_t abs_arg2 = arg2 >= 0 ? arg2 : -arg2;
@@ -2888,7 +2885,7 @@ void helper_msa_min_a_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_min_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 < arg2 ? arg1 : arg2;
 }
@@ -2960,7 +2957,7 @@ void helper_msa_min_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_min_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -3050,7 +3047,7 @@ void helper_msa_min_u_d(CPUMIPSState *env,
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_mod_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     if (arg1 == DF_MIN_INT(df) && arg2 == -1) {
         return 0;
@@ -3124,7 +3121,7 @@ void helper_msa_mod_s_d(CPUMIPSState *env,
     pwd->d[1]  = msa_mod_s_df(DF_DOUBLE, pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_mod_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -3218,7 +3215,7 @@ void helper_msa_mod_u_d(CPUMIPSState *env,
  * +---------------+----------------------------------------------------------+
  */
 
-static inline int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
+static int64_t msa_maddv_df(uint32_t df, int64_t dest, int64_t arg1,
                                    int64_t arg2)
 {
     return dest + arg1 * arg2;
@@ -3290,7 +3287,7 @@ void helper_msa_maddv_d(CPUMIPSState *env,
     pwd->d[1]  = msa_maddv_df(DF_DOUBLE, pwd->d[1],  pws->d[1],  pwt->d[1]);
 }
 
-static inline int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
+static int64_t msa_msubv_df(uint32_t df, int64_t dest, int64_t arg1,
                                    int64_t arg2)
 {
     return dest - arg1 * arg2;
@@ -3363,7 +3360,7 @@ void helper_msa_msubv_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_mulv_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 * arg2;
 }
@@ -3478,7 +3475,7 @@ void helper_msa_mulv_d(CPUMIPSState *env,
  */
 
 
-static inline int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_asub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     /* signed compare */
     return (arg1 < arg2) ?
@@ -3552,7 +3549,7 @@ void helper_msa_asub_s_d(CPUMIPSState *env,
 }
 
 
-static inline uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
+static uint64_t msa_asub_u_df(uint32_t df, uint64_t arg1, uint64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -3628,7 +3625,7 @@ void helper_msa_asub_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_hsub_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return SIGNED_ODD(arg1, df) - SIGNED_EVEN(arg2, df);
 }
@@ -3675,7 +3672,7 @@ void helper_msa_hsub_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_hsub_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return UNSIGNED_ODD(arg1, df) - UNSIGNED_EVEN(arg2, df);
 }
@@ -3722,7 +3719,7 @@ void helper_msa_hsub_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_subs_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int64_t max_int = DF_MAX_INT(df);
     int64_t min_int = DF_MIN_INT(df);
@@ -3800,7 +3797,7 @@ void helper_msa_subs_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_subs_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -3874,7 +3871,7 @@ void helper_msa_subs_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_subsus_u_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t max_uint = DF_MAX_UINT(df);
@@ -3958,7 +3955,7 @@ void helper_msa_subsus_u_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_subsuu_s_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     uint64_t u_arg2 = UNSIGNED(arg2, df);
@@ -4042,7 +4039,7 @@ void helper_msa_subsuu_s_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_subv_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     return arg1 - arg2;
 }
@@ -4618,7 +4615,7 @@ void helper_msa_xor_v(CPUMIPSState *env, uint32_t wd, uint32_t ws, uint32_t wt)
  * +---------------+----------------------------------------------------------+
  */
 
-static inline void msa_move_v(wr_t *pwd, wr_t *pws)
+static void msa_move_v(wr_t *pwd, wr_t *pws)
 {
     pwd->d[0] = pws->d[0];
     pwd->d[1] = pws->d[1];
@@ -4892,7 +4889,7 @@ void helper_msa_pckod_d(CPUMIPSState *env,
  */
 
 
-static inline int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_sll_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int32_t b_arg2 = BIT_POSITION(arg2, df);
     return arg1 << b_arg2;
@@ -4965,7 +4962,7 @@ void helper_msa_sll_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_sra_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int32_t b_arg2 = BIT_POSITION(arg2, df);
     return arg1 >> b_arg2;
@@ -5038,7 +5035,7 @@ void helper_msa_sra_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_srar_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int32_t b_arg2 = BIT_POSITION(arg2, df);
     if (b_arg2 == 0) {
@@ -5116,7 +5113,7 @@ void helper_msa_srar_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_srl_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     int32_t b_arg2 = BIT_POSITION(arg2, df);
@@ -5190,7 +5187,7 @@ void helper_msa_srl_d(CPUMIPSState *env,
 }
 
 
-static inline int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_srlr_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     uint64_t u_arg1 = UNSIGNED(arg1, df);
     int32_t b_arg2 = BIT_POSITION(arg2, df);
@@ -5417,14 +5414,14 @@ void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     }
 }
 
-static inline int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
+static int64_t msa_sat_s_df(uint32_t df, int64_t arg, uint32_t m)
 {
     return arg < M_MIN_INT(m + 1) ? M_MIN_INT(m + 1) :
                                     arg > M_MAX_INT(m + 1) ? M_MAX_INT(m + 1) :
                                                              arg;
 }
 
-static inline int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
+static int64_t msa_sat_u_df(uint32_t df, int64_t arg, uint32_t m)
 {
     uint64_t u_arg = UNSIGNED(arg, df);
     return  u_arg < M_MAX_UINT(m + 1) ? u_arg :
@@ -5530,8 +5527,7 @@ MSA_TEROP_IMMU_DF(binsri, binsr)
         }                                       \
     } while (0)
 
-static inline void msa_sld_df(uint32_t df, wr_t *pwd,
-                              wr_t *pws, target_ulong rt)
+static void msa_sld_df(uint32_t df, wr_t *pwd, wr_t *pws, target_ulong rt)
 {
     uint32_t n = rt % DF_ELEMENTS(df);
     uint8_t v[64];
@@ -5561,7 +5557,7 @@ static inline void msa_sld_df(uint32_t df, wr_t *pwd,
     }
 }
 
-static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int64_t q_min = DF_MIN_INT(df);
     int64_t q_max = DF_MAX_INT(df);
@@ -5572,7 +5568,7 @@ static inline int64_t msa_mul_q_df(uint32_t df, int64_t arg1, int64_t arg2)
     return (arg1 * arg2) >> (DF_BITS(df) - 1);
 }
 
-static inline int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
+static int64_t msa_mulr_q_df(uint32_t df, int64_t arg1, int64_t arg2)
 {
     int64_t q_min = DF_MIN_INT(df);
     int64_t q_max = DF_MAX_INT(df);
@@ -5649,8 +5645,8 @@ void helper_msa_sld_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     msa_sld_df(df, pwd, pws, env->active_tc.gpr[rt]);
 }
 
-static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
-                                    int64_t arg2)
+static int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
+                             int64_t arg2)
 {
     int64_t q_prod, q_ret;
 
@@ -5663,8 +5659,8 @@ static inline int64_t msa_madd_q_df(uint32_t df, int64_t dest, int64_t arg1,
     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
 }
 
-static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
-                                    int64_t arg2)
+static int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
+                             int64_t arg2)
 {
     int64_t q_prod, q_ret;
 
@@ -5677,8 +5673,8 @@ static inline int64_t msa_msub_q_df(uint32_t df, int64_t dest, int64_t arg1,
     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
 }
 
-static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
-                                     int64_t arg2)
+static int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
+                              int64_t arg2)
 {
     int64_t q_prod, q_ret;
 
@@ -5692,8 +5688,8 @@ static inline int64_t msa_maddr_q_df(uint32_t df, int64_t dest, int64_t arg1,
     return (q_ret < q_min) ? q_min : (q_max < q_ret) ? q_max : q_ret;
 }
 
-static inline int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
-                                     int64_t arg2)
+static int64_t msa_msubr_q_df(uint32_t df, int64_t dest, int64_t arg1,
+                              int64_t arg2)
 {
     int64_t q_prod, q_ret;
 
@@ -5783,8 +5779,7 @@ MSA_TEROP_DF(maddr_q)
 MSA_TEROP_DF(msubr_q)
 #undef MSA_TEROP_DF
 
-static inline void msa_splat_df(uint32_t df, wr_t *pwd,
-                                wr_t *pws, target_ulong rt)
+static void msa_splat_df(uint32_t df, wr_t *pwd, wr_t *pws, target_ulong rt)
 {
     uint32_t n = rt % DF_ELEMENTS(df);
     uint32_t i;
@@ -6165,12 +6160,12 @@ void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
 #define FLOAT_SNAN64(s) (float64_default_nan(s) ^ 0x0008000000000020ULL)
         /* 0x7ff0000000000020 */
 
-static inline void clear_msacsr_cause(CPUMIPSState *env)
+static void clear_msacsr_cause(CPUMIPSState *env)
 {
     SET_FP_CAUSE(env->active_tc.msacsr, 0);
 }
 
-static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
+static void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
 {
     if ((GET_FP_CAUSE(env->active_tc.msacsr) &
             (GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED)) == 0) {
@@ -6187,7 +6182,7 @@ static inline void check_msacsr_cause(CPUMIPSState *env, uintptr_t retaddr)
 #define RECIPROCAL_INEXACT 4
 
 
-static inline int ieee_to_mips_xcpt_msa(int ieee_xcpt)
+static int ieee_to_mips_xcpt_msa(int ieee_xcpt)
 {
     int mips_xcpt = 0;
 
@@ -6210,7 +6205,7 @@ static inline int ieee_to_mips_xcpt_msa(int ieee_xcpt)
     return mips_xcpt;
 }
 
-static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
+static int update_msacsr(CPUMIPSState *env, int action, int denormal)
 {
     int ieee_exception_flags;
     int mips_exception_flags = 0;
@@ -6296,14 +6291,13 @@ static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
     return mips_exception_flags;
 }
 
-static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
+static int get_enabled_exceptions(const CPUMIPSState *env, int c)
 {
     int enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
     return c & enable;
 }
 
-static inline float16 float16_from_float32(int32_t a, bool ieee,
-                                           float_status *status)
+static float16 float16_from_float32(int32_t a, bool ieee, float_status *status)
 {
       float16 f_val;
 
@@ -6312,7 +6306,7 @@ static inline float16 float16_from_float32(int32_t a, bool ieee,
       return a < 0 ? (f_val | (1 << 15)) : f_val;
 }
 
-static inline float32 float32_from_float64(int64_t a, float_status *status)
+static float32 float32_from_float64(int64_t a, float_status *status)
 {
       float32 f_val;
 
@@ -6321,8 +6315,7 @@ static inline float32 float32_from_float64(int64_t a, float_status *status)
       return a < 0 ? (f_val | (1 << 31)) : f_val;
 }
 
-static inline float32 float32_from_float16(int16_t a, bool ieee,
-                                           float_status *status)
+static float32 float32_from_float16(int16_t a, bool ieee, float_status *status)
 {
       float32 f_val;
 
@@ -6331,7 +6324,7 @@ static inline float32 float32_from_float16(int16_t a, bool ieee,
       return a < 0 ? (f_val | (1 << 31)) : f_val;
 }
 
-static inline float64 float64_from_float32(int32_t a, float_status *status)
+static float64 float64_from_float32(int32_t a, float_status *status)
 {
       float64 f_val;
 
@@ -6340,7 +6333,7 @@ static inline float64 float64_from_float32(int32_t a, float_status *status)
       return a < 0 ? (f_val | (1ULL << 63)) : f_val;
 }
 
-static inline float32 float32_from_q16(int16_t a, float_status *status)
+static float32 float32_from_q16(int16_t a, float_status *status)
 {
     float32 f_val;
 
@@ -6351,7 +6344,7 @@ static inline float32 float32_from_q16(int16_t a, float_status *status)
     return f_val;
 }
 
-static inline float64 float64_from_q32(int32_t a, float_status *status)
+static float64 float64_from_q32(int32_t a, float_status *status)
 {
     float64 f_val;
 
@@ -6362,7 +6355,7 @@ static inline float64 float64_from_q32(int32_t a, float_status *status)
     return f_val;
 }
 
-static inline int16_t float32_to_q16(float32 a, float_status *status)
+static int16_t float32_to_q16(float32 a, float_status *status)
 {
     int32_t q_val;
     int32_t q_min = 0xffff8000;
@@ -6414,7 +6407,7 @@ static inline int16_t float32_to_q16(float32 a, float_status *status)
     return (int16_t)q_val;
 }
 
-static inline int32_t float64_to_q32(float64 a, float_status *status)
+static int32_t float64_to_q32(float64 a, float_status *status)
 {
     int64_t q_val;
     int64_t q_min = 0xffffffff80000000LL;
@@ -6544,9 +6537,8 @@ static inline int32_t float64_to_q32(float64 a, float_status *status)
         }                                                           \
     } while (0)
 
-static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6573,9 +6565,8 @@ static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6604,9 +6595,8 @@ static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6633,9 +6623,8 @@ static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                               wr_t *pwt, uint32_t df, int quiet,
-                               uintptr_t retaddr)
+static void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                        wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6662,9 +6651,8 @@ static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6691,9 +6679,8 @@ static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                               wr_t *pwt, uint32_t df, int quiet,
-                               uintptr_t retaddr)
+static void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                        wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6720,9 +6707,8 @@ static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6749,9 +6735,8 @@ static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                               wr_t *pwt, uint32_t df, int quiet,
-                               uintptr_t retaddr)
+static void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                        wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6778,9 +6763,8 @@ static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6807,9 +6791,8 @@ static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                               wr_t *pwt, uint32_t df, int quiet,
-                               uintptr_t retaddr)
+static void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                        wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -6836,9 +6819,8 @@ static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
     msa_move_v(pwd, pwx);
 }
 
-static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
-                              wr_t *pwt, uint32_t df, int quiet,
-                              uintptr_t retaddr)
+static void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
+                       wr_t *pwt, uint32_t df, int quiet, uintptr_t retaddr)
 {
     wr_t wx, *pwx = &wx;
     uint32_t i;
@@ -8395,10 +8377,8 @@ void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd,
 #define MSA_PAGESPAN(x) \
         ((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN / 8 - 1) >= TARGET_PAGE_SIZE)
 
-static inline void ensure_writable_pages(CPUMIPSState *env,
-                                         target_ulong addr,
-                                         int mmu_idx,
-                                         uintptr_t retaddr)
+static void ensure_writable_pages(CPUMIPSState *env, target_ulong addr,
+                                  int mmu_idx, uintptr_t retaddr)
 {
     /* FIXME: Probe the actual accesses (pass and use a size) */
     if (unlikely(MSA_PAGESPAN(addr))) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 10/11] target/mips: Do not check MSACSR_FS_MASK in update_msacsr
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (8 preceding siblings ...)
  2021-05-27  4:14 ` [PATCH 09/11] target/mips: Drop inline markers from msa_helper.c Richard Henderson
@ 2021-05-27  4:14 ` Richard Henderson
  2021-06-19 15:15   ` Philippe Mathieu-Daudé
  2021-05-27  4:14 ` [PATCH 11/11] target/mips: Drop denormal operand to update_msacsr Richard Henderson
  2021-06-07 16:31 ` [PATCH 00/11] softfloat: Improve denormal handling Alex Bennée
  11 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:14 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell, Philippe Mathieu-Daudé

The FS_MASK has already been taken into account with
restore_msa_fp_status.  The definition of iflush and
oflush is that we *have* flushed to zero.

Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/mips/tcg/msa_helper.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index 2f89abe166..ffe6e630ed 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -6225,8 +6225,7 @@ static int update_msacsr(CPUMIPSState *env, int action, int denormal)
     enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
 
     /* Set Inexact (I) when flushing inputs to zero */
-    if ((ieee_exception_flags & float_flag_iflush_denormal) &&
-            (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
+    if (ieee_exception_flags & float_flag_iflush_denormal) {
         if (action & CLEAR_IS_INEXACT) {
             mips_exception_flags &= ~FP_INEXACT;
         } else {
@@ -6235,8 +6234,7 @@ static int update_msacsr(CPUMIPSState *env, int action, int denormal)
     }
 
     /* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
-    if ((ieee_exception_flags & float_flag_oflush_denormal) &&
-            (env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
+    if (ieee_exception_flags & float_flag_oflush_denormal) {
         mips_exception_flags |= FP_INEXACT;
         if (action & CLEAR_FS_UNDERFLOW) {
             mips_exception_flags &= ~FP_UNDERFLOW;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 11/11] target/mips: Drop denormal operand to update_msacsr
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (9 preceding siblings ...)
  2021-05-27  4:14 ` [PATCH 10/11] target/mips: Do not check MSACSR_FS_MASK in update_msacsr Richard Henderson
@ 2021-05-27  4:14 ` Richard Henderson
  2021-06-01  3:29   ` Philippe Mathieu-Daudé
  2021-06-07 16:31 ` [PATCH 00/11] softfloat: Improve denormal handling Alex Bennée
  11 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-27  4:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: alex.bennee, Yongbok Kim, mmorrell, Philippe Mathieu-Daudé

The comment about not signaling all underflow cases is
almost certainly incorrect.  It has been there since the
initial commit of the file.

There is a bit of code below that sets underflow with
float_flag_oflush_denormal, which is probably the fix
for whatever the original case may have been.

Cc: Yongbok Kim <yongbok.kim@mips.com>
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/mips/tcg/msa_helper.c | 32 ++++++++++----------------------
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/target/mips/tcg/msa_helper.c b/target/mips/tcg/msa_helper.c
index ffe6e630ed..b752373bce 100644
--- a/target/mips/tcg/msa_helper.c
+++ b/target/mips/tcg/msa_helper.c
@@ -6205,7 +6205,7 @@ static int ieee_to_mips_xcpt_msa(int ieee_xcpt)
     return mips_xcpt;
 }
 
-static int update_msacsr(CPUMIPSState *env, int action, int denormal)
+static int update_msacsr(CPUMIPSState *env, int action)
 {
     int ieee_exception_flags;
     int mips_exception_flags = 0;
@@ -6215,10 +6215,6 @@ static int update_msacsr(CPUMIPSState *env, int action, int denormal)
     ieee_exception_flags = get_float_exception_flags(
                                &env->active_tc.msa_fp_status);
 
-    /* QEMU softfloat does not signal all underflow cases */
-    if (denormal) {
-        ieee_exception_flags |= float_flag_underflow;
-    }
     if (ieee_exception_flags) {
         mips_exception_flags = ieee_to_mips_xcpt_msa(ieee_exception_flags);
     }
@@ -6469,7 +6465,7 @@ static int32_t float64_to_q32(float64 a, float_status *status)
             cond = float ## BITS ## _ ## OP ## _quiet(ARG1, ARG2, status);  \
         }                                                                   \
         DEST = cond ? M_MAX_UINT(BITS) : 0;                                 \
-        c = update_msacsr(env, CLEAR_IS_INEXACT, 0);                        \
+        c = update_msacsr(env, CLEAR_IS_INEXACT);                           \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7043,13 +7039,6 @@ void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
     compare_ne(env, pwd, pws, pwt, df, 0, GETPC());
 }
 
-#define float16_is_zero(ARG) 0
-#define float16_is_zero_or_denormal(ARG) 0
-
-#define IS_DENORMAL(ARG, BITS)                      \
-    (!float ## BITS ## _is_zero(ARG)                \
-    && float ## BITS ## _is_zero_or_denormal(ARG))
-
 #define MSA_FLOAT_BINOP(DEST, OP, ARG1, ARG2, BITS)                         \
     do {                                                                    \
         float_status *status = &env->active_tc.msa_fp_status;               \
@@ -7057,7 +7046,7 @@ void helper_msa_fsne_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
                                                                             \
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
-        c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
+        c = update_msacsr(env, 0);                                          \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7193,7 +7182,7 @@ void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
                                                                             \
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _muladd(ARG2, ARG3, ARG1, NEGATE, status);  \
-        c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
+        c = update_msacsr(env, 0);                                          \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7312,7 +7301,7 @@ void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
                                                                             \
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
-        c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
+        c = update_msacsr(env, 0);                                          \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7365,7 +7354,7 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
                                                                             \
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
-        c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
+        c = update_msacsr(env, CLEAR_FS_UNDERFLOW);                         \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## XBITS(status) >> 6) << 6) | c;           \
@@ -7416,7 +7405,7 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
                                                                             \
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _ ## OP(ARG1, ARG2, status);                \
-        c = update_msacsr(env, 0, 0);                                       \
+        c = update_msacsr(env, 0);                                          \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7672,7 +7661,7 @@ void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
                                                                             \
         set_float_exception_flags(0, status);                               \
         DEST = float ## BITS ## _ ## OP(ARG, status);                       \
-        c = update_msacsr(env, CLEAR_FS_UNDERFLOW, 0);                      \
+        c = update_msacsr(env, CLEAR_FS_UNDERFLOW);                         \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7780,8 +7769,7 @@ void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
         DEST = float ## BITS ## _ ## div(FLOAT_ONE ## BITS, ARG, status);   \
         c = update_msacsr(env, float ## BITS ## _is_infinity(ARG) ||        \
                           float ## BITS ## _is_quiet_nan(DEST, status) ?    \
-                          0 : RECIPROCAL_INEXACT,                           \
-                          IS_DENORMAL(DEST, BITS));                         \
+                          0 : RECIPROCAL_INEXACT);                          \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
@@ -7897,7 +7885,7 @@ void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
                                   (~float_flag_inexact),                    \
                                   status);                                  \
                                                                             \
-        c = update_msacsr(env, 0, IS_DENORMAL(DEST, BITS));                 \
+        c = update_msacsr(env, 0);                                          \
                                                                             \
         if (get_enabled_exceptions(env, c)) {                               \
             DEST = ((FLOAT_SNAN ## BITS(status) >> 6) << 6) | c;            \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH 06/11] target/rx: Handle the FPSW.DN bit in helper_set_fpsw
  2021-05-27  4:14 ` [PATCH 06/11] target/rx: Handle the FPSW.DN bit in helper_set_fpsw Richard Henderson
@ 2021-05-28 15:34   ` Yoshinori Sato
  0 siblings, 0 replies; 38+ messages in thread
From: Yoshinori Sato @ 2021-05-28 15:34 UTC (permalink / raw)
  To: Richard Henderson
  Cc: mmorrell, alex.bennee, qemu-devel, Philippe Mathieu-Daudé

On Thu, 27 May 2021 13:14:00 +0900,
Richard Henderson wrote:
> 
> Both input and output denormals flush to zero when DN is set.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewd-by: Yoshinori Sato <ysato@users.sourceforge.jp>

> ---
>  target/rx/op_helper.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
> index ef904eb5f9..2139def3b2 100644
> --- a/target/rx/op_helper.c
> +++ b/target/rx/op_helper.c
> @@ -127,13 +127,20 @@ void helper_set_fpsw(CPURXState *env, uint32_t val)
>          float_round_down,
>      };
>      uint32_t fpsw = env->fpsw;
> +    bool dn;
> +
>      fpsw |= 0x7fffff03;
>      val &= ~0x80000000;
>      fpsw &= val;
>      FIELD_DP32(fpsw, FPSW, FS, FIELD_EX32(fpsw, FPSW, FLAGS) != 0);
>      env->fpsw = fpsw;
> -    set_float_rounding_mode(roundmode[FIELD_EX32(env->fpsw, FPSW, RM)],
> +
> +    set_float_rounding_mode(roundmode[FIELD_EX32(fpsw, FPSW, RM)],
>                              &env->fp_status);
> +
> +    dn = FIELD_EX32(env->fpsw, FPSW, DN);
> +    set_flush_to_zero(dn, &env->fp_status);
> +    set_flush_inputs_to_zero(dn, &env->fp_status);
>  }
>  
>  #define FLOATOP(op, func)                                           \
> -- 
> 2.25.1
> 
> 


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 07/11] target/rx: Use FloatRoundMode in helper_set_fpsw
  2021-05-27  4:14 ` [PATCH 07/11] target/rx: Use FloatRoundMode " Richard Henderson
@ 2021-05-28 15:35   ` Yoshinori Sato
  2021-06-01  3:27   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Yoshinori Sato @ 2021-05-28 15:35 UTC (permalink / raw)
  To: Richard Henderson
  Cc: mmorrell, alex.bennee, qemu-devel, Philippe Mathieu-Daudé

On Thu, 27 May 2021 13:14:01 +0900,
Richard Henderson wrote:
> 
> Use the proper type for the roundmode array.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewd-by: Yoshinori Sato <ysato@users.sourceforge.jp>

> ---
>  target/rx/op_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
> index 2139def3b2..b1772e9538 100644
> --- a/target/rx/op_helper.c
> +++ b/target/rx/op_helper.c
> @@ -120,7 +120,7 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
>  
>  void helper_set_fpsw(CPURXState *env, uint32_t val)
>  {
> -    static const int roundmode[] = {
> +    static const FloatRoundMode roundmode[] = {
>          float_round_nearest_even,
>          float_round_to_zero,
>          float_round_up,
> -- 
> 2.25.1
> 
> 


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 08/11] target/rx: Fix setting of FPSW.CE
  2021-05-27  4:14 ` [PATCH 08/11] target/rx: Fix setting of FPSW.CE Richard Henderson
@ 2021-05-28 15:35   ` Yoshinori Sato
  0 siblings, 0 replies; 38+ messages in thread
From: Yoshinori Sato @ 2021-05-28 15:35 UTC (permalink / raw)
  To: Richard Henderson
  Cc: mmorrell, alex.bennee, qemu-devel, Philippe Mathieu-Daudé

On Thu, 27 May 2021 13:14:02 +0900,
Richard Henderson wrote:
> 
> The existing check was completely wrong, confused about the
> definition of the (previous) float_flag_{input,output}_denormal
> flags, then making sure that DN, the flush-to-zero bit, was off.
> 
> Update for the introduction of float_flag_inorm_denormal and
> float_flag_result_denormal, taking into account that DN now sets
> the softfloat flush-to-zero bits.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewd-by: Yoshinori Sato <ysato@users.sourceforge.jp>

> ---
>  target/rx/op_helper.c | 8 +++++---
>  1 file changed, 5 insertions(+), 3 deletions(-)
> 
> diff --git a/target/rx/op_helper.c b/target/rx/op_helper.c
> index b1772e9538..c2e4f9a5e3 100644
> --- a/target/rx/op_helper.c
> +++ b/target/rx/op_helper.c
> @@ -97,9 +97,11 @@ static void update_fpsw(CPURXState *env, float32 ret, uintptr_t retaddr)
>          if (xcpt & float_flag_inexact) {
>              SET_FPSW(X);
>          }
> -        if ((xcpt & (float_flag_iflush_denormal
> -                     | float_flag_oflush_denormal))
> -            && !FIELD_EX32(env->fpsw, FPSW, DN)) {
> +        /*
> +         * If any input or output denormals, not flushed to zero, raise CE:
> +         * unimplemented processing has been encountered.
> +         */
> +        if (xcpt & (float_flag_inorm_denormal | float_flag_result_denormal)) {
>              env->fpsw = FIELD_DP32(env->fpsw, FPSW, CE, 1);
>          }
>  
> -- 
> 2.25.1
> 
> 


^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-05-27  4:13 ` [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal Richard Henderson
@ 2021-05-28 17:41   ` Michael Morrell
  2021-05-29 15:21     ` Richard Henderson
  2021-06-07 15:35   ` Alex Bennée
  1 sibling, 1 reply; 38+ messages in thread
From: Michael Morrell @ 2021-05-28 17:41 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee

I'm probably missing something, but why do we need both "float_flag_inorm_denormal" and "float_flag_iflush_denormal"?

Couldn't the code that sets these flags set just a single flag for all denormal inputs and the code that checks these flags check that single flag
combined with the "flush_inputs_to_zero" flag to accomplish what the two separate "input denormal" flags do?

   Michael

-----Original Message-----
From: Richard Henderson <richard.henderson@linaro.org> 
Sent: Wednesday, May 26, 2021 9:14 PM
To: qemu-devel@nongnu.org
Cc: Michael Morrell <mmorrell@tachyum.com>; alex.bennee@linaro.org
Subject: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal

Create a new exception flag for reporting input denormals that are not flushed to zero, they are normalized and treated as normal numbers.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 15 ++++---
 fpu/softfloat.c               | 84 +++++++++++------------------------
 fpu/softfloat-parts.c.inc     |  1 +
 3 files changed, 36 insertions(+), 64 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h index e2d70ff556..174100e50e 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -143,13 +143,14 @@ typedef enum __attribute__((__packed__)) {
  */
 
 enum {
-    float_flag_invalid   =  1,
-    float_flag_divbyzero =  4,
-    float_flag_overflow  =  8,
-    float_flag_underflow = 16,
-    float_flag_inexact   = 32,
-    float_flag_iflush_denormal = 64,
-    float_flag_oflush_denormal = 128
+    float_flag_invalid         = 0x0001,
+    float_flag_divbyzero       = 0x0002,
+    float_flag_overflow        = 0x0004,
+    float_flag_underflow       = 0x0008,
+    float_flag_inexact         = 0x0010,
+    float_flag_inorm_denormal  = 0x0020,  /* denormal input, normalized */
+    float_flag_iflush_denormal = 0x0040,  /* denormal input, flushed to zero */
+    float_flag_oflush_denormal = 0x0080,  /* denormal result, flushed 
+ to zero */
 };
 
 /*
diff --git a/fpu/softfloat.c b/fpu/softfloat.c index cb077cf111..e54cdb274d 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -126,61 +126,23 @@ this code that are retained.
  * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0 result
  * and the result is < the minimum normal.
  */
-#define GEN_INPUT_FLUSH__NOCHECK(name, soft_t)                          \
+
+#define GEN_INPUT_FLUSH(name, soft_t)                                   \
     static inline void name(soft_t *a, float_status *s)                 \
     {                                                                   \
         if (unlikely(soft_t ## _is_denormal(*a))) {                     \
-            *a = soft_t ## _set_sign(soft_t ## _zero,                   \
-                                     soft_t ## _is_neg(*a));            \
-            float_raise(float_flag_iflush_denormal, s);                  \
+            if (s->flush_inputs_to_zero) {                              \
+                *a = soft_t ## _set_sign(0, soft_t ## _is_neg(*a));     \
+                float_raise(float_flag_iflush_denormal, s);             \
+            } else {                                                    \
+                float_raise(float_flag_inorm_denormal, s);              \
+            }                                                           \
         }                                                               \
     }
 
-GEN_INPUT_FLUSH__NOCHECK(float32_input_flush__nocheck, float32) -GEN_INPUT_FLUSH__NOCHECK(float64_input_flush__nocheck, float64) -#undef GEN_INPUT_FLUSH__NOCHECK
-
-#define GEN_INPUT_FLUSH1(name, soft_t)                  \
-    static inline void name(soft_t *a, float_status *s) \
-    {                                                   \
-        if (likely(!s->flush_inputs_to_zero)) {         \
-            return;                                     \
-        }                                               \
-        soft_t ## _input_flush__nocheck(a, s);          \
-    }
-
-GEN_INPUT_FLUSH1(float32_input_flush1, float32) -GEN_INPUT_FLUSH1(float64_input_flush1, float64) -#undef GEN_INPUT_FLUSH1
-
-#define GEN_INPUT_FLUSH2(name, soft_t)                                  \
-    static inline void name(soft_t *a, soft_t *b, float_status *s)      \
-    {                                                                   \
-        if (likely(!s->flush_inputs_to_zero)) {                         \
-            return;                                                     \
-        }                                                               \
-        soft_t ## _input_flush__nocheck(a, s);                          \
-        soft_t ## _input_flush__nocheck(b, s);                          \
-    }
-
-GEN_INPUT_FLUSH2(float32_input_flush2, float32) -GEN_INPUT_FLUSH2(float64_input_flush2, float64) -#undef GEN_INPUT_FLUSH2
-
-#define GEN_INPUT_FLUSH3(name, soft_t)                                  \
-    static inline void name(soft_t *a, soft_t *b, soft_t *c, float_status *s) \
-    {                                                                   \
-        if (likely(!s->flush_inputs_to_zero)) {                         \
-            return;                                                     \
-        }                                                               \
-        soft_t ## _input_flush__nocheck(a, s);                          \
-        soft_t ## _input_flush__nocheck(b, s);                          \
-        soft_t ## _input_flush__nocheck(c, s);                          \
-    }
-
-GEN_INPUT_FLUSH3(float32_input_flush3, float32) -GEN_INPUT_FLUSH3(float64_input_flush3, float64) -#undef GEN_INPUT_FLUSH3
+GEN_INPUT_FLUSH(float32_input_flush, float32) 
+GEN_INPUT_FLUSH(float64_input_flush, float64) #undef GEN_INPUT_FLUSH
 
 /*
  * Choose whether to use fpclassify or float32/64_* primitives in the generated @@ -353,7 +315,8 @@ float32_gen2(float32 xa, float32 xb, float_status *s,
         goto soft;
     }
 
-    float32_input_flush2(&ua.s, &ub.s, s);
+    float32_input_flush(&ua.s, s);
+    float32_input_flush(&ub.s, s);
     if (unlikely(!pre(ua, ub))) {
         goto soft;
     }
@@ -384,7 +347,8 @@ float64_gen2(float64 xa, float64 xb, float_status *s,
         goto soft;
     }
 
-    float64_input_flush2(&ua.s, &ub.s, s);
+    float64_input_flush(&ua.s, s);
+    float64_input_flush(&ub.s, s);
     if (unlikely(!pre(ua, ub))) {
         goto soft;
     }
@@ -2161,7 +2125,9 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s)
         goto soft;
     }
 
-    float32_input_flush3(&ua.s, &ub.s, &uc.s, s);
+    float32_input_flush(&ua.s, s);
+    float32_input_flush(&ub.s, s);
+    float32_input_flush(&uc.s, s);
     if (unlikely(!f32_is_zon3(ua, ub, uc))) {
         goto soft;
     }
@@ -2232,7 +2198,9 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
         goto soft;
     }
 
-    float64_input_flush3(&ua.s, &ub.s, &uc.s, s);
+    float64_input_flush(&ua.s, s);
+    float64_input_flush(&ub.s, s);
+    float64_input_flush(&uc.s, s);
     if (unlikely(!f64_is_zon3(ua, ub, uc))) {
         goto soft;
     }
@@ -3988,7 +3956,8 @@ float32_hs_compare(float32 xa, float32 xb, float_status *s, bool is_quiet)
         goto soft;
     }
 
-    float32_input_flush2(&ua.s, &ub.s, s);
+    float32_input_flush(&ua.s, s);
+    float32_input_flush(&ub.s, s);
     if (isgreaterequal(ua.h, ub.h)) {
         if (isgreater(ua.h, ub.h)) {
             return float_relation_greater; @@ -4038,7 +4007,8 @@ float64_hs_compare(float64 xa, float64 xb, float_status *s, bool is_quiet)
         goto soft;
     }
 
-    float64_input_flush2(&ua.s, &ub.s, s);
+    float64_input_flush(&ua.s, s);
+    float64_input_flush(&ub.s, s);
     if (isgreaterequal(ua.h, ub.h)) {
         if (isgreater(ua.h, ub.h)) {
             return float_relation_greater; @@ -4230,7 +4200,7 @@ float32 QEMU_FLATTEN float32_sqrt(float32 xa, float_status *s)
         goto soft;
     }
 
-    float32_input_flush1(&ua.s, s);
+    float32_input_flush(&ua.s, s);
     if (QEMU_HARDFLOAT_1F32_USE_FP) {
         if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
                        fpclassify(ua.h) == FP_ZERO) || @@ -4257,7 +4227,7 @@ float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s)
         goto soft;
     }
 
-    float64_input_flush1(&ua.s, s);
+    float64_input_flush(&ua.s, s);
     if (QEMU_HARDFLOAT_1F64_USE_FP) {
         if (unlikely(!(fpclassify(ua.h) == FP_NORMAL ||
                        fpclassify(ua.h) == FP_ZERO) || diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index 72e2b24539..16d4425419 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -119,6 +119,7 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status,
             int shift = frac_normalize(p);
             p->cls = float_class_normal;
             p->exp = fmt->frac_shift - fmt->exp_bias - shift + 1;
+            float_raise(float_flag_inorm_denormal, status);
         }
     } else if (likely(p->exp < fmt->exp_max) || fmt->arm_althp) {
         p->cls = float_class_normal;
--
2.25.1



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-05-28 17:41   ` Michael Morrell
@ 2021-05-29 15:21     ` Richard Henderson
  2021-07-14 16:44       ` Michael Morrell
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-05-29 15:21 UTC (permalink / raw)
  To: Michael Morrell, qemu-devel; +Cc: alex.bennee

On 5/28/21 10:41 AM, Michael Morrell wrote:
> I'm probably missing something, but why do we need both "float_flag_inorm_denormal" and "float_flag_iflush_denormal"?
> 
> Couldn't the code that sets these flags set just a single flag for all denormal inputs and the code that checks these flags check that single flag
> combined with the "flush_inputs_to_zero" flag to accomplish what the two separate "input denormal" flags do?

The thing that you're missing is that many guests leave the accumulated 
softfloat exceptions in the float_status structure until the guest FPSCR 
register is read. Unless the guest needs to raise an exception immediately, 
there's no reason to do otherwise.

With this setup, you have no temporal connection between "any denormal" and 
"flush-to-zero is set", thus two flags.


r~


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 07/11] target/rx: Use FloatRoundMode in helper_set_fpsw
  2021-05-27  4:14 ` [PATCH 07/11] target/rx: Use FloatRoundMode " Richard Henderson
  2021-05-28 15:35   ` Yoshinori Sato
@ 2021-06-01  3:27   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-01  3:27 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: mmorrell, alex.bennee, Yoshinori Sato

On 5/27/21 6:14 AM, Richard Henderson wrote:
> Use the proper type for the roundmode array.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/rx/op_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 09/11] target/mips: Drop inline markers from msa_helper.c
  2021-05-27  4:14 ` [PATCH 09/11] target/mips: Drop inline markers from msa_helper.c Richard Henderson
@ 2021-06-01  3:27   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-01  3:27 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: mmorrell, alex.bennee

On 5/27/21 6:14 AM, Richard Henderson wrote:
> Some of these functions are quite large.
> Let the compiler decide whether to inline.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/mips/tcg/msa_helper.c | 262 ++++++++++++++++-------------------
>  1 file changed, 121 insertions(+), 141 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 11/11] target/mips: Drop denormal operand to update_msacsr
  2021-05-27  4:14 ` [PATCH 11/11] target/mips: Drop denormal operand to update_msacsr Richard Henderson
@ 2021-06-01  3:29   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-01  3:29 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: Yongbok Kim, alex.bennee, mmorrell

On 5/27/21 6:14 AM, Richard Henderson wrote:
> The comment about not signaling all underflow cases is
> almost certainly incorrect.  It has been there since the
> initial commit of the file.
> 
> There is a bit of code below that sets underflow with
> float_flag_oflush_denormal, which is probably the fix
> for whatever the original case may have been.
> 
> Cc: Yongbok Kim <yongbok.kim@mips.com>
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/mips/tcg/msa_helper.c | 32 ++++++++++----------------------
>  1 file changed, 10 insertions(+), 22 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal
  2021-05-27  4:13 ` [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal Richard Henderson
@ 2021-06-07 15:16   ` Alex Bennée
  2021-06-19 15:08   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 15:16 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Richard Henderson <richard.henderson@linaro.org> writes:

> The new name emphasizes that the input denormal has been flushed to zero.
>
> Patch created mechanically using:
>   sed -i s,float_flag_input_denormal,float_flag_iflush_denormal,g \
>     $(git grep -l float_flag_input_denormal)
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal
  2021-05-27  4:13 ` [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal Richard Henderson
@ 2021-06-07 15:16   ` Alex Bennée
  2021-06-19 15:08   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 15:16 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Richard Henderson <richard.henderson@linaro.org> writes:

> The new name emphasizes that the output denormal has been flushed to zero.
>
> Patch created mechanically using:
>   sed -i s,float_flag_output_denormal,float_flag_oflush_denormal,g \
>     $(git grep -l float_flag_output_denormal)
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-05-27  4:13 ` [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal Richard Henderson
  2021-05-28 17:41   ` Michael Morrell
@ 2021-06-07 15:35   ` Alex Bennée
  2021-06-07 16:28     ` Alex Bennée
  2021-06-07 16:41     ` Richard Henderson
  1 sibling, 2 replies; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 15:35 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Richard Henderson <richard.henderson@linaro.org> writes:

> Create a new exception flag for reporting input denormals that are not
> flushed to zero, they are normalized and treated as normal numbers.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/fpu/softfloat-types.h | 15 ++++---
>  fpu/softfloat.c               | 84 +++++++++++------------------------
>  fpu/softfloat-parts.c.inc     |  1 +
>  3 files changed, 36 insertions(+), 64 deletions(-)
>
> diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
> index e2d70ff556..174100e50e 100644
> --- a/include/fpu/softfloat-types.h
> +++ b/include/fpu/softfloat-types.h
> @@ -143,13 +143,14 @@ typedef enum __attribute__((__packed__)) {
>   */
>  
>  enum {
> -    float_flag_invalid   =  1,
> -    float_flag_divbyzero =  4,
> -    float_flag_overflow  =  8,
> -    float_flag_underflow = 16,
> -    float_flag_inexact   = 32,
> -    float_flag_iflush_denormal = 64,
> -    float_flag_oflush_denormal = 128
> +    float_flag_invalid         = 0x0001,
> +    float_flag_divbyzero       = 0x0002,
> +    float_flag_overflow        = 0x0004,
> +    float_flag_underflow       = 0x0008,
> +    float_flag_inexact         = 0x0010,
> +    float_flag_inorm_denormal  = 0x0020,  /* denormal input, normalized */
> +    float_flag_iflush_denormal = 0x0040,  /* denormal input, flushed to zero */
> +    float_flag_oflush_denormal = 0x0080,  /* denormal result, flushed to zero */
>  };
>  
>  /*
> diff --git a/fpu/softfloat.c b/fpu/softfloat.c
> index cb077cf111..e54cdb274d 100644
> --- a/fpu/softfloat.c
> +++ b/fpu/softfloat.c
> @@ -126,61 +126,23 @@ this code that are retained.
>   * denormal/inf/NaN; (2) when operands are not guaranteed to lead to a 0 result
>   * and the result is < the minimum normal.
>   */
> -#define GEN_INPUT_FLUSH__NOCHECK(name, soft_t)                          \
> +
> +#define GEN_INPUT_FLUSH(name, soft_t)                                   \
>      static inline void name(soft_t *a, float_status *s)                 \
>      {                                                                   \
>          if (unlikely(soft_t ## _is_denormal(*a))) {                     \
> -            *a = soft_t ## _set_sign(soft_t ## _zero,                   \
> -                                     soft_t ## _is_neg(*a));            \
> -            float_raise(float_flag_iflush_denormal, s);                  \
> +            if (s->flush_inputs_to_zero) {                              \
> +                *a = soft_t ## _set_sign(0, soft_t ## _is_neg(*a));     \
> +                float_raise(float_flag_iflush_denormal, s);             \
> +            } else {                                                    \
> +                float_raise(float_flag_inorm_denormal, s);              \
> +            }                                                           \
>          }                                                               \
>      }

So I'm guessing Emilio had the original flush code split was to avoid
multiple checks against s->flush_inputs_to_zero in the code. The was
possibly a good reason, comparing the before/after of float32_mul:

  Dump of assembler code for function float32_mul:
     0x0000000000934240 <+0>:	movzbl 0x1(%rdx),%eax
     0x0000000000934244 <+4>:	test   $0x20,%al
     0x0000000000934246 <+6>:	je     0x9342b0 <float32_mul+112>
     0x0000000000934248 <+8>:	cmpb   $0x0,(%rdx)
     0x000000000093424b <+11>:	jne    0x9342b0 <float32_mul+112>
     0x000000000093424d <+13>:	cmpb   $0x0,0x5(%rdx)
     0x0000000000934251 <+17>:	jne    0x9342d0 <float32_mul+144>
     0x0000000000934253 <+19>:	mov    %edi,%eax
     0x0000000000934255 <+21>:	shr    $0x17,%eax
     0x0000000000934258 <+24>:	add    $0x1,%eax
     0x000000000093425b <+27>:	test   $0xfe,%al
     0x000000000093425d <+29>:	je     0x9342a8 <float32_mul+104>
     0x000000000093425f <+31>:	mov    %esi,%eax
     0x0000000000934261 <+33>:	shr    $0x17,%eax
     0x0000000000934264 <+36>:	add    $0x1,%eax
     0x0000000000934267 <+39>:	test   $0xfe,%al
     0x0000000000934269 <+41>:	jne    0x934273 <float32_mul+51>
     0x000000000093426b <+43>:	test   $0x7fffffff,%esi
     0x0000000000934271 <+49>:	jne    0x9342b0 <float32_mul+112>
     0x0000000000934273 <+51>:	mov    %esi,-0xc(%rsp)
     0x0000000000934277 <+55>:	movss  -0xc(%rsp),%xmm0
     0x000000000093427d <+61>:	mov    %edi,-0xc(%rsp)
     0x0000000000934281 <+65>:	movss  -0xc(%rsp),%xmm2
     0x0000000000934287 <+71>:	mulss  %xmm2,%xmm0
     0x000000000093428b <+75>:	movd   %xmm0,%eax
     0x000000000093428f <+79>:	andps  0x3b805a(%rip),%xmm0        # 0xcec2f0
     0x0000000000934296 <+86>:	ucomiss 0x3b8047(%rip),%xmm0        # 0xcec2e4
     0x000000000093429d <+93>:	jbe    0x9342b8 <float32_mul+120>
     0x000000000093429f <+95>:	orb    $0x8,0x1(%rdx)
     0x00000000009342a3 <+99>:	retq   
     0x00000000009342a4 <+100>:	nopl   0x0(%rax)
     0x00000000009342a8 <+104>:	test   $0x7fffffff,%edi
     0x00000000009342ae <+110>:	je     0x93425f <float32_mul+31>
     0x00000000009342b0 <+112>:	jmpq   0x9290d0 <soft_f32_mul>
     0x00000000009342b5 <+117>:	nopl   (%rax)
     0x00000000009342b8 <+120>:	movss  0x3b8020(%rip),%xmm1        # 0xcec2e0
     0x00000000009342c0 <+128>:	comiss %xmm0,%xmm1
     0x00000000009342c3 <+131>:	jae    0x934320 <float32_mul+224>
     0x00000000009342c5 <+133>:	retq   
     0x00000000009342c6 <+134>:	nopw   %cs:0x0(%rax,%rax,1)
     0x00000000009342d0 <+144>:	test   $0x7f800000,%edi
     0x00000000009342d6 <+150>:	jne    0x9342f0 <float32_mul+176>
     0x00000000009342d8 <+152>:	test   $0x7fffffff,%edi
     0x00000000009342de <+158>:	je     0x9342f0 <float32_mul+176>
     0x00000000009342e0 <+160>:	or     $0x40,%eax
     0x00000000009342e3 <+163>:	and    $0x80000000,%edi
     0x00000000009342e9 <+169>:	mov    %al,0x1(%rdx)
     0x00000000009342ec <+172>:	nopl   0x0(%rax)
     0x00000000009342f0 <+176>:	test   $0x7f800000,%esi
     0x00000000009342f6 <+182>:	jne    0x934253 <float32_mul+19>
     0x00000000009342fc <+188>:	test   $0x7fffffff,%esi
     0x0000000000934302 <+194>:	je     0x934253 <float32_mul+19>
     0x0000000000934308 <+200>:	and    $0x80000000,%esi
     0x000000000093430e <+206>:	orb    $0x40,0x1(%rdx)
     0x0000000000934312 <+210>:	jmpq   0x934253 <float32_mul+19>
     0x0000000000934317 <+215>:	nopw   0x0(%rax,%rax,1)
     0x0000000000934320 <+224>:	mov    %edi,%ecx
     0x0000000000934322 <+226>:	or     %esi,%ecx
     0x0000000000934324 <+228>:	and    $0x7fffffff,%ecx
     0x000000000093432a <+234>:	jne    0x9342b0 <float32_mul+112>
     0x000000000093432c <+236>:	jmp    0x9342c5 <float32_mul+133>
  End of assembler dump.

And after this change:

  Dump of assembler code for function float32_mul:
     0x0000000000895d60 <+0>:	movzbl 0x1(%rdx),%eax
     0x0000000000895d64 <+4>:	test   $0x10,%al
     0x0000000000895d66 <+6>:	je     0x895e30 <float32_mul+208>
     0x0000000000895d6c <+12>:	cmpb   $0x0,(%rdx)
     0x0000000000895d6f <+15>:	jne    0x895e30 <float32_mul+208>
     0x0000000000895d75 <+21>:	test   $0x7f800000,%edi
     0x0000000000895d7b <+27>:	jne    0x895da0 <float32_mul+64>
     0x0000000000895d7d <+29>:	test   $0x7fffffff,%edi
     0x0000000000895d83 <+35>:	je     0x895da0 <float32_mul+64>
     0x0000000000895d85 <+37>:	cmpb   $0x0,0x5(%rdx)
     0x0000000000895d89 <+41>:	je     0x895e60 <float32_mul+256>
     0x0000000000895d8f <+47>:	or     $0x40,%eax
     0x0000000000895d92 <+50>:	and    $0x80000000,%edi
     0x0000000000895d98 <+56>:	mov    %al,0x1(%rdx)
     0x0000000000895d9b <+59>:	nopl   0x0(%rax,%rax,1)
     0x0000000000895da0 <+64>:	test   $0x7f800000,%esi
     0x0000000000895da6 <+70>:	jne    0x895dd0 <float32_mul+112>
     0x0000000000895da8 <+72>:	test   $0x7fffffff,%esi
     0x0000000000895dae <+78>:	je     0x895dd0 <float32_mul+112>
     0x0000000000895db0 <+80>:	cmpb   $0x0,0x5(%rdx)
     0x0000000000895db4 <+84>:	movzbl 0x1(%rdx),%eax
     0x0000000000895db8 <+88>:	je     0x895e50 <float32_mul+240>
     0x0000000000895dbe <+94>:	or     $0x40,%eax
     0x0000000000895dc1 <+97>:	and    $0x80000000,%esi
     0x0000000000895dc7 <+103>:	mov    %al,0x1(%rdx)
     0x0000000000895dca <+106>:	nopw   0x0(%rax,%rax,1)
     0x0000000000895dd0 <+112>:	mov    %edi,%eax
     0x0000000000895dd2 <+114>:	shr    $0x17,%eax
     0x0000000000895dd5 <+117>:	add    $0x1,%eax
     0x0000000000895dd8 <+120>:	test   $0xfe,%al
     0x0000000000895dda <+122>:	je     0x895e28 <float32_mul+200>
     0x0000000000895ddc <+124>:	mov    %esi,%eax
     0x0000000000895dde <+126>:	shr    $0x17,%eax
     0x0000000000895de1 <+129>:	add    $0x1,%eax
     0x0000000000895de4 <+132>:	test   $0xfe,%al
     0x0000000000895de6 <+134>:	jne    0x895df0 <float32_mul+144>
     0x0000000000895de8 <+136>:	test   $0x7fffffff,%esi
     0x0000000000895dee <+142>:	jne    0x895e30 <float32_mul+208>
     0x0000000000895df0 <+144>:	mov    %esi,-0xc(%rsp)
     0x0000000000895df4 <+148>:	movss  -0xc(%rsp),%xmm0
     0x0000000000895dfa <+154>:	mov    %edi,-0xc(%rsp)
     0x0000000000895dfe <+158>:	movss  -0xc(%rsp),%xmm2
     0x0000000000895e04 <+164>:	mulss  %xmm2,%xmm0
     0x0000000000895e08 <+168>:	movd   %xmm0,%eax
     0x0000000000895e0c <+172>:	andps  0x46bb5d(%rip),%xmm0        # 0xd01970
     0x0000000000895e13 <+179>:	ucomiss 0x46bb4a(%rip),%xmm0        # 0xd01964
     0x0000000000895e1a <+186>:	jbe    0x895e38 <float32_mul+216>
     0x0000000000895e1c <+188>:	orb    $0x4,0x1(%rdx)
     0x0000000000895e20 <+192>:	retq   
     0x0000000000895e21 <+193>:	nopl   0x0(%rax)
     0x0000000000895e28 <+200>:	test   $0x7fffffff,%edi
     0x0000000000895e2e <+206>:	je     0x895ddc <float32_mul+124>
     0x0000000000895e30 <+208>:	jmpq   0x88a8c0 <soft_f32_mul>
     0x0000000000895e35 <+213>:	nopl   (%rax)
     0x0000000000895e38 <+216>:	movss  0x46bb20(%rip),%xmm1        # 0xd01960
     0x0000000000895e40 <+224>:	comiss %xmm0,%xmm1
     0x0000000000895e43 <+227>:	jae    0x895e70 <float32_mul+272>
     0x0000000000895e45 <+229>:	retq   
     0x0000000000895e46 <+230>:	nopw   %cs:0x0(%rax,%rax,1)
     0x0000000000895e50 <+240>:	or     $0x20,%eax
     0x0000000000895e53 <+243>:	mov    %al,0x1(%rdx)
     0x0000000000895e56 <+246>:	jmpq   0x895dd0 <float32_mul+112>
     0x0000000000895e5b <+251>:	nopl   0x0(%rax,%rax,1)
     0x0000000000895e60 <+256>:	or     $0x20,%eax
     0x0000000000895e63 <+259>:	mov    %al,0x1(%rdx)
     0x0000000000895e66 <+262>:	jmpq   0x895da0 <float32_mul+64>
     0x0000000000895e6b <+267>:	nopl   0x0(%rax,%rax,1)
     0x0000000000895e70 <+272>:	mov    %esi,%ecx
     0x0000000000895e72 <+274>:	or     %edi,%ecx
     0x0000000000895e74 <+276>:	and    $0x7fffffff,%ecx
     0x0000000000895e7a <+282>:	jne    0x895e30 <float32_mul+208>
     0x0000000000895e7c <+284>:	jmp    0x895e45 <float32_mul+229>
  End of assembler dump.

However I'm not sure how much of that increase is down to the change of
macro expansion and how much is due to the extra leg for the flushing.

Anyway other than that observation seems OK to me:

Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-06-07 15:35   ` Alex Bennée
@ 2021-06-07 16:28     ` Alex Bennée
  2021-06-07 16:41     ` Richard Henderson
  1 sibling, 0 replies; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 16:28 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Alex Bennée <alex.bennee@linaro.org> writes:

> Richard Henderson <richard.henderson@linaro.org> writes:
>
>> Create a new exception flag for reporting input denormals that are not
>> flushed to zero, they are normalized and treated as normal numbers.
>>
>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
<snip>
>
> Anyway other than that observation seems OK to me:
>
> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>

I of course meant:

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 04/11] softfloat: Introduce float_flag_result_denormal
  2021-05-27  4:13 ` [PATCH 04/11] softfloat: Introduce float_flag_result_denormal Richard Henderson
@ 2021-06-07 16:30   ` Alex Bennée
  2021-06-19 15:10   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 16:30 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Richard Henderson <richard.henderson@linaro.org> writes:

> Create a new exception flag for reporting output denormals
> that are not flushed to zero.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alex Bennée <alex.bennee@linaro.org>

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 00/11] softfloat: Improve denormal handling
  2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
                   ` (10 preceding siblings ...)
  2021-05-27  4:14 ` [PATCH 11/11] target/mips: Drop denormal operand to update_msacsr Richard Henderson
@ 2021-06-07 16:31 ` Alex Bennée
  11 siblings, 0 replies; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 16:31 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Richard Henderson <richard.henderson@linaro.org> writes:

> This attempts to fix the x86 denormal-exception flag, which is the
> inverse of the existing float_flag_input_denormal flag.  I have not
> created a new test case for this yet, fwiw.
>
> While auditing all uses of float_flag_*_denormal, I found some errors
> in target/rx and target/mips.

Softfloat code looks good to me, I'm leaving the target specific stuff
to the arch maintainers as I have a hard enough time with just one
architectures FP vagaries ;-)

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-06-07 15:35   ` Alex Bennée
  2021-06-07 16:28     ` Alex Bennée
@ 2021-06-07 16:41     ` Richard Henderson
  2021-06-07 17:19       ` Alex Bennée
  1 sibling, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-06-07 16:41 UTC (permalink / raw)
  To: Alex Bennée; +Cc: mmorrell, qemu-devel

On 6/7/21 8:35 AM, Alex Bennée wrote:
> So I'm guessing Emilio had the original flush code split was to avoid
> multiple checks against s->flush_inputs_to_zero in the code. The was
> possibly a good reason, comparing the before/after of float32_mul:

I assumed that the most important thing now is that we test floatN_is_denormal 
only once -- the test for flush_inputs_to_zero is fairly trivial.

If you've got a better ordering of operations for this, do tell.


r~


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-06-07 16:41     ` Richard Henderson
@ 2021-06-07 17:19       ` Alex Bennée
  2021-06-07 20:52         ` Richard Henderson
  0 siblings, 1 reply; 38+ messages in thread
From: Alex Bennée @ 2021-06-07 17:19 UTC (permalink / raw)
  To: Richard Henderson; +Cc: mmorrell, qemu-devel


Richard Henderson <richard.henderson@linaro.org> writes:

> On 6/7/21 8:35 AM, Alex Bennée wrote:
>> So I'm guessing Emilio had the original flush code split was to avoid
>> multiple checks against s->flush_inputs_to_zero in the code. The was
>> possibly a good reason, comparing the before/after of float32_mul:
>
> I assumed that the most important thing now is that we test
> floatN_is_denormal only once -- the test for flush_inputs_to_zero is
> fairly trivial.
>
> If you've got a better ordering of operations for this, do tell.

What I really want is to know which instructions translate into the if
(s->flush_inputs_to_zero) and verifying that is only checked once. Maybe
I'm just suspicious of compilers ability to optimise things away...

-- 
Alex Bennée


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-06-07 17:19       ` Alex Bennée
@ 2021-06-07 20:52         ` Richard Henderson
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Henderson @ 2021-06-07 20:52 UTC (permalink / raw)
  To: Alex Bennée; +Cc: mmorrell, qemu-devel

On 6/7/21 10:19 AM, Alex Bennée wrote:
>> If you've got a better ordering of operations for this, do tell.
> 
> What I really want is to know which instructions translate into the if
> (s->flush_inputs_to_zero) and verifying that is only checked once. Maybe
> I'm just suspicious of compilers ability to optimise things away...




>   Dump of assembler code for function float32_mul:
>      0x0000000000895d60 <+0>:	movzbl 0x1(%rdx),%eax
>      0x0000000000895d64 <+4>:	test   $0x10,%al
>      0x0000000000895d66 <+6>:	je     0x895e30 <float32_mul+208>

s->float_exception_flags & float_flag_inexact

>      0x0000000000895d6c <+12>:	cmpb   $0x0,(%rdx)
>      0x0000000000895d6f <+15>:	jne    0x895e30 <float32_mul+208>

s->float_rounding_mode == float_round_nearest_even

>      0x0000000000895d75 <+21>:	test   $0x7f800000,%edi
>      0x0000000000895d7b <+27>:	jne    0x895da0 <float32_mul+64>
>      0x0000000000895d7d <+29>:	test   $0x7fffffff,%edi
>      0x0000000000895d83 <+35>:	je     0x895da0 <float32_mul+64>

float32_is_denormal

>      0x0000000000895d85 <+37>:	cmpb   $0x0,0x5(%rdx)
>      0x0000000000895d89 <+41>:	je     0x895e60 <float32_mul+256>

s->flush_inputs_to_zero

>      0x0000000000895d8f <+47>:	or     $0x40,%eax
>      0x0000000000895d92 <+50>:	and    $0x80000000,%edi
>      0x0000000000895d98 <+56>:	mov    %al,0x1(%rdx)

flush-to-zero and set iflush_denormal

>      0x0000000000895da0 <+64>:	test   $0x7f800000,%esi
>      0x0000000000895da6 <+70>:	jne    0x895dd0 <float32_mul+112>
>      0x0000000000895da8 <+72>:	test   $0x7fffffff,%esi
>      0x0000000000895dae <+78>:	je     0x895dd0 <float32_mul+112>

float32_is_denormal (second operand)

>      0x0000000000895db0 <+80>:	cmpb   $0x0,0x5(%rdx)
>      0x0000000000895db4 <+84>:	movzbl 0x1(%rdx),%eax
>      0x0000000000895db8 <+88>:	je     0x895e50 <float32_mul+240>
>      0x0000000000895dbe <+94>:	or     $0x40,%eax
>      0x0000000000895dc1 <+97>:	and    $0x80000000,%esi

s->flush_inputs_to_zero,
flush-to-zero,
set iflush_denormal.

...

>      0x0000000000895e50 <+240>:	or     $0x20,%eax
>      0x0000000000895e53 <+243>:	mov    %al,0x1(%rdx)
>      0x0000000000895e56 <+246>:	jmpq   0x895dd0 <float32_mul+112>

set inorm_denormal (second operand)

>      0x0000000000895e60 <+256>:	or     $0x20,%eax
>      0x0000000000895e63 <+259>:	mov    %al,0x1(%rdx)
>      0x0000000000895e66 <+262>:	jmpq   0x895da0 <float32_mul+64>

set inorm_denormal (first operand)

There do seem to be 3 reads/writes to exception_flags for float_raise.


r~


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal
  2021-05-27  4:13 ` [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal Richard Henderson
  2021-06-07 15:16   ` Alex Bennée
@ 2021-06-19 15:08   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19 15:08 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: mmorrell, alex.bennee

On 5/27/21 6:13 AM, Richard Henderson wrote:
> The new name emphasizes that the input denormal has been flushed to zero.
> 
> Patch created mechanically using:
>   sed -i s,float_flag_input_denormal,float_flag_iflush_denormal,g \
>     $(git grep -l float_flag_input_denormal)
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/fpu/softfloat-types.h |  2 +-
>  fpu/softfloat.c               |  4 ++--
>  target/arm/sve_helper.c       |  6 +++---
>  target/arm/vfp_helper.c       | 10 +++++-----
>  target/i386/tcg/fpu_helper.c  |  6 +++---
>  target/mips/tcg/msa_helper.c  |  2 +-
>  target/rx/op_helper.c         |  2 +-
>  fpu/softfloat-parts.c.inc     |  2 +-
>  8 files changed, 17 insertions(+), 17 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal
  2021-05-27  4:13 ` [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal Richard Henderson
  2021-06-07 15:16   ` Alex Bennée
@ 2021-06-19 15:08   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19 15:08 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: mmorrell, alex.bennee

On 5/27/21 6:13 AM, Richard Henderson wrote:
> The new name emphasizes that the output denormal has been flushed to zero.
> 
> Patch created mechanically using:
>   sed -i s,float_flag_output_denormal,float_flag_oflush_denormal,g \
>     $(git grep -l float_flag_output_denormal)
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/fpu/softfloat-types.h | 2 +-
>  fpu/softfloat.c               | 2 +-
>  target/arm/vfp_helper.c       | 2 +-
>  target/i386/tcg/fpu_helper.c  | 2 +-
>  target/mips/tcg/msa_helper.c  | 2 +-
>  target/rx/op_helper.c         | 2 +-
>  target/tricore/fpu_helper.c   | 6 +++---
>  fpu/softfloat-parts.c.inc     | 2 +-
>  8 files changed, 10 insertions(+), 10 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 04/11] softfloat: Introduce float_flag_result_denormal
  2021-05-27  4:13 ` [PATCH 04/11] softfloat: Introduce float_flag_result_denormal Richard Henderson
  2021-06-07 16:30   ` Alex Bennée
@ 2021-06-19 15:10   ` Philippe Mathieu-Daudé
  1 sibling, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19 15:10 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: mmorrell, alex.bennee

On 5/27/21 6:13 AM, Richard Henderson wrote:
> Create a new exception flag for reporting output denormals
> that are not flushed to zero.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/fpu/softfloat-types.h | 3 ++-
>  fpu/softfloat-parts.c.inc     | 8 ++++++--
>  2 files changed, 8 insertions(+), 3 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 10/11] target/mips: Do not check MSACSR_FS_MASK in update_msacsr
  2021-05-27  4:14 ` [PATCH 10/11] target/mips: Do not check MSACSR_FS_MASK in update_msacsr Richard Henderson
@ 2021-06-19 15:15   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 38+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-06-19 15:15 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: mmorrell, alex.bennee

On 5/27/21 6:14 AM, Richard Henderson wrote:
> The FS_MASK has already been taken into account with
> restore_msa_fp_status.  The definition of iflush and
> oflush is that we *have* flushed to zero.
> 
> Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/mips/tcg/msa_helper.c | 6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 05/11] target/i386: Use float_flag_inorm_denormal
  2021-05-27  4:13 ` [PATCH 05/11] target/i386: Use float_flag_inorm_denormal Richard Henderson
@ 2021-06-19 18:41   ` Richard Henderson
  0 siblings, 0 replies; 38+ messages in thread
From: Richard Henderson @ 2021-06-19 18:41 UTC (permalink / raw)
  To: qemu-devel; +Cc: alex.bennee, mmorrell, Eduardo Habkost, Paolo Bonzini

Ping.  Cc paolo, ed.

This is the last unreviewed patch in this series, and the one that sparked the work in the 
first place.

r~

On 5/26/21 9:13 PM, Richard Henderson wrote:
> The FSR and MXCSR DE flags have the semantics of the new flag.
> We get to remove a big fixme in update_mxcsr_from_sse_status
> vs float_flag_iflush_denormal.
> 
> Reported-by: Michael Morrell <mmorrell@tachyum.com>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   target/i386/tcg/fpu_helper.c | 18 ++++++------------
>   1 file changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
> index c9779a9fe0..edc550de55 100644
> --- a/target/i386/tcg/fpu_helper.c
> +++ b/target/i386/tcg/fpu_helper.c
> @@ -148,7 +148,7 @@ static void merge_exception_flags(CPUX86State *env, uint8_t old_flags)
>                          (new_flags & float_flag_overflow ? FPUS_OE : 0) |
>                          (new_flags & float_flag_underflow ? FPUS_UE : 0) |
>                          (new_flags & float_flag_inexact ? FPUS_PE : 0) |
> -                       (new_flags & float_flag_iflush_denormal ? FPUS_DE : 0)));
> +                       (new_flags & float_flag_inorm_denormal ? FPUS_DE : 0)));
>   }
>   
>   static inline floatx80 helper_fdiv(CPUX86State *env, floatx80 a, floatx80 b)
> @@ -1742,7 +1742,7 @@ void helper_fxtract(CPUX86State *env)
>               int shift = clz64(temp.l.lower);
>               temp.l.lower <<= shift;
>               expdif = 1 - EXPBIAS - shift;
> -            float_raise(float_flag_iflush_denormal, &env->fp_status);
> +            float_raise(float_flag_inorm_denormal, &env->fp_status);
>           } else {
>               expdif = EXPD(temp) - EXPBIAS;
>           }
> @@ -2976,7 +2976,8 @@ void update_mxcsr_status(CPUX86State *env)
>                                 (mxcsr & FPUS_ZE ? float_flag_divbyzero : 0) |
>                                 (mxcsr & FPUS_OE ? float_flag_overflow : 0) |
>                                 (mxcsr & FPUS_UE ? float_flag_underflow : 0) |
> -                              (mxcsr & FPUS_PE ? float_flag_inexact : 0),
> +                              (mxcsr & FPUS_PE ? float_flag_inexact : 0) |
> +                              (mxcsr & FPUS_DE ? float_flag_inorm_denormal : 0),
>                                 &env->sse_status);
>   
>       /* set denormals are zero */
> @@ -2989,20 +2990,13 @@ void update_mxcsr_status(CPUX86State *env)
>   void update_mxcsr_from_sse_status(CPUX86State *env)
>   {
>       uint8_t flags = get_float_exception_flags(&env->sse_status);
> -    /*
> -     * The MXCSR denormal flag has opposite semantics to
> -     * float_flag_iflush_denormal (the softfloat code sets that flag
> -     * only when flushing input denormals to zero, but SSE sets it
> -     * only when not flushing them to zero), so is not converted
> -     * here.
> -     */
>       env->mxcsr |= ((flags & float_flag_invalid ? FPUS_IE : 0) |
>                      (flags & float_flag_divbyzero ? FPUS_ZE : 0) |
>                      (flags & float_flag_overflow ? FPUS_OE : 0) |
>                      (flags & float_flag_underflow ? FPUS_UE : 0) |
>                      (flags & float_flag_inexact ? FPUS_PE : 0) |
> -                   (flags & float_flag_oflush_denormal ? FPUS_UE | FPUS_PE :
> -                    0));
> +                   (flags & float_flag_inorm_denormal ? FPUS_DE : 0) |
> +                   (flags & float_flag_oflush_denormal ? FPUS_UE | FPUS_PE : 0));
>   }
>   
>   void helper_update_mxcsr(CPUX86State *env)
> 



^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-05-29 15:21     ` Richard Henderson
@ 2021-07-14 16:44       ` Michael Morrell
  2021-07-14 16:57         ` Richard Henderson
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Morrell @ 2021-07-14 16:44 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Just curious.  What's the expected timeline to get these denormal patches in the tree?

-----Original Message-----
From: Richard Henderson <richard.henderson@linaro.org> 
Sent: Saturday, May 29, 2021 8:21 AM
To: Michael Morrell <mmorrell@tachyum.com>; qemu-devel@nongnu.org
Cc: alex.bennee@linaro.org
Subject: Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal

On 5/28/21 10:41 AM, Michael Morrell wrote:
> I'm probably missing something, but why do we need both "float_flag_inorm_denormal" and "float_flag_iflush_denormal"?
> 
> Couldn't the code that sets these flags set just a single flag for all 
> denormal inputs and the code that checks these flags check that single flag combined with the "flush_inputs_to_zero" flag to accomplish what the two separate "input denormal" flags do?

The thing that you're missing is that many guests leave the accumulated softfloat exceptions in the float_status structure until the guest FPSCR register is read. Unless the guest needs to raise an exception immediately, there's no reason to do otherwise.

With this setup, you have no temporal connection between "any denormal" and "flush-to-zero is set", thus two flags.


r~

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-07-14 16:44       ` Michael Morrell
@ 2021-07-14 16:57         ` Richard Henderson
  2021-07-14 17:50           ` Michael Morrell
  0 siblings, 1 reply; 38+ messages in thread
From: Richard Henderson @ 2021-07-14 16:57 UTC (permalink / raw)
  To: Michael Morrell, qemu-devel

On 7/14/21 9:44 AM, Michael Morrell wrote:
> Just curious.  What's the expected timeline to get these denormal patches in the tree?

Next development cycle, at minimum.  I need to fix the problems vs NaNs that you identified.


r~


^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-07-14 16:57         ` Richard Henderson
@ 2021-07-14 17:50           ` Michael Morrell
  2022-01-12  0:02             ` Michael Morrell
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Morrell @ 2021-07-14 17:50 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

OK, thanks for the update.  I also appreciate you looking at the NaN issue.

   Michael

-----Original Message-----
From: Richard Henderson <richard.henderson@linaro.org> 
Sent: Wednesday, July 14, 2021 9:57 AM
To: Michael Morrell <mmorrell@tachyum.com>; qemu-devel@nongnu.org
Subject: Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal

On 7/14/21 9:44 AM, Michael Morrell wrote:
> Just curious.  What's the expected timeline to get these denormal patches in the tree?

Next development cycle, at minimum.  I need to fix the problems vs NaNs that you identified.


r~

^ permalink raw reply	[flat|nested] 38+ messages in thread

* RE: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal
  2021-07-14 17:50           ` Michael Morrell
@ 2022-01-12  0:02             ` Michael Morrell
  0 siblings, 0 replies; 38+ messages in thread
From: Michael Morrell @ 2022-01-12  0:02 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel

Richard,

It's been 6 months so I thought I'd check in again.   Do you have an estimate of when this will go in?

   Michael

-----Original Message-----
From: Michael Morrell 
Sent: Wednesday, July 14, 2021 10:50 AM
To: 'Richard Henderson' <richard.henderson@linaro.org>; qemu-devel@nongnu.org
Subject: RE: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal

OK, thanks for the update.  I also appreciate you looking at the NaN issue.

   Michael

-----Original Message-----
From: Richard Henderson <richard.henderson@linaro.org> 
Sent: Wednesday, July 14, 2021 9:57 AM
To: Michael Morrell <mmorrell@tachyum.com>; qemu-devel@nongnu.org
Subject: Re: [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal

On 7/14/21 9:44 AM, Michael Morrell wrote:
> Just curious.  What's the expected timeline to get these denormal patches in the tree?

Next development cycle, at minimum.  I need to fix the problems vs NaNs that you identified.


r~

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2022-01-12  0:03 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-27  4:13 [PATCH 00/11] softfloat: Improve denormal handling Richard Henderson
2021-05-27  4:13 ` [PATCH 01/11] softfloat: Rename float_flag_input_denormal to float_flag_iflush_denormal Richard Henderson
2021-06-07 15:16   ` Alex Bennée
2021-06-19 15:08   ` Philippe Mathieu-Daudé
2021-05-27  4:13 ` [PATCH 02/11] softfloat: Rename float_flag_output_denormal to float_flag_oflush_denormal Richard Henderson
2021-06-07 15:16   ` Alex Bennée
2021-06-19 15:08   ` Philippe Mathieu-Daudé
2021-05-27  4:13 ` [PATCH 03/11] softfloat: Introduce float_flag_inorm_denormal Richard Henderson
2021-05-28 17:41   ` Michael Morrell
2021-05-29 15:21     ` Richard Henderson
2021-07-14 16:44       ` Michael Morrell
2021-07-14 16:57         ` Richard Henderson
2021-07-14 17:50           ` Michael Morrell
2022-01-12  0:02             ` Michael Morrell
2021-06-07 15:35   ` Alex Bennée
2021-06-07 16:28     ` Alex Bennée
2021-06-07 16:41     ` Richard Henderson
2021-06-07 17:19       ` Alex Bennée
2021-06-07 20:52         ` Richard Henderson
2021-05-27  4:13 ` [PATCH 04/11] softfloat: Introduce float_flag_result_denormal Richard Henderson
2021-06-07 16:30   ` Alex Bennée
2021-06-19 15:10   ` Philippe Mathieu-Daudé
2021-05-27  4:13 ` [PATCH 05/11] target/i386: Use float_flag_inorm_denormal Richard Henderson
2021-06-19 18:41   ` Richard Henderson
2021-05-27  4:14 ` [PATCH 06/11] target/rx: Handle the FPSW.DN bit in helper_set_fpsw Richard Henderson
2021-05-28 15:34   ` Yoshinori Sato
2021-05-27  4:14 ` [PATCH 07/11] target/rx: Use FloatRoundMode " Richard Henderson
2021-05-28 15:35   ` Yoshinori Sato
2021-06-01  3:27   ` Philippe Mathieu-Daudé
2021-05-27  4:14 ` [PATCH 08/11] target/rx: Fix setting of FPSW.CE Richard Henderson
2021-05-28 15:35   ` Yoshinori Sato
2021-05-27  4:14 ` [PATCH 09/11] target/mips: Drop inline markers from msa_helper.c Richard Henderson
2021-06-01  3:27   ` Philippe Mathieu-Daudé
2021-05-27  4:14 ` [PATCH 10/11] target/mips: Do not check MSACSR_FS_MASK in update_msacsr Richard Henderson
2021-06-19 15:15   ` Philippe Mathieu-Daudé
2021-05-27  4:14 ` [PATCH 11/11] target/mips: Drop denormal operand to update_msacsr Richard Henderson
2021-06-01  3:29   ` Philippe Mathieu-Daudé
2021-06-07 16:31 ` [PATCH 00/11] softfloat: Improve denormal handling Alex Bennée

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).