qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411]
@ 2023-01-15 16:06 Richard Henderson
  2023-01-15 16:06 ` [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm Richard Henderson
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Richard Henderson @ 2023-01-15 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, bin.meng, abdulras

These double calls tickle an assertion in decode_save_opc,
and isn't efficient anyway.  Introduce a new helper to do
exactly what was desired.


r~


Richard Henderson (2):
  target/arm: Introduce helper_set_rounding_mode_chkfrm
  target/riscv: Remove helper_set_rod_rounding_mode

 target/riscv/helper.h                   |  2 +-
 target/riscv/fpu_helper.c               | 36 +++++++++++++++++++++++--
 target/riscv/translate.c                | 21 ++++++++++++---
 target/riscv/insn_trans/trans_rvv.c.inc | 24 +++--------------
 4 files changed, 57 insertions(+), 26 deletions(-)

-- 
2.34.1



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

* [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm
  2023-01-15 16:06 [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson
@ 2023-01-15 16:06 ` Richard Henderson
  2023-01-18 10:00   ` Daniel Henrique Barboza
  2023-01-18 22:51   ` Alistair Francis
  2023-01-15 16:06 ` [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode Richard Henderson
  2023-01-15 16:21 ` [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson
  2 siblings, 2 replies; 9+ messages in thread
From: Richard Henderson @ 2023-01-15 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, bin.meng, abdulras

The new helper always validates the contents of FRM, even
if the new rounding mode is not DYN.  This is required by
the vector unit.

Track whether we've validated FRM separately from whether
we've updated fp_status with a given rounding mode, so that
we can elide calls correctly.

This partially reverts d6c4d3f2a69 which attempted the to do
the same thing, but with two calls to gen_set_rm(), which is
both inefficient and tickles an assertion in decode_save_opc.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1441
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/helper.h                   |  1 +
 target/riscv/fpu_helper.c               | 37 +++++++++++++++++++++++++
 target/riscv/translate.c                | 19 +++++++++++++
 target/riscv/insn_trans/trans_rvv.c.inc | 24 +++-------------
 4 files changed, 61 insertions(+), 20 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 227c7122ef..9792ab5086 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -3,6 +3,7 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
 
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
+DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
 DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
 
 /* Floating Point - fused */
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 5699c9517f..96817df8ef 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -81,6 +81,43 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
     set_float_rounding_mode(softrm, &env->fp_status);
 }
 
+void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
+{
+    int softrm;
+
+    /* Always validate frm, even if rm != DYN. */
+    if (unlikely(env->frm >= 5)) {
+        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+    }
+    if (rm == RISCV_FRM_DYN) {
+        rm = env->frm;
+    }
+    switch (rm) {
+    case RISCV_FRM_RNE:
+        softrm = float_round_nearest_even;
+        break;
+    case RISCV_FRM_RTZ:
+        softrm = float_round_to_zero;
+        break;
+    case RISCV_FRM_RDN:
+        softrm = float_round_down;
+        break;
+    case RISCV_FRM_RUP:
+        softrm = float_round_up;
+        break;
+    case RISCV_FRM_RMM:
+        softrm = float_round_ties_away;
+        break;
+    case RISCV_FRM_ROD:
+        softrm = float_round_to_odd;
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    set_float_rounding_mode(softrm, &env->fp_status);
+}
+
 void helper_set_rod_rounding_mode(CPURISCVState *env)
 {
     set_float_rounding_mode(float_round_to_odd, &env->fp_status);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index df38db7553..493c3815e1 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -114,6 +114,8 @@ typedef struct DisasContext {
     bool pm_base_enabled;
     /* Use icount trigger for native debug */
     bool itrigger;
+    /* FRM is known to contain a valid value. */
+    bool frm_valid;
     /* TCG of the current insn_start */
     TCGOp *insn_start;
 } DisasContext;
@@ -674,12 +676,29 @@ static void gen_set_rm(DisasContext *ctx, int rm)
         gen_helper_set_rod_rounding_mode(cpu_env);
         return;
     }
+    if (rm == RISCV_FRM_DYN) {
+        /* The helper will return only if frm valid. */
+        ctx->frm_valid = true;
+    }
 
     /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
     decode_save_opc(ctx);
     gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
 }
 
+static void gen_set_rm_chkfrm(DisasContext *ctx, int rm)
+{
+    if (ctx->frm == rm && ctx->frm_valid) {
+        return;
+    }
+    ctx->frm = rm;
+    ctx->frm_valid = true;
+
+    /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
+    decode_save_opc(ctx);
+    gen_helper_set_rounding_mode_chkfrm(cpu_env, tcg_constant_i32(rm));
+}
+
 static int ex_plus_1(DisasContext *ctx, int nf)
 {
     return nf + 1;
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index d455acedbf..bbb5c3a7b5 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -2679,13 +2679,9 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
                     int rm)
 {
     if (checkfn(s, a)) {
-        if (rm != RISCV_FRM_DYN) {
-            gen_set_rm(s, RISCV_FRM_DYN);
-        }
-
         uint32_t data = 0;
         TCGLabel *over = gen_new_label();
-        gen_set_rm(s, rm);
+        gen_set_rm_chkfrm(s, rm);
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
         tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
 
@@ -2882,17 +2878,13 @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
 {                                                                  \
     if (CHECK(s, a)) {                                             \
-        if (FRM != RISCV_FRM_DYN) {                                \
-            gen_set_rm(s, RISCV_FRM_DYN);                          \
-        }                                                          \
-                                                                   \
         uint32_t data = 0;                                         \
         static gen_helper_gvec_3_ptr * const fns[2] = {            \
             gen_helper_##HELPER##_h,                               \
             gen_helper_##HELPER##_w,                               \
         };                                                         \
         TCGLabel *over = gen_new_label();                          \
-        gen_set_rm(s, FRM);                                        \
+        gen_set_rm_chkfrm(s, FRM);                                 \
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
         tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
                                                                    \
@@ -3005,17 +2997,13 @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
 {                                                                  \
     if (CHECK(s, a)) {                                             \
-        if (FRM != RISCV_FRM_DYN) {                                \
-            gen_set_rm(s, RISCV_FRM_DYN);                          \
-        }                                                          \
-                                                                   \
         uint32_t data = 0;                                         \
         static gen_helper_gvec_3_ptr * const fns[2] = {            \
             gen_helper_##HELPER##_h,                               \
             gen_helper_##HELPER##_w,                               \
         };                                                         \
         TCGLabel *over = gen_new_label();                          \
-        gen_set_rm(s, FRM);                                        \
+        gen_set_rm_chkfrm(s, FRM);                                 \
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
         tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
                                                                    \
@@ -3060,10 +3048,6 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
 static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
 {                                                                  \
     if (opxfv_narrow_check(s, a)) {                                \
-        if (FRM != RISCV_FRM_DYN) {                                \
-            gen_set_rm(s, RISCV_FRM_DYN);                          \
-        }                                                          \
-                                                                   \
         uint32_t data = 0;                                         \
         static gen_helper_gvec_3_ptr * const fns[3] = {            \
             gen_helper_##HELPER##_b,                               \
@@ -3071,7 +3055,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
             gen_helper_##HELPER##_w,                               \
         };                                                         \
         TCGLabel *over = gen_new_label();                          \
-        gen_set_rm(s, FRM);                                        \
+        gen_set_rm_chkfrm(s, FRM);                                 \
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
         tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
                                                                    \
-- 
2.34.1



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

* [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode
  2023-01-15 16:06 [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson
  2023-01-15 16:06 ` [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm Richard Henderson
@ 2023-01-15 16:06 ` Richard Henderson
  2023-01-18 10:01   ` Daniel Henrique Barboza
  2023-01-18 22:53   ` Alistair Francis
  2023-01-15 16:21 ` [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson
  2 siblings, 2 replies; 9+ messages in thread
From: Richard Henderson @ 2023-01-15 16:06 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, bin.meng, abdulras

The only setting of RISCV_FRM_ROD is from the vector unit,
and now handled by helper_set_rounding_mode_chkfrm.
This helper is now unused.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/helper.h     | 1 -
 target/riscv/fpu_helper.c | 5 -----
 target/riscv/translate.c  | 4 ----
 3 files changed, 10 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 9792ab5086..58a30f03d6 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -4,7 +4,6 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
 /* Floating Point - rounding mode */
 DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
 DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
-DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
 
 /* Floating Point - fused */
 DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
index 96817df8ef..449d236df6 100644
--- a/target/riscv/fpu_helper.c
+++ b/target/riscv/fpu_helper.c
@@ -118,11 +118,6 @@ void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
     set_float_rounding_mode(softrm, &env->fp_status);
 }
 
-void helper_set_rod_rounding_mode(CPURISCVState *env)
-{
-    set_float_rounding_mode(float_round_to_odd, &env->fp_status);
-}
-
 static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
                            uint64_t rs3, int flags)
 {
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 493c3815e1..01cc30a365 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -672,10 +672,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
     }
     ctx->frm = rm;
 
-    if (rm == RISCV_FRM_ROD) {
-        gen_helper_set_rod_rounding_mode(cpu_env);
-        return;
-    }
     if (rm == RISCV_FRM_DYN) {
         /* The helper will return only if frm valid. */
         ctx->frm_valid = true;
-- 
2.34.1



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

* Re: [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411]
  2023-01-15 16:06 [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson
  2023-01-15 16:06 ` [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm Richard Henderson
  2023-01-15 16:06 ` [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode Richard Henderson
@ 2023-01-15 16:21 ` Richard Henderson
  2 siblings, 0 replies; 9+ messages in thread
From: Richard Henderson @ 2023-01-15 16:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis, bin.meng

On 1/15/23 06:06, Richard Henderson wrote:
> These double calls tickle an assertion in decode_save_opc,
> and isn't efficient anyway.  Introduce a new helper to do
> exactly what was desired.

Also #1339.


r~



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

* Re: [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm
  2023-01-15 16:06 ` [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm Richard Henderson
@ 2023-01-18 10:00   ` Daniel Henrique Barboza
  2023-01-18 23:49     ` Alistair Francis
  2023-01-18 22:51   ` Alistair Francis
  1 sibling, 1 reply; 9+ messages in thread
From: Daniel Henrique Barboza @ 2023-01-18 10:00 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: qemu-riscv, alistair.francis, bin.meng, abdulras

[-- Attachment #1: Type: text/plain, Size: 9559 bytes --]

s/arm/riscv in subject/commit title ^

On 1/15/23 13:06, Richard Henderson wrote:
> The new helper always validates the contents of FRM, even
> if the new rounding mode is not DYN.  This is required by
> the vector unit.
>
> Track whether we've validated FRM separately from whether
> we've updated fp_status with a given rounding mode, so that
> we can elide calls correctly.
>
> This partially reverts d6c4d3f2a69 which attempted the to do
> the same thing, but with two calls to gen_set_rm(), which is
> both inefficient and tickles an assertion in decode_save_opc.
>
> Resolves:https://gitlab.com/qemu-project/qemu/-/issues/1441
> Signed-off-by: Richard Henderson<richard.henderson@linaro.org>
> ---

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

>   target/riscv/helper.h                   |  1 +
>   target/riscv/fpu_helper.c               | 37 +++++++++++++++++++++++++
>   target/riscv/translate.c                | 19 +++++++++++++
>   target/riscv/insn_trans/trans_rvv.c.inc | 24 +++-------------
>   4 files changed, 61 insertions(+), 20 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 227c7122ef..9792ab5086 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -3,6 +3,7 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
>   
>   /* Floating Point - rounding mode */
>   DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
> +DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
>   DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
>   
>   /* Floating Point - fused */
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 5699c9517f..96817df8ef 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -81,6 +81,43 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
>       set_float_rounding_mode(softrm, &env->fp_status);
>   }
>   
> +void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
> +{
> +    int softrm;
> +
> +    /* Always validate frm, even if rm != DYN. */
> +    if (unlikely(env->frm >= 5)) {
> +        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> +    }
> +    if (rm == RISCV_FRM_DYN) {
> +        rm = env->frm;
> +    }
> +    switch (rm) {
> +    case RISCV_FRM_RNE:
> +        softrm = float_round_nearest_even;
> +        break;
> +    case RISCV_FRM_RTZ:
> +        softrm = float_round_to_zero;
> +        break;
> +    case RISCV_FRM_RDN:
> +        softrm = float_round_down;
> +        break;
> +    case RISCV_FRM_RUP:
> +        softrm = float_round_up;
> +        break;
> +    case RISCV_FRM_RMM:
> +        softrm = float_round_ties_away;
> +        break;
> +    case RISCV_FRM_ROD:
> +        softrm = float_round_to_odd;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    set_float_rounding_mode(softrm, &env->fp_status);
> +}
> +
>   void helper_set_rod_rounding_mode(CPURISCVState *env)
>   {
>       set_float_rounding_mode(float_round_to_odd, &env->fp_status);
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index df38db7553..493c3815e1 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -114,6 +114,8 @@ typedef struct DisasContext {
>       bool pm_base_enabled;
>       /* Use icount trigger for native debug */
>       bool itrigger;
> +    /* FRM is known to contain a valid value. */
> +    bool frm_valid;
>       /* TCG of the current insn_start */
>       TCGOp *insn_start;
>   } DisasContext;
> @@ -674,12 +676,29 @@ static void gen_set_rm(DisasContext *ctx, int rm)
>           gen_helper_set_rod_rounding_mode(cpu_env);
>           return;
>       }
> +    if (rm == RISCV_FRM_DYN) {
> +        /* The helper will return only if frm valid. */
> +        ctx->frm_valid = true;
> +    }
>   
>       /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
>       decode_save_opc(ctx);
>       gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
>   }
>   
> +static void gen_set_rm_chkfrm(DisasContext *ctx, int rm)
> +{
> +    if (ctx->frm == rm && ctx->frm_valid) {
> +        return;
> +    }
> +    ctx->frm = rm;
> +    ctx->frm_valid = true;
> +
> +    /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
> +    decode_save_opc(ctx);
> +    gen_helper_set_rounding_mode_chkfrm(cpu_env, tcg_constant_i32(rm));
> +}
> +
>   static int ex_plus_1(DisasContext *ctx, int nf)
>   {
>       return nf + 1;
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index d455acedbf..bbb5c3a7b5 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2679,13 +2679,9 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
>                       int rm)
>   {
>       if (checkfn(s, a)) {
> -        if (rm != RISCV_FRM_DYN) {
> -            gen_set_rm(s, RISCV_FRM_DYN);
> -        }
> -
>           uint32_t data = 0;
>           TCGLabel *over = gen_new_label();
> -        gen_set_rm(s, rm);
> +        gen_set_rm_chkfrm(s, rm);
>           tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>           tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
>   
> @@ -2882,17 +2878,13 @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
>   static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>   {                                                                  \
>       if (CHECK(s, a)) {                                             \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>           uint32_t data = 0;                                         \
>           static gen_helper_gvec_3_ptr * const fns[2] = {            \
>               gen_helper_##HELPER##_h,                               \
>               gen_helper_##HELPER##_w,                               \
>           };                                                         \
>           TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>           tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>           tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                      \
> @@ -3005,17 +2997,13 @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
>   static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>   {                                                                  \
>       if (CHECK(s, a)) {                                             \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>           uint32_t data = 0;                                         \
>           static gen_helper_gvec_3_ptr * const fns[2] = {            \
>               gen_helper_##HELPER##_h,                               \
>               gen_helper_##HELPER##_w,                               \
>           };                                                         \
>           TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>           tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>           tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                      \
> @@ -3060,10 +3048,6 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
>   static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>   {                                                                  \
>       if (opxfv_narrow_check(s, a)) {                                \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>           uint32_t data = 0;                                         \
>           static gen_helper_gvec_3_ptr * const fns[3] = {            \
>               gen_helper_##HELPER##_b,                               \
> @@ -3071,7 +3055,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>               gen_helper_##HELPER##_w,                               \
>           };                                                         \
>           TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>           tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>           tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                      \

[-- Attachment #2: Type: text/html, Size: 9987 bytes --]

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

* Re: [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode
  2023-01-15 16:06 ` [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode Richard Henderson
@ 2023-01-18 10:01   ` Daniel Henrique Barboza
  2023-01-18 22:53   ` Alistair Francis
  1 sibling, 0 replies; 9+ messages in thread
From: Daniel Henrique Barboza @ 2023-01-18 10:01 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel
  Cc: qemu-riscv, alistair.francis, bin.meng, abdulras



On 1/15/23 13:06, Richard Henderson wrote:
> The only setting of RISCV_FRM_ROD is from the vector unit,
> and now handled by helper_set_rounding_mode_chkfrm.
> This helper is now unused.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

>   target/riscv/helper.h     | 1 -
>   target/riscv/fpu_helper.c | 5 -----
>   target/riscv/translate.c  | 4 ----
>   3 files changed, 10 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 9792ab5086..58a30f03d6 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -4,7 +4,6 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
>   /* Floating Point - rounding mode */
>   DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
>   DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
> -DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
>   
>   /* Floating Point - fused */
>   DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 96817df8ef..449d236df6 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -118,11 +118,6 @@ void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
>       set_float_rounding_mode(softrm, &env->fp_status);
>   }
>   
> -void helper_set_rod_rounding_mode(CPURISCVState *env)
> -{
> -    set_float_rounding_mode(float_round_to_odd, &env->fp_status);
> -}
> -
>   static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
>                              uint64_t rs3, int flags)
>   {
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 493c3815e1..01cc30a365 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -672,10 +672,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
>       }
>       ctx->frm = rm;
>   
> -    if (rm == RISCV_FRM_ROD) {
> -        gen_helper_set_rod_rounding_mode(cpu_env);
> -        return;
> -    }
>       if (rm == RISCV_FRM_DYN) {
>           /* The helper will return only if frm valid. */
>           ctx->frm_valid = true;



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

* Re: [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm
  2023-01-15 16:06 ` [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm Richard Henderson
  2023-01-18 10:00   ` Daniel Henrique Barboza
@ 2023-01-18 22:51   ` Alistair Francis
  1 sibling, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2023-01-18 22:51 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, qemu-riscv, alistair.francis, bin.meng, abdulras

On Mon, Jan 16, 2023 at 2:08 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The new helper always validates the contents of FRM, even
> if the new rounding mode is not DYN.  This is required by
> the vector unit.
>
> Track whether we've validated FRM separately from whether
> we've updated fp_status with a given rounding mode, so that
> we can elide calls correctly.
>
> This partially reverts d6c4d3f2a69 which attempted the to do
> the same thing, but with two calls to gen_set_rm(), which is
> both inefficient and tickles an assertion in decode_save_opc.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1441
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Acked-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/helper.h                   |  1 +
>  target/riscv/fpu_helper.c               | 37 +++++++++++++++++++++++++
>  target/riscv/translate.c                | 19 +++++++++++++
>  target/riscv/insn_trans/trans_rvv.c.inc | 24 +++-------------
>  4 files changed, 61 insertions(+), 20 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 227c7122ef..9792ab5086 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -3,6 +3,7 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
>
>  /* Floating Point - rounding mode */
>  DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
> +DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
>  DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
>
>  /* Floating Point - fused */
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 5699c9517f..96817df8ef 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -81,6 +81,43 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
>      set_float_rounding_mode(softrm, &env->fp_status);
>  }
>
> +void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
> +{
> +    int softrm;
> +
> +    /* Always validate frm, even if rm != DYN. */
> +    if (unlikely(env->frm >= 5)) {
> +        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> +    }
> +    if (rm == RISCV_FRM_DYN) {
> +        rm = env->frm;
> +    }
> +    switch (rm) {
> +    case RISCV_FRM_RNE:
> +        softrm = float_round_nearest_even;
> +        break;
> +    case RISCV_FRM_RTZ:
> +        softrm = float_round_to_zero;
> +        break;
> +    case RISCV_FRM_RDN:
> +        softrm = float_round_down;
> +        break;
> +    case RISCV_FRM_RUP:
> +        softrm = float_round_up;
> +        break;
> +    case RISCV_FRM_RMM:
> +        softrm = float_round_ties_away;
> +        break;
> +    case RISCV_FRM_ROD:
> +        softrm = float_round_to_odd;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    set_float_rounding_mode(softrm, &env->fp_status);
> +}
> +
>  void helper_set_rod_rounding_mode(CPURISCVState *env)
>  {
>      set_float_rounding_mode(float_round_to_odd, &env->fp_status);
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index df38db7553..493c3815e1 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -114,6 +114,8 @@ typedef struct DisasContext {
>      bool pm_base_enabled;
>      /* Use icount trigger for native debug */
>      bool itrigger;
> +    /* FRM is known to contain a valid value. */
> +    bool frm_valid;
>      /* TCG of the current insn_start */
>      TCGOp *insn_start;
>  } DisasContext;
> @@ -674,12 +676,29 @@ static void gen_set_rm(DisasContext *ctx, int rm)
>          gen_helper_set_rod_rounding_mode(cpu_env);
>          return;
>      }
> +    if (rm == RISCV_FRM_DYN) {
> +        /* The helper will return only if frm valid. */
> +        ctx->frm_valid = true;
> +    }
>
>      /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
>      decode_save_opc(ctx);
>      gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
>  }
>
> +static void gen_set_rm_chkfrm(DisasContext *ctx, int rm)
> +{
> +    if (ctx->frm == rm && ctx->frm_valid) {
> +        return;
> +    }
> +    ctx->frm = rm;
> +    ctx->frm_valid = true;
> +
> +    /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
> +    decode_save_opc(ctx);
> +    gen_helper_set_rounding_mode_chkfrm(cpu_env, tcg_constant_i32(rm));
> +}
> +
>  static int ex_plus_1(DisasContext *ctx, int nf)
>  {
>      return nf + 1;
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index d455acedbf..bbb5c3a7b5 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2679,13 +2679,9 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
>                      int rm)
>  {
>      if (checkfn(s, a)) {
> -        if (rm != RISCV_FRM_DYN) {
> -            gen_set_rm(s, RISCV_FRM_DYN);
> -        }
> -
>          uint32_t data = 0;
>          TCGLabel *over = gen_new_label();
> -        gen_set_rm(s, rm);
> +        gen_set_rm_chkfrm(s, rm);
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
>
> @@ -2882,17 +2878,13 @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
>  static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>  {                                                                  \
>      if (CHECK(s, a)) {                                             \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>          uint32_t data = 0;                                         \
>          static gen_helper_gvec_3_ptr * const fns[2] = {            \
>              gen_helper_##HELPER##_h,                               \
>              gen_helper_##HELPER##_w,                               \
>          };                                                         \
>          TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                     \
> @@ -3005,17 +2997,13 @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
>  static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>  {                                                                  \
>      if (CHECK(s, a)) {                                             \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>          uint32_t data = 0;                                         \
>          static gen_helper_gvec_3_ptr * const fns[2] = {            \
>              gen_helper_##HELPER##_h,                               \
>              gen_helper_##HELPER##_w,                               \
>          };                                                         \
>          TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                     \
> @@ -3060,10 +3048,6 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
>  static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>  {                                                                  \
>      if (opxfv_narrow_check(s, a)) {                                \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>          uint32_t data = 0;                                         \
>          static gen_helper_gvec_3_ptr * const fns[3] = {            \
>              gen_helper_##HELPER##_b,                               \
> @@ -3071,7 +3055,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>              gen_helper_##HELPER##_w,                               \
>          };                                                         \
>          TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                     \
> --
> 2.34.1
>
>


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

* Re: [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode
  2023-01-15 16:06 ` [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode Richard Henderson
  2023-01-18 10:01   ` Daniel Henrique Barboza
@ 2023-01-18 22:53   ` Alistair Francis
  1 sibling, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2023-01-18 22:53 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel, qemu-riscv, alistair.francis, bin.meng, abdulras

On Mon, Jan 16, 2023 at 2:08 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> The only setting of RISCV_FRM_ROD is from the vector unit,
> and now handled by helper_set_rounding_mode_chkfrm.
> This helper is now unused.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/helper.h     | 1 -
>  target/riscv/fpu_helper.c | 5 -----
>  target/riscv/translate.c  | 4 ----
>  3 files changed, 10 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 9792ab5086..58a30f03d6 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -4,7 +4,6 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
>  /* Floating Point - rounding mode */
>  DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
>  DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
> -DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
>
>  /* Floating Point - fused */
>  DEF_HELPER_FLAGS_4(fmadd_s, TCG_CALL_NO_RWG, i64, env, i64, i64, i64)
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 96817df8ef..449d236df6 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -118,11 +118,6 @@ void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
>      set_float_rounding_mode(softrm, &env->fp_status);
>  }
>
> -void helper_set_rod_rounding_mode(CPURISCVState *env)
> -{
> -    set_float_rounding_mode(float_round_to_odd, &env->fp_status);
> -}
> -
>  static uint64_t do_fmadd_h(CPURISCVState *env, uint64_t rs1, uint64_t rs2,
>                             uint64_t rs3, int flags)
>  {
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 493c3815e1..01cc30a365 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -672,10 +672,6 @@ static void gen_set_rm(DisasContext *ctx, int rm)
>      }
>      ctx->frm = rm;
>
> -    if (rm == RISCV_FRM_ROD) {
> -        gen_helper_set_rod_rounding_mode(cpu_env);
> -        return;
> -    }
>      if (rm == RISCV_FRM_DYN) {
>          /* The helper will return only if frm valid. */
>          ctx->frm_valid = true;
> --
> 2.34.1
>
>


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

* Re: [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm
  2023-01-18 10:00   ` Daniel Henrique Barboza
@ 2023-01-18 23:49     ` Alistair Francis
  0 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2023-01-18 23:49 UTC (permalink / raw)
  To: Daniel Henrique Barboza
  Cc: Richard Henderson, qemu-devel, qemu-riscv, alistair.francis,
	bin.meng, abdulras

On Wed, Jan 18, 2023 at 8:02 PM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> s/arm/riscv in subject/commit title ^

Fixed when committing

Thanks!

Applied to riscv-to-apply.next

Alistair

>
> On 1/15/23 13:06, Richard Henderson wrote:
>
> The new helper always validates the contents of FRM, even
> if the new rounding mode is not DYN.  This is required by
> the vector unit.
>
> Track whether we've validated FRM separately from whether
> we've updated fp_status with a given rounding mode, so that
> we can elide calls correctly.
>
> This partially reverts d6c4d3f2a69 which attempted the to do
> the same thing, but with two calls to gen_set_rm(), which is
> both inefficient and tickles an assertion in decode_save_opc.
>
> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1441
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>
>
> Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
>
>  target/riscv/helper.h                   |  1 +
>  target/riscv/fpu_helper.c               | 37 +++++++++++++++++++++++++
>  target/riscv/translate.c                | 19 +++++++++++++
>  target/riscv/insn_trans/trans_rvv.c.inc | 24 +++-------------
>  4 files changed, 61 insertions(+), 20 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 227c7122ef..9792ab5086 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -3,6 +3,7 @@ DEF_HELPER_2(raise_exception, noreturn, env, i32)
>
>  /* Floating Point - rounding mode */
>  DEF_HELPER_FLAGS_2(set_rounding_mode, TCG_CALL_NO_WG, void, env, i32)
> +DEF_HELPER_FLAGS_2(set_rounding_mode_chkfrm, TCG_CALL_NO_WG, void, env, i32)
>  DEF_HELPER_FLAGS_1(set_rod_rounding_mode, TCG_CALL_NO_WG, void, env)
>
>  /* Floating Point - fused */
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index 5699c9517f..96817df8ef 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -81,6 +81,43 @@ void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm)
>      set_float_rounding_mode(softrm, &env->fp_status);
>  }
>
> +void helper_set_rounding_mode_chkfrm(CPURISCVState *env, uint32_t rm)
> +{
> +    int softrm;
> +
> +    /* Always validate frm, even if rm != DYN. */
> +    if (unlikely(env->frm >= 5)) {
> +        riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> +    }
> +    if (rm == RISCV_FRM_DYN) {
> +        rm = env->frm;
> +    }
> +    switch (rm) {
> +    case RISCV_FRM_RNE:
> +        softrm = float_round_nearest_even;
> +        break;
> +    case RISCV_FRM_RTZ:
> +        softrm = float_round_to_zero;
> +        break;
> +    case RISCV_FRM_RDN:
> +        softrm = float_round_down;
> +        break;
> +    case RISCV_FRM_RUP:
> +        softrm = float_round_up;
> +        break;
> +    case RISCV_FRM_RMM:
> +        softrm = float_round_ties_away;
> +        break;
> +    case RISCV_FRM_ROD:
> +        softrm = float_round_to_odd;
> +        break;
> +    default:
> +        g_assert_not_reached();
> +    }
> +
> +    set_float_rounding_mode(softrm, &env->fp_status);
> +}
> +
>  void helper_set_rod_rounding_mode(CPURISCVState *env)
>  {
>      set_float_rounding_mode(float_round_to_odd, &env->fp_status);
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index df38db7553..493c3815e1 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -114,6 +114,8 @@ typedef struct DisasContext {
>      bool pm_base_enabled;
>      /* Use icount trigger for native debug */
>      bool itrigger;
> +    /* FRM is known to contain a valid value. */
> +    bool frm_valid;
>      /* TCG of the current insn_start */
>      TCGOp *insn_start;
>  } DisasContext;
> @@ -674,12 +676,29 @@ static void gen_set_rm(DisasContext *ctx, int rm)
>          gen_helper_set_rod_rounding_mode(cpu_env);
>          return;
>      }
> +    if (rm == RISCV_FRM_DYN) {
> +        /* The helper will return only if frm valid. */
> +        ctx->frm_valid = true;
> +    }
>
>      /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
>      decode_save_opc(ctx);
>      gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
>  }
>
> +static void gen_set_rm_chkfrm(DisasContext *ctx, int rm)
> +{
> +    if (ctx->frm == rm && ctx->frm_valid) {
> +        return;
> +    }
> +    ctx->frm = rm;
> +    ctx->frm_valid = true;
> +
> +    /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
> +    decode_save_opc(ctx);
> +    gen_helper_set_rounding_mode_chkfrm(cpu_env, tcg_constant_i32(rm));
> +}
> +
>  static int ex_plus_1(DisasContext *ctx, int nf)
>  {
>      return nf + 1;
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index d455acedbf..bbb5c3a7b5 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -2679,13 +2679,9 @@ static bool do_opfv(DisasContext *s, arg_rmr *a,
>                      int rm)
>  {
>      if (checkfn(s, a)) {
> -        if (rm != RISCV_FRM_DYN) {
> -            gen_set_rm(s, RISCV_FRM_DYN);
> -        }
> -
>          uint32_t data = 0;
>          TCGLabel *over = gen_new_label();
> -        gen_set_rm(s, rm);
> +        gen_set_rm_chkfrm(s, rm);
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over);
>
> @@ -2882,17 +2878,13 @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
>  static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>  {                                                                  \
>      if (CHECK(s, a)) {                                             \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>          uint32_t data = 0;                                         \
>          static gen_helper_gvec_3_ptr * const fns[2] = {            \
>              gen_helper_##HELPER##_h,                               \
>              gen_helper_##HELPER##_w,                               \
>          };                                                         \
>          TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                     \
> @@ -3005,17 +2997,13 @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
>  static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>  {                                                                  \
>      if (CHECK(s, a)) {                                             \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>          uint32_t data = 0;                                         \
>          static gen_helper_gvec_3_ptr * const fns[2] = {            \
>              gen_helper_##HELPER##_h,                               \
>              gen_helper_##HELPER##_w,                               \
>          };                                                         \
>          TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                     \
> @@ -3060,10 +3048,6 @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
>  static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>  {                                                                  \
>      if (opxfv_narrow_check(s, a)) {                                \
> -        if (FRM != RISCV_FRM_DYN) {                                \
> -            gen_set_rm(s, RISCV_FRM_DYN);                          \
> -        }                                                          \
> -                                                                   \
>          uint32_t data = 0;                                         \
>          static gen_helper_gvec_3_ptr * const fns[3] = {            \
>              gen_helper_##HELPER##_b,                               \
> @@ -3071,7 +3055,7 @@ static bool trans_##NAME(DisasContext *s, arg_rmr *a)              \
>              gen_helper_##HELPER##_w,                               \
>          };                                                         \
>          TCGLabel *over = gen_new_label();                          \
> -        gen_set_rm(s, FRM);                                        \
> +        gen_set_rm_chkfrm(s, FRM);                                 \
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);          \
>          tcg_gen_brcond_tl(TCG_COND_GEU, cpu_vstart, cpu_vl, over); \
>                                                                     \
>
>


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

end of thread, other threads:[~2023-01-18 23:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-15 16:06 [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson
2023-01-15 16:06 ` [PATCH 1/2] target/arm: Introduce helper_set_rounding_mode_chkfrm Richard Henderson
2023-01-18 10:00   ` Daniel Henrique Barboza
2023-01-18 23:49     ` Alistair Francis
2023-01-18 22:51   ` Alistair Francis
2023-01-15 16:06 ` [PATCH 2/2] target/riscv: Remove helper_set_rod_rounding_mode Richard Henderson
2023-01-18 10:01   ` Daniel Henrique Barboza
2023-01-18 22:53   ` Alistair Francis
2023-01-15 16:21 ` [PATCH 0/2] target/riscv: Fix double calls to gen_set_rm [#1411] Richard Henderson

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).