diff mbox series

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

Message ID 20220225210936.1749575-45-matheus.ferst@eldorado.org.br (mailing list archive)
State New, archived
Headers show
Series target/ppc: PowerISA Vector/VSX instruction batch | expand

Commit Message

Matheus K. Ferst Feb. 25, 2022, 9:09 p.m. UTC
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(-)

Comments

Richard Henderson Feb. 25, 2022, 10:10 p.m. UTC | #1
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~
diff mbox series

Patch

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;                                                                  \
+}
 
-VSX_MAX_MINC(XSMAXCDP, 1);
-VSX_MAX_MINC(XSMINCDP, 0);
+VSX_MAX_MINC(XSMAXCDP, true, float64, VsrD(0));
+VSX_MAX_MINC(XSMINCDP, false, float64, VsrD(0));
 
 #define VSX_MAX_MINJ(name, max)                                               \
 void helper_##name(CPUPPCState *env,                                          \