qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v5 44/49] target/ppc: Refactor VSX_MAX_MINC helper


From: Richard Henderson
Subject: Re: [PATCH v5 44/49] target/ppc: Refactor VSX_MAX_MINC helper
Date: Fri, 25 Feb 2022 12:10:31 -1000
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0

On 2/25/22 11:09, matheus.ferst@eldorado.org.br wrote:
From: Víctor Colombo <victor.colombo@eldorado.org.br>

Refactor xs{max,min}cdp VSX_MAX_MINC helper to prepare for
xs{max,min}cqp implementation.

Signed-off-by: Víctor Colombo <victor.colombo@eldorado.org.br>
Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br>
---
changes for v5:
- use float_flag_invalid_snan as suggested by Richard Henderson
---
  target/ppc/fpu_helper.c | 41 +++++++++++++++++------------------------
  1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 4bfa1c4283..0aaf529ac8 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -2533,40 +2533,33 @@ VSX_MAX_MIN(xsmindp, minnum, 1, float64, VsrD(0))
  VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i))
  VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))
-#define VSX_MAX_MINC(name, max) \
+#define VSX_MAX_MINC(name, max, tp, fld)                                      \
  void helper_##name(CPUPPCState *env,                                          
\
                     ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)               
\
  {                                                                             
\
      ppc_vsr_t t = { };                                                        
\
-    bool vxsnan_flag = false, vex_flag = false;                               \
+    bool first;                                                               \
                                                                                
\
-    if (unlikely(float64_is_any_nan(xa->VsrD(0)) ||                           \
-                 float64_is_any_nan(xb->VsrD(0)))) {                          \
-        if (float64_is_signaling_nan(xa->VsrD(0), &env->fp_status) ||         \
-            float64_is_signaling_nan(xb->VsrD(0), &env->fp_status)) {         \
-            vxsnan_flag = true;                                               \
-        }                                                                     \
-        t.VsrD(0) = xb->VsrD(0);                                              \
-    } else if ((max &&                                                        \
-               !float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status)) ||     \
-               (!max &&                                                       \
-               float64_lt(xa->VsrD(0), xb->VsrD(0), &env->fp_status))) {      \
-        t.VsrD(0) = xa->VsrD(0);                                              \
+    if (max) {                                                                \
+        first = tp##_le_quiet(xb->fld, xa->fld, &env->fp_status);             \
      } else {                                                                  
\
-        t.VsrD(0) = xb->VsrD(0);                                              \
+        first = tp##_lt_quiet(xa->fld, xb->fld, &env->fp_status);             \
      }                                                                         
\
                                                                                
\
-    vex_flag = fpscr_ve & vxsnan_flag;                                        \
-    if (vxsnan_flag) {                                                        \
-        float_invalid_op_vxsnan(env, GETPC());                                \
+    if (first) {                                                              \
+        t.fld = xa->fld;                                                      \
+    } else {                                                                  \
+        t.fld = xb->fld;                                                      \
+        if (env->fp_status.float_exception_flags & float_flag_invalid_snan) { \
+            float_invalid_op_vxsnan(env, GETPC());                            \
+        }                                                                     \
      }                                                                         
\
-    if (!vex_flag) {                                                          \
-        *xt = t;                                                              \
-    }                                                                         \
-}                                                                             \
+                                                                              \
+    *xt = t;                                                                  \
+}

I just noticed that we're missing reset_fpstatus at the beginning here.
Since invalid via snan is the only possible exception for min/max, we do not need do_float_check_status at the end.

Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]