All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-09  4:25 ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Replace use of tcg_const_*, which makes a copy into a temp
which must be freed, with direct use of the constant.

Reorg handling of $zero, with different accessors for
source and destination.

Reorg handling of csrs, passing the actual write_mask
instead of a regno.

Use more helpers for RVH expansion.


r~


Richard Henderson (17):
  target/riscv: Use tcg_constant_*
  target/riscv: Introduce gpr_src, gpr_dst
  target/riscv: Use gpr_{src,dst} in shift operations
  target/riscv: Use gpr_{src,dst} in word division operations
  target/riscv: Use gpr_{src,dst} and tcg_constant_tl in gen_grevi
  target/riscv: Use gpr_src in branches
  target/riscv: Use gpr_{src,dst} for integer load/store
  target/riscv: Use gpr_{src,dst} for word shift operations
  target/riscv: Reorg csr instructions
  target/riscv: Use gpr_{src,dst} for RVA
  target/riscv: Use gpr_{src,dst} for RVB
  target/riscv: Use gpr_{src,dst} for RVF
  target/riscv: Use gpr_{src,dst} for RVD
  target/riscv: Tidy trans_rvh.c.inc
  target/riscv: Use gen_arith for mulh and mulhu
  target/riscv: Use gpr_{src,dst} for RVV
  target/riscv: Remove gen_get_gpr

 target/riscv/helper.h                   |   6 +-
 target/riscv/insn32.decode              |   1 +
 target/riscv/op_helper.c                |  18 +-
 target/riscv/translate.c                | 273 +++++++++-----------
 target/riscv/insn_trans/trans_rva.c.inc |  42 ++--
 target/riscv/insn_trans/trans_rvb.c.inc |  11 +-
 target/riscv/insn_trans/trans_rvd.c.inc | 116 ++++-----
 target/riscv/insn_trans/trans_rvf.c.inc | 134 ++++------
 target/riscv/insn_trans/trans_rvh.c.inc | 264 ++++---------------
 target/riscv/insn_trans/trans_rvi.c.inc | 322 ++++++++++++++----------
 target/riscv/insn_trans/trans_rvm.c.inc |  24 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 144 ++++-------
 12 files changed, 534 insertions(+), 821 deletions(-)

-- 
2.25.1



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

* [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-09  4:25 ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Replace use of tcg_const_*, which makes a copy into a temp
which must be freed, with direct use of the constant.

Reorg handling of $zero, with different accessors for
source and destination.

Reorg handling of csrs, passing the actual write_mask
instead of a regno.

Use more helpers for RVH expansion.


r~


Richard Henderson (17):
  target/riscv: Use tcg_constant_*
  target/riscv: Introduce gpr_src, gpr_dst
  target/riscv: Use gpr_{src,dst} in shift operations
  target/riscv: Use gpr_{src,dst} in word division operations
  target/riscv: Use gpr_{src,dst} and tcg_constant_tl in gen_grevi
  target/riscv: Use gpr_src in branches
  target/riscv: Use gpr_{src,dst} for integer load/store
  target/riscv: Use gpr_{src,dst} for word shift operations
  target/riscv: Reorg csr instructions
  target/riscv: Use gpr_{src,dst} for RVA
  target/riscv: Use gpr_{src,dst} for RVB
  target/riscv: Use gpr_{src,dst} for RVF
  target/riscv: Use gpr_{src,dst} for RVD
  target/riscv: Tidy trans_rvh.c.inc
  target/riscv: Use gen_arith for mulh and mulhu
  target/riscv: Use gpr_{src,dst} for RVV
  target/riscv: Remove gen_get_gpr

 target/riscv/helper.h                   |   6 +-
 target/riscv/insn32.decode              |   1 +
 target/riscv/op_helper.c                |  18 +-
 target/riscv/translate.c                | 273 +++++++++-----------
 target/riscv/insn_trans/trans_rva.c.inc |  42 ++--
 target/riscv/insn_trans/trans_rvb.c.inc |  11 +-
 target/riscv/insn_trans/trans_rvd.c.inc | 116 ++++-----
 target/riscv/insn_trans/trans_rvf.c.inc | 134 ++++------
 target/riscv/insn_trans/trans_rvh.c.inc | 264 ++++---------------
 target/riscv/insn_trans/trans_rvi.c.inc | 322 ++++++++++++++----------
 target/riscv/insn_trans/trans_rvm.c.inc |  24 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 144 ++++-------
 12 files changed, 534 insertions(+), 821 deletions(-)

-- 
2.25.1



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

* [PATCH 01/17] target/riscv: Use tcg_constant_*
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Replace uses of tcg_const_* with the allocate and free close together.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c                | 36 ++++----------
 target/riscv/insn_trans/trans_rvf.c.inc |  3 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
 3 files changed, 34 insertions(+), 70 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 62a7d7e4c7..bba5ad8ec4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -104,20 +104,16 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
  */
 static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
 {
-    TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull);
-    TCGv_i64 t_nan = tcg_const_i64(0xffffffff7fc00000ull);
+    TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
+    TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
 
     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
-    tcg_temp_free_i64(t_max);
-    tcg_temp_free_i64(t_nan);
 }
 
 static void generate_exception(DisasContext *ctx, int excp)
 {
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-    TCGv_i32 helper_tmp = tcg_const_i32(excp);
-    gen_helper_raise_exception(cpu_env, helper_tmp);
-    tcg_temp_free_i32(helper_tmp);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
@@ -125,17 +121,13 @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
 {
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
-    TCGv_i32 helper_tmp = tcg_const_i32(excp);
-    gen_helper_raise_exception(cpu_env, helper_tmp);
-    tcg_temp_free_i32(helper_tmp);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_exception_debug(void)
 {
-    TCGv_i32 helper_tmp = tcg_const_i32(EXCP_DEBUG);
-    gen_helper_raise_exception(cpu_env, helper_tmp);
-    tcg_temp_free_i32(helper_tmp);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
 }
 
 /* Wrapper around tcg_gen_exit_tb that handles single stepping */
@@ -247,7 +239,7 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
      */
     cond1 = tcg_temp_new();
     cond2 = tcg_temp_new();
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
@@ -268,7 +260,6 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
 
     tcg_temp_free(cond1);
     tcg_temp_free(cond2);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -277,7 +268,7 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
     TCGv cond1, zeroreg, resultopt1;
     cond1 = tcg_temp_new();
 
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
@@ -290,7 +281,6 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
     tcg_gen_divu_tl(ret, source1, source2);
 
     tcg_temp_free(cond1);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -300,7 +290,7 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
 
     cond1 = tcg_temp_new();
     cond2 = tcg_temp_new();
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_movi_tl(resultopt1, 1L);
@@ -320,7 +310,6 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
 
     tcg_temp_free(cond1);
     tcg_temp_free(cond2);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -328,7 +317,7 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
 {
     TCGv cond1, zeroreg, resultopt1;
     cond1 = tcg_temp_new();
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_movi_tl(resultopt1, (target_ulong)1);
@@ -341,7 +330,6 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
             source1);
 
     tcg_temp_free(cond1);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -402,15 +390,11 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
 
 static void gen_set_rm(DisasContext *ctx, int rm)
 {
-    TCGv_i32 t0;
-
     if (ctx->frm == rm) {
         return;
     }
     ctx->frm = rm;
-    t0 = tcg_const_i32(rm);
-    gen_helper_set_rounding_mode(cpu_env, t0);
-    tcg_temp_free_i32(t0);
+    gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
 }
 
 static int ex_plus_1(DisasContext *ctx, int nf)
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index db1c0c9974..89f78701e7 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -200,12 +200,11 @@ static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a)
          * Replace bit 31 in rs1 with inverse in rs2.
          * This formulation retains the nanboxing of rs1.
          */
-        mask = tcg_const_i64(~MAKE_64BIT_MASK(31, 1));
+        mask = tcg_constant_i64(~MAKE_64BIT_MASK(31, 1));
         tcg_gen_nor_i64(rs2, rs2, mask);
         tcg_gen_and_i64(rs1, mask, rs1);
         tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2);
 
-        tcg_temp_free_i64(mask);
         tcg_temp_free_i64(rs2);
     }
     tcg_temp_free_i64(rs1);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 83d9a285ba..a8e7272487 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -33,7 +33,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-        s1 = tcg_const_tl(RV_VLEN_MAX);
+        s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
         s1 = tcg_temp_new();
         gen_get_gpr(s1, a->rs1);
@@ -59,13 +59,13 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
         return false;
     }
 
-    s2 = tcg_const_tl(a->zimm);
+    s2 = tcg_constant_tl(a->zimm);
     dst = tcg_temp_new();
 
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-        s1 = tcg_const_tl(RV_VLEN_MAX);
+        s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
         s1 = tcg_temp_new();
         gen_get_gpr(s1, a->rs1);
@@ -76,7 +76,6 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
     ctx->base.is_jmp = DISAS_NORETURN;
 
     tcg_temp_free(s1);
-    tcg_temp_free(s2);
     tcg_temp_free(dst);
     return true;
 }
@@ -183,7 +182,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
      * The first part is vlen in bytes, encoded in maxsz of simd_desc.
      * The second part is lmul, encoded in data of simd_desc.
      */
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -194,7 +193,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -334,7 +332,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
     mask = tcg_temp_new_ptr();
     base = tcg_temp_new();
     stride = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     gen_get_gpr(stride, rs2);
@@ -347,7 +345,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
     tcg_temp_free_ptr(mask);
     tcg_temp_free(base);
     tcg_temp_free(stride);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -462,7 +459,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
     base = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -475,7 +472,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -594,7 +590,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     base = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -605,7 +601,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -671,7 +666,7 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
     base = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -684,7 +679,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -874,7 +868,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -886,7 +880,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
     tcg_temp_free(src1);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -1014,14 +1007,14 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
     if (zx) {
-        src1 = tcg_const_tl(imm);
+        src1 = tcg_constant_tl(imm);
     } else {
-        src1 = tcg_const_tl(sextract64(imm, 0, 5));
+        src1 = tcg_constant_tl(sextract64(imm, 0, 5));
     }
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1032,8 +1025,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
-    tcg_temp_free(src1);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -1080,9 +1071,8 @@ GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
 static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
                                int64_t c, uint32_t oprsz, uint32_t maxsz)
 {
-    TCGv_i64 tmp = tcg_const_i64(c);
+    TCGv_i64 tmp = tcg_constant_i64(c);
     tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
-    tcg_temp_free_i64(tmp);
 }
 
 GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
@@ -1682,7 +1672,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
                                 MAXSZ(s), MAXSZ(s), s1);
         } else {
-            TCGv_i32 desc ;
+            TCGv_i32 desc;
             TCGv_i64 s1_i64 = tcg_temp_new_i64();
             TCGv_ptr dest = tcg_temp_new_ptr();
             uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
@@ -1692,12 +1682,11 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             };
 
             tcg_gen_ext_tl_i64(s1_i64, s1);
-            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
             tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
             fns[s->sew](dest, s1_i64, cpu_env, desc);
 
             tcg_temp_free_ptr(dest);
-            tcg_temp_free_i32(desc);
             tcg_temp_free_i64(s1_i64);
         }
 
@@ -1729,15 +1718,13 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
             TCGLabel *over = gen_new_label();
             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-            s1 = tcg_const_i64(simm);
+            s1 = tcg_constant_i64(simm);
             dest = tcg_temp_new_ptr();
-            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
             tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
             fns[s->sew](dest, s1, cpu_env, desc);
 
             tcg_temp_free_ptr(dest);
-            tcg_temp_free_i32(desc);
-            tcg_temp_free_i64(s1);
             gen_set_label(over);
         }
         return true;
@@ -1866,7 +1853,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1877,7 +1864,6 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -2231,12 +2217,11 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
             dest = tcg_temp_new_ptr();
-            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
             tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
             fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
 
             tcg_temp_free_ptr(dest);
-            tcg_temp_free_i32(desc);
             gen_set_label(over);
         }
         return true;
@@ -2428,7 +2413,7 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
         dst = tcg_temp_new();
-        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -2439,7 +2424,6 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
         tcg_temp_free(dst);
-        tcg_temp_free_i32(desc);
         return true;
     }
     return false;
@@ -2460,7 +2444,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
         dst = tcg_temp_new();
-        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -2471,7 +2455,6 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
         tcg_temp_free(dst);
-        tcg_temp_free_i32(desc);
         return true;
     }
     return false;
@@ -2636,15 +2619,13 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
     tcg_temp_free_i32(ofs);
 
     /* Flush out-of-range indexing to zero.  */
-    t_vlmax = tcg_const_i64(vlmax);
-    t_zero = tcg_const_i64(0);
+    t_vlmax = tcg_constant_i64(vlmax);
+    t_zero = tcg_constant_i64(0);
     tcg_gen_extu_tl_i64(t_idx, idx);
 
     tcg_gen_movcond_i64(TCG_COND_LTU, dest, t_idx,
                         t_vlmax, dest, t_zero);
 
-    tcg_temp_free_i64(t_vlmax);
-    tcg_temp_free_i64(t_zero);
     tcg_temp_free_i64(t_idx);
 }
 
-- 
2.25.1



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

* [PATCH 01/17] target/riscv: Use tcg_constant_*
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Replace uses of tcg_const_* with the allocate and free close together.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c                | 36 ++++----------
 target/riscv/insn_trans/trans_rvf.c.inc |  3 +-
 target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
 3 files changed, 34 insertions(+), 70 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 62a7d7e4c7..bba5ad8ec4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -104,20 +104,16 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
  */
 static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
 {
-    TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull);
-    TCGv_i64 t_nan = tcg_const_i64(0xffffffff7fc00000ull);
+    TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
+    TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
 
     tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
-    tcg_temp_free_i64(t_max);
-    tcg_temp_free_i64(t_nan);
 }
 
 static void generate_exception(DisasContext *ctx, int excp)
 {
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
-    TCGv_i32 helper_tmp = tcg_const_i32(excp);
-    gen_helper_raise_exception(cpu_env, helper_tmp);
-    tcg_temp_free_i32(helper_tmp);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
@@ -125,17 +121,13 @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
 {
     tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
     tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
-    TCGv_i32 helper_tmp = tcg_const_i32(excp);
-    gen_helper_raise_exception(cpu_env, helper_tmp);
-    tcg_temp_free_i32(helper_tmp);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
     ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_exception_debug(void)
 {
-    TCGv_i32 helper_tmp = tcg_const_i32(EXCP_DEBUG);
-    gen_helper_raise_exception(cpu_env, helper_tmp);
-    tcg_temp_free_i32(helper_tmp);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
 }
 
 /* Wrapper around tcg_gen_exit_tb that handles single stepping */
@@ -247,7 +239,7 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
      */
     cond1 = tcg_temp_new();
     cond2 = tcg_temp_new();
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
@@ -268,7 +260,6 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
 
     tcg_temp_free(cond1);
     tcg_temp_free(cond2);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -277,7 +268,7 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
     TCGv cond1, zeroreg, resultopt1;
     cond1 = tcg_temp_new();
 
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
@@ -290,7 +281,6 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
     tcg_gen_divu_tl(ret, source1, source2);
 
     tcg_temp_free(cond1);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -300,7 +290,7 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
 
     cond1 = tcg_temp_new();
     cond2 = tcg_temp_new();
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_movi_tl(resultopt1, 1L);
@@ -320,7 +310,6 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
 
     tcg_temp_free(cond1);
     tcg_temp_free(cond2);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -328,7 +317,7 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
 {
     TCGv cond1, zeroreg, resultopt1;
     cond1 = tcg_temp_new();
-    zeroreg = tcg_const_tl(0);
+    zeroreg = tcg_constant_tl(0);
     resultopt1 = tcg_temp_new();
 
     tcg_gen_movi_tl(resultopt1, (target_ulong)1);
@@ -341,7 +330,6 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
             source1);
 
     tcg_temp_free(cond1);
-    tcg_temp_free(zeroreg);
     tcg_temp_free(resultopt1);
 }
 
@@ -402,15 +390,11 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
 
 static void gen_set_rm(DisasContext *ctx, int rm)
 {
-    TCGv_i32 t0;
-
     if (ctx->frm == rm) {
         return;
     }
     ctx->frm = rm;
-    t0 = tcg_const_i32(rm);
-    gen_helper_set_rounding_mode(cpu_env, t0);
-    tcg_temp_free_i32(t0);
+    gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
 }
 
 static int ex_plus_1(DisasContext *ctx, int nf)
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index db1c0c9974..89f78701e7 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -200,12 +200,11 @@ static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a)
          * Replace bit 31 in rs1 with inverse in rs2.
          * This formulation retains the nanboxing of rs1.
          */
-        mask = tcg_const_i64(~MAKE_64BIT_MASK(31, 1));
+        mask = tcg_constant_i64(~MAKE_64BIT_MASK(31, 1));
         tcg_gen_nor_i64(rs2, rs2, mask);
         tcg_gen_and_i64(rs1, mask, rs1);
         tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2);
 
-        tcg_temp_free_i64(mask);
         tcg_temp_free_i64(rs2);
     }
     tcg_temp_free_i64(rs1);
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index 83d9a285ba..a8e7272487 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -33,7 +33,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-        s1 = tcg_const_tl(RV_VLEN_MAX);
+        s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
         s1 = tcg_temp_new();
         gen_get_gpr(s1, a->rs1);
@@ -59,13 +59,13 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
         return false;
     }
 
-    s2 = tcg_const_tl(a->zimm);
+    s2 = tcg_constant_tl(a->zimm);
     dst = tcg_temp_new();
 
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
-        s1 = tcg_const_tl(RV_VLEN_MAX);
+        s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
         s1 = tcg_temp_new();
         gen_get_gpr(s1, a->rs1);
@@ -76,7 +76,6 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
     ctx->base.is_jmp = DISAS_NORETURN;
 
     tcg_temp_free(s1);
-    tcg_temp_free(s2);
     tcg_temp_free(dst);
     return true;
 }
@@ -183,7 +182,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
      * The first part is vlen in bytes, encoded in maxsz of simd_desc.
      * The second part is lmul, encoded in data of simd_desc.
      */
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -194,7 +193,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -334,7 +332,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
     mask = tcg_temp_new_ptr();
     base = tcg_temp_new();
     stride = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     gen_get_gpr(stride, rs2);
@@ -347,7 +345,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
     tcg_temp_free_ptr(mask);
     tcg_temp_free(base);
     tcg_temp_free(stride);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -462,7 +459,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
     base = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -475,7 +472,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -594,7 +590,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     base = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -605,7 +601,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -671,7 +666,7 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
     base = tcg_temp_new();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
@@ -684,7 +679,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
     tcg_temp_free(base);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -874,7 +868,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -886,7 +880,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
     tcg_temp_free(src1);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -1014,14 +1007,14 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
     if (zx) {
-        src1 = tcg_const_tl(imm);
+        src1 = tcg_constant_tl(imm);
     } else {
-        src1 = tcg_const_tl(sextract64(imm, 0, 5));
+        src1 = tcg_constant_tl(sextract64(imm, 0, 5));
     }
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
     data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1032,8 +1025,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
-    tcg_temp_free(src1);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -1080,9 +1071,8 @@ GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
 static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
                                int64_t c, uint32_t oprsz, uint32_t maxsz)
 {
-    TCGv_i64 tmp = tcg_const_i64(c);
+    TCGv_i64 tmp = tcg_constant_i64(c);
     tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
-    tcg_temp_free_i64(tmp);
 }
 
 GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
@@ -1682,7 +1672,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
                                 MAXSZ(s), MAXSZ(s), s1);
         } else {
-            TCGv_i32 desc ;
+            TCGv_i32 desc;
             TCGv_i64 s1_i64 = tcg_temp_new_i64();
             TCGv_ptr dest = tcg_temp_new_ptr();
             uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
@@ -1692,12 +1682,11 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             };
 
             tcg_gen_ext_tl_i64(s1_i64, s1);
-            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
             tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
             fns[s->sew](dest, s1_i64, cpu_env, desc);
 
             tcg_temp_free_ptr(dest);
-            tcg_temp_free_i32(desc);
             tcg_temp_free_i64(s1_i64);
         }
 
@@ -1729,15 +1718,13 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
             TCGLabel *over = gen_new_label();
             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-            s1 = tcg_const_i64(simm);
+            s1 = tcg_constant_i64(simm);
             dest = tcg_temp_new_ptr();
-            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
             tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
             fns[s->sew](dest, s1, cpu_env, desc);
 
             tcg_temp_free_ptr(dest);
-            tcg_temp_free_i32(desc);
-            tcg_temp_free_i64(s1);
             gen_set_label(over);
         }
         return true;
@@ -1866,7 +1853,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
@@ -1877,7 +1864,6 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
-    tcg_temp_free_i32(desc);
     gen_set_label(over);
     return true;
 }
@@ -2231,12 +2217,11 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
             dest = tcg_temp_new_ptr();
-            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
             tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
             fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
 
             tcg_temp_free_ptr(dest);
-            tcg_temp_free_i32(desc);
             gen_set_label(over);
         }
         return true;
@@ -2428,7 +2413,7 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
         dst = tcg_temp_new();
-        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -2439,7 +2424,6 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
         tcg_temp_free(dst);
-        tcg_temp_free_i32(desc);
         return true;
     }
     return false;
@@ -2460,7 +2444,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
         dst = tcg_temp_new();
-        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
+        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -2471,7 +2455,6 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
         tcg_temp_free(dst);
-        tcg_temp_free_i32(desc);
         return true;
     }
     return false;
@@ -2636,15 +2619,13 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
     tcg_temp_free_i32(ofs);
 
     /* Flush out-of-range indexing to zero.  */
-    t_vlmax = tcg_const_i64(vlmax);
-    t_zero = tcg_const_i64(0);
+    t_vlmax = tcg_constant_i64(vlmax);
+    t_zero = tcg_constant_i64(0);
     tcg_gen_extu_tl_i64(t_idx, idx);
 
     tcg_gen_movcond_i64(TCG_COND_LTU, dest, t_idx,
                         t_vlmax, dest, t_zero);
 
-    tcg_temp_free_i64(t_vlmax);
-    tcg_temp_free_i64(t_zero);
     tcg_temp_free_i64(t_idx);
 }
 
-- 
2.25.1



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

* [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

New helpers that do not force tcg globals into temps,
returning a constant 0 for $zero as source and a new
temp for $zero as destination.

Use them in gen_arith_imm_{fn,tl}, gen_arith, gen_unary.
These are simplest because no further temps required.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 83 ++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 38 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index bba5ad8ec4..2cfcb849b8 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -65,6 +65,8 @@ typedef struct DisasContext {
     uint16_t mlen;
     bool vl_eq_vlmax;
     CPUState *cs;
+    TCGv zero;
+    TCGv sink;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -202,6 +204,14 @@ static inline void gen_get_gpr(TCGv t, int reg_num)
     }
 }
 
+static TCGv gpr_src(DisasContext *ctx, int reg_num)
+{
+    if (reg_num == 0) {
+        return ctx->zero;
+    }
+    return cpu_gpr[reg_num];
+}
+
 /* Wrapper for setting reg values - need to check of reg is zero since
  * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
  * since we usually avoid calling the OP_TYPE_gen function if we see a write to
@@ -214,6 +224,17 @@ static inline void gen_set_gpr(int reg_num_dst, TCGv t)
     }
 }
 
+static TCGv gpr_dst(DisasContext *ctx, int reg_num)
+{
+    if (reg_num == 0) {
+        if (ctx->sink == NULL) {
+            ctx->sink = tcg_temp_new();
+        }
+        return ctx->sink;
+    }
+    return cpu_gpr[reg_num];
+}
+
 static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 {
     TCGv rl = tcg_temp_new();
@@ -442,33 +463,21 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a,
                              void (*func)(TCGv, TCGv, target_long))
 {
-    TCGv source1;
-    source1 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
-    gen_get_gpr(source1, a->rs1);
-
-    (*func)(source1, source1, a->imm);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
+    (*func)(dest, src1, a->imm);
     return true;
 }
 
 static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
                              void (*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = tcg_constant_tl(a->imm);
 
-    gen_get_gpr(source1, a->rs1);
-    tcg_gen_movi_tl(source2, a->imm);
-
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    (*func)(dest, src1, src2);
     return true;
 }
 
@@ -758,18 +767,11 @@ static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
 static bool gen_arith(DisasContext *ctx, arg_r *a,
                       void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    (*func)(dest, src1, src2);
     return true;
 }
 
@@ -871,14 +873,10 @@ static void gen_clz(TCGv ret, TCGv arg1)
 static bool gen_unary(DisasContext *ctx, arg_r2 *a,
                       void(*func)(TCGv, TCGv))
 {
-    TCGv source = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
-    gen_get_gpr(source, a->rs1);
-
-    (*func)(source, source);
-
-    gen_set_gpr(a->rd, source);
-    tcg_temp_free(source);
+    (*func)(dest, src1);
     return true;
 }
 
@@ -952,8 +950,12 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->cs = cs;
 }
 
-static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+static void riscv_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
 {
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+    ctx->sink = NULL;
+    ctx->zero = tcg_constant_tl(0);
 }
 
 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
@@ -988,6 +990,11 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
     decode_opc(env, ctx, opcode16);
     ctx->base.pc_next = ctx->pc_succ_insn;
 
+    if (ctx->sink) {
+        tcg_temp_free(ctx->sink);
+        ctx->sink = NULL;
+    }
+
     if (ctx->base.is_jmp == DISAS_NEXT) {
         target_ulong page_start;
 
-- 
2.25.1



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

* [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

New helpers that do not force tcg globals into temps,
returning a constant 0 for $zero as source and a new
temp for $zero as destination.

Use them in gen_arith_imm_{fn,tl}, gen_arith, gen_unary.
These are simplest because no further temps required.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 83 ++++++++++++++++++++++------------------
 1 file changed, 45 insertions(+), 38 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index bba5ad8ec4..2cfcb849b8 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -65,6 +65,8 @@ typedef struct DisasContext {
     uint16_t mlen;
     bool vl_eq_vlmax;
     CPUState *cs;
+    TCGv zero;
+    TCGv sink;
 } DisasContext;
 
 static inline bool has_ext(DisasContext *ctx, uint32_t ext)
@@ -202,6 +204,14 @@ static inline void gen_get_gpr(TCGv t, int reg_num)
     }
 }
 
+static TCGv gpr_src(DisasContext *ctx, int reg_num)
+{
+    if (reg_num == 0) {
+        return ctx->zero;
+    }
+    return cpu_gpr[reg_num];
+}
+
 /* Wrapper for setting reg values - need to check of reg is zero since
  * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
  * since we usually avoid calling the OP_TYPE_gen function if we see a write to
@@ -214,6 +224,17 @@ static inline void gen_set_gpr(int reg_num_dst, TCGv t)
     }
 }
 
+static TCGv gpr_dst(DisasContext *ctx, int reg_num)
+{
+    if (reg_num == 0) {
+        if (ctx->sink == NULL) {
+            ctx->sink = tcg_temp_new();
+        }
+        return ctx->sink;
+    }
+    return cpu_gpr[reg_num];
+}
+
 static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 {
     TCGv rl = tcg_temp_new();
@@ -442,33 +463,21 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
 static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a,
                              void (*func)(TCGv, TCGv, target_long))
 {
-    TCGv source1;
-    source1 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
-    gen_get_gpr(source1, a->rs1);
-
-    (*func)(source1, source1, a->imm);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
+    (*func)(dest, src1, a->imm);
     return true;
 }
 
 static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
                              void (*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = tcg_constant_tl(a->imm);
 
-    gen_get_gpr(source1, a->rs1);
-    tcg_gen_movi_tl(source2, a->imm);
-
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    (*func)(dest, src1, src2);
     return true;
 }
 
@@ -758,18 +767,11 @@ static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
 static bool gen_arith(DisasContext *ctx, arg_r *a,
                       void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    (*func)(dest, src1, src2);
     return true;
 }
 
@@ -871,14 +873,10 @@ static void gen_clz(TCGv ret, TCGv arg1)
 static bool gen_unary(DisasContext *ctx, arg_r2 *a,
                       void(*func)(TCGv, TCGv))
 {
-    TCGv source = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
-    gen_get_gpr(source, a->rs1);
-
-    (*func)(source, source);
-
-    gen_set_gpr(a->rd, source);
-    tcg_temp_free(source);
+    (*func)(dest, src1);
     return true;
 }
 
@@ -952,8 +950,12 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
     ctx->cs = cs;
 }
 
-static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+static void riscv_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
 {
+    DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+    ctx->sink = NULL;
+    ctx->zero = tcg_constant_tl(0);
 }
 
 static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
@@ -988,6 +990,11 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
     decode_opc(env, ctx, opcode16);
     ctx->base.pc_next = ctx->pc_succ_insn;
 
+    if (ctx->sink) {
+        tcg_temp_free(ctx->sink);
+        ctx->sink = NULL;
+    }
+
     if (ctx->base.is_jmp == DISAS_NEXT) {
         target_ulong page_start;
 
-- 
2.25.1



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

* [PATCH 03/17] target/riscv: Use gpr_{src,dst} in shift operations
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

These operations are slightly more complicated since
we need to crop the shift operand.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 68 +++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 42 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2cfcb849b8..a60b198623 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -778,18 +778,14 @@ static bool gen_arith(DisasContext *ctx, arg_r *a,
 static bool gen_shift(DisasContext *ctx, arg_r *a,
                         void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_andi_tl(ext2, src2, TARGET_LONG_BITS - 1);
+    (*func)(dest, src1, ext2);
+    tcg_temp_free(ext2);
     return true;
 }
 
@@ -805,58 +801,46 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
 static bool gen_shifti(DisasContext *ctx, arg_shift *a,
                        void(*func)(TCGv, TCGv, TCGv))
 {
+    TCGv dest, src1, src2;
+
     if (a->shamt >= TARGET_LONG_BITS) {
         return false;
     }
 
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    dest = gpr_dst(ctx, a->rd);
+    src1 = gpr_src(ctx, a->rs1);
+    src2 = tcg_constant_tl(a->shamt);
 
-    gen_get_gpr(source1, a->rs1);
-
-    tcg_gen_movi_tl(source2, a->shamt);
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    (*func)(dest, src1, src2);
     return true;
 }
 
 static bool gen_shiftw(DisasContext *ctx, arg_r *a,
                        void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    tcg_gen_andi_tl(ext2, src2, 31);
+    (*func)(dest, src1, ext2);
+    tcg_gen_ext32s_tl(dest, dest);
 
-    tcg_gen_andi_tl(source2, source2, 31);
-    (*func)(source1, source1, source2);
-    tcg_gen_ext32s_tl(source1, source1);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_temp_free(ext2);
     return true;
 }
 
 static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
                         void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = tcg_constant_tl(a->shamt);
 
-    gen_get_gpr(source1, a->rs1);
-    tcg_gen_movi_tl(source2, a->shamt);
+    (*func)(dest, src1, src2);
+    tcg_gen_ext32s_tl(dest, dest);
 
-    (*func)(source1, source1, source2);
-    tcg_gen_ext32s_tl(source1, source1);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 03/17] target/riscv: Use gpr_{src,dst} in shift operations
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

These operations are slightly more complicated since
we need to crop the shift operand.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 68 +++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 42 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 2cfcb849b8..a60b198623 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -778,18 +778,14 @@ static bool gen_arith(DisasContext *ctx, arg_r *a,
 static bool gen_shift(DisasContext *ctx, arg_r *a,
                         void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_andi_tl(ext2, src2, TARGET_LONG_BITS - 1);
+    (*func)(dest, src1, ext2);
+    tcg_temp_free(ext2);
     return true;
 }
 
@@ -805,58 +801,46 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
 static bool gen_shifti(DisasContext *ctx, arg_shift *a,
                        void(*func)(TCGv, TCGv, TCGv))
 {
+    TCGv dest, src1, src2;
+
     if (a->shamt >= TARGET_LONG_BITS) {
         return false;
     }
 
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    dest = gpr_dst(ctx, a->rd);
+    src1 = gpr_src(ctx, a->rs1);
+    src2 = tcg_constant_tl(a->shamt);
 
-    gen_get_gpr(source1, a->rs1);
-
-    tcg_gen_movi_tl(source2, a->shamt);
-    (*func)(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    (*func)(dest, src1, src2);
     return true;
 }
 
 static bool gen_shiftw(DisasContext *ctx, arg_r *a,
                        void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    tcg_gen_andi_tl(ext2, src2, 31);
+    (*func)(dest, src1, ext2);
+    tcg_gen_ext32s_tl(dest, dest);
 
-    tcg_gen_andi_tl(source2, source2, 31);
-    (*func)(source1, source1, source2);
-    tcg_gen_ext32s_tl(source1, source1);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_temp_free(ext2);
     return true;
 }
 
 static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
                         void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = tcg_constant_tl(a->shamt);
 
-    gen_get_gpr(source1, a->rs1);
-    tcg_gen_movi_tl(source2, a->shamt);
+    (*func)(dest, src1, src2);
+    tcg_gen_ext32s_tl(dest, dest);
 
-    (*func)(source1, source1, source2);
-    tcg_gen_ext32s_tl(source1, source1);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Allocate new temps to hold the source extensions, and
extend directly from the source registers.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 46 +++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a60b198623..7dedfd548b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -502,42 +502,40 @@ static void gen_mulw(TCGv ret, TCGv arg1, TCGv arg2)
 static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
                             void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext1 = tcg_temp_new();
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-    tcg_gen_ext32s_tl(source1, source1);
-    tcg_gen_ext32s_tl(source2, source2);
+    tcg_gen_ext32s_tl(ext1, src1);
+    tcg_gen_ext32s_tl(ext2, src2);
 
-    (*func)(source1, source1, source2);
+    (*func)(dest, ext1, ext2);
+    tcg_temp_free(ext1);
+    tcg_temp_free(ext2);
 
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_ext32s_tl(dest, dest);
     return true;
 }
 
 static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
                             void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext1 = tcg_temp_new();
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-    tcg_gen_ext32u_tl(source1, source1);
-    tcg_gen_ext32u_tl(source2, source2);
+    tcg_gen_ext32u_tl(ext1, src1);
+    tcg_gen_ext32u_tl(ext2, src2);
 
-    (*func)(source1, source1, source2);
+    (*func)(dest, ext1, ext2);
+    tcg_temp_free(ext1);
+    tcg_temp_free(ext2);
 
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_ext32s_tl(dest, dest);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Allocate new temps to hold the source extensions, and
extend directly from the source registers.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 46 +++++++++++++++++++---------------------
 1 file changed, 22 insertions(+), 24 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a60b198623..7dedfd548b 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -502,42 +502,40 @@ static void gen_mulw(TCGv ret, TCGv arg1, TCGv arg2)
 static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
                             void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext1 = tcg_temp_new();
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-    tcg_gen_ext32s_tl(source1, source1);
-    tcg_gen_ext32s_tl(source2, source2);
+    tcg_gen_ext32s_tl(ext1, src1);
+    tcg_gen_ext32s_tl(ext2, src2);
 
-    (*func)(source1, source1, source2);
+    (*func)(dest, ext1, ext2);
+    tcg_temp_free(ext1);
+    tcg_temp_free(ext2);
 
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_ext32s_tl(dest, dest);
     return true;
 }
 
 static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
                             void(*func)(TCGv, TCGv, TCGv))
 {
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext1 = tcg_temp_new();
+    TCGv ext2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-    tcg_gen_ext32u_tl(source1, source1);
-    tcg_gen_ext32u_tl(source2, source2);
+    tcg_gen_ext32u_tl(ext1, src1);
+    tcg_gen_ext32u_tl(ext2, src2);
 
-    (*func)(source1, source1, source2);
+    (*func)(dest, ext1, ext2);
+    tcg_temp_free(ext1);
+    tcg_temp_free(ext2);
 
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_ext32s_tl(dest, dest);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7dedfd548b..6ad40e43b0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -620,23 +620,16 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
 
 static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2;
-
-    gen_get_gpr(source1, a->rs1);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
     if (a->shamt == (TARGET_LONG_BITS - 8)) {
         /* rev8, byte swaps */
-        tcg_gen_bswap_tl(source1, source1);
+        tcg_gen_bswap_tl(dest, src1);
     } else {
-        source2 = tcg_temp_new();
-        tcg_gen_movi_tl(source2, a->shamt);
-        gen_helper_grev(source1, source1, source2);
-        tcg_temp_free(source2);
+        TCGv src2 = tcg_constant_tl(a->shamt);
+        gen_helper_grev(dest, src1, src2);
     }
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 7dedfd548b..6ad40e43b0 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -620,23 +620,16 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
 
 static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
 {
-    TCGv source1 = tcg_temp_new();
-    TCGv source2;
-
-    gen_get_gpr(source1, a->rs1);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
     if (a->shamt == (TARGET_LONG_BITS - 8)) {
         /* rev8, byte swaps */
-        tcg_gen_bswap_tl(source1, source1);
+        tcg_gen_bswap_tl(dest, src1);
     } else {
-        source2 = tcg_temp_new();
-        tcg_gen_movi_tl(source2, a->shamt);
-        gen_helper_grev(source1, source1, source2);
-        tcg_temp_free(source2);
+        TCGv src2 = tcg_constant_tl(a->shamt);
+        gen_helper_grev(dest, src1, src2);
     }
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 06/17] target/riscv: Use gpr_src in branches
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Narrow the scope of t0 in trans_jalr.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 6e736c9d0d..a603925637 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -54,24 +54,25 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
 
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 {
-    /* no chaining with JALR */
     TCGLabel *misaligned = NULL;
-    TCGv t0 = tcg_temp_new();
 
-
-    gen_get_gpr(cpu_pc, a->rs1);
-    tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
+    tcg_gen_addi_tl(cpu_pc, gpr_src(ctx, a->rs1), a->imm);
     tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
     if (!has_ext(ctx, RVC)) {
+        TCGv t0 = tcg_temp_new();
+
         misaligned = gen_new_label();
         tcg_gen_andi_tl(t0, cpu_pc, 0x2);
         tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
+        tcg_temp_free(t0);
     }
 
     if (a->rd != 0) {
         tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
     }
+
+    /* No chaining with JALR. */
     lookup_and_goto_ptr(ctx);
 
     if (misaligned) {
@@ -80,21 +81,18 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
     }
     ctx->base.is_jmp = DISAS_NORETURN;
 
-    tcg_temp_free(t0);
     return true;
 }
 
 static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
 {
     TCGLabel *l = gen_new_label();
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
 
-    tcg_gen_brcond_tl(cond, source1, source2, l);
+    tcg_gen_brcond_tl(cond, src1, src2, l);
     gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+
     gen_set_label(l); /* branch taken */
 
     if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
@@ -105,9 +103,6 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
     }
     ctx->base.is_jmp = DISAS_NORETURN;
 
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 06/17] target/riscv: Use gpr_src in branches
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Narrow the scope of t0 in trans_jalr.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 25 ++++++++++---------------
 1 file changed, 10 insertions(+), 15 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 6e736c9d0d..a603925637 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -54,24 +54,25 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
 
 static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
 {
-    /* no chaining with JALR */
     TCGLabel *misaligned = NULL;
-    TCGv t0 = tcg_temp_new();
 
-
-    gen_get_gpr(cpu_pc, a->rs1);
-    tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
+    tcg_gen_addi_tl(cpu_pc, gpr_src(ctx, a->rs1), a->imm);
     tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
     if (!has_ext(ctx, RVC)) {
+        TCGv t0 = tcg_temp_new();
+
         misaligned = gen_new_label();
         tcg_gen_andi_tl(t0, cpu_pc, 0x2);
         tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
+        tcg_temp_free(t0);
     }
 
     if (a->rd != 0) {
         tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
     }
+
+    /* No chaining with JALR. */
     lookup_and_goto_ptr(ctx);
 
     if (misaligned) {
@@ -80,21 +81,18 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
     }
     ctx->base.is_jmp = DISAS_NORETURN;
 
-    tcg_temp_free(t0);
     return true;
 }
 
 static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
 {
     TCGLabel *l = gen_new_label();
-    TCGv source1, source2;
-    source1 = tcg_temp_new();
-    source2 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
 
-    tcg_gen_brcond_tl(cond, source1, source2, l);
+    tcg_gen_brcond_tl(cond, src1, src2, l);
     gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
+
     gen_set_label(l); /* branch taken */
 
     if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
@@ -105,9 +103,6 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
     }
     ctx->base.is_jmp = DISAS_NORETURN;
 
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 07/17] target/riscv: Use gpr_{src,dst} for integer load/store
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 45 +++++++++++++++----------
 1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index a603925637..a422dc9ef4 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -138,15 +138,21 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 
 static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
-    gen_set_gpr(a->rd, t1);
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
@@ -177,19 +183,24 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 
 static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
-    gen_get_gpr(dat, a->rs2);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv data = gpr_src(ctx, a->rs2);
+    TCGv temp = NULL;
 
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
-
 static bool trans_sb(DisasContext *ctx, arg_sb *a)
 {
     return gen_store(ctx, a, MO_SB);
-- 
2.25.1



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

* [PATCH 07/17] target/riscv: Use gpr_{src,dst} for integer load/store
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 45 +++++++++++++++----------
 1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index a603925637..a422dc9ef4 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -138,15 +138,21 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
 
 static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
 {
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
-    gen_set_gpr(a->rd, t1);
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
@@ -177,19 +183,24 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
 
 static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
 {
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
-    gen_get_gpr(dat, a->rs2);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv data = gpr_src(ctx, a->rs2);
+    TCGv temp = NULL;
 
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
-
 static bool trans_sb(DisasContext *ctx, arg_sb *a)
 {
     return gen_store(ctx, a, MO_SB);
-- 
2.25.1



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

* [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:25   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

For trans_sllw, we can just use gen_shiftw.  The others use
various tricks to reduce the tcg operation count.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 82 ++++++++++---------------
 1 file changed, 31 insertions(+), 51 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index a422dc9ef4..840187a4d6 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -352,24 +352,23 @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
 static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv t = tcg_temp_new();
-    gen_get_gpr(t, a->rs1);
-    tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
-    /* sign-extend for W instructions */
-    tcg_gen_ext32s_tl(t, t);
-    gen_set_gpr(a->rd, t);
-    tcg_temp_free(t);
+
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+
+    tcg_gen_extract_tl(dest, src1, a->shamt, 32 - a->shamt);
+    tcg_gen_ext32s_tl(dest, dest);
     return true;
 }
 
 static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv t = tcg_temp_new();
-    gen_get_gpr(t, a->rs1);
-    tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
-    gen_set_gpr(a->rd, t);
-    tcg_temp_free(t);
+
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+
+    tcg_gen_sextract_tl(dest, src1, a->shamt, 32 - a->shamt);
     return true;
 }
 
@@ -388,64 +387,45 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
-
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_andi_tl(source2, source2, 0x1F);
-    tcg_gen_shl_tl(source1, source1, source2);
-
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-    return true;
+    return gen_shiftw(ctx, a, tcg_gen_shl_tl);
 }
 
 static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
-    /* clear upper 32 */
-    tcg_gen_ext32u_tl(source1, source1);
-    tcg_gen_andi_tl(source2, source2, 0x1F);
-    tcg_gen_shr_tl(source1, source1, source2);
+    tcg_gen_andi_tl(ext2, src2, 31);
+    tcg_gen_ext32u_tl(dest, src1);
+    tcg_gen_shr_tl(dest, dest, ext2);
+    tcg_gen_ext32s_tl(dest, dest);
 
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_temp_free(ext2);
     return true;
 }
 
 static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
+    tcg_gen_andi_tl(ext2, src2, 31);
     /*
-     * first, trick to get it to act like working on 32 bits (get rid of
-     * upper 32, sign extend to fill space)
+     * First, trick to get it to act like working on 32 bits
+     * (get rid of upper 32, sign extend to fill space)
      */
-    tcg_gen_ext32s_tl(source1, source1);
-    tcg_gen_andi_tl(source2, source2, 0x1F);
-    tcg_gen_sar_tl(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_ext32s_tl(dest, src1);
+    tcg_gen_sar_tl(dest, dest, ext2);
 
+    tcg_temp_free(ext2);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations
@ 2021-07-09  4:25   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:25 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

For trans_sllw, we can just use gen_shiftw.  The others use
various tricks to reduce the tcg operation count.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 82 ++++++++++---------------
 1 file changed, 31 insertions(+), 51 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index a422dc9ef4..840187a4d6 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -352,24 +352,23 @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
 static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv t = tcg_temp_new();
-    gen_get_gpr(t, a->rs1);
-    tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
-    /* sign-extend for W instructions */
-    tcg_gen_ext32s_tl(t, t);
-    gen_set_gpr(a->rd, t);
-    tcg_temp_free(t);
+
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+
+    tcg_gen_extract_tl(dest, src1, a->shamt, 32 - a->shamt);
+    tcg_gen_ext32s_tl(dest, dest);
     return true;
 }
 
 static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv t = tcg_temp_new();
-    gen_get_gpr(t, a->rs1);
-    tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
-    gen_set_gpr(a->rd, t);
-    tcg_temp_free(t);
+
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+
+    tcg_gen_sextract_tl(dest, src1, a->shamt, 32 - a->shamt);
     return true;
 }
 
@@ -388,64 +387,45 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
 static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
-
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_andi_tl(source2, source2, 0x1F);
-    tcg_gen_shl_tl(source1, source1, source2);
-
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-    return true;
+    return gen_shiftw(ctx, a, tcg_gen_shl_tl);
 }
 
 static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
-    /* clear upper 32 */
-    tcg_gen_ext32u_tl(source1, source1);
-    tcg_gen_andi_tl(source2, source2, 0x1F);
-    tcg_gen_shr_tl(source1, source1, source2);
+    tcg_gen_andi_tl(ext2, src2, 31);
+    tcg_gen_ext32u_tl(dest, src1);
+    tcg_gen_shr_tl(dest, dest, ext2);
+    tcg_gen_ext32s_tl(dest, dest);
 
-    tcg_gen_ext32s_tl(source1, source1);
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_temp_free(ext2);
     return true;
 }
 
 static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
 {
     REQUIRE_64BIT(ctx);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
 
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
+    TCGv ext2 = tcg_temp_new();
 
+    tcg_gen_andi_tl(ext2, src2, 31);
     /*
-     * first, trick to get it to act like working on 32 bits (get rid of
-     * upper 32, sign extend to fill space)
+     * First, trick to get it to act like working on 32 bits
+     * (get rid of upper 32, sign extend to fill space)
      */
-    tcg_gen_ext32s_tl(source1, source1);
-    tcg_gen_andi_tl(source2, source2, 0x1F);
-    tcg_gen_sar_tl(source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
+    tcg_gen_ext32s_tl(dest, src1);
+    tcg_gen_sar_tl(dest, dest, ext2);
 
+    tcg_temp_free(ext2);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 09/17] target/riscv: Reorg csr instructions
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Introduce csrr and csrw helpers, for read-only and write-only insns.

Note that we do not properly implement this in riscv_csrrw, in that
we cannot distinguish true read-only (rs1 == 0) from any other zero
write_mask another source register -- this should still raise an
exception for read-only registers.

Only issue gen_io_start for CF_USE_ICOUNT.
Use ctx->zero for csrrc.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/helper.h                   |   6 +-
 target/riscv/op_helper.c                |  18 +--
 target/riscv/insn_trans/trans_rvi.c.inc | 170 +++++++++++++++++-------
 3 files changed, 129 insertions(+), 65 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 415e37bc37..460eee9988 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -65,9 +65,9 @@ DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 
 /* Special functions */
-DEF_HELPER_3(csrrw, tl, env, tl, tl)
-DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
-DEF_HELPER_4(csrrc, tl, env, tl, tl, tl)
+DEF_HELPER_2(csrr, tl, env, int)
+DEF_HELPER_3(csrw, void, env, int, tl)
+DEF_HELPER_4(csrrw, tl, env, int, tl, tl)
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_2(sret, tl, env, tl)
 DEF_HELPER_2(mret, tl, env, tl)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 3c48e739ac..ee7c24efe7 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -37,11 +37,10 @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception)
     riscv_raise_exception(env, exception, 0);
 }
 
-target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
-        target_ulong csr)
+target_ulong helper_csrr(CPURISCVState *env, int csr)
 {
     target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, src, -1);
+    RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
@@ -49,23 +48,20 @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
     return val;
 }
 
-target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
-        target_ulong csr, target_ulong rs1_pass)
+void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
 {
-    target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
+    RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
     }
-    return val;
 }
 
-target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
-        target_ulong csr, target_ulong rs1_pass)
+target_ulong helper_csrrw(CPURISCVState *env, int csr,
+                          target_ulong src, target_ulong write_mask)
 {
     target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
+    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 840187a4d6..3705aad380 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -452,80 +452,148 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
     return true;
 }
 
-#define RISCV_OP_CSR_PRE do {\
-    source1 = tcg_temp_new(); \
-    csr_store = tcg_temp_new(); \
-    dest = tcg_temp_new(); \
-    rs1_pass = tcg_temp_new(); \
-    gen_get_gpr(source1, a->rs1); \
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
-    tcg_gen_movi_tl(rs1_pass, a->rs1); \
-    tcg_gen_movi_tl(csr_store, a->csr); \
-    gen_io_start();\
-} while (0)
+static bool do_csr_post(DisasContext *ctx)
+{
+    /* We may have changed important cpu state -- exit to main loop. */
+    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    exit_tb(ctx);
+    ctx->base.is_jmp = DISAS_NORETURN;
+    return true;
+}
 
-#define RISCV_OP_CSR_POST do {\
-    gen_set_gpr(a->rd, dest); \
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
-    exit_tb(ctx); \
-    ctx->base.is_jmp = DISAS_NORETURN; \
-    tcg_temp_free(source1); \
-    tcg_temp_free(csr_store); \
-    tcg_temp_free(dest); \
-    tcg_temp_free(rs1_pass); \
-} while (0)
+static bool do_csrr(DisasContext *ctx, int rd, int rc)
+{
+    TCGv dest = gpr_dst(ctx, rd);
+    TCGv_i32 csr = tcg_constant_i32(rc);
 
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_helper_csrr(dest, cpu_env, csr);
+    return do_csr_post(ctx);
+}
+
+static bool do_csrw(DisasContext *ctx, int rc, TCGv src)
+{
+    TCGv_i32 csr = tcg_constant_i32(rc);
+
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_helper_csrw(cpu_env, csr, src);
+    return do_csr_post(ctx);
+}
+
+static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
+{
+    TCGv dest = gpr_dst(ctx, rd);
+    TCGv_i32 csr = tcg_constant_i32(rc);
+
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_helper_csrrw(dest, cpu_env, csr, src, mask);
+    return do_csr_post(ctx);
+}
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrw(dest, cpu_env, source1, csr_store);
-    RISCV_OP_CSR_POST;
-    return true;
+    TCGv src = gpr_src(ctx, a->rs1);
+
+    /*
+     * If rd == 0, the insn shall not read the csr, nor cause any of the
+     * side effects that might occur on a csr read.
+     */
+    if (a->rd == 0) {
+        return do_csrw(ctx, a->csr, src);
+    }
+
+    TCGv mask = tcg_constant_tl(-1);
+    return do_csrrw(ctx, a->rd, a->csr, src, mask);
 }
 
 static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv ones = tcg_constant_tl(-1);
+    TCGv mask = gpr_src(ctx, a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
 }
 
 static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv mask = gpr_src(ctx, a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
 }
 
 static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
-    RISCV_OP_CSR_POST;
-    return true;
+    TCGv src = tcg_constant_tl(a->rs1);
+
+    /*
+     * If rd == 0, the insn shall not read the csr, nor cause any of the
+     * side effects that might occur on a csr read.
+     */
+    if (a->rd == 0) {
+        return do_csrw(ctx, a->csr, src);
+    }
+
+    TCGv mask = tcg_constant_tl(-1);
+    return do_csrrw(ctx, a->rd, a->csr, src, mask);
 }
 
 static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv ones = tcg_constant_tl(-1);
+    TCGv mask = tcg_constant_tl(a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
 }
 
 static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv mask = tcg_constant_tl(a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
 }
-- 
2.25.1



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

* [PATCH 09/17] target/riscv: Reorg csr instructions
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Introduce csrr and csrw helpers, for read-only and write-only insns.

Note that we do not properly implement this in riscv_csrrw, in that
we cannot distinguish true read-only (rs1 == 0) from any other zero
write_mask another source register -- this should still raise an
exception for read-only registers.

Only issue gen_io_start for CF_USE_ICOUNT.
Use ctx->zero for csrrc.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/helper.h                   |   6 +-
 target/riscv/op_helper.c                |  18 +--
 target/riscv/insn_trans/trans_rvi.c.inc | 170 +++++++++++++++++-------
 3 files changed, 129 insertions(+), 65 deletions(-)

diff --git a/target/riscv/helper.h b/target/riscv/helper.h
index 415e37bc37..460eee9988 100644
--- a/target/riscv/helper.h
+++ b/target/riscv/helper.h
@@ -65,9 +65,9 @@ DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
 
 /* Special functions */
-DEF_HELPER_3(csrrw, tl, env, tl, tl)
-DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
-DEF_HELPER_4(csrrc, tl, env, tl, tl, tl)
+DEF_HELPER_2(csrr, tl, env, int)
+DEF_HELPER_3(csrw, void, env, int, tl)
+DEF_HELPER_4(csrrw, tl, env, int, tl, tl)
 #ifndef CONFIG_USER_ONLY
 DEF_HELPER_2(sret, tl, env, tl)
 DEF_HELPER_2(mret, tl, env, tl)
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 3c48e739ac..ee7c24efe7 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -37,11 +37,10 @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception)
     riscv_raise_exception(env, exception, 0);
 }
 
-target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
-        target_ulong csr)
+target_ulong helper_csrr(CPURISCVState *env, int csr)
 {
     target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, src, -1);
+    RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
@@ -49,23 +48,20 @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
     return val;
 }
 
-target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
-        target_ulong csr, target_ulong rs1_pass)
+void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
 {
-    target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
+    RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
     }
-    return val;
 }
 
-target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
-        target_ulong csr, target_ulong rs1_pass)
+target_ulong helper_csrrw(CPURISCVState *env, int csr,
+                          target_ulong src, target_ulong write_mask)
 {
     target_ulong val = 0;
-    RISCVException ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
+    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
 
     if (ret != RISCV_EXCP_NONE) {
         riscv_raise_exception(env, ret, GETPC());
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 840187a4d6..3705aad380 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -452,80 +452,148 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
     return true;
 }
 
-#define RISCV_OP_CSR_PRE do {\
-    source1 = tcg_temp_new(); \
-    csr_store = tcg_temp_new(); \
-    dest = tcg_temp_new(); \
-    rs1_pass = tcg_temp_new(); \
-    gen_get_gpr(source1, a->rs1); \
-    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
-    tcg_gen_movi_tl(rs1_pass, a->rs1); \
-    tcg_gen_movi_tl(csr_store, a->csr); \
-    gen_io_start();\
-} while (0)
+static bool do_csr_post(DisasContext *ctx)
+{
+    /* We may have changed important cpu state -- exit to main loop. */
+    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
+    exit_tb(ctx);
+    ctx->base.is_jmp = DISAS_NORETURN;
+    return true;
+}
 
-#define RISCV_OP_CSR_POST do {\
-    gen_set_gpr(a->rd, dest); \
-    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
-    exit_tb(ctx); \
-    ctx->base.is_jmp = DISAS_NORETURN; \
-    tcg_temp_free(source1); \
-    tcg_temp_free(csr_store); \
-    tcg_temp_free(dest); \
-    tcg_temp_free(rs1_pass); \
-} while (0)
+static bool do_csrr(DisasContext *ctx, int rd, int rc)
+{
+    TCGv dest = gpr_dst(ctx, rd);
+    TCGv_i32 csr = tcg_constant_i32(rc);
 
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_helper_csrr(dest, cpu_env, csr);
+    return do_csr_post(ctx);
+}
+
+static bool do_csrw(DisasContext *ctx, int rc, TCGv src)
+{
+    TCGv_i32 csr = tcg_constant_i32(rc);
+
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_helper_csrw(cpu_env, csr, src);
+    return do_csr_post(ctx);
+}
+
+static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
+{
+    TCGv dest = gpr_dst(ctx, rd);
+    TCGv_i32 csr = tcg_constant_i32(rc);
+
+    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
+        gen_io_start();
+    }
+    gen_helper_csrrw(dest, cpu_env, csr, src, mask);
+    return do_csr_post(ctx);
+}
 
 static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrw(dest, cpu_env, source1, csr_store);
-    RISCV_OP_CSR_POST;
-    return true;
+    TCGv src = gpr_src(ctx, a->rs1);
+
+    /*
+     * If rd == 0, the insn shall not read the csr, nor cause any of the
+     * side effects that might occur on a csr read.
+     */
+    if (a->rd == 0) {
+        return do_csrw(ctx, a->csr, src);
+    }
+
+    TCGv mask = tcg_constant_tl(-1);
+    return do_csrrw(ctx, a->rd, a->csr, src, mask);
 }
 
 static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv ones = tcg_constant_tl(-1);
+    TCGv mask = gpr_src(ctx, a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
 }
 
 static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv mask = gpr_src(ctx, a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
 }
 
 static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
-    RISCV_OP_CSR_POST;
-    return true;
+    TCGv src = tcg_constant_tl(a->rs1);
+
+    /*
+     * If rd == 0, the insn shall not read the csr, nor cause any of the
+     * side effects that might occur on a csr read.
+     */
+    if (a->rd == 0) {
+        return do_csrw(ctx, a->csr, src);
+    }
+
+    TCGv mask = tcg_constant_tl(-1);
+    return do_csrrw(ctx, a->rd, a->csr, src, mask);
 }
 
 static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv ones = tcg_constant_tl(-1);
+    TCGv mask = tcg_constant_tl(a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
 }
 
 static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
 {
-    TCGv source1, csr_store, dest, rs1_pass;
-    RISCV_OP_CSR_PRE;
-    gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
-    RISCV_OP_CSR_POST;
-    return true;
+    /*
+     * If rs1 == 0, the insn shall not write to the csr at all, nor
+     * cause any of the side effects that might occur on a csr write.
+     * Note that if rs1 specifies a register other than x0, holding
+     * a zero value, the instruction will still attempt to write the
+     * unmodified value back to the csr and will cause side effects.
+     */
+    if (a->rs1 == 0) {
+        return do_csrr(ctx, a->rd, a->csr);
+    }
+
+    TCGv mask = tcg_constant_tl(a->rs1);
+    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
 }
-- 
2.25.1



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

* [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rva.c.inc | 42 +++++++++----------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index ab2ec4f0a5..5bb5bbd09c 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -18,11 +18,11 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
+static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = tcg_temp_new();
+    TCGv src1 = gpr_src(ctx, a->rs1);
+
     /* Put addr in load_res, data in load_val.  */
-    gen_get_gpr(src1, a->rs1);
     if (a->rl) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
     }
@@ -33,30 +33,26 @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
     tcg_gen_mov_tl(load_res, src1);
     gen_set_gpr(a->rd, load_val);
 
-    tcg_temp_free(src1);
     return true;
 }
 
-static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
+static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = tcg_temp_new();
-    TCGv src2 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
     TCGLabel *l1 = gen_new_label();
     TCGLabel *l2 = gen_new_label();
 
-    gen_get_gpr(src1, a->rs1);
     tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
-    gen_get_gpr(src2, a->rs2);
     /*
      * Note that the TCG atomic primitives are SC,
      * so we can ignore AQ/RL along this path.
      */
-    tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
+    tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
                               ctx->mem_idx, mop);
-    tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
-    gen_set_gpr(a->rd, dat);
+    tcg_gen_setcond_tl(TCG_COND_NE, dest, dest, load_val);
     tcg_gen_br(l2);
 
     gen_set_label(l1);
@@ -65,8 +61,7 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
      * provide the memory barrier implied by AQ/RL.
      */
     tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
-    tcg_gen_movi_tl(dat, 1);
-    gen_set_gpr(a->rd, dat);
+    tcg_gen_movi_tl(dest, 1);
 
     gen_set_label(l2);
     /*
@@ -75,9 +70,6 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
      */
     tcg_gen_movi_tl(load_res, -1);
 
-    tcg_temp_free(dat);
-    tcg_temp_free(src1);
-    tcg_temp_free(src2);
     return true;
 }
 
@@ -85,17 +77,11 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
                     void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
                     MemOp mop)
 {
-    TCGv src1 = tcg_temp_new();
-    TCGv src2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
 
-    gen_get_gpr(src1, a->rs1);
-    gen_get_gpr(src2, a->rs2);
-
-    (*func)(src2, src1, src2, ctx->mem_idx, mop);
-
-    gen_set_gpr(a->rd, src2);
-    tcg_temp_free(src1);
-    tcg_temp_free(src2);
+    (*func)(dest, src1, src2, ctx->mem_idx, mop);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rva.c.inc | 42 +++++++++----------------
 1 file changed, 14 insertions(+), 28 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
index ab2ec4f0a5..5bb5bbd09c 100644
--- a/target/riscv/insn_trans/trans_rva.c.inc
+++ b/target/riscv/insn_trans/trans_rva.c.inc
@@ -18,11 +18,11 @@
  * this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
+static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = tcg_temp_new();
+    TCGv src1 = gpr_src(ctx, a->rs1);
+
     /* Put addr in load_res, data in load_val.  */
-    gen_get_gpr(src1, a->rs1);
     if (a->rl) {
         tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
     }
@@ -33,30 +33,26 @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
     tcg_gen_mov_tl(load_res, src1);
     gen_set_gpr(a->rd, load_val);
 
-    tcg_temp_free(src1);
     return true;
 }
 
-static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
+static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
 {
-    TCGv src1 = tcg_temp_new();
-    TCGv src2 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
     TCGLabel *l1 = gen_new_label();
     TCGLabel *l2 = gen_new_label();
 
-    gen_get_gpr(src1, a->rs1);
     tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
 
-    gen_get_gpr(src2, a->rs2);
     /*
      * Note that the TCG atomic primitives are SC,
      * so we can ignore AQ/RL along this path.
      */
-    tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
+    tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
                               ctx->mem_idx, mop);
-    tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
-    gen_set_gpr(a->rd, dat);
+    tcg_gen_setcond_tl(TCG_COND_NE, dest, dest, load_val);
     tcg_gen_br(l2);
 
     gen_set_label(l1);
@@ -65,8 +61,7 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
      * provide the memory barrier implied by AQ/RL.
      */
     tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
-    tcg_gen_movi_tl(dat, 1);
-    gen_set_gpr(a->rd, dat);
+    tcg_gen_movi_tl(dest, 1);
 
     gen_set_label(l2);
     /*
@@ -75,9 +70,6 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
      */
     tcg_gen_movi_tl(load_res, -1);
 
-    tcg_temp_free(dat);
-    tcg_temp_free(src1);
-    tcg_temp_free(src2);
     return true;
 }
 
@@ -85,17 +77,11 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
                     void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
                     MemOp mop)
 {
-    TCGv src1 = tcg_temp_new();
-    TCGv src2 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
+    TCGv src2 = gpr_src(ctx, a->rs2);
 
-    gen_get_gpr(src1, a->rs1);
-    gen_get_gpr(src2, a->rs2);
-
-    (*func)(src2, src1, src2, ctx->mem_idx, mop);
-
-    gen_set_gpr(a->rd, src2);
-    tcg_temp_free(src1);
-    tcg_temp_free(src2);
+    (*func)(dest, src1, src2, ctx->mem_idx, mop);
     return true;
 }
 
-- 
2.25.1



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

* [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvb.c.inc | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
index 9e81f6e3de..58921f3224 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -423,16 +423,13 @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVB);
 
-    TCGv source1 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
     if (a->shamt < 32) {
-        tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
+        tcg_gen_deposit_z_tl(dest, src1, a->shamt, 32);
     } else {
-        tcg_gen_shli_tl(source1, source1, a->shamt);
+        tcg_gen_shli_tl(dest, src1, a->shamt);
     }
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
     return true;
 }
-- 
2.25.1



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

* [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvb.c.inc | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
index 9e81f6e3de..58921f3224 100644
--- a/target/riscv/insn_trans/trans_rvb.c.inc
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
@@ -423,16 +423,13 @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVB);
 
-    TCGv source1 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
+    TCGv dest = gpr_dst(ctx, a->rd);
+    TCGv src1 = gpr_src(ctx, a->rs1);
 
     if (a->shamt < 32) {
-        tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
+        tcg_gen_deposit_z_tl(dest, src1, a->shamt, 32);
     } else {
-        tcg_gen_shli_tl(source1, source1, a->shamt);
+        tcg_gen_shli_tl(dest, src1, a->shamt);
     }
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
     return true;
 }
-- 
2.25.1



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

* [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvf.c.inc | 131 +++++++++---------------
 1 file changed, 49 insertions(+), 82 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index 89f78701e7..ff8e942199 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -27,14 +27,23 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
 
-    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
-    gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_temp_free(t0);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    TCGv_i64 dest = cpu_fpr[a->rd];
+    tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
+    gen_nanbox_s(dest, dest);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     mark_fs_dirty(ctx);
     return true;
 }
@@ -43,14 +52,21 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
 
-    tcg_gen_addi_tl(t0, t0, a->imm);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUL);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
 
-    tcg_temp_free(t0);
+    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
@@ -271,12 +287,8 @@ static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_w_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -285,12 +297,8 @@ static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_wu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -300,17 +308,14 @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
 
 #if defined(TARGET_RISCV64)
-    tcg_gen_ext32s_tl(t0, cpu_fpr[a->rs1]);
+    tcg_gen_ext32s_tl(dest, cpu_fpr[a->rs1]);
 #else
-    tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
+    tcg_gen_extrl_i64_i32(dest, cpu_fpr[a->rs1]);
 #endif
 
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -318,10 +323,9 @@ static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+
+    gen_helper_feq_s(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -329,10 +333,9 @@ static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+
+    gen_helper_flt_s(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -340,10 +343,9 @@ static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+
+    gen_helper_fle_s(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -352,13 +354,7 @@ static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-
-    gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
-
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fclass_s(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -367,15 +363,10 @@ static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -384,15 +375,10 @@ static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -402,15 +388,10 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
+    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
     gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -420,11 +401,8 @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_l_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -434,11 +412,8 @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_lu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -448,14 +423,10 @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
     return true;
 }
 
@@ -465,13 +436,9 @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
     return true;
 }
-- 
2.25.1



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

* [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvf.c.inc | 131 +++++++++---------------
 1 file changed, 49 insertions(+), 82 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
index 89f78701e7..ff8e942199 100644
--- a/target/riscv/insn_trans/trans_rvf.c.inc
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
@@ -27,14 +27,23 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
 
-    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
-    gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_temp_free(t0);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    TCGv_i64 dest = cpu_fpr[a->rd];
+    tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
+    gen_nanbox_s(dest, dest);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     mark_fs_dirty(ctx);
     return true;
 }
@@ -43,14 +52,21 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
 
-    tcg_gen_addi_tl(t0, t0, a->imm);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUL);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
 
-    tcg_temp_free(t0);
+    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
@@ -271,12 +287,8 @@ static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_w_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -285,12 +297,8 @@ static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_wu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -300,17 +308,14 @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
+    TCGv dest = gpr_dst(ctx, a->rd);
 
 #if defined(TARGET_RISCV64)
-    tcg_gen_ext32s_tl(t0, cpu_fpr[a->rs1]);
+    tcg_gen_ext32s_tl(dest, cpu_fpr[a->rs1]);
 #else
-    tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
+    tcg_gen_extrl_i64_i32(dest, cpu_fpr[a->rs1]);
 #endif
 
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -318,10 +323,9 @@ static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+
+    gen_helper_feq_s(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -329,10 +333,9 @@ static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+
+    gen_helper_flt_s(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -340,10 +343,9 @@ static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
-    TCGv t0 = tcg_temp_new();
-    gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+
+    gen_helper_fle_s(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -352,13 +354,7 @@ static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-
-    gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
-
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fclass_s(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -367,15 +363,10 @@ static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -384,15 +375,10 @@ static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -402,15 +388,10 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
+    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
     gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
-
     return true;
 }
 
@@ -420,11 +401,8 @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_l_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -434,11 +412,8 @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_lu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -448,14 +423,10 @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
     return true;
 }
 
@@ -465,13 +436,9 @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVF);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
+    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
     return true;
 }
-- 
2.25.1



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

* [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvd.c.inc | 116 +++++++++---------------
 1 file changed, 44 insertions(+), 72 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index 7e45538ae0..9bb15fdc12 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -22,14 +22,22 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
 
-    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
     return true;
 }
 
@@ -37,13 +45,21 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
 
-    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_temp_free(t0);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
@@ -252,11 +268,8 @@ static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_feq_d(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -265,11 +278,8 @@ static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_flt_d(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -278,11 +288,8 @@ static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fle_d(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -291,10 +298,7 @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fclass_d(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -303,12 +307,8 @@ static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_w_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -317,12 +317,8 @@ static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_wu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -331,12 +327,8 @@ static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
     return true;
@@ -347,12 +339,8 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
     return true;
@@ -364,11 +352,8 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_l_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -378,11 +363,8 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_lu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -406,12 +388,9 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
+
     mark_fs_dirty(ctx);
     return true;
 }
@@ -422,12 +401,9 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
+
     mark_fs_dirty(ctx);
     return true;
 }
@@ -439,11 +415,7 @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
     REQUIRE_EXT(ctx, RVD);
 
 #ifdef TARGET_RISCV64
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
-    tcg_temp_free(t0);
+    tcg_gen_mov_tl(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
     mark_fs_dirty(ctx);
     return true;
 #else
-- 
2.25.1



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

* [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvd.c.inc | 116 +++++++++---------------
 1 file changed, 44 insertions(+), 72 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
index 7e45538ae0..9bb15fdc12 100644
--- a/target/riscv/insn_trans/trans_rvd.c.inc
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
@@ -22,14 +22,22 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
 
-    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     mark_fs_dirty(ctx);
-    tcg_temp_free(t0);
     return true;
 }
 
@@ -37,13 +45,21 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
 {
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_addi_tl(t0, t0, a->imm);
 
-    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
+    TCGv addr = gpr_src(ctx, a->rs1);
+    TCGv temp = NULL;
 
-    tcg_temp_free(t0);
+    if (a->imm) {
+        temp = tcg_temp_new();
+        tcg_gen_addi_tl(temp, addr, a->imm);
+        addr = temp;
+    }
+
+    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
+
+    if (temp) {
+        tcg_temp_free(temp);
+    }
     return true;
 }
 
@@ -252,11 +268,8 @@ static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_feq_d(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -265,11 +278,8 @@ static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_flt_d(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -278,11 +288,8 @@ static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fle_d(gpr_dst(ctx, a->rd), cpu_env,
+                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
     return true;
 }
 
@@ -291,10 +298,7 @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fclass_d(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -303,12 +307,8 @@ static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_w_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -317,12 +317,8 @@ static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
-
+    gen_helper_fcvt_wu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -331,12 +327,8 @@ static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
     return true;
@@ -347,12 +339,8 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
 
     mark_fs_dirty(ctx);
     return true;
@@ -364,11 +352,8 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_l_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -378,11 +363,8 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
-    gen_set_gpr(a->rd, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_lu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
     return true;
 }
 
@@ -406,12 +388,9 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
+
     mark_fs_dirty(ctx);
     return true;
 }
@@ -422,12 +401,9 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
     REQUIRE_FPU;
     REQUIRE_EXT(ctx, RVD);
 
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
     gen_set_rm(ctx, a->rm);
-    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
-    tcg_temp_free(t0);
+    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
+
     mark_fs_dirty(ctx);
     return true;
 }
@@ -439,11 +415,7 @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
     REQUIRE_EXT(ctx, RVD);
 
 #ifdef TARGET_RISCV64
-    TCGv t0 = tcg_temp_new();
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
-    tcg_temp_free(t0);
+    tcg_gen_mov_tl(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
     mark_fs_dirty(ctx);
     return true;
 #else
-- 
2.25.1



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

* [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Exit early if check_access fails.
Split out do_hlv, do_hsv, do_hlvx subroutines.
Use gpr_src, gpr_dst in the new subroutines.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn32.decode              |   1 +
 target/riscv/insn_trans/trans_rvh.c.inc | 264 +++++-------------------
 2 files changed, 55 insertions(+), 210 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f09f8d5faf..2cd921d51c 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -42,6 +42,7 @@
 &j    imm rd
 &r    rd rs1 rs2
 &r2   rd rs1
+&r2_s rs1 rs2
 &s    imm rs1 rs2
 &u    imm rd
 &shift     shamt rs1 rd
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
index 6b5edf82b7..dac732024b 100644
--- a/target/riscv/insn_trans/trans_rvh.c.inc
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
@@ -17,281 +17,137 @@
  */
 
 #ifndef CONFIG_USER_ONLY
-static void check_access(DisasContext *ctx) {
+static bool check_access(DisasContext *ctx)
+{
     if (!ctx->hlsx) {
         if (ctx->virt_enabled) {
             generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
         } else {
             generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
         }
+        return false;
     }
+    return true;
 }
 #endif
 
+static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
+{
+#ifdef CONFIG_USER_ONLY
+    return false;
+#else
+    if (check_access(ctx)) {
+        TCGv dest = gpr_dst(ctx, a->rd);
+        TCGv addr = gpr_src(ctx, a->rs1);
+        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+        tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
+    }
+    return true;
+#endif
+}
+
 static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_SB);
 }
 
 static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TESW);
 }
 
 static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TESL);
 }
 
 static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_UB);
 }
 
 static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
+    return do_hlv(ctx, a, MO_TEUW);
+}
 
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
+static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
+{
+#ifdef CONFIG_USER_ONLY
     return false;
+#else
+    if (check_access(ctx)) {
+        TCGv addr = gpr_src(ctx, a->rs1);
+        TCGv data = gpr_src(ctx, a->rs2);
+        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+        tcg_gen_qemu_ld_tl(data, addr, mem_idx, mop);
+    }
+    return true;
 #endif
 }
 
 static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-    return true;
-#else
-    return false;
-#endif
+    return do_hsv(ctx, a, MO_SB);
 }
 
 static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-    return true;
-#else
-    return false;
-#endif
+    return do_hsv(ctx, a, MO_TESW);
 }
 
 static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-    return true;
-#else
-    return false;
-#endif
+    return do_hsv(ctx, a, MO_TESL);
 }
 
 static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
 {
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVH);
-
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TEUL);
 }
 
 static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
 {
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVH);
-
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TEQ);
 }
 
 static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
 {
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVH);
+    return do_hsv(ctx, a, MO_TEQ);
+}
 
 #ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
+static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
+                    void (*func)(TCGv, TCGv_env, TCGv))
+{
+    if (check_access(ctx)) {
+        TCGv dest = gpr_dst(ctx, a->rd);
+        TCGv addr = gpr_src(ctx, a->rs1);
+        func(dest, cpu_env, addr);
+    }
     return true;
-#else
-    return false;
-#endif
 }
+#endif
 
 static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
 {
     REQUIRE_EXT(ctx, RVH);
 #ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
+    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
 #else
     return false;
 #endif
@@ -301,19 +157,7 @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
 {
     REQUIRE_EXT(ctx, RVH);
 #ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
+    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
 #else
     return false;
 #endif
-- 
2.25.1



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

* [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Exit early if check_access fails.
Split out do_hlv, do_hsv, do_hlvx subroutines.
Use gpr_src, gpr_dst in the new subroutines.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn32.decode              |   1 +
 target/riscv/insn_trans/trans_rvh.c.inc | 264 +++++-------------------
 2 files changed, 55 insertions(+), 210 deletions(-)

diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
index f09f8d5faf..2cd921d51c 100644
--- a/target/riscv/insn32.decode
+++ b/target/riscv/insn32.decode
@@ -42,6 +42,7 @@
 &j    imm rd
 &r    rd rs1 rs2
 &r2   rd rs1
+&r2_s rs1 rs2
 &s    imm rs1 rs2
 &u    imm rd
 &shift     shamt rs1 rd
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
index 6b5edf82b7..dac732024b 100644
--- a/target/riscv/insn_trans/trans_rvh.c.inc
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
@@ -17,281 +17,137 @@
  */
 
 #ifndef CONFIG_USER_ONLY
-static void check_access(DisasContext *ctx) {
+static bool check_access(DisasContext *ctx)
+{
     if (!ctx->hlsx) {
         if (ctx->virt_enabled) {
             generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
         } else {
             generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
         }
+        return false;
     }
+    return true;
 }
 #endif
 
+static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
+{
+#ifdef CONFIG_USER_ONLY
+    return false;
+#else
+    if (check_access(ctx)) {
+        TCGv dest = gpr_dst(ctx, a->rd);
+        TCGv addr = gpr_src(ctx, a->rs1);
+        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+        tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
+    }
+    return true;
+#endif
+}
+
 static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_SB);
 }
 
 static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TESW);
 }
 
 static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TESL);
 }
 
 static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_UB);
 }
 
 static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
+    return do_hlv(ctx, a, MO_TEUW);
+}
 
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
+static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
+{
+#ifdef CONFIG_USER_ONLY
     return false;
+#else
+    if (check_access(ctx)) {
+        TCGv addr = gpr_src(ctx, a->rs1);
+        TCGv data = gpr_src(ctx, a->rs2);
+        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
+        tcg_gen_qemu_ld_tl(data, addr, mem_idx, mop);
+    }
+    return true;
 #endif
 }
 
 static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-    return true;
-#else
-    return false;
-#endif
+    return do_hsv(ctx, a, MO_SB);
 }
 
 static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-    return true;
-#else
-    return false;
-#endif
+    return do_hsv(ctx, a, MO_TESW);
 }
 
 static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
 {
     REQUIRE_EXT(ctx, RVH);
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
-    return true;
-#else
-    return false;
-#endif
+    return do_hsv(ctx, a, MO_TESL);
 }
 
 static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
 {
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVH);
-
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TEUL);
 }
 
 static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
 {
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVH);
-
-#ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
-#else
-    return false;
-#endif
+    return do_hlv(ctx, a, MO_TEQ);
 }
 
 static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
 {
     REQUIRE_64BIT(ctx);
     REQUIRE_EXT(ctx, RVH);
+    return do_hsv(ctx, a, MO_TEQ);
+}
 
 #ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv dat = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-    gen_get_gpr(dat, a->rs2);
-
-    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(dat);
+static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
+                    void (*func)(TCGv, TCGv_env, TCGv))
+{
+    if (check_access(ctx)) {
+        TCGv dest = gpr_dst(ctx, a->rd);
+        TCGv addr = gpr_src(ctx, a->rs1);
+        func(dest, cpu_env, addr);
+    }
     return true;
-#else
-    return false;
-#endif
 }
+#endif
 
 static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
 {
     REQUIRE_EXT(ctx, RVH);
 #ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
+    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
 #else
     return false;
 #endif
@@ -301,19 +157,7 @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
 {
     REQUIRE_EXT(ctx, RVH);
 #ifndef CONFIG_USER_ONLY
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-
-    check_access(ctx);
-
-    gen_get_gpr(t0, a->rs1);
-
-    gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
-    gen_set_gpr(a->rd, t1);
-
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-    return true;
+    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
 #else
     return false;
 #endif
-- 
2.25.1



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

* [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Split out gen_mulh and gen_mulhu and use the common helper.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c                | 16 ++++++++++++++++
 target/riscv/insn_trans/trans_rvm.c.inc | 24 ++----------------------
 2 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6ad40e43b0..8ff75a5798 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -235,6 +235,22 @@ static TCGv gpr_dst(DisasContext *ctx, int reg_num)
     return cpu_gpr[reg_num];
 }
 
+static void gen_mulh(TCGv ret, TCGv s1, TCGv s2)
+{
+    TCGv discard = tcg_temp_new();
+
+    tcg_gen_muls2_tl(discard, ret, s1, s2);
+    tcg_temp_free(discard);
+}
+
+static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
+{
+    TCGv discard = tcg_temp_new();
+
+    tcg_gen_mulu2_tl(discard, ret, s1, s2);
+    tcg_temp_free(discard);
+}
+
 static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 {
     TCGv rl = tcg_temp_new();
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
index 10ecc456fc..34220b824d 100644
--- a/target/riscv/insn_trans/trans_rvm.c.inc
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
@@ -28,17 +28,7 @@ static bool trans_mul(DisasContext *ctx, arg_mul *a)
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 {
     REQUIRE_EXT(ctx, RVM);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_muls2_tl(source2, source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-    return true;
+    return gen_arith(ctx, a, gen_mulh);
 }
 
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
@@ -50,17 +40,7 @@ static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 {
     REQUIRE_EXT(ctx, RVM);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_mulu2_tl(source2, source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-    return true;
+    return gen_arith(ctx, a, gen_mulhu);
 }
 
 static bool trans_div(DisasContext *ctx, arg_div *a)
-- 
2.25.1



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

* [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Split out gen_mulh and gen_mulhu and use the common helper.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c                | 16 ++++++++++++++++
 target/riscv/insn_trans/trans_rvm.c.inc | 24 ++----------------------
 2 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 6ad40e43b0..8ff75a5798 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -235,6 +235,22 @@ static TCGv gpr_dst(DisasContext *ctx, int reg_num)
     return cpu_gpr[reg_num];
 }
 
+static void gen_mulh(TCGv ret, TCGv s1, TCGv s2)
+{
+    TCGv discard = tcg_temp_new();
+
+    tcg_gen_muls2_tl(discard, ret, s1, s2);
+    tcg_temp_free(discard);
+}
+
+static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
+{
+    TCGv discard = tcg_temp_new();
+
+    tcg_gen_mulu2_tl(discard, ret, s1, s2);
+    tcg_temp_free(discard);
+}
+
 static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
 {
     TCGv rl = tcg_temp_new();
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
index 10ecc456fc..34220b824d 100644
--- a/target/riscv/insn_trans/trans_rvm.c.inc
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
@@ -28,17 +28,7 @@ static bool trans_mul(DisasContext *ctx, arg_mul *a)
 static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
 {
     REQUIRE_EXT(ctx, RVM);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_muls2_tl(source2, source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-    return true;
+    return gen_arith(ctx, a, gen_mulh);
 }
 
 static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
@@ -50,17 +40,7 @@ static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
 static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
 {
     REQUIRE_EXT(ctx, RVM);
-    TCGv source1 = tcg_temp_new();
-    TCGv source2 = tcg_temp_new();
-    gen_get_gpr(source1, a->rs1);
-    gen_get_gpr(source2, a->rs2);
-
-    tcg_gen_mulu2_tl(source2, source1, source1, source2);
-
-    gen_set_gpr(a->rd, source1);
-    tcg_temp_free(source1);
-    tcg_temp_free(source2);
-    return true;
+    return gen_arith(ctx, a, gen_mulhu);
 }
 
 static bool trans_div(DisasContext *ctx, arg_div *a)
-- 
2.25.1



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

* [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 79 +++++++------------------
 1 file changed, 20 insertions(+), 59 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index a8e7272487..84a45fac38 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -27,27 +27,21 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
         return false;
     }
 
-    s2 = tcg_temp_new();
-    dst = tcg_temp_new();
+    s2 = gpr_src(ctx, a->rs2);
+    dst = gpr_dst(ctx, a->rd);
 
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
         s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
+        s1 = gpr_src(ctx, a->rs1);
     }
-    gen_get_gpr(s2, a->rs2);
     gen_helper_vsetvl(dst, cpu_env, s1, s2);
-    gen_set_gpr(a->rd, dst);
+
     tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
     lookup_and_goto_ptr(ctx);
     ctx->base.is_jmp = DISAS_NORETURN;
-
-    tcg_temp_free(s1);
-    tcg_temp_free(s2);
-    tcg_temp_free(dst);
     return true;
 }
 
@@ -60,23 +54,19 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
     }
 
     s2 = tcg_constant_tl(a->zimm);
-    dst = tcg_temp_new();
+    dst = gpr_dst(ctx, a->rd);
 
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
         s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
+        s1 = gpr_src(ctx, a->rs1);
     }
     gen_helper_vsetvl(dst, cpu_env, s1, s2);
-    gen_set_gpr(a->rd, dst);
+
     gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
     ctx->base.is_jmp = DISAS_NORETURN;
-
-    tcg_temp_free(s1);
-    tcg_temp_free(dst);
     return true;
 }
 
@@ -173,7 +163,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
 
     /*
      * As simd_desc supports at most 256 bytes, and in this implementation,
@@ -184,7 +174,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
      */
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
@@ -192,7 +181,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -330,12 +318,10 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
 
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
-    base = tcg_temp_new();
-    stride = tcg_temp_new();
+    base = gpr_src(s, rs1);
+    stride = gpr_src(s, rs2);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
-    gen_get_gpr(stride, rs2);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
@@ -343,8 +329,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
 
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
-    tcg_temp_free(base);
-    tcg_temp_free(stride);
     gen_set_label(over);
     return true;
 }
@@ -458,10 +442,9 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -471,7 +454,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -589,10 +571,9 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
@@ -600,7 +581,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -665,10 +645,9 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -678,7 +657,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -862,8 +840,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    src1 = tcg_temp_new();
-    gen_get_gpr(src1, rs1);
+    src1 = gpr_src(s, rs1);
 
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
@@ -879,7 +856,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
-    tcg_temp_free(src1);
     gen_set_label(over);
     return true;
 }
@@ -905,15 +881,12 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
 
     if (a->vm && s->vl_eq_vlmax) {
         TCGv_i64 src1 = tcg_temp_new_i64();
-        TCGv tmp = tcg_temp_new();
 
-        gen_get_gpr(tmp, a->rs1);
-        tcg_gen_ext_tl_i64(src1, tmp);
+        tcg_gen_ext_tl_i64(src1, gpr_src(s, a->rs1));
         gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
                 src1, MAXSZ(s), MAXSZ(s));
 
         tcg_temp_free_i64(src1);
-        tcg_temp_free(tmp);
         return true;
     }
     return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
@@ -1398,16 +1371,13 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
 
     if (a->vm && s->vl_eq_vlmax) {
         TCGv_i32 src1 = tcg_temp_new_i32();
-        TCGv tmp = tcg_temp_new();
 
-        gen_get_gpr(tmp, a->rs1);
-        tcg_gen_trunc_tl_i32(src1, tmp);
+        tcg_gen_trunc_tl_i32(src1, gpr_src(s, a->rs1));
         tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
         gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
                 src1, MAXSZ(s), MAXSZ(s));
 
         tcg_temp_free_i32(src1);
-        tcg_temp_free(tmp);
         return true;
     }
     return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
@@ -1665,8 +1635,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
         TCGLabel *over = gen_new_label();
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
+        s1 = gpr_src(s, a->rs1);
 
         if (s->vl_eq_vlmax) {
             tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
@@ -1690,7 +1659,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             tcg_temp_free_i64(s1_i64);
         }
 
-        tcg_temp_free(s1);
         gen_set_label(over);
         return true;
     }
@@ -2412,18 +2380,16 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
 
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
-        dst = tcg_temp_new();
+        dst = gpr_dst(s, a->rd);
         desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
         gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
-        gen_set_gpr(a->rd, dst);
 
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
-        tcg_temp_free(dst);
         return true;
     }
     return false;
@@ -2443,18 +2409,16 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
 
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
-        dst = tcg_temp_new();
+        dst = gpr_dst(s, a->rd);
         desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
         gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
-        gen_set_gpr(a->rd, dst);
 
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
-        tcg_temp_free(dst);
         return true;
     }
     return false;
@@ -2638,7 +2602,6 @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
 static bool trans_vext_x_v(DisasContext *s, arg_r *a)
 {
     TCGv_i64 tmp = tcg_temp_new_i64();
-    TCGv dest = tcg_temp_new();
 
     if (a->rs1 == 0) {
         /* Special case vmv.x.s rd, vs2. */
@@ -2648,10 +2611,8 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
         int vlmax = s->vlen >> (3 + s->sew);
         vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
     }
-    tcg_gen_trunc_i64_tl(dest, tmp);
-    gen_set_gpr(a->rd, dest);
 
-    tcg_temp_free(dest);
+    tcg_gen_trunc_i64_tl(gpr_dst(s, a->rd), tmp);
     tcg_temp_free_i64(tmp);
     return true;
 }
-- 
2.25.1



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

* [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/insn_trans/trans_rvv.c.inc | 79 +++++++------------------
 1 file changed, 20 insertions(+), 59 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
index a8e7272487..84a45fac38 100644
--- a/target/riscv/insn_trans/trans_rvv.c.inc
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
@@ -27,27 +27,21 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
         return false;
     }
 
-    s2 = tcg_temp_new();
-    dst = tcg_temp_new();
+    s2 = gpr_src(ctx, a->rs2);
+    dst = gpr_dst(ctx, a->rd);
 
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
         s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
+        s1 = gpr_src(ctx, a->rs1);
     }
-    gen_get_gpr(s2, a->rs2);
     gen_helper_vsetvl(dst, cpu_env, s1, s2);
-    gen_set_gpr(a->rd, dst);
+
     tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
     lookup_and_goto_ptr(ctx);
     ctx->base.is_jmp = DISAS_NORETURN;
-
-    tcg_temp_free(s1);
-    tcg_temp_free(s2);
-    tcg_temp_free(dst);
     return true;
 }
 
@@ -60,23 +54,19 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
     }
 
     s2 = tcg_constant_tl(a->zimm);
-    dst = tcg_temp_new();
+    dst = gpr_dst(ctx, a->rd);
 
     /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
     if (a->rs1 == 0) {
         /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
         s1 = tcg_constant_tl(RV_VLEN_MAX);
     } else {
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
+        s1 = gpr_src(ctx, a->rs1);
     }
     gen_helper_vsetvl(dst, cpu_env, s1, s2);
-    gen_set_gpr(a->rd, dst);
+
     gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
     ctx->base.is_jmp = DISAS_NORETURN;
-
-    tcg_temp_free(s1);
-    tcg_temp_free(dst);
     return true;
 }
 
@@ -173,7 +163,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
 
     /*
      * As simd_desc supports at most 256 bytes, and in this implementation,
@@ -184,7 +174,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
      */
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
@@ -192,7 +181,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -330,12 +318,10 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
 
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
-    base = tcg_temp_new();
-    stride = tcg_temp_new();
+    base = gpr_src(s, rs1);
+    stride = gpr_src(s, rs2);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
-    gen_get_gpr(stride, rs2);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
@@ -343,8 +329,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
 
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
-    tcg_temp_free(base);
-    tcg_temp_free(stride);
     gen_set_label(over);
     return true;
 }
@@ -458,10 +442,9 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -471,7 +454,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -589,10 +571,9 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
@@ -600,7 +581,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
 
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -665,10 +645,9 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     index = tcg_temp_new_ptr();
-    base = tcg_temp_new();
+    base = gpr_src(s, rs1);
     desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
-    gen_get_gpr(base, rs1);
     tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
     tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
     tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
@@ -678,7 +657,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(index);
-    tcg_temp_free(base);
     gen_set_label(over);
     return true;
 }
@@ -862,8 +840,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     dest = tcg_temp_new_ptr();
     mask = tcg_temp_new_ptr();
     src2 = tcg_temp_new_ptr();
-    src1 = tcg_temp_new();
-    gen_get_gpr(src1, rs1);
+    src1 = gpr_src(s, rs1);
 
     data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
     data = FIELD_DP32(data, VDATA, VM, vm);
@@ -879,7 +856,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
     tcg_temp_free_ptr(dest);
     tcg_temp_free_ptr(mask);
     tcg_temp_free_ptr(src2);
-    tcg_temp_free(src1);
     gen_set_label(over);
     return true;
 }
@@ -905,15 +881,12 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
 
     if (a->vm && s->vl_eq_vlmax) {
         TCGv_i64 src1 = tcg_temp_new_i64();
-        TCGv tmp = tcg_temp_new();
 
-        gen_get_gpr(tmp, a->rs1);
-        tcg_gen_ext_tl_i64(src1, tmp);
+        tcg_gen_ext_tl_i64(src1, gpr_src(s, a->rs1));
         gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
                 src1, MAXSZ(s), MAXSZ(s));
 
         tcg_temp_free_i64(src1);
-        tcg_temp_free(tmp);
         return true;
     }
     return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
@@ -1398,16 +1371,13 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
 
     if (a->vm && s->vl_eq_vlmax) {
         TCGv_i32 src1 = tcg_temp_new_i32();
-        TCGv tmp = tcg_temp_new();
 
-        gen_get_gpr(tmp, a->rs1);
-        tcg_gen_trunc_tl_i32(src1, tmp);
+        tcg_gen_trunc_tl_i32(src1, gpr_src(s, a->rs1));
         tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
         gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
                 src1, MAXSZ(s), MAXSZ(s));
 
         tcg_temp_free_i32(src1);
-        tcg_temp_free(tmp);
         return true;
     }
     return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
@@ -1665,8 +1635,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
         TCGLabel *over = gen_new_label();
         tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
 
-        s1 = tcg_temp_new();
-        gen_get_gpr(s1, a->rs1);
+        s1 = gpr_src(s, a->rs1);
 
         if (s->vl_eq_vlmax) {
             tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
@@ -1690,7 +1659,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
             tcg_temp_free_i64(s1_i64);
         }
 
-        tcg_temp_free(s1);
         gen_set_label(over);
         return true;
     }
@@ -2412,18 +2380,16 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
 
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
-        dst = tcg_temp_new();
+        dst = gpr_dst(s, a->rd);
         desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
         gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
-        gen_set_gpr(a->rd, dst);
 
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
-        tcg_temp_free(dst);
         return true;
     }
     return false;
@@ -2443,18 +2409,16 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
 
         mask = tcg_temp_new_ptr();
         src2 = tcg_temp_new_ptr();
-        dst = tcg_temp_new();
+        dst = gpr_dst(s, a->rd);
         desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
 
         tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
         tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
 
         gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
-        gen_set_gpr(a->rd, dst);
 
         tcg_temp_free_ptr(mask);
         tcg_temp_free_ptr(src2);
-        tcg_temp_free(dst);
         return true;
     }
     return false;
@@ -2638,7 +2602,6 @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
 static bool trans_vext_x_v(DisasContext *s, arg_r *a)
 {
     TCGv_i64 tmp = tcg_temp_new_i64();
-    TCGv dest = tcg_temp_new();
 
     if (a->rs1 == 0) {
         /* Special case vmv.x.s rd, vs2. */
@@ -2648,10 +2611,8 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
         int vlmax = s->vlen >> (3 + s->sew);
         vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
     }
-    tcg_gen_trunc_i64_tl(dest, tmp);
-    gen_set_gpr(a->rd, dest);
 
-    tcg_temp_free(dest);
+    tcg_gen_trunc_i64_tl(gpr_dst(s, a->rd), tmp);
     tcg_temp_free_i64(tmp);
     return true;
 }
-- 
2.25.1



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

* [PATCH 17/17] target/riscv: Remove gen_get_gpr
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-09  4:26   ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: alistair.francis, qemu-riscv

This function is now unused.
The corresponding gen_set_gpr function is still in use.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8ff75a5798..a6c850e9d3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -195,15 +195,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 /* Wrapper for getting reg values - need to check of reg is zero since
  * cpu_gpr[0] is not actually allocated
  */
-static inline void gen_get_gpr(TCGv t, int reg_num)
-{
-    if (reg_num == 0) {
-        tcg_gen_movi_tl(t, 0);
-    } else {
-        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
-    }
-}
-
 static TCGv gpr_src(DisasContext *ctx, int reg_num)
 {
     if (reg_num == 0) {
@@ -1046,9 +1037,11 @@ void riscv_translate_init(void)
 {
     int i;
 
-    /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
-    /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
-    /* registers, unless you specifically block reads/writes to reg 0 */
+    /*
+     * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
+     * Use the gpr_src and gpr_dst helper functions when accessing regs,
+     * unless you specifically block reads/writes to reg 0.
+     */
     cpu_gpr[0] = NULL;
 
     for (i = 1; i < 32; i++) {
-- 
2.25.1



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

* [PATCH 17/17] target/riscv: Remove gen_get_gpr
@ 2021-07-09  4:26   ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-09  4:26 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-riscv, alistair.francis

This function is now unused.
The corresponding gen_set_gpr function is still in use.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/riscv/translate.c | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 8ff75a5798..a6c850e9d3 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -195,15 +195,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
 /* Wrapper for getting reg values - need to check of reg is zero since
  * cpu_gpr[0] is not actually allocated
  */
-static inline void gen_get_gpr(TCGv t, int reg_num)
-{
-    if (reg_num == 0) {
-        tcg_gen_movi_tl(t, 0);
-    } else {
-        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
-    }
-}
-
 static TCGv gpr_src(DisasContext *ctx, int reg_num)
 {
     if (reg_num == 0) {
@@ -1046,9 +1037,11 @@ void riscv_translate_init(void)
 {
     int i;
 
-    /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
-    /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
-    /* registers, unless you specifically block reads/writes to reg 0 */
+    /*
+     * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
+     * Use the gpr_src and gpr_dst helper functions when accessing regs,
+     * unless you specifically block reads/writes to reg 0.
+     */
     cpu_gpr[0] = NULL;
 
     for (i = 1; i < 32; i++) {
-- 
2.25.1



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

* Re: [PATCH 01/17] target/riscv: Use tcg_constant_*
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-09  5:41     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-09  5:41 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:36 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Replace uses of tcg_const_* with the allocate and free close together.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c                | 36 ++++----------
>  target/riscv/insn_trans/trans_rvf.c.inc |  3 +-
>  target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
>  3 files changed, 34 insertions(+), 70 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 62a7d7e4c7..bba5ad8ec4 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -104,20 +104,16 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
>   */
>  static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
>  {
> -    TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull);
> -    TCGv_i64 t_nan = tcg_const_i64(0xffffffff7fc00000ull);
> +    TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
> +    TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
>
>      tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
> -    tcg_temp_free_i64(t_max);
> -    tcg_temp_free_i64(t_nan);
>  }
>
>  static void generate_exception(DisasContext *ctx, int excp)
>  {
>      tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
> -    TCGv_i32 helper_tmp = tcg_const_i32(excp);
> -    gen_helper_raise_exception(cpu_env, helper_tmp);
> -    tcg_temp_free_i32(helper_tmp);
> +    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
>
> @@ -125,17 +121,13 @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
>  {
>      tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
>      tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> -    TCGv_i32 helper_tmp = tcg_const_i32(excp);
> -    gen_helper_raise_exception(cpu_env, helper_tmp);
> -    tcg_temp_free_i32(helper_tmp);
> +    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
>
>  static void gen_exception_debug(void)
>  {
> -    TCGv_i32 helper_tmp = tcg_const_i32(EXCP_DEBUG);
> -    gen_helper_raise_exception(cpu_env, helper_tmp);
> -    tcg_temp_free_i32(helper_tmp);
> +    gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
>  }
>
>  /* Wrapper around tcg_gen_exit_tb that handles single stepping */
> @@ -247,7 +239,7 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
>       */
>      cond1 = tcg_temp_new();
>      cond2 = tcg_temp_new();
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
> @@ -268,7 +260,6 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
>
>      tcg_temp_free(cond1);
>      tcg_temp_free(cond2);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -277,7 +268,7 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
>      TCGv cond1, zeroreg, resultopt1;
>      cond1 = tcg_temp_new();
>
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
> @@ -290,7 +281,6 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
>      tcg_gen_divu_tl(ret, source1, source2);
>
>      tcg_temp_free(cond1);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -300,7 +290,7 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
>
>      cond1 = tcg_temp_new();
>      cond2 = tcg_temp_new();
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_movi_tl(resultopt1, 1L);
> @@ -320,7 +310,6 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
>
>      tcg_temp_free(cond1);
>      tcg_temp_free(cond2);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -328,7 +317,7 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
>  {
>      TCGv cond1, zeroreg, resultopt1;
>      cond1 = tcg_temp_new();
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_movi_tl(resultopt1, (target_ulong)1);
> @@ -341,7 +330,6 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
>              source1);
>
>      tcg_temp_free(cond1);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -402,15 +390,11 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
>
>  static void gen_set_rm(DisasContext *ctx, int rm)
>  {
> -    TCGv_i32 t0;
> -
>      if (ctx->frm == rm) {
>          return;
>      }
>      ctx->frm = rm;
> -    t0 = tcg_const_i32(rm);
> -    gen_helper_set_rounding_mode(cpu_env, t0);
> -    tcg_temp_free_i32(t0);
> +    gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
>  }
>
>  static int ex_plus_1(DisasContext *ctx, int nf)
> diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
> index db1c0c9974..89f78701e7 100644
> --- a/target/riscv/insn_trans/trans_rvf.c.inc
> +++ b/target/riscv/insn_trans/trans_rvf.c.inc
> @@ -200,12 +200,11 @@ static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a)
>           * Replace bit 31 in rs1 with inverse in rs2.
>           * This formulation retains the nanboxing of rs1.
>           */
> -        mask = tcg_const_i64(~MAKE_64BIT_MASK(31, 1));
> +        mask = tcg_constant_i64(~MAKE_64BIT_MASK(31, 1));
>          tcg_gen_nor_i64(rs2, rs2, mask);
>          tcg_gen_and_i64(rs1, mask, rs1);
>          tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2);
>
> -        tcg_temp_free_i64(mask);
>          tcg_temp_free_i64(rs2);
>      }
>      tcg_temp_free_i64(rs1);
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 83d9a285ba..a8e7272487 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -33,7 +33,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
> -        s1 = tcg_const_tl(RV_VLEN_MAX);
> +        s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
>          s1 = tcg_temp_new();
>          gen_get_gpr(s1, a->rs1);
> @@ -59,13 +59,13 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
>          return false;
>      }
>
> -    s2 = tcg_const_tl(a->zimm);
> +    s2 = tcg_constant_tl(a->zimm);
>      dst = tcg_temp_new();
>
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
> -        s1 = tcg_const_tl(RV_VLEN_MAX);
> +        s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
>          s1 = tcg_temp_new();
>          gen_get_gpr(s1, a->rs1);
> @@ -76,7 +76,6 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
>      ctx->base.is_jmp = DISAS_NORETURN;
>
>      tcg_temp_free(s1);
> -    tcg_temp_free(s2);
>      tcg_temp_free(dst);
>      return true;
>  }
> @@ -183,7 +182,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>       * The first part is vlen in bytes, encoded in maxsz of simd_desc.
>       * The second part is lmul, encoded in data of simd_desc.
>       */
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -194,7 +193,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -334,7 +332,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>      mask = tcg_temp_new_ptr();
>      base = tcg_temp_new();
>      stride = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      gen_get_gpr(stride, rs2);
> @@ -347,7 +345,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free(base);
>      tcg_temp_free(stride);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -462,7 +459,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
>      base = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -475,7 +472,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -594,7 +590,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      base = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -605,7 +601,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -671,7 +666,7 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
>      base = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -684,7 +679,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -874,7 +868,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
>      data = FIELD_DP32(data, VDATA, VM, vm);
>      data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
> @@ -886,7 +880,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
>      tcg_temp_free(src1);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -1014,14 +1007,14 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
>      if (zx) {
> -        src1 = tcg_const_tl(imm);
> +        src1 = tcg_constant_tl(imm);
>      } else {
> -        src1 = tcg_const_tl(sextract64(imm, 0, 5));
> +        src1 = tcg_constant_tl(sextract64(imm, 0, 5));
>      }
>      data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
>      data = FIELD_DP32(data, VDATA, VM, vm);
>      data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
> @@ -1032,8 +1025,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
> -    tcg_temp_free(src1);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -1080,9 +1071,8 @@ GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
>  static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
>                                 int64_t c, uint32_t oprsz, uint32_t maxsz)
>  {
> -    TCGv_i64 tmp = tcg_const_i64(c);
> +    TCGv_i64 tmp = tcg_constant_i64(c);
>      tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
> -    tcg_temp_free_i64(tmp);
>  }
>
>  GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
> @@ -1682,7 +1672,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>              tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
>                                  MAXSZ(s), MAXSZ(s), s1);
>          } else {
> -            TCGv_i32 desc ;
> +            TCGv_i32 desc;
>              TCGv_i64 s1_i64 = tcg_temp_new_i64();
>              TCGv_ptr dest = tcg_temp_new_ptr();
>              uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
> @@ -1692,12 +1682,11 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>              };
>
>              tcg_gen_ext_tl_i64(s1_i64, s1);
> -            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>              tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
>              fns[s->sew](dest, s1_i64, cpu_env, desc);
>
>              tcg_temp_free_ptr(dest);
> -            tcg_temp_free_i32(desc);
>              tcg_temp_free_i64(s1_i64);
>          }
>
> @@ -1729,15 +1718,13 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
>              TCGLabel *over = gen_new_label();
>              tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
> -            s1 = tcg_const_i64(simm);
> +            s1 = tcg_constant_i64(simm);
>              dest = tcg_temp_new_ptr();
> -            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>              tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
>              fns[s->sew](dest, s1, cpu_env, desc);
>
>              tcg_temp_free_ptr(dest);
> -            tcg_temp_free_i32(desc);
> -            tcg_temp_free_i64(s1);
>              gen_set_label(over);
>          }
>          return true;
> @@ -1866,7 +1853,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
> @@ -1877,7 +1864,6 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -2231,12 +2217,11 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
>              tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
>              dest = tcg_temp_new_ptr();
> -            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>              tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
>              fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
>
>              tcg_temp_free_ptr(dest);
> -            tcg_temp_free_i32(desc);
>              gen_set_label(over);
>          }
>          return true;
> @@ -2428,7 +2413,7 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
>          dst = tcg_temp_new();
> -        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -2439,7 +2424,6 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
>          tcg_temp_free(dst);
> -        tcg_temp_free_i32(desc);
>          return true;
>      }
>      return false;
> @@ -2460,7 +2444,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
>          dst = tcg_temp_new();
> -        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -2471,7 +2455,6 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
>          tcg_temp_free(dst);
> -        tcg_temp_free_i32(desc);
>          return true;
>      }
>      return false;
> @@ -2636,15 +2619,13 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
>      tcg_temp_free_i32(ofs);
>
>      /* Flush out-of-range indexing to zero.  */
> -    t_vlmax = tcg_const_i64(vlmax);
> -    t_zero = tcg_const_i64(0);
> +    t_vlmax = tcg_constant_i64(vlmax);
> +    t_zero = tcg_constant_i64(0);
>      tcg_gen_extu_tl_i64(t_idx, idx);
>
>      tcg_gen_movcond_i64(TCG_COND_LTU, dest, t_idx,
>                          t_vlmax, dest, t_zero);
>
> -    tcg_temp_free_i64(t_vlmax);
> -    tcg_temp_free_i64(t_zero);
>      tcg_temp_free_i64(t_idx);
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 01/17] target/riscv: Use tcg_constant_*
@ 2021-07-09  5:41     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-09  5:41 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:36 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Replace uses of tcg_const_* with the allocate and free close together.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c                | 36 ++++----------
>  target/riscv/insn_trans/trans_rvf.c.inc |  3 +-
>  target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
>  3 files changed, 34 insertions(+), 70 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 62a7d7e4c7..bba5ad8ec4 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -104,20 +104,16 @@ static void gen_nanbox_s(TCGv_i64 out, TCGv_i64 in)
>   */
>  static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
>  {
> -    TCGv_i64 t_max = tcg_const_i64(0xffffffff00000000ull);
> -    TCGv_i64 t_nan = tcg_const_i64(0xffffffff7fc00000ull);
> +    TCGv_i64 t_max = tcg_constant_i64(0xffffffff00000000ull);
> +    TCGv_i64 t_nan = tcg_constant_i64(0xffffffff7fc00000ull);
>
>      tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
> -    tcg_temp_free_i64(t_max);
> -    tcg_temp_free_i64(t_nan);
>  }
>
>  static void generate_exception(DisasContext *ctx, int excp)
>  {
>      tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
> -    TCGv_i32 helper_tmp = tcg_const_i32(excp);
> -    gen_helper_raise_exception(cpu_env, helper_tmp);
> -    tcg_temp_free_i32(helper_tmp);
> +    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
>
> @@ -125,17 +121,13 @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
>  {
>      tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
>      tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
> -    TCGv_i32 helper_tmp = tcg_const_i32(excp);
> -    gen_helper_raise_exception(cpu_env, helper_tmp);
> -    tcg_temp_free_i32(helper_tmp);
> +    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
>      ctx->base.is_jmp = DISAS_NORETURN;
>  }
>
>  static void gen_exception_debug(void)
>  {
> -    TCGv_i32 helper_tmp = tcg_const_i32(EXCP_DEBUG);
> -    gen_helper_raise_exception(cpu_env, helper_tmp);
> -    tcg_temp_free_i32(helper_tmp);
> +    gen_helper_raise_exception(cpu_env, tcg_constant_i32(EXCP_DEBUG));
>  }
>
>  /* Wrapper around tcg_gen_exit_tb that handles single stepping */
> @@ -247,7 +239,7 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
>       */
>      cond1 = tcg_temp_new();
>      cond2 = tcg_temp_new();
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_movi_tl(resultopt1, (target_ulong)-1);
> @@ -268,7 +260,6 @@ static void gen_div(TCGv ret, TCGv source1, TCGv source2)
>
>      tcg_temp_free(cond1);
>      tcg_temp_free(cond2);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -277,7 +268,7 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
>      TCGv cond1, zeroreg, resultopt1;
>      cond1 = tcg_temp_new();
>
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_setcondi_tl(TCG_COND_EQ, cond1, source2, 0);
> @@ -290,7 +281,6 @@ static void gen_divu(TCGv ret, TCGv source1, TCGv source2)
>      tcg_gen_divu_tl(ret, source1, source2);
>
>      tcg_temp_free(cond1);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -300,7 +290,7 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
>
>      cond1 = tcg_temp_new();
>      cond2 = tcg_temp_new();
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_movi_tl(resultopt1, 1L);
> @@ -320,7 +310,6 @@ static void gen_rem(TCGv ret, TCGv source1, TCGv source2)
>
>      tcg_temp_free(cond1);
>      tcg_temp_free(cond2);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -328,7 +317,7 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
>  {
>      TCGv cond1, zeroreg, resultopt1;
>      cond1 = tcg_temp_new();
> -    zeroreg = tcg_const_tl(0);
> +    zeroreg = tcg_constant_tl(0);
>      resultopt1 = tcg_temp_new();
>
>      tcg_gen_movi_tl(resultopt1, (target_ulong)1);
> @@ -341,7 +330,6 @@ static void gen_remu(TCGv ret, TCGv source1, TCGv source2)
>              source1);
>
>      tcg_temp_free(cond1);
> -    tcg_temp_free(zeroreg);
>      tcg_temp_free(resultopt1);
>  }
>
> @@ -402,15 +390,11 @@ static inline void mark_fs_dirty(DisasContext *ctx) { }
>
>  static void gen_set_rm(DisasContext *ctx, int rm)
>  {
> -    TCGv_i32 t0;
> -
>      if (ctx->frm == rm) {
>          return;
>      }
>      ctx->frm = rm;
> -    t0 = tcg_const_i32(rm);
> -    gen_helper_set_rounding_mode(cpu_env, t0);
> -    tcg_temp_free_i32(t0);
> +    gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
>  }
>
>  static int ex_plus_1(DisasContext *ctx, int nf)
> diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
> index db1c0c9974..89f78701e7 100644
> --- a/target/riscv/insn_trans/trans_rvf.c.inc
> +++ b/target/riscv/insn_trans/trans_rvf.c.inc
> @@ -200,12 +200,11 @@ static bool trans_fsgnjn_s(DisasContext *ctx, arg_fsgnjn_s *a)
>           * Replace bit 31 in rs1 with inverse in rs2.
>           * This formulation retains the nanboxing of rs1.
>           */
> -        mask = tcg_const_i64(~MAKE_64BIT_MASK(31, 1));
> +        mask = tcg_constant_i64(~MAKE_64BIT_MASK(31, 1));
>          tcg_gen_nor_i64(rs2, rs2, mask);
>          tcg_gen_and_i64(rs1, mask, rs1);
>          tcg_gen_or_i64(cpu_fpr[a->rd], rs1, rs2);
>
> -        tcg_temp_free_i64(mask);
>          tcg_temp_free_i64(rs2);
>      }
>      tcg_temp_free_i64(rs1);
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index 83d9a285ba..a8e7272487 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -33,7 +33,7 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
> -        s1 = tcg_const_tl(RV_VLEN_MAX);
> +        s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
>          s1 = tcg_temp_new();
>          gen_get_gpr(s1, a->rs1);
> @@ -59,13 +59,13 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
>          return false;
>      }
>
> -    s2 = tcg_const_tl(a->zimm);
> +    s2 = tcg_constant_tl(a->zimm);
>      dst = tcg_temp_new();
>
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
> -        s1 = tcg_const_tl(RV_VLEN_MAX);
> +        s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
>          s1 = tcg_temp_new();
>          gen_get_gpr(s1, a->rs1);
> @@ -76,7 +76,6 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
>      ctx->base.is_jmp = DISAS_NORETURN;
>
>      tcg_temp_free(s1);
> -    tcg_temp_free(s2);
>      tcg_temp_free(dst);
>      return true;
>  }
> @@ -183,7 +182,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>       * The first part is vlen in bytes, encoded in maxsz of simd_desc.
>       * The second part is lmul, encoded in data of simd_desc.
>       */
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -194,7 +193,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -334,7 +332,7 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>      mask = tcg_temp_new_ptr();
>      base = tcg_temp_new();
>      stride = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      gen_get_gpr(stride, rs2);
> @@ -347,7 +345,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free(base);
>      tcg_temp_free(stride);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -462,7 +459,7 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
>      base = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -475,7 +472,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -594,7 +590,7 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      base = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -605,7 +601,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -671,7 +666,7 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
>      base = tcg_temp_new();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
> @@ -684,7 +679,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
>      tcg_temp_free(base);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -874,7 +868,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
>      data = FIELD_DP32(data, VDATA, VM, vm);
>      data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
> @@ -886,7 +880,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
>      tcg_temp_free(src1);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -1014,14 +1007,14 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
>      if (zx) {
> -        src1 = tcg_const_tl(imm);
> +        src1 = tcg_constant_tl(imm);
>      } else {
> -        src1 = tcg_const_tl(sextract64(imm, 0, 5));
> +        src1 = tcg_constant_tl(sextract64(imm, 0, 5));
>      }
>      data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
>      data = FIELD_DP32(data, VDATA, VM, vm);
>      data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
> @@ -1032,8 +1025,6 @@ static bool opivi_trans(uint32_t vd, uint32_t imm, uint32_t vs2, uint32_t vm,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
> -    tcg_temp_free(src1);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -1080,9 +1071,8 @@ GEN_OPIVI_GVEC_TRANS(vadd_vi, 0, vadd_vx, addi)
>  static void tcg_gen_gvec_rsubi(unsigned vece, uint32_t dofs, uint32_t aofs,
>                                 int64_t c, uint32_t oprsz, uint32_t maxsz)
>  {
> -    TCGv_i64 tmp = tcg_const_i64(c);
> +    TCGv_i64 tmp = tcg_constant_i64(c);
>      tcg_gen_gvec_rsubs(vece, dofs, aofs, tmp, oprsz, maxsz);
> -    tcg_temp_free_i64(tmp);
>  }
>
>  GEN_OPIVI_GVEC_TRANS(vrsub_vi, 0, vrsub_vx, rsubi)
> @@ -1682,7 +1672,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>              tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
>                                  MAXSZ(s), MAXSZ(s), s1);
>          } else {
> -            TCGv_i32 desc ;
> +            TCGv_i32 desc;
>              TCGv_i64 s1_i64 = tcg_temp_new_i64();
>              TCGv_ptr dest = tcg_temp_new_ptr();
>              uint32_t data = FIELD_DP32(0, VDATA, LMUL, s->lmul);
> @@ -1692,12 +1682,11 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>              };
>
>              tcg_gen_ext_tl_i64(s1_i64, s1);
> -            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>              tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
>              fns[s->sew](dest, s1_i64, cpu_env, desc);
>
>              tcg_temp_free_ptr(dest);
> -            tcg_temp_free_i32(desc);
>              tcg_temp_free_i64(s1_i64);
>          }
>
> @@ -1729,15 +1718,13 @@ static bool trans_vmv_v_i(DisasContext *s, arg_vmv_v_i *a)
>              TCGLabel *over = gen_new_label();
>              tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
> -            s1 = tcg_const_i64(simm);
> +            s1 = tcg_constant_i64(simm);
>              dest = tcg_temp_new_ptr();
> -            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>              tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
>              fns[s->sew](dest, s1, cpu_env, desc);
>
>              tcg_temp_free_ptr(dest);
> -            tcg_temp_free_i32(desc);
> -            tcg_temp_free_i64(s1);
>              gen_set_label(over);
>          }
>          return true;
> @@ -1866,7 +1853,7 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
> -    desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +    desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, vs2));
> @@ -1877,7 +1864,6 @@ static bool opfvf_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
> -    tcg_temp_free_i32(desc);
>      gen_set_label(over);
>      return true;
>  }
> @@ -2231,12 +2217,11 @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
>              tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
>              dest = tcg_temp_new_ptr();
> -            desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +            desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>              tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, a->rd));
>              fns[s->sew - 1](dest, cpu_fpr[a->rs1], cpu_env, desc);
>
>              tcg_temp_free_ptr(dest);
> -            tcg_temp_free_i32(desc);
>              gen_set_label(over);
>          }
>          return true;
> @@ -2428,7 +2413,7 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
>          dst = tcg_temp_new();
> -        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -2439,7 +2424,6 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
>          tcg_temp_free(dst);
> -        tcg_temp_free_i32(desc);
>          return true;
>      }
>      return false;
> @@ -2460,7 +2444,7 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
>          dst = tcg_temp_new();
> -        desc = tcg_const_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
> +        desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -2471,7 +2455,6 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
>          tcg_temp_free(dst);
> -        tcg_temp_free_i32(desc);
>          return true;
>      }
>      return false;
> @@ -2636,15 +2619,13 @@ static void vec_element_loadx(DisasContext *s, TCGv_i64 dest,
>      tcg_temp_free_i32(ofs);
>
>      /* Flush out-of-range indexing to zero.  */
> -    t_vlmax = tcg_const_i64(vlmax);
> -    t_zero = tcg_const_i64(0);
> +    t_vlmax = tcg_constant_i64(vlmax);
> +    t_zero = tcg_constant_i64(0);
>      tcg_gen_extu_tl_i64(t_idx, idx);
>
>      tcg_gen_movcond_i64(TCG_COND_LTU, dest, t_idx,
>                          t_vlmax, dest, t_zero);
>
> -    tcg_temp_free_i64(t_vlmax);
> -    tcg_temp_free_i64(t_zero);
>      tcg_temp_free_i64(t_idx);
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-09  5:45     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-09  5:45 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:42 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> New helpers that do not force tcg globals into temps,
> returning a constant 0 for $zero as source and a new
> temp for $zero as destination.
>
> Use them in gen_arith_imm_{fn,tl}, gen_arith, gen_unary.
> These are simplest because no further temps required.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 83 ++++++++++++++++++++++------------------
>  1 file changed, 45 insertions(+), 38 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index bba5ad8ec4..2cfcb849b8 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -65,6 +65,8 @@ typedef struct DisasContext {
>      uint16_t mlen;
>      bool vl_eq_vlmax;
>      CPUState *cs;
> +    TCGv zero;
> +    TCGv sink;
>  } DisasContext;
>
>  static inline bool has_ext(DisasContext *ctx, uint32_t ext)
> @@ -202,6 +204,14 @@ static inline void gen_get_gpr(TCGv t, int reg_num)
>      }
>  }
>
> +static TCGv gpr_src(DisasContext *ctx, int reg_num)
> +{
> +    if (reg_num == 0) {
> +        return ctx->zero;
> +    }
> +    return cpu_gpr[reg_num];
> +}
> +
>  /* Wrapper for setting reg values - need to check of reg is zero since
>   * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
>   * since we usually avoid calling the OP_TYPE_gen function if we see a write to
> @@ -214,6 +224,17 @@ static inline void gen_set_gpr(int reg_num_dst, TCGv t)
>      }
>  }
>
> +static TCGv gpr_dst(DisasContext *ctx, int reg_num)
> +{
> +    if (reg_num == 0) {
> +        if (ctx->sink == NULL) {
> +            ctx->sink = tcg_temp_new();
> +        }
> +        return ctx->sink;
> +    }
> +    return cpu_gpr[reg_num];
> +}
> +
>  static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
>  {
>      TCGv rl = tcg_temp_new();
> @@ -442,33 +463,21 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
>  static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a,
>                               void (*func)(TCGv, TCGv, target_long))
>  {
> -    TCGv source1;
> -    source1 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
> -    gen_get_gpr(source1, a->rs1);
> -
> -    (*func)(source1, source1, a->imm);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> +    (*func)(dest, src1, a->imm);
>      return true;
>  }
>
>  static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
>                               void (*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = tcg_constant_tl(a->imm);
>
> -    gen_get_gpr(source1, a->rs1);
> -    tcg_gen_movi_tl(source2, a->imm);
> -
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    (*func)(dest, src1, src2);
>      return true;
>  }
>
> @@ -758,18 +767,11 @@ static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
>  static bool gen_arith(DisasContext *ctx, arg_r *a,
>                        void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    (*func)(dest, src1, src2);
>      return true;
>  }
>
> @@ -871,14 +873,10 @@ static void gen_clz(TCGv ret, TCGv arg1)
>  static bool gen_unary(DisasContext *ctx, arg_r2 *a,
>                        void(*func)(TCGv, TCGv))
>  {
> -    TCGv source = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
> -    gen_get_gpr(source, a->rs1);
> -
> -    (*func)(source, source);
> -
> -    gen_set_gpr(a->rd, source);
> -    tcg_temp_free(source);
> +    (*func)(dest, src1);
>      return true;
>  }
>
> @@ -952,8 +950,12 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>      ctx->cs = cs;
>  }
>
> -static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
> +static void riscv_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
>  {
> +    DisasContext *ctx = container_of(dcbase, DisasContext, base);
> +
> +    ctx->sink = NULL;
> +    ctx->zero = tcg_constant_tl(0);
>  }
>
>  static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
> @@ -988,6 +990,11 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
>      decode_opc(env, ctx, opcode16);
>      ctx->base.pc_next = ctx->pc_succ_insn;
>
> +    if (ctx->sink) {
> +        tcg_temp_free(ctx->sink);
> +        ctx->sink = NULL;
> +    }
> +
>      if (ctx->base.is_jmp == DISAS_NEXT) {
>          target_ulong page_start;
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst
@ 2021-07-09  5:45     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-09  5:45 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:42 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> New helpers that do not force tcg globals into temps,
> returning a constant 0 for $zero as source and a new
> temp for $zero as destination.
>
> Use them in gen_arith_imm_{fn,tl}, gen_arith, gen_unary.
> These are simplest because no further temps required.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 83 ++++++++++++++++++++++------------------
>  1 file changed, 45 insertions(+), 38 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index bba5ad8ec4..2cfcb849b8 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -65,6 +65,8 @@ typedef struct DisasContext {
>      uint16_t mlen;
>      bool vl_eq_vlmax;
>      CPUState *cs;
> +    TCGv zero;
> +    TCGv sink;
>  } DisasContext;
>
>  static inline bool has_ext(DisasContext *ctx, uint32_t ext)
> @@ -202,6 +204,14 @@ static inline void gen_get_gpr(TCGv t, int reg_num)
>      }
>  }
>
> +static TCGv gpr_src(DisasContext *ctx, int reg_num)
> +{
> +    if (reg_num == 0) {
> +        return ctx->zero;
> +    }
> +    return cpu_gpr[reg_num];
> +}
> +
>  /* Wrapper for setting reg values - need to check of reg is zero since
>   * cpu_gpr[0] is not actually allocated. this is more for safety purposes,
>   * since we usually avoid calling the OP_TYPE_gen function if we see a write to
> @@ -214,6 +224,17 @@ static inline void gen_set_gpr(int reg_num_dst, TCGv t)
>      }
>  }
>
> +static TCGv gpr_dst(DisasContext *ctx, int reg_num)
> +{
> +    if (reg_num == 0) {
> +        if (ctx->sink == NULL) {
> +            ctx->sink = tcg_temp_new();
> +        }
> +        return ctx->sink;
> +    }
> +    return cpu_gpr[reg_num];
> +}
> +
>  static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
>  {
>      TCGv rl = tcg_temp_new();
> @@ -442,33 +463,21 @@ static int ex_rvc_shifti(DisasContext *ctx, int imm)
>  static bool gen_arith_imm_fn(DisasContext *ctx, arg_i *a,
>                               void (*func)(TCGv, TCGv, target_long))
>  {
> -    TCGv source1;
> -    source1 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
> -    gen_get_gpr(source1, a->rs1);
> -
> -    (*func)(source1, source1, a->imm);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> +    (*func)(dest, src1, a->imm);
>      return true;
>  }
>
>  static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a,
>                               void (*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = tcg_constant_tl(a->imm);
>
> -    gen_get_gpr(source1, a->rs1);
> -    tcg_gen_movi_tl(source2, a->imm);
> -
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    (*func)(dest, src1, src2);
>      return true;
>  }
>
> @@ -758,18 +767,11 @@ static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
>  static bool gen_arith(DisasContext *ctx, arg_r *a,
>                        void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    (*func)(dest, src1, src2);
>      return true;
>  }
>
> @@ -871,14 +873,10 @@ static void gen_clz(TCGv ret, TCGv arg1)
>  static bool gen_unary(DisasContext *ctx, arg_r2 *a,
>                        void(*func)(TCGv, TCGv))
>  {
> -    TCGv source = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
> -    gen_get_gpr(source, a->rs1);
> -
> -    (*func)(source, source);
> -
> -    gen_set_gpr(a->rd, source);
> -    tcg_temp_free(source);
> +    (*func)(dest, src1);
>      return true;
>  }
>
> @@ -952,8 +950,12 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
>      ctx->cs = cs;
>  }
>
> -static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
> +static void riscv_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
>  {
> +    DisasContext *ctx = container_of(dcbase, DisasContext, base);
> +
> +    ctx->sink = NULL;
> +    ctx->zero = tcg_constant_tl(0);
>  }
>
>  static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
> @@ -988,6 +990,11 @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
>      decode_opc(env, ctx, opcode16);
>      ctx->base.pc_next = ctx->pc_succ_insn;
>
> +    if (ctx->sink) {
> +        tcg_temp_free(ctx->sink);
> +        ctx->sink = NULL;
> +    }
> +
>      if (ctx->base.is_jmp == DISAS_NEXT) {
>          target_ulong page_start;
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 01/17] target/riscv: Use tcg_constant_*
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-09 16:20     ` Philippe Mathieu-Daudé
  -1 siblings, 0 replies; 80+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-09 16:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis

On 7/9/21 6:25 AM, Richard Henderson wrote:
> Replace uses of tcg_const_* with the allocate and free close together.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/riscv/translate.c                | 36 ++++----------
>  target/riscv/insn_trans/trans_rvf.c.inc |  3 +-
>  target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
>  3 files changed, 34 insertions(+), 70 deletions(-)

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


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

* Re: [PATCH 01/17] target/riscv: Use tcg_constant_*
@ 2021-07-09 16:20     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 80+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-09 16:20 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alistair.francis, qemu-riscv

On 7/9/21 6:25 AM, Richard Henderson wrote:
> Replace uses of tcg_const_* with the allocate and free close together.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/riscv/translate.c                | 36 ++++----------
>  target/riscv/insn_trans/trans_rvf.c.inc |  3 +-
>  target/riscv/insn_trans/trans_rvv.c.inc | 65 +++++++++----------------
>  3 files changed, 34 insertions(+), 70 deletions(-)

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


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

* Re: [PATCH 03/17] target/riscv: Use gpr_{src, dst} in shift operations
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-13  4:10     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:10 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:43 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> These operations are slightly more complicated since
> we need to crop the shift operand.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 68 +++++++++++++++-------------------------
>  1 file changed, 26 insertions(+), 42 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 2cfcb849b8..a60b198623 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -778,18 +778,14 @@ static bool gen_arith(DisasContext *ctx, arg_r *a,
>  static bool gen_shift(DisasContext *ctx, arg_r *a,
>                          void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_andi_tl(ext2, src2, TARGET_LONG_BITS - 1);
> +    (*func)(dest, src1, ext2);
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
> @@ -805,58 +801,46 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
>  static bool gen_shifti(DisasContext *ctx, arg_shift *a,
>                         void(*func)(TCGv, TCGv, TCGv))
>  {
> +    TCGv dest, src1, src2;
> +
>      if (a->shamt >= TARGET_LONG_BITS) {
>          return false;
>      }
>
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    dest = gpr_dst(ctx, a->rd);
> +    src1 = gpr_src(ctx, a->rs1);
> +    src2 = tcg_constant_tl(a->shamt);
>
> -    gen_get_gpr(source1, a->rs1);
> -
> -    tcg_gen_movi_tl(source2, a->shamt);
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    (*func)(dest, src1, src2);
>      return true;
>  }
>
>  static bool gen_shiftw(DisasContext *ctx, arg_r *a,
>                         void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    tcg_gen_andi_tl(ext2, src2, 31);
> +    (*func)(dest, src1, ext2);
> +    tcg_gen_ext32s_tl(dest, dest);
>
> -    tcg_gen_andi_tl(source2, source2, 31);
> -    (*func)(source1, source1, source2);
> -    tcg_gen_ext32s_tl(source1, source1);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
>  static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
>                          void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = tcg_constant_tl(a->shamt);
>
> -    gen_get_gpr(source1, a->rs1);
> -    tcg_gen_movi_tl(source2, a->shamt);
> +    (*func)(dest, src1, src2);
> +    tcg_gen_ext32s_tl(dest, dest);
>
> -    (*func)(source1, source1, source2);
> -    tcg_gen_ext32s_tl(source1, source1);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 03/17] target/riscv: Use gpr_{src, dst} in shift operations
@ 2021-07-13  4:10     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:10 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:43 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> These operations are slightly more complicated since
> we need to crop the shift operand.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 68 +++++++++++++++-------------------------
>  1 file changed, 26 insertions(+), 42 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 2cfcb849b8..a60b198623 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -778,18 +778,14 @@ static bool gen_arith(DisasContext *ctx, arg_r *a,
>  static bool gen_shift(DisasContext *ctx, arg_r *a,
>                          void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1);
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_andi_tl(ext2, src2, TARGET_LONG_BITS - 1);
> +    (*func)(dest, src1, ext2);
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
> @@ -805,58 +801,46 @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
>  static bool gen_shifti(DisasContext *ctx, arg_shift *a,
>                         void(*func)(TCGv, TCGv, TCGv))
>  {
> +    TCGv dest, src1, src2;
> +
>      if (a->shamt >= TARGET_LONG_BITS) {
>          return false;
>      }
>
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    dest = gpr_dst(ctx, a->rd);
> +    src1 = gpr_src(ctx, a->rs1);
> +    src2 = tcg_constant_tl(a->shamt);
>
> -    gen_get_gpr(source1, a->rs1);
> -
> -    tcg_gen_movi_tl(source2, a->shamt);
> -    (*func)(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    (*func)(dest, src1, src2);
>      return true;
>  }
>
>  static bool gen_shiftw(DisasContext *ctx, arg_r *a,
>                         void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    tcg_gen_andi_tl(ext2, src2, 31);
> +    (*func)(dest, src1, ext2);
> +    tcg_gen_ext32s_tl(dest, dest);
>
> -    tcg_gen_andi_tl(source2, source2, 31);
> -    (*func)(source1, source1, source2);
> -    tcg_gen_ext32s_tl(source1, source1);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
>  static bool gen_shiftiw(DisasContext *ctx, arg_shift *a,
>                          void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = tcg_constant_tl(a->shamt);
>
> -    gen_get_gpr(source1, a->rs1);
> -    tcg_gen_movi_tl(source2, a->shamt);
> +    (*func)(dest, src1, src2);
> +    tcg_gen_ext32s_tl(dest, dest);
>
> -    (*func)(source1, source1, source2);
> -    tcg_gen_ext32s_tl(source1, source1);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-13  4:11     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:11 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:44 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Allocate new temps to hold the source extensions, and
> extend directly from the source registers.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 46 +++++++++++++++++++---------------------
>  1 file changed, 22 insertions(+), 24 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index a60b198623..7dedfd548b 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -502,42 +502,40 @@ static void gen_mulw(TCGv ret, TCGv arg1, TCGv arg2)
>  static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
>                              void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext1 = tcg_temp_new();
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -    tcg_gen_ext32s_tl(source1, source1);
> -    tcg_gen_ext32s_tl(source2, source2);
> +    tcg_gen_ext32s_tl(ext1, src1);
> +    tcg_gen_ext32s_tl(ext2, src2);
>
> -    (*func)(source1, source1, source2);
> +    (*func)(dest, ext1, ext2);
> +    tcg_temp_free(ext1);
> +    tcg_temp_free(ext2);
>
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_ext32s_tl(dest, dest);
>      return true;
>  }
>
>  static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
>                              void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext1 = tcg_temp_new();
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -    tcg_gen_ext32u_tl(source1, source1);
> -    tcg_gen_ext32u_tl(source2, source2);
> +    tcg_gen_ext32u_tl(ext1, src1);
> +    tcg_gen_ext32u_tl(ext2, src2);
>
> -    (*func)(source1, source1, source2);
> +    (*func)(dest, ext1, ext2);
> +    tcg_temp_free(ext1);
> +    tcg_temp_free(ext2);
>
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_ext32s_tl(dest, dest);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations
@ 2021-07-13  4:11     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:11 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:44 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Allocate new temps to hold the source extensions, and
> extend directly from the source registers.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 46 +++++++++++++++++++---------------------
>  1 file changed, 22 insertions(+), 24 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index a60b198623..7dedfd548b 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -502,42 +502,40 @@ static void gen_mulw(TCGv ret, TCGv arg1, TCGv arg2)
>  static bool gen_arith_div_w(DisasContext *ctx, arg_r *a,
>                              void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext1 = tcg_temp_new();
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -    tcg_gen_ext32s_tl(source1, source1);
> -    tcg_gen_ext32s_tl(source2, source2);
> +    tcg_gen_ext32s_tl(ext1, src1);
> +    tcg_gen_ext32s_tl(ext2, src2);
>
> -    (*func)(source1, source1, source2);
> +    (*func)(dest, ext1, ext2);
> +    tcg_temp_free(ext1);
> +    tcg_temp_free(ext2);
>
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_ext32s_tl(dest, dest);
>      return true;
>  }
>
>  static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
>                              void(*func)(TCGv, TCGv, TCGv))
>  {
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext1 = tcg_temp_new();
> +    TCGv ext2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -    tcg_gen_ext32u_tl(source1, source1);
> -    tcg_gen_ext32u_tl(source2, source2);
> +    tcg_gen_ext32u_tl(ext1, src1);
> +    tcg_gen_ext32u_tl(ext2, src2);
>
> -    (*func)(source1, source1, source2);
> +    (*func)(dest, ext1, ext2);
> +    tcg_temp_free(ext1);
> +    tcg_temp_free(ext2);
>
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_ext32s_tl(dest, dest);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-13  4:12     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:12 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:47 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 17 +++++------------
>  1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 7dedfd548b..6ad40e43b0 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -620,23 +620,16 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
>
>  static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2;
> -
> -    gen_get_gpr(source1, a->rs1);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
>      if (a->shamt == (TARGET_LONG_BITS - 8)) {
>          /* rev8, byte swaps */
> -        tcg_gen_bswap_tl(source1, source1);
> +        tcg_gen_bswap_tl(dest, src1);
>      } else {
> -        source2 = tcg_temp_new();
> -        tcg_gen_movi_tl(source2, a->shamt);
> -        gen_helper_grev(source1, source1, source2);
> -        tcg_temp_free(source2);
> +        TCGv src2 = tcg_constant_tl(a->shamt);
> +        gen_helper_grev(dest, src1, src2);
>      }
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi
@ 2021-07-13  4:12     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:12 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:47 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 17 +++++------------
>  1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 7dedfd548b..6ad40e43b0 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -620,23 +620,16 @@ static void gen_sro(TCGv ret, TCGv arg1, TCGv arg2)
>
>  static bool gen_grevi(DisasContext *ctx, arg_grevi *a)
>  {
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2;
> -
> -    gen_get_gpr(source1, a->rs1);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
>      if (a->shamt == (TARGET_LONG_BITS - 8)) {
>          /* rev8, byte swaps */
> -        tcg_gen_bswap_tl(source1, source1);
> +        tcg_gen_bswap_tl(dest, src1);
>      } else {
> -        source2 = tcg_temp_new();
> -        tcg_gen_movi_tl(source2, a->shamt);
> -        gen_helper_grev(source1, source1, source2);
> -        tcg_temp_free(source2);
> +        TCGv src2 = tcg_constant_tl(a->shamt);
> +        gen_helper_grev(dest, src1, src2);
>      }
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 06/17] target/riscv: Use gpr_src in branches
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-13  4:14     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:14 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:39 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Narrow the scope of t0 in trans_jalr.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 25 ++++++++++---------------
>  1 file changed, 10 insertions(+), 15 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 6e736c9d0d..a603925637 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -54,24 +54,25 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
>
>  static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>  {
> -    /* no chaining with JALR */
>      TCGLabel *misaligned = NULL;
> -    TCGv t0 = tcg_temp_new();
>
> -
> -    gen_get_gpr(cpu_pc, a->rs1);
> -    tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
> +    tcg_gen_addi_tl(cpu_pc, gpr_src(ctx, a->rs1), a->imm);
>      tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
>
>      if (!has_ext(ctx, RVC)) {
> +        TCGv t0 = tcg_temp_new();
> +
>          misaligned = gen_new_label();
>          tcg_gen_andi_tl(t0, cpu_pc, 0x2);
>          tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> +        tcg_temp_free(t0);
>      }
>
>      if (a->rd != 0) {
>          tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
>      }
> +
> +    /* No chaining with JALR. */
>      lookup_and_goto_ptr(ctx);
>
>      if (misaligned) {
> @@ -80,21 +81,18 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>      }
>      ctx->base.is_jmp = DISAS_NORETURN;
>
> -    tcg_temp_free(t0);
>      return true;
>  }
>
>  static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>  {
>      TCGLabel *l = gen_new_label();
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>
> -    tcg_gen_brcond_tl(cond, source1, source2, l);
> +    tcg_gen_brcond_tl(cond, src1, src2, l);
>      gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
> +
>      gen_set_label(l); /* branch taken */
>
>      if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
> @@ -105,9 +103,6 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>      }
>      ctx->base.is_jmp = DISAS_NORETURN;
>
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 06/17] target/riscv: Use gpr_src in branches
@ 2021-07-13  4:14     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:14 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:39 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Narrow the scope of t0 in trans_jalr.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 25 ++++++++++---------------
>  1 file changed, 10 insertions(+), 15 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 6e736c9d0d..a603925637 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -54,24 +54,25 @@ static bool trans_jal(DisasContext *ctx, arg_jal *a)
>
>  static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>  {
> -    /* no chaining with JALR */
>      TCGLabel *misaligned = NULL;
> -    TCGv t0 = tcg_temp_new();
>
> -
> -    gen_get_gpr(cpu_pc, a->rs1);
> -    tcg_gen_addi_tl(cpu_pc, cpu_pc, a->imm);
> +    tcg_gen_addi_tl(cpu_pc, gpr_src(ctx, a->rs1), a->imm);
>      tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
>
>      if (!has_ext(ctx, RVC)) {
> +        TCGv t0 = tcg_temp_new();
> +
>          misaligned = gen_new_label();
>          tcg_gen_andi_tl(t0, cpu_pc, 0x2);
>          tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
> +        tcg_temp_free(t0);
>      }
>
>      if (a->rd != 0) {
>          tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
>      }
> +
> +    /* No chaining with JALR. */
>      lookup_and_goto_ptr(ctx);
>
>      if (misaligned) {
> @@ -80,21 +81,18 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
>      }
>      ctx->base.is_jmp = DISAS_NORETURN;
>
> -    tcg_temp_free(t0);
>      return true;
>  }
>
>  static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>  {
>      TCGLabel *l = gen_new_label();
> -    TCGv source1, source2;
> -    source1 = tcg_temp_new();
> -    source2 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>
> -    tcg_gen_brcond_tl(cond, source1, source2, l);
> +    tcg_gen_brcond_tl(cond, src1, src2, l);
>      gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
> +
>      gen_set_label(l); /* branch taken */
>
>      if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + a->imm) & 0x3)) {
> @@ -105,9 +103,6 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond)
>      }
>      ctx->base.is_jmp = DISAS_NORETURN;
>
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 07/17] target/riscv: Use gpr_{src, dst} for integer load/store
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-13  4:18     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:18 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:32 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 45 +++++++++++++++----------
>  1 file changed, 28 insertions(+), 17 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index a603925637..a422dc9ef4 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -138,15 +138,21 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
>
>  static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
>  {
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
> -    gen_set_gpr(a->rd, t1);
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> @@ -177,19 +183,24 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
>
>  static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
>  {
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
> -    gen_get_gpr(dat, a->rs2);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv data = gpr_src(ctx, a->rs2);
> +    TCGv temp = NULL;
>
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> -
>  static bool trans_sb(DisasContext *ctx, arg_sb *a)
>  {
>      return gen_store(ctx, a, MO_SB);
> --
> 2.25.1
>
>


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

* Re: [PATCH 07/17] target/riscv: Use gpr_{src, dst} for integer load/store
@ 2021-07-13  4:18     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-13  4:18 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:32 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 45 +++++++++++++++----------
>  1 file changed, 28 insertions(+), 17 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index a603925637..a422dc9ef4 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -138,15 +138,21 @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
>
>  static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
>  {
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
> -    gen_set_gpr(a->rd, t1);
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> @@ -177,19 +183,24 @@ static bool trans_lhu(DisasContext *ctx, arg_lhu *a)
>
>  static bool gen_store(DisasContext *ctx, arg_sb *a, MemOp memop)
>  {
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
> -    gen_get_gpr(dat, a->rs2);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv data = gpr_src(ctx, a->rs2);
> +    TCGv temp = NULL;
>
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> -
>  static bool trans_sb(DisasContext *ctx, arg_sb *a)
>  {
>      return gen_store(ctx, a, MO_SB);
> --
> 2.25.1
>
>


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

* Re: [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations
  2021-07-09  4:25   ` Richard Henderson
@ 2021-07-15  4:49     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:49 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:35 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> For trans_sllw, we can just use gen_shiftw.  The others use
> various tricks to reduce the tcg operation count.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 82 ++++++++++---------------
>  1 file changed, 31 insertions(+), 51 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index a422dc9ef4..840187a4d6 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -352,24 +352,23 @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
>  static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv t = tcg_temp_new();
> -    gen_get_gpr(t, a->rs1);
> -    tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
> -    /* sign-extend for W instructions */
> -    tcg_gen_ext32s_tl(t, t);
> -    gen_set_gpr(a->rd, t);
> -    tcg_temp_free(t);
> +
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +
> +    tcg_gen_extract_tl(dest, src1, a->shamt, 32 - a->shamt);
> +    tcg_gen_ext32s_tl(dest, dest);
>      return true;
>  }
>
>  static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv t = tcg_temp_new();
> -    gen_get_gpr(t, a->rs1);
> -    tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
> -    gen_set_gpr(a->rd, t);
> -    tcg_temp_free(t);
> +
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +
> +    tcg_gen_sextract_tl(dest, src1, a->shamt, 32 - a->shamt);
>      return true;
>  }
>
> @@ -388,64 +387,45 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
>  static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> -
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_andi_tl(source2, source2, 0x1F);
> -    tcg_gen_shl_tl(source1, source1, source2);
> -
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -    return true;
> +    return gen_shiftw(ctx, a, tcg_gen_shl_tl);
>  }
>
>  static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> -    /* clear upper 32 */
> -    tcg_gen_ext32u_tl(source1, source1);
> -    tcg_gen_andi_tl(source2, source2, 0x1F);
> -    tcg_gen_shr_tl(source1, source1, source2);
> +    tcg_gen_andi_tl(ext2, src2, 31);
> +    tcg_gen_ext32u_tl(dest, src1);
> +    tcg_gen_shr_tl(dest, dest, ext2);
> +    tcg_gen_ext32s_tl(dest, dest);
>
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
>  static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> +    tcg_gen_andi_tl(ext2, src2, 31);
>      /*
> -     * first, trick to get it to act like working on 32 bits (get rid of
> -     * upper 32, sign extend to fill space)
> +     * First, trick to get it to act like working on 32 bits
> +     * (get rid of upper 32, sign extend to fill space)
>       */
> -    tcg_gen_ext32s_tl(source1, source1);
> -    tcg_gen_andi_tl(source2, source2, 0x1F);
> -    tcg_gen_sar_tl(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_ext32s_tl(dest, src1);
> +    tcg_gen_sar_tl(dest, dest, ext2);
>
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations
@ 2021-07-15  4:49     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:49 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:35 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> For trans_sllw, we can just use gen_shiftw.  The others use
> various tricks to reduce the tcg operation count.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 82 ++++++++++---------------
>  1 file changed, 31 insertions(+), 51 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index a422dc9ef4..840187a4d6 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -352,24 +352,23 @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
>  static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv t = tcg_temp_new();
> -    gen_get_gpr(t, a->rs1);
> -    tcg_gen_extract_tl(t, t, a->shamt, 32 - a->shamt);
> -    /* sign-extend for W instructions */
> -    tcg_gen_ext32s_tl(t, t);
> -    gen_set_gpr(a->rd, t);
> -    tcg_temp_free(t);
> +
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +
> +    tcg_gen_extract_tl(dest, src1, a->shamt, 32 - a->shamt);
> +    tcg_gen_ext32s_tl(dest, dest);
>      return true;
>  }
>
>  static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv t = tcg_temp_new();
> -    gen_get_gpr(t, a->rs1);
> -    tcg_gen_sextract_tl(t, t, a->shamt, 32 - a->shamt);
> -    gen_set_gpr(a->rd, t);
> -    tcg_temp_free(t);
> +
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +
> +    tcg_gen_sextract_tl(dest, src1, a->shamt, 32 - a->shamt);
>      return true;
>  }
>
> @@ -388,64 +387,45 @@ static bool trans_subw(DisasContext *ctx, arg_subw *a)
>  static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> -
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_andi_tl(source2, source2, 0x1F);
> -    tcg_gen_shl_tl(source1, source1, source2);
> -
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -    return true;
> +    return gen_shiftw(ctx, a, tcg_gen_shl_tl);
>  }
>
>  static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> -    /* clear upper 32 */
> -    tcg_gen_ext32u_tl(source1, source1);
> -    tcg_gen_andi_tl(source2, source2, 0x1F);
> -    tcg_gen_shr_tl(source1, source1, source2);
> +    tcg_gen_andi_tl(ext2, src2, 31);
> +    tcg_gen_ext32u_tl(dest, src1);
> +    tcg_gen_shr_tl(dest, dest, ext2);
> +    tcg_gen_ext32s_tl(dest, dest);
>
> -    tcg_gen_ext32s_tl(source1, source1);
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
>  static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
>  {
>      REQUIRE_64BIT(ctx);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
>
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
> +    TCGv ext2 = tcg_temp_new();
>
> +    tcg_gen_andi_tl(ext2, src2, 31);
>      /*
> -     * first, trick to get it to act like working on 32 bits (get rid of
> -     * upper 32, sign extend to fill space)
> +     * First, trick to get it to act like working on 32 bits
> +     * (get rid of upper 32, sign extend to fill space)
>       */
> -    tcg_gen_ext32s_tl(source1, source1);
> -    tcg_gen_andi_tl(source2, source2, 0x1F);
> -    tcg_gen_sar_tl(source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> +    tcg_gen_ext32s_tl(dest, src1);
> +    tcg_gen_sar_tl(dest, dest, ext2);
>
> +    tcg_temp_free(ext2);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  4:50     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:50 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:39 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rva.c.inc | 42 +++++++++----------------
>  1 file changed, 14 insertions(+), 28 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
> index ab2ec4f0a5..5bb5bbd09c 100644
> --- a/target/riscv/insn_trans/trans_rva.c.inc
> +++ b/target/riscv/insn_trans/trans_rva.c.inc
> @@ -18,11 +18,11 @@
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>
> -static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
> +static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
>  {
> -    TCGv src1 = tcg_temp_new();
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +
>      /* Put addr in load_res, data in load_val.  */
> -    gen_get_gpr(src1, a->rs1);
>      if (a->rl) {
>          tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
>      }
> @@ -33,30 +33,26 @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
>      tcg_gen_mov_tl(load_res, src1);
>      gen_set_gpr(a->rd, load_val);
>
> -    tcg_temp_free(src1);
>      return true;
>  }
>
> -static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
> +static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
>  {
> -    TCGv src1 = tcg_temp_new();
> -    TCGv src2 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>      TCGLabel *l1 = gen_new_label();
>      TCGLabel *l2 = gen_new_label();
>
> -    gen_get_gpr(src1, a->rs1);
>      tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
>
> -    gen_get_gpr(src2, a->rs2);
>      /*
>       * Note that the TCG atomic primitives are SC,
>       * so we can ignore AQ/RL along this path.
>       */
> -    tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
> +    tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
>                                ctx->mem_idx, mop);
> -    tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
> -    gen_set_gpr(a->rd, dat);
> +    tcg_gen_setcond_tl(TCG_COND_NE, dest, dest, load_val);
>      tcg_gen_br(l2);
>
>      gen_set_label(l1);
> @@ -65,8 +61,7 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
>       * provide the memory barrier implied by AQ/RL.
>       */
>      tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
> -    tcg_gen_movi_tl(dat, 1);
> -    gen_set_gpr(a->rd, dat);
> +    tcg_gen_movi_tl(dest, 1);
>
>      gen_set_label(l2);
>      /*
> @@ -75,9 +70,6 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
>       */
>      tcg_gen_movi_tl(load_res, -1);
>
> -    tcg_temp_free(dat);
> -    tcg_temp_free(src1);
> -    tcg_temp_free(src2);
>      return true;
>  }
>
> @@ -85,17 +77,11 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
>                      void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
>                      MemOp mop)
>  {
> -    TCGv src1 = tcg_temp_new();
> -    TCGv src2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>
> -    gen_get_gpr(src1, a->rs1);
> -    gen_get_gpr(src2, a->rs2);
> -
> -    (*func)(src2, src1, src2, ctx->mem_idx, mop);
> -
> -    gen_set_gpr(a->rd, src2);
> -    tcg_temp_free(src1);
> -    tcg_temp_free(src2);
> +    (*func)(dest, src1, src2, ctx->mem_idx, mop);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA
@ 2021-07-15  4:50     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:50 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:39 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rva.c.inc | 42 +++++++++----------------
>  1 file changed, 14 insertions(+), 28 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
> index ab2ec4f0a5..5bb5bbd09c 100644
> --- a/target/riscv/insn_trans/trans_rva.c.inc
> +++ b/target/riscv/insn_trans/trans_rva.c.inc
> @@ -18,11 +18,11 @@
>   * this program.  If not, see <http://www.gnu.org/licenses/>.
>   */
>
> -static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
> +static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
>  {
> -    TCGv src1 = tcg_temp_new();
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +
>      /* Put addr in load_res, data in load_val.  */
> -    gen_get_gpr(src1, a->rs1);
>      if (a->rl) {
>          tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
>      }
> @@ -33,30 +33,26 @@ static inline bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
>      tcg_gen_mov_tl(load_res, src1);
>      gen_set_gpr(a->rd, load_val);
>
> -    tcg_temp_free(src1);
>      return true;
>  }
>
> -static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
> +static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
>  {
> -    TCGv src1 = tcg_temp_new();
> -    TCGv src2 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>      TCGLabel *l1 = gen_new_label();
>      TCGLabel *l2 = gen_new_label();
>
> -    gen_get_gpr(src1, a->rs1);
>      tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
>
> -    gen_get_gpr(src2, a->rs2);
>      /*
>       * Note that the TCG atomic primitives are SC,
>       * so we can ignore AQ/RL along this path.
>       */
> -    tcg_gen_atomic_cmpxchg_tl(src1, load_res, load_val, src2,
> +    tcg_gen_atomic_cmpxchg_tl(dest, load_res, load_val, src2,
>                                ctx->mem_idx, mop);
> -    tcg_gen_setcond_tl(TCG_COND_NE, dat, src1, load_val);
> -    gen_set_gpr(a->rd, dat);
> +    tcg_gen_setcond_tl(TCG_COND_NE, dest, dest, load_val);
>      tcg_gen_br(l2);
>
>      gen_set_label(l1);
> @@ -65,8 +61,7 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
>       * provide the memory barrier implied by AQ/RL.
>       */
>      tcg_gen_mb(TCG_MO_ALL + a->aq * TCG_BAR_LDAQ + a->rl * TCG_BAR_STRL);
> -    tcg_gen_movi_tl(dat, 1);
> -    gen_set_gpr(a->rd, dat);
> +    tcg_gen_movi_tl(dest, 1);
>
>      gen_set_label(l2);
>      /*
> @@ -75,9 +70,6 @@ static inline bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
>       */
>      tcg_gen_movi_tl(load_res, -1);
>
> -    tcg_temp_free(dat);
> -    tcg_temp_free(src1);
> -    tcg_temp_free(src2);
>      return true;
>  }
>
> @@ -85,17 +77,11 @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
>                      void(*func)(TCGv, TCGv, TCGv, TCGArg, MemOp),
>                      MemOp mop)
>  {
> -    TCGv src1 = tcg_temp_new();
> -    TCGv src2 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
> +    TCGv src2 = gpr_src(ctx, a->rs2);
>
> -    gen_get_gpr(src1, a->rs1);
> -    gen_get_gpr(src2, a->rs2);
> -
> -    (*func)(src2, src1, src2, ctx->mem_idx, mop);
> -
> -    gen_set_gpr(a->rd, src2);
> -    tcg_temp_free(src1);
> -    tcg_temp_free(src2);
> +    (*func)(dest, src1, src2, ctx->mem_idx, mop);
>      return true;
>  }
>
> --
> 2.25.1
>
>


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

* Re: [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  4:52     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:52 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:37 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvb.c.inc | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
> index 9e81f6e3de..58921f3224 100644
> --- a/target/riscv/insn_trans/trans_rvb.c.inc
> +++ b/target/riscv/insn_trans/trans_rvb.c.inc
> @@ -423,16 +423,13 @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVB);
>
> -    TCGv source1 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
>      if (a->shamt < 32) {
> -        tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
> +        tcg_gen_deposit_z_tl(dest, src1, a->shamt, 32);
>      } else {
> -        tcg_gen_shli_tl(source1, source1, a->shamt);
> +        tcg_gen_shli_tl(dest, src1, a->shamt);
>      }
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
>      return true;
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB
@ 2021-07-15  4:52     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:52 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:37 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvb.c.inc | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
> index 9e81f6e3de..58921f3224 100644
> --- a/target/riscv/insn_trans/trans_rvb.c.inc
> +++ b/target/riscv/insn_trans/trans_rvb.c.inc
> @@ -423,16 +423,13 @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVB);
>
> -    TCGv source1 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> +    TCGv dest = gpr_dst(ctx, a->rd);
> +    TCGv src1 = gpr_src(ctx, a->rs1);
>
>      if (a->shamt < 32) {
> -        tcg_gen_deposit_z_tl(source1, source1, a->shamt, 32);
> +        tcg_gen_deposit_z_tl(dest, src1, a->shamt, 32);
>      } else {
> -        tcg_gen_shli_tl(source1, source1, a->shamt);
> +        tcg_gen_shli_tl(dest, src1, a->shamt);
>      }
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
>      return true;
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  4:58     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:58 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:49 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvf.c.inc | 131 +++++++++---------------
>  1 file changed, 49 insertions(+), 82 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
> index 89f78701e7..ff8e942199 100644
> --- a/target/riscv/insn_trans/trans_rvf.c.inc
> +++ b/target/riscv/insn_trans/trans_rvf.c.inc
> @@ -27,14 +27,23 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
>
> -    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
> -    gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_temp_free(t0);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    TCGv_i64 dest = cpu_fpr[a->rd];
> +    tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
> +    gen_nanbox_s(dest, dest);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      mark_fs_dirty(ctx);
>      return true;
>  }
> @@ -43,14 +52,21 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
>
> -    tcg_gen_addi_tl(t0, t0, a->imm);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUL);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
>
> -    tcg_temp_free(t0);
> +    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> @@ -271,12 +287,8 @@ static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_w_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -285,12 +297,8 @@ static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_wu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -300,17 +308,14 @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
>
>  #if defined(TARGET_RISCV64)
> -    tcg_gen_ext32s_tl(t0, cpu_fpr[a->rs1]);
> +    tcg_gen_ext32s_tl(dest, cpu_fpr[a->rs1]);
>  #else
> -    tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
> +    tcg_gen_extrl_i64_i32(dest, cpu_fpr[a->rs1]);
>  #endif
>
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -318,10 +323,9 @@ static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +
> +    gen_helper_feq_s(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -329,10 +333,9 @@ static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +
> +    gen_helper_flt_s(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -340,10 +343,9 @@ static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +
> +    gen_helper_fle_s(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -352,13 +354,7 @@ static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -
> -    gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
> -
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fclass_s(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -367,15 +363,10 @@ static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -384,15 +375,10 @@ static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -402,15 +388,10 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
> +    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
>      gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -420,11 +401,8 @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_l_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -434,11 +412,8 @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_lu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -448,14 +423,10 @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
>      return true;
>  }
>
> @@ -465,13 +436,9 @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
>      return true;
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF
@ 2021-07-15  4:58     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  4:58 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:49 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvf.c.inc | 131 +++++++++---------------
>  1 file changed, 49 insertions(+), 82 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
> index 89f78701e7..ff8e942199 100644
> --- a/target/riscv/insn_trans/trans_rvf.c.inc
> +++ b/target/riscv/insn_trans/trans_rvf.c.inc
> @@ -27,14 +27,23 @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
>
> -    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
> -    gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_temp_free(t0);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    TCGv_i64 dest = cpu_fpr[a->rd];
> +    tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
> +    gen_nanbox_s(dest, dest);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      mark_fs_dirty(ctx);
>      return true;
>  }
> @@ -43,14 +52,21 @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
>
> -    tcg_gen_addi_tl(t0, t0, a->imm);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEUL);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
>
> -    tcg_temp_free(t0);
> +    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> @@ -271,12 +287,8 @@ static bool trans_fcvt_w_s(DisasContext *ctx, arg_fcvt_w_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_w_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_w_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -285,12 +297,8 @@ static bool trans_fcvt_wu_s(DisasContext *ctx, arg_fcvt_wu_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_wu_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_wu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -300,17 +308,14 @@ static bool trans_fmv_x_w(DisasContext *ctx, arg_fmv_x_w *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> +    TCGv dest = gpr_dst(ctx, a->rd);
>
>  #if defined(TARGET_RISCV64)
> -    tcg_gen_ext32s_tl(t0, cpu_fpr[a->rs1]);
> +    tcg_gen_ext32s_tl(dest, cpu_fpr[a->rs1]);
>  #else
> -    tcg_gen_extrl_i64_i32(t0, cpu_fpr[a->rs1]);
> +    tcg_gen_extrl_i64_i32(dest, cpu_fpr[a->rs1]);
>  #endif
>
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -318,10 +323,9 @@ static bool trans_feq_s(DisasContext *ctx, arg_feq_s *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_feq_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +
> +    gen_helper_feq_s(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -329,10 +333,9 @@ static bool trans_flt_s(DisasContext *ctx, arg_flt_s *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_flt_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +
> +    gen_helper_flt_s(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -340,10 +343,9 @@ static bool trans_fle_s(DisasContext *ctx, arg_fle_s *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_fle_s(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +
> +    gen_helper_fle_s(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -352,13 +354,7 @@ static bool trans_fclass_s(DisasContext *ctx, arg_fclass_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -
> -    gen_helper_fclass_s(t0, cpu_fpr[a->rs1]);
> -
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fclass_s(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -367,15 +363,10 @@ static bool trans_fcvt_s_w(DisasContext *ctx, arg_fcvt_s_w *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -384,15 +375,10 @@ static bool trans_fcvt_s_wu(DisasContext *ctx, arg_fcvt_s_wu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -402,15 +388,10 @@ static bool trans_fmv_w_x(DisasContext *ctx, arg_fmv_w_x *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], t0);
> +    tcg_gen_extu_tl_i64(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
>      gen_nanbox_s(cpu_fpr[a->rd], cpu_fpr[a->rd]);
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
> -
>      return true;
>  }
>
> @@ -420,11 +401,8 @@ static bool trans_fcvt_l_s(DisasContext *ctx, arg_fcvt_l_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_l_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_l_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -434,11 +412,8 @@ static bool trans_fcvt_lu_s(DisasContext *ctx, arg_fcvt_lu_s *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_lu_s(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_lu_s(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -448,14 +423,10 @@ static bool trans_fcvt_s_l(DisasContext *ctx, arg_fcvt_s_l *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
>      return true;
>  }
>
> @@ -465,13 +436,9 @@ static bool trans_fcvt_s_lu(DisasContext *ctx, arg_fcvt_s_lu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVF);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, t0);
> +    gen_helper_fcvt_s_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
>      return true;
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  5:00     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:00 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:42 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvd.c.inc | 116 +++++++++---------------
>  1 file changed, 44 insertions(+), 72 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
> index 7e45538ae0..9bb15fdc12 100644
> --- a/target/riscv/insn_trans/trans_rvd.c.inc
> +++ b/target/riscv/insn_trans/trans_rvd.c.inc
> @@ -22,14 +22,22 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
>
> -    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
>      return true;
>  }
>
> @@ -37,13 +45,21 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
>
> -    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_temp_free(t0);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> @@ -252,11 +268,8 @@ static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_feq_d(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -265,11 +278,8 @@ static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_flt_d(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -278,11 +288,8 @@ static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fle_d(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -291,10 +298,7 @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fclass_d(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -303,12 +307,8 @@ static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_w_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -317,12 +317,8 @@ static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_wu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -331,12 +327,8 @@ static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
>      return true;
> @@ -347,12 +339,8 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
>      return true;
> @@ -364,11 +352,8 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_l_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -378,11 +363,8 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_lu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -406,12 +388,9 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
> +
>      mark_fs_dirty(ctx);
>      return true;
>  }
> @@ -422,12 +401,9 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
> +
>      mark_fs_dirty(ctx);
>      return true;
>  }
> @@ -439,11 +415,7 @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
>      REQUIRE_EXT(ctx, RVD);
>
>  #ifdef TARGET_RISCV64
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
> -    tcg_temp_free(t0);
> +    tcg_gen_mov_tl(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
>      mark_fs_dirty(ctx);
>      return true;
>  #else
> --
> 2.25.1
>
>


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

* Re: [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD
@ 2021-07-15  5:00     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:00 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:42 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvd.c.inc | 116 +++++++++---------------
>  1 file changed, 44 insertions(+), 72 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
> index 7e45538ae0..9bb15fdc12 100644
> --- a/target/riscv/insn_trans/trans_rvd.c.inc
> +++ b/target/riscv/insn_trans/trans_rvd.c.inc
> @@ -22,14 +22,22 @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
>
> -    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEQ);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEQ);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      mark_fs_dirty(ctx);
> -    tcg_temp_free(t0);
>      return true;
>  }
>
> @@ -37,13 +45,21 @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
>  {
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_addi_tl(t0, t0, a->imm);
>
> -    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], t0, ctx->mem_idx, MO_TEQ);
> +    TCGv addr = gpr_src(ctx, a->rs1);
> +    TCGv temp = NULL;
>
> -    tcg_temp_free(t0);
> +    if (a->imm) {
> +        temp = tcg_temp_new();
> +        tcg_gen_addi_tl(temp, addr, a->imm);
> +        addr = temp;
> +    }
> +
> +    tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEQ);
> +
> +    if (temp) {
> +        tcg_temp_free(temp);
> +    }
>      return true;
>  }
>
> @@ -252,11 +268,8 @@ static bool trans_feq_d(DisasContext *ctx, arg_feq_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_feq_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_feq_d(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -265,11 +278,8 @@ static bool trans_flt_d(DisasContext *ctx, arg_flt_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_flt_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_flt_d(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -278,11 +288,8 @@ static bool trans_fle_d(DisasContext *ctx, arg_fle_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_fle_d(t0, cpu_env, cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fle_d(gpr_dst(ctx, a->rd), cpu_env,
> +                     cpu_fpr[a->rs1], cpu_fpr[a->rs2]);
>      return true;
>  }
>
> @@ -291,10 +298,7 @@ static bool trans_fclass_d(DisasContext *ctx, arg_fclass_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_helper_fclass_d(t0, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fclass_d(gpr_dst(ctx, a->rd), cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -303,12 +307,8 @@ static bool trans_fcvt_w_d(DisasContext *ctx, arg_fcvt_w_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_w_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_w_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -317,12 +317,8 @@ static bool trans_fcvt_wu_d(DisasContext *ctx, arg_fcvt_wu_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_wu_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> -
> +    gen_helper_fcvt_wu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -331,12 +327,8 @@ static bool trans_fcvt_d_w(DisasContext *ctx, arg_fcvt_d_w *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_w(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
>      return true;
> @@ -347,12 +339,8 @@ static bool trans_fcvt_d_wu(DisasContext *ctx, arg_fcvt_d_wu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_wu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
>
>      mark_fs_dirty(ctx);
>      return true;
> @@ -364,11 +352,8 @@ static bool trans_fcvt_l_d(DisasContext *ctx, arg_fcvt_l_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_l_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_l_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -378,11 +363,8 @@ static bool trans_fcvt_lu_d(DisasContext *ctx, arg_fcvt_lu_d *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_lu_d(t0, cpu_env, cpu_fpr[a->rs1]);
> -    gen_set_gpr(a->rd, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_lu_d(gpr_dst(ctx, a->rd), cpu_env, cpu_fpr[a->rs1]);
>      return true;
>  }
>
> @@ -406,12 +388,9 @@ static bool trans_fcvt_d_l(DisasContext *ctx, arg_fcvt_d_l *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_l(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
> +
>      mark_fs_dirty(ctx);
>      return true;
>  }
> @@ -422,12 +401,9 @@ static bool trans_fcvt_d_lu(DisasContext *ctx, arg_fcvt_d_lu *a)
>      REQUIRE_FPU;
>      REQUIRE_EXT(ctx, RVD);
>
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
>      gen_set_rm(ctx, a->rm);
> -    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, t0);
> -    tcg_temp_free(t0);
> +    gen_helper_fcvt_d_lu(cpu_fpr[a->rd], cpu_env, gpr_src(ctx, a->rs1));
> +
>      mark_fs_dirty(ctx);
>      return true;
>  }
> @@ -439,11 +415,7 @@ static bool trans_fmv_d_x(DisasContext *ctx, arg_fmv_d_x *a)
>      REQUIRE_EXT(ctx, RVD);
>
>  #ifdef TARGET_RISCV64
> -    TCGv t0 = tcg_temp_new();
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_mov_tl(cpu_fpr[a->rd], t0);
> -    tcg_temp_free(t0);
> +    tcg_gen_mov_tl(cpu_fpr[a->rd], gpr_src(ctx, a->rs1));
>      mark_fs_dirty(ctx);
>      return true;
>  #else
> --
> 2.25.1
>
>


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

* Re: [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  5:02     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:02 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:40 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Split out gen_mulh and gen_mulhu and use the common helper.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c                | 16 ++++++++++++++++
>  target/riscv/insn_trans/trans_rvm.c.inc | 24 ++----------------------
>  2 files changed, 18 insertions(+), 22 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 6ad40e43b0..8ff75a5798 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -235,6 +235,22 @@ static TCGv gpr_dst(DisasContext *ctx, int reg_num)
>      return cpu_gpr[reg_num];
>  }
>
> +static void gen_mulh(TCGv ret, TCGv s1, TCGv s2)
> +{
> +    TCGv discard = tcg_temp_new();
> +
> +    tcg_gen_muls2_tl(discard, ret, s1, s2);
> +    tcg_temp_free(discard);
> +}
> +
> +static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
> +{
> +    TCGv discard = tcg_temp_new();
> +
> +    tcg_gen_mulu2_tl(discard, ret, s1, s2);
> +    tcg_temp_free(discard);
> +}
> +
>  static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
>  {
>      TCGv rl = tcg_temp_new();
> diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
> index 10ecc456fc..34220b824d 100644
> --- a/target/riscv/insn_trans/trans_rvm.c.inc
> +++ b/target/riscv/insn_trans/trans_rvm.c.inc
> @@ -28,17 +28,7 @@ static bool trans_mul(DisasContext *ctx, arg_mul *a)
>  static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
>  {
>      REQUIRE_EXT(ctx, RVM);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_muls2_tl(source2, source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -    return true;
> +    return gen_arith(ctx, a, gen_mulh);
>  }
>
>  static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
> @@ -50,17 +40,7 @@ static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
>  static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
>  {
>      REQUIRE_EXT(ctx, RVM);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_mulu2_tl(source2, source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -    return true;
> +    return gen_arith(ctx, a, gen_mulhu);
>  }
>
>  static bool trans_div(DisasContext *ctx, arg_div *a)
> --
> 2.25.1
>
>


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

* Re: [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu
@ 2021-07-15  5:02     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:02 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:40 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Split out gen_mulh and gen_mulhu and use the common helper.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c                | 16 ++++++++++++++++
>  target/riscv/insn_trans/trans_rvm.c.inc | 24 ++----------------------
>  2 files changed, 18 insertions(+), 22 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 6ad40e43b0..8ff75a5798 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -235,6 +235,22 @@ static TCGv gpr_dst(DisasContext *ctx, int reg_num)
>      return cpu_gpr[reg_num];
>  }
>
> +static void gen_mulh(TCGv ret, TCGv s1, TCGv s2)
> +{
> +    TCGv discard = tcg_temp_new();
> +
> +    tcg_gen_muls2_tl(discard, ret, s1, s2);
> +    tcg_temp_free(discard);
> +}
> +
> +static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
> +{
> +    TCGv discard = tcg_temp_new();
> +
> +    tcg_gen_mulu2_tl(discard, ret, s1, s2);
> +    tcg_temp_free(discard);
> +}
> +
>  static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
>  {
>      TCGv rl = tcg_temp_new();
> diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
> index 10ecc456fc..34220b824d 100644
> --- a/target/riscv/insn_trans/trans_rvm.c.inc
> +++ b/target/riscv/insn_trans/trans_rvm.c.inc
> @@ -28,17 +28,7 @@ static bool trans_mul(DisasContext *ctx, arg_mul *a)
>  static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
>  {
>      REQUIRE_EXT(ctx, RVM);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_muls2_tl(source2, source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -    return true;
> +    return gen_arith(ctx, a, gen_mulh);
>  }
>
>  static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
> @@ -50,17 +40,7 @@ static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
>  static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
>  {
>      REQUIRE_EXT(ctx, RVM);
> -    TCGv source1 = tcg_temp_new();
> -    TCGv source2 = tcg_temp_new();
> -    gen_get_gpr(source1, a->rs1);
> -    gen_get_gpr(source2, a->rs2);
> -
> -    tcg_gen_mulu2_tl(source2, source1, source1, source2);
> -
> -    gen_set_gpr(a->rd, source1);
> -    tcg_temp_free(source1);
> -    tcg_temp_free(source2);
> -    return true;
> +    return gen_arith(ctx, a, gen_mulhu);
>  }
>
>  static bool trans_div(DisasContext *ctx, arg_div *a)
> --
> 2.25.1
>
>


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

* Re: [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  5:04     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:04 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:43 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 79 +++++++------------------
>  1 file changed, 20 insertions(+), 59 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index a8e7272487..84a45fac38 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -27,27 +27,21 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>          return false;
>      }
>
> -    s2 = tcg_temp_new();
> -    dst = tcg_temp_new();
> +    s2 = gpr_src(ctx, a->rs2);
> +    dst = gpr_dst(ctx, a->rd);
>
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
>          s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> +        s1 = gpr_src(ctx, a->rs1);
>      }
> -    gen_get_gpr(s2, a->rs2);
>      gen_helper_vsetvl(dst, cpu_env, s1, s2);
> -    gen_set_gpr(a->rd, dst);
> +
>      tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
>      lookup_and_goto_ptr(ctx);
>      ctx->base.is_jmp = DISAS_NORETURN;
> -
> -    tcg_temp_free(s1);
> -    tcg_temp_free(s2);
> -    tcg_temp_free(dst);
>      return true;
>  }
>
> @@ -60,23 +54,19 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
>      }
>
>      s2 = tcg_constant_tl(a->zimm);
> -    dst = tcg_temp_new();
> +    dst = gpr_dst(ctx, a->rd);
>
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
>          s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> +        s1 = gpr_src(ctx, a->rs1);
>      }
>      gen_helper_vsetvl(dst, cpu_env, s1, s2);
> -    gen_set_gpr(a->rd, dst);
> +
>      gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
>      ctx->base.is_jmp = DISAS_NORETURN;
> -
> -    tcg_temp_free(s1);
> -    tcg_temp_free(dst);
>      return true;
>  }
>
> @@ -173,7 +163,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>
>      /*
>       * As simd_desc supports at most 256 bytes, and in this implementation,
> @@ -184,7 +174,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>       */
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
> @@ -192,7 +181,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -330,12 +318,10 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> -    stride = tcg_temp_new();
> +    base = gpr_src(s, rs1);
> +    stride = gpr_src(s, rs2);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
> -    gen_get_gpr(stride, rs2);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
> @@ -343,8 +329,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
> -    tcg_temp_free(base);
> -    tcg_temp_free(stride);
>      gen_set_label(over);
>      return true;
>  }
> @@ -458,10 +442,9 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -471,7 +454,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -589,10 +571,9 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
> @@ -600,7 +581,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -665,10 +645,9 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -678,7 +657,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -862,8 +840,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
> -    src1 = tcg_temp_new();
> -    gen_get_gpr(src1, rs1);
> +    src1 = gpr_src(s, rs1);
>
>      data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
>      data = FIELD_DP32(data, VDATA, VM, vm);
> @@ -879,7 +856,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
> -    tcg_temp_free(src1);
>      gen_set_label(over);
>      return true;
>  }
> @@ -905,15 +881,12 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
>
>      if (a->vm && s->vl_eq_vlmax) {
>          TCGv_i64 src1 = tcg_temp_new_i64();
> -        TCGv tmp = tcg_temp_new();
>
> -        gen_get_gpr(tmp, a->rs1);
> -        tcg_gen_ext_tl_i64(src1, tmp);
> +        tcg_gen_ext_tl_i64(src1, gpr_src(s, a->rs1));
>          gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
>                  src1, MAXSZ(s), MAXSZ(s));
>
>          tcg_temp_free_i64(src1);
> -        tcg_temp_free(tmp);
>          return true;
>      }
>      return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
> @@ -1398,16 +1371,13 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
>
>      if (a->vm && s->vl_eq_vlmax) {
>          TCGv_i32 src1 = tcg_temp_new_i32();
> -        TCGv tmp = tcg_temp_new();
>
> -        gen_get_gpr(tmp, a->rs1);
> -        tcg_gen_trunc_tl_i32(src1, tmp);
> +        tcg_gen_trunc_tl_i32(src1, gpr_src(s, a->rs1));
>          tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
>          gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
>                  src1, MAXSZ(s), MAXSZ(s));
>
>          tcg_temp_free_i32(src1);
> -        tcg_temp_free(tmp);
>          return true;
>      }
>      return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
> @@ -1665,8 +1635,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>          TCGLabel *over = gen_new_label();
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> +        s1 = gpr_src(s, a->rs1);
>
>          if (s->vl_eq_vlmax) {
>              tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
> @@ -1690,7 +1659,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>              tcg_temp_free_i64(s1_i64);
>          }
>
> -        tcg_temp_free(s1);
>          gen_set_label(over);
>          return true;
>      }
> @@ -2412,18 +2380,16 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
>
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
> -        dst = tcg_temp_new();
> +        dst = gpr_dst(s, a->rd);
>          desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
>          gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
> -        gen_set_gpr(a->rd, dst);
>
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
> -        tcg_temp_free(dst);
>          return true;
>      }
>      return false;
> @@ -2443,18 +2409,16 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
>
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
> -        dst = tcg_temp_new();
> +        dst = gpr_dst(s, a->rd);
>          desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
>          gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
> -        gen_set_gpr(a->rd, dst);
>
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
> -        tcg_temp_free(dst);
>          return true;
>      }
>      return false;
> @@ -2638,7 +2602,6 @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
>  static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>  {
>      TCGv_i64 tmp = tcg_temp_new_i64();
> -    TCGv dest = tcg_temp_new();
>
>      if (a->rs1 == 0) {
>          /* Special case vmv.x.s rd, vs2. */
> @@ -2648,10 +2611,8 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>          int vlmax = s->vlen >> (3 + s->sew);
>          vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
>      }
> -    tcg_gen_trunc_i64_tl(dest, tmp);
> -    gen_set_gpr(a->rd, dest);
>
> -    tcg_temp_free(dest);
> +    tcg_gen_trunc_i64_tl(gpr_dst(s, a->rd), tmp);
>      tcg_temp_free_i64(tmp);
>      return true;
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV
@ 2021-07-15  5:04     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:04 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:43 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn_trans/trans_rvv.c.inc | 79 +++++++------------------
>  1 file changed, 20 insertions(+), 59 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
> index a8e7272487..84a45fac38 100644
> --- a/target/riscv/insn_trans/trans_rvv.c.inc
> +++ b/target/riscv/insn_trans/trans_rvv.c.inc
> @@ -27,27 +27,21 @@ static bool trans_vsetvl(DisasContext *ctx, arg_vsetvl *a)
>          return false;
>      }
>
> -    s2 = tcg_temp_new();
> -    dst = tcg_temp_new();
> +    s2 = gpr_src(ctx, a->rs2);
> +    dst = gpr_dst(ctx, a->rd);
>
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
>          s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> +        s1 = gpr_src(ctx, a->rs1);
>      }
> -    gen_get_gpr(s2, a->rs2);
>      gen_helper_vsetvl(dst, cpu_env, s1, s2);
> -    gen_set_gpr(a->rd, dst);
> +
>      tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
>      lookup_and_goto_ptr(ctx);
>      ctx->base.is_jmp = DISAS_NORETURN;
> -
> -    tcg_temp_free(s1);
> -    tcg_temp_free(s2);
> -    tcg_temp_free(dst);
>      return true;
>  }
>
> @@ -60,23 +54,19 @@ static bool trans_vsetvli(DisasContext *ctx, arg_vsetvli *a)
>      }
>
>      s2 = tcg_constant_tl(a->zimm);
> -    dst = tcg_temp_new();
> +    dst = gpr_dst(ctx, a->rd);
>
>      /* Using x0 as the rs1 register specifier, encodes an infinite AVL */
>      if (a->rs1 == 0) {
>          /* As the mask is at least one bit, RV_VLEN_MAX is >= VLMAX */
>          s1 = tcg_constant_tl(RV_VLEN_MAX);
>      } else {
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> +        s1 = gpr_src(ctx, a->rs1);
>      }
>      gen_helper_vsetvl(dst, cpu_env, s1, s2);
> -    gen_set_gpr(a->rd, dst);
> +
>      gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
>      ctx->base.is_jmp = DISAS_NORETURN;
> -
> -    tcg_temp_free(s1);
> -    tcg_temp_free(dst);
>      return true;
>  }
>
> @@ -173,7 +163,7 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>
>      /*
>       * As simd_desc supports at most 256 bytes, and in this implementation,
> @@ -184,7 +174,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>       */
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
> @@ -192,7 +181,6 @@ static bool ldst_us_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -330,12 +318,10 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> -    stride = tcg_temp_new();
> +    base = gpr_src(s, rs1);
> +    stride = gpr_src(s, rs2);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
> -    gen_get_gpr(stride, rs2);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
> @@ -343,8 +329,6 @@ static bool ldst_stride_trans(uint32_t vd, uint32_t rs1, uint32_t rs2,
>
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
> -    tcg_temp_free(base);
> -    tcg_temp_free(stride);
>      gen_set_label(over);
>      return true;
>  }
> @@ -458,10 +442,9 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -471,7 +454,6 @@ static bool ldst_index_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -589,10 +571,9 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
> @@ -600,7 +581,6 @@ static bool ldff_trans(uint32_t vd, uint32_t rs1, uint32_t data,
>
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -665,10 +645,9 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      index = tcg_temp_new_ptr();
> -    base = tcg_temp_new();
> +    base = gpr_src(s, rs1);
>      desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
> -    gen_get_gpr(base, rs1);
>      tcg_gen_addi_ptr(dest, cpu_env, vreg_ofs(s, vd));
>      tcg_gen_addi_ptr(index, cpu_env, vreg_ofs(s, vs2));
>      tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
> @@ -678,7 +657,6 @@ static bool amo_trans(uint32_t vd, uint32_t rs1, uint32_t vs2,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(index);
> -    tcg_temp_free(base);
>      gen_set_label(over);
>      return true;
>  }
> @@ -862,8 +840,7 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      dest = tcg_temp_new_ptr();
>      mask = tcg_temp_new_ptr();
>      src2 = tcg_temp_new_ptr();
> -    src1 = tcg_temp_new();
> -    gen_get_gpr(src1, rs1);
> +    src1 = gpr_src(s, rs1);
>
>      data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
>      data = FIELD_DP32(data, VDATA, VM, vm);
> @@ -879,7 +856,6 @@ static bool opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
>      tcg_temp_free_ptr(dest);
>      tcg_temp_free_ptr(mask);
>      tcg_temp_free_ptr(src2);
> -    tcg_temp_free(src1);
>      gen_set_label(over);
>      return true;
>  }
> @@ -905,15 +881,12 @@ do_opivx_gvec(DisasContext *s, arg_rmrr *a, GVecGen2sFn *gvec_fn,
>
>      if (a->vm && s->vl_eq_vlmax) {
>          TCGv_i64 src1 = tcg_temp_new_i64();
> -        TCGv tmp = tcg_temp_new();
>
> -        gen_get_gpr(tmp, a->rs1);
> -        tcg_gen_ext_tl_i64(src1, tmp);
> +        tcg_gen_ext_tl_i64(src1, gpr_src(s, a->rs1));
>          gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
>                  src1, MAXSZ(s), MAXSZ(s));
>
>          tcg_temp_free_i64(src1);
> -        tcg_temp_free(tmp);
>          return true;
>      }
>      return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
> @@ -1398,16 +1371,13 @@ do_opivx_gvec_shift(DisasContext *s, arg_rmrr *a, GVecGen2sFn32 *gvec_fn,
>
>      if (a->vm && s->vl_eq_vlmax) {
>          TCGv_i32 src1 = tcg_temp_new_i32();
> -        TCGv tmp = tcg_temp_new();
>
> -        gen_get_gpr(tmp, a->rs1);
> -        tcg_gen_trunc_tl_i32(src1, tmp);
> +        tcg_gen_trunc_tl_i32(src1, gpr_src(s, a->rs1));
>          tcg_gen_extract_i32(src1, src1, 0, s->sew + 3);
>          gvec_fn(s->sew, vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2),
>                  src1, MAXSZ(s), MAXSZ(s));
>
>          tcg_temp_free_i32(src1);
> -        tcg_temp_free(tmp);
>          return true;
>      }
>      return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
> @@ -1665,8 +1635,7 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>          TCGLabel *over = gen_new_label();
>          tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
>
> -        s1 = tcg_temp_new();
> -        gen_get_gpr(s1, a->rs1);
> +        s1 = gpr_src(s, a->rs1);
>
>          if (s->vl_eq_vlmax) {
>              tcg_gen_gvec_dup_tl(s->sew, vreg_ofs(s, a->rd),
> @@ -1690,7 +1659,6 @@ static bool trans_vmv_v_x(DisasContext *s, arg_vmv_v_x *a)
>              tcg_temp_free_i64(s1_i64);
>          }
>
> -        tcg_temp_free(s1);
>          gen_set_label(over);
>          return true;
>      }
> @@ -2412,18 +2380,16 @@ static bool trans_vmpopc_m(DisasContext *s, arg_rmr *a)
>
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
> -        dst = tcg_temp_new();
> +        dst = gpr_dst(s, a->rd);
>          desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
>          gen_helper_vmpopc_m(dst, mask, src2, cpu_env, desc);
> -        gen_set_gpr(a->rd, dst);
>
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
> -        tcg_temp_free(dst);
>          return true;
>      }
>      return false;
> @@ -2443,18 +2409,16 @@ static bool trans_vmfirst_m(DisasContext *s, arg_rmr *a)
>
>          mask = tcg_temp_new_ptr();
>          src2 = tcg_temp_new_ptr();
> -        dst = tcg_temp_new();
> +        dst = gpr_dst(s, a->rd);
>          desc = tcg_constant_i32(simd_desc(s->vlen / 8, s->vlen / 8, data));
>
>          tcg_gen_addi_ptr(src2, cpu_env, vreg_ofs(s, a->rs2));
>          tcg_gen_addi_ptr(mask, cpu_env, vreg_ofs(s, 0));
>
>          gen_helper_vmfirst_m(dst, mask, src2, cpu_env, desc);
> -        gen_set_gpr(a->rd, dst);
>
>          tcg_temp_free_ptr(mask);
>          tcg_temp_free_ptr(src2);
> -        tcg_temp_free(dst);
>          return true;
>      }
>      return false;
> @@ -2638,7 +2602,6 @@ static void vec_element_loadi(DisasContext *s, TCGv_i64 dest,
>  static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>  {
>      TCGv_i64 tmp = tcg_temp_new_i64();
> -    TCGv dest = tcg_temp_new();
>
>      if (a->rs1 == 0) {
>          /* Special case vmv.x.s rd, vs2. */
> @@ -2648,10 +2611,8 @@ static bool trans_vext_x_v(DisasContext *s, arg_r *a)
>          int vlmax = s->vlen >> (3 + s->sew);
>          vec_element_loadx(s, tmp, a->rs2, cpu_gpr[a->rs1], vlmax);
>      }
> -    tcg_gen_trunc_i64_tl(dest, tmp);
> -    gen_set_gpr(a->rd, dest);
>
> -    tcg_temp_free(dest);
> +    tcg_gen_trunc_i64_tl(gpr_dst(s, a->rd), tmp);
>      tcg_temp_free_i64(tmp);
>      return true;
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 17/17] target/riscv: Remove gen_get_gpr
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-15  5:08     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:08 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:48 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This function is now unused.
> The corresponding gen_set_gpr function is still in use.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 17 +++++------------
>  1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 8ff75a5798..a6c850e9d3 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -195,15 +195,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
>  /* Wrapper for getting reg values - need to check of reg is zero since
>   * cpu_gpr[0] is not actually allocated
>   */
> -static inline void gen_get_gpr(TCGv t, int reg_num)
> -{
> -    if (reg_num == 0) {
> -        tcg_gen_movi_tl(t, 0);
> -    } else {
> -        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
> -    }
> -}
> -
>  static TCGv gpr_src(DisasContext *ctx, int reg_num)
>  {
>      if (reg_num == 0) {
> @@ -1046,9 +1037,11 @@ void riscv_translate_init(void)
>  {
>      int i;
>
> -    /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
> -    /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
> -    /* registers, unless you specifically block reads/writes to reg 0 */
> +    /*
> +     * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
> +     * Use the gpr_src and gpr_dst helper functions when accessing regs,
> +     * unless you specifically block reads/writes to reg 0.
> +     */
>      cpu_gpr[0] = NULL;
>
>      for (i = 1; i < 32; i++) {
> --
> 2.25.1
>
>


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

* Re: [PATCH 17/17] target/riscv: Remove gen_get_gpr
@ 2021-07-15  5:08     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-15  5:08 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:48 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> This function is now unused.
> The corresponding gen_set_gpr function is still in use.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/translate.c | 17 +++++------------
>  1 file changed, 5 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 8ff75a5798..a6c850e9d3 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -195,15 +195,6 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
>  /* Wrapper for getting reg values - need to check of reg is zero since
>   * cpu_gpr[0] is not actually allocated
>   */
> -static inline void gen_get_gpr(TCGv t, int reg_num)
> -{
> -    if (reg_num == 0) {
> -        tcg_gen_movi_tl(t, 0);
> -    } else {
> -        tcg_gen_mov_tl(t, cpu_gpr[reg_num]);
> -    }
> -}
> -
>  static TCGv gpr_src(DisasContext *ctx, int reg_num)
>  {
>      if (reg_num == 0) {
> @@ -1046,9 +1037,11 @@ void riscv_translate_init(void)
>  {
>      int i;
>
> -    /* cpu_gpr[0] is a placeholder for the zero register. Do not use it. */
> -    /* Use the gen_set_gpr and gen_get_gpr helper functions when accessing */
> -    /* registers, unless you specifically block reads/writes to reg 0 */
> +    /*
> +     * cpu_gpr[0] is a placeholder for the zero register. Do not use it.
> +     * Use the gpr_src and gpr_dst helper functions when accessing regs,
> +     * unless you specifically block reads/writes to reg 0.
> +     */
>      cpu_gpr[0] = NULL;
>
>      for (i = 1; i < 32; i++) {
> --
> 2.25.1
>
>


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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
  2021-07-09  4:25 ` Richard Henderson
@ 2021-07-15 11:21   ` LIU Zhiwei
  -1 siblings, 0 replies; 80+ messages in thread
From: LIU Zhiwei @ 2021-07-15 11:21 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis


On 2021/7/9 下午12:25, Richard Henderson wrote:
> Replace use of tcg_const_*, which makes a copy into a temp
> which must be freed, with direct use of the constant.
>
> Reorg handling of $zero, with different accessors for
> source and destination.
>
> Reorg handling of csrs, passing the actual write_mask
> instead of a regno.
>
> Use more helpers for RVH expansion.

Hi Richard,

In patch 09-17  target/riscv: Reorg csr instruction,  I think the 
parameter name 'rc'  can be renamed to 'csrno'.

Otherwise,
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Also on a side note, could you give me some advice for the following 
question?

I have been supporting  running 32bit application on qemu-riscv64. After 
this patch set,
it is hard to define a  method,  such as gpr_dst_s or gpr_dst_u, to 
extend the destination
register. I can only extend the destination register(ext32s or ext32u) 
in each instruction
with scattered code.

Can we just omit the extension of the destination register?

Best Regards,
Zhiwei



>
> r~
>
>
> Richard Henderson (17):
>    target/riscv: Use tcg_constant_*
>    target/riscv: Introduce gpr_src, gpr_dst
>    target/riscv: Use gpr_{src,dst} in shift operations
>    target/riscv: Use gpr_{src,dst} in word division operations
>    target/riscv: Use gpr_{src,dst} and tcg_constant_tl in gen_grevi
>    target/riscv: Use gpr_src in branches
>    target/riscv: Use gpr_{src,dst} for integer load/store
>    target/riscv: Use gpr_{src,dst} for word shift operations
>    target/riscv: Reorg csr instructions
>    target/riscv: Use gpr_{src,dst} for RVA
>    target/riscv: Use gpr_{src,dst} for RVB
>    target/riscv: Use gpr_{src,dst} for RVF
>    target/riscv: Use gpr_{src,dst} for RVD
>    target/riscv: Tidy trans_rvh.c.inc
>    target/riscv: Use gen_arith for mulh and mulhu
>    target/riscv: Use gpr_{src,dst} for RVV
>    target/riscv: Remove gen_get_gpr
>
>   target/riscv/helper.h                   |   6 +-
>   target/riscv/insn32.decode              |   1 +
>   target/riscv/op_helper.c                |  18 +-
>   target/riscv/translate.c                | 273 +++++++++-----------
>   target/riscv/insn_trans/trans_rva.c.inc |  42 ++--
>   target/riscv/insn_trans/trans_rvb.c.inc |  11 +-
>   target/riscv/insn_trans/trans_rvd.c.inc | 116 ++++-----
>   target/riscv/insn_trans/trans_rvf.c.inc | 134 ++++------
>   target/riscv/insn_trans/trans_rvh.c.inc | 264 ++++---------------
>   target/riscv/insn_trans/trans_rvi.c.inc | 322 ++++++++++++++----------
>   target/riscv/insn_trans/trans_rvm.c.inc |  24 +-
>   target/riscv/insn_trans/trans_rvv.c.inc | 144 ++++-------
>   12 files changed, 534 insertions(+), 821 deletions(-)
>


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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-15 11:21   ` LIU Zhiwei
  0 siblings, 0 replies; 80+ messages in thread
From: LIU Zhiwei @ 2021-07-15 11:21 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alistair.francis, qemu-riscv


On 2021/7/9 下午12:25, Richard Henderson wrote:
> Replace use of tcg_const_*, which makes a copy into a temp
> which must be freed, with direct use of the constant.
>
> Reorg handling of $zero, with different accessors for
> source and destination.
>
> Reorg handling of csrs, passing the actual write_mask
> instead of a regno.
>
> Use more helpers for RVH expansion.

Hi Richard,

In patch 09-17  target/riscv: Reorg csr instruction,  I think the 
parameter name 'rc'  can be renamed to 'csrno'.

Otherwise,
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

Also on a side note, could you give me some advice for the following 
question?

I have been supporting  running 32bit application on qemu-riscv64. After 
this patch set,
it is hard to define a  method,  such as gpr_dst_s or gpr_dst_u, to 
extend the destination
register. I can only extend the destination register(ext32s or ext32u) 
in each instruction
with scattered code.

Can we just omit the extension of the destination register?

Best Regards,
Zhiwei



>
> r~
>
>
> Richard Henderson (17):
>    target/riscv: Use tcg_constant_*
>    target/riscv: Introduce gpr_src, gpr_dst
>    target/riscv: Use gpr_{src,dst} in shift operations
>    target/riscv: Use gpr_{src,dst} in word division operations
>    target/riscv: Use gpr_{src,dst} and tcg_constant_tl in gen_grevi
>    target/riscv: Use gpr_src in branches
>    target/riscv: Use gpr_{src,dst} for integer load/store
>    target/riscv: Use gpr_{src,dst} for word shift operations
>    target/riscv: Reorg csr instructions
>    target/riscv: Use gpr_{src,dst} for RVA
>    target/riscv: Use gpr_{src,dst} for RVB
>    target/riscv: Use gpr_{src,dst} for RVF
>    target/riscv: Use gpr_{src,dst} for RVD
>    target/riscv: Tidy trans_rvh.c.inc
>    target/riscv: Use gen_arith for mulh and mulhu
>    target/riscv: Use gpr_{src,dst} for RVV
>    target/riscv: Remove gen_get_gpr
>
>   target/riscv/helper.h                   |   6 +-
>   target/riscv/insn32.decode              |   1 +
>   target/riscv/op_helper.c                |  18 +-
>   target/riscv/translate.c                | 273 +++++++++-----------
>   target/riscv/insn_trans/trans_rva.c.inc |  42 ++--
>   target/riscv/insn_trans/trans_rvb.c.inc |  11 +-
>   target/riscv/insn_trans/trans_rvd.c.inc | 116 ++++-----
>   target/riscv/insn_trans/trans_rvf.c.inc | 134 ++++------
>   target/riscv/insn_trans/trans_rvh.c.inc | 264 ++++---------------
>   target/riscv/insn_trans/trans_rvi.c.inc | 322 ++++++++++++++----------
>   target/riscv/insn_trans/trans_rvm.c.inc |  24 +-
>   target/riscv/insn_trans/trans_rvv.c.inc | 144 ++++-------
>   12 files changed, 534 insertions(+), 821 deletions(-)
>


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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
  2021-07-15 11:21   ` LIU Zhiwei
@ 2021-07-15 16:15     ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-15 16:15 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel; +Cc: qemu-riscv, alistair.francis

On 7/15/21 4:21 AM, LIU Zhiwei wrote:
> Also on a side note, could you give me some advice for the following question?
> 
> I have been supporting  running 32bit application on qemu-riscv64. After this patch set,
> it is hard to define a  method,  such as gpr_dst_s or gpr_dst_u, to extend the destination
> register. I can only extend the destination register(ext32s or ext32u) in each instruction
> with scattered code.
> 
> Can we just omit the extension of the destination register?

It's hard to give advice on code that I haven't seen.

In general I would think that the destination register need not be extended for 32-bit 
mode, unless the architecture says otherwise.  (What does the architecture say about the 
contents of the registers when transitioning from a 32-bit mode user program to a 64-bit 
mode kernel?)


r~


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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-15 16:15     ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-15 16:15 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel; +Cc: alistair.francis, qemu-riscv

On 7/15/21 4:21 AM, LIU Zhiwei wrote:
> Also on a side note, could you give me some advice for the following question?
> 
> I have been supporting  running 32bit application on qemu-riscv64. After this patch set,
> it is hard to define a  method,  such as gpr_dst_s or gpr_dst_u, to extend the destination
> register. I can only extend the destination register(ext32s or ext32u) in each instruction
> with scattered code.
> 
> Can we just omit the extension of the destination register?

It's hard to give advice on code that I haven't seen.

In general I would think that the destination register need not be extended for 32-bit 
mode, unless the architecture says otherwise.  (What does the architecture say about the 
contents of the registers when transitioning from a 32-bit mode user program to a 64-bit 
mode kernel?)


r~


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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
  2021-07-15 16:15     ` Richard Henderson
@ 2021-07-17  3:59       ` LIU Zhiwei
  -1 siblings, 0 replies; 80+ messages in thread
From: LIU Zhiwei @ 2021-07-17  3:59 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-riscv, alistair.francis

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


On 2021/7/16 上午12:15, Richard Henderson wrote:
> On 7/15/21 4:21 AM, LIU Zhiwei wrote:
>> Also on a side note, could you give me some advice for the following 
>> question?
>>
>> I have been supporting  running 32bit application on qemu-riscv64. 
>> After this patch set,
>> it is hard to define a  method,  such as gpr_dst_s or gpr_dst_u, to 
>> extend the destination
>> register. I can only extend the destination register(ext32s or 
>> ext32u) in each instruction
>> with scattered code.
>>
>> Can we just omit the extension of the destination register?
>
> It's hard to give advice on code that I haven't seen.
>
> In general I would think that the destination register need not be 
> extended for 32-bit mode, unless the architecture says otherwise. 
> (What does the architecture say about the contents of the registers 
> when transitioning from a 32-bit mode user program to a 64-bit mode 
> kernel?)
>
As privileged specification says,

"Whenever XLEN in any mode is set to a value less than the widest supported XLEN, all operations
must ignore source operand register bits above the configured XLEN, and must sign-extend results
to fill the entire widest supported XLEN in the destination register. Similarly, pc bits above XLEN
are ignored, and when the pc is written, it is sign-extended to fill the widest supported XLEN."

If we want to strictly obey the spec, we should
1) Ignore MSB 32bits for source register, and sign-extend the 
destination register.
2) Always use 32bit operation(TCG 32bit OP).

I want to still use TCG 64bit OP and just extend the source to 64bit by 
ext32s or ext32u.

Is is OK?

Thanks,
Zhiwei
>
> r~

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

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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-17  3:59       ` LIU Zhiwei
  0 siblings, 0 replies; 80+ messages in thread
From: LIU Zhiwei @ 2021-07-17  3:59 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alistair.francis, qemu-riscv

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


On 2021/7/16 上午12:15, Richard Henderson wrote:
> On 7/15/21 4:21 AM, LIU Zhiwei wrote:
>> Also on a side note, could you give me some advice for the following 
>> question?
>>
>> I have been supporting  running 32bit application on qemu-riscv64. 
>> After this patch set,
>> it is hard to define a  method,  such as gpr_dst_s or gpr_dst_u, to 
>> extend the destination
>> register. I can only extend the destination register(ext32s or 
>> ext32u) in each instruction
>> with scattered code.
>>
>> Can we just omit the extension of the destination register?
>
> It's hard to give advice on code that I haven't seen.
>
> In general I would think that the destination register need not be 
> extended for 32-bit mode, unless the architecture says otherwise. 
> (What does the architecture say about the contents of the registers 
> when transitioning from a 32-bit mode user program to a 64-bit mode 
> kernel?)
>
As privileged specification says,

"Whenever XLEN in any mode is set to a value less than the widest supported XLEN, all operations
must ignore source operand register bits above the configured XLEN, and must sign-extend results
to fill the entire widest supported XLEN in the destination register. Similarly, pc bits above XLEN
are ignored, and when the pc is written, it is sign-extended to fill the widest supported XLEN."

If we want to strictly obey the spec, we should
1) Ignore MSB 32bits for source register, and sign-extend the 
destination register.
2) Always use 32bit operation(TCG 32bit OP).

I want to still use TCG 64bit OP and just extend the source to 64bit by 
ext32s or ext32u.

Is is OK?

Thanks,
Zhiwei
>
> r~

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

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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
  2021-07-17  3:59       ` LIU Zhiwei
@ 2021-07-17 15:41         ` Richard Henderson
  -1 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-17 15:41 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel; +Cc: qemu-riscv, alistair.francis

On 7/16/21 8:59 PM, LIU Zhiwei wrote:
> If we want to strictly obey the spec, we should
> 1) Ignore MSB 32bits for source register, and sign-extend the destination register.
> 2) Always use 32bit operation(TCG 32bit OP).
> 
> I want to still use TCG 64bit OP and just extend the source to 64bit by ext32s or ext32u.
> 
> Is is OK?

Yes, that sounds right.


r~



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

* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-17 15:41         ` Richard Henderson
  0 siblings, 0 replies; 80+ messages in thread
From: Richard Henderson @ 2021-07-17 15:41 UTC (permalink / raw)
  To: LIU Zhiwei, qemu-devel; +Cc: alistair.francis, qemu-riscv

On 7/16/21 8:59 PM, LIU Zhiwei wrote:
> If we want to strictly obey the spec, we should
> 1) Ignore MSB 32bits for source register, and sign-extend the destination register.
> 2) Always use 32bit operation(TCG 32bit OP).
> 
> I want to still use TCG 64bit OP and just extend the source to 64bit by ext32s or ext32u.
> 
> Is is OK?

Yes, that sounds right.


r~



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

* Re: [PATCH 09/17] target/riscv: Reorg csr instructions
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-23  5:00     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-23  5:00 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:46 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Introduce csrr and csrw helpers, for read-only and write-only insns.
>
> Note that we do not properly implement this in riscv_csrrw, in that
> we cannot distinguish true read-only (rs1 == 0) from any other zero
> write_mask another source register -- this should still raise an
> exception for read-only registers.
>
> Only issue gen_io_start for CF_USE_ICOUNT.
> Use ctx->zero for csrrc.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/helper.h                   |   6 +-
>  target/riscv/op_helper.c                |  18 +--
>  target/riscv/insn_trans/trans_rvi.c.inc | 170 +++++++++++++++++-------
>  3 files changed, 129 insertions(+), 65 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 415e37bc37..460eee9988 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -65,9 +65,9 @@ DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
>  DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
>
>  /* Special functions */
> -DEF_HELPER_3(csrrw, tl, env, tl, tl)
> -DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
> -DEF_HELPER_4(csrrc, tl, env, tl, tl, tl)
> +DEF_HELPER_2(csrr, tl, env, int)
> +DEF_HELPER_3(csrw, void, env, int, tl)
> +DEF_HELPER_4(csrrw, tl, env, int, tl, tl)
>  #ifndef CONFIG_USER_ONLY
>  DEF_HELPER_2(sret, tl, env, tl)
>  DEF_HELPER_2(mret, tl, env, tl)
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 3c48e739ac..ee7c24efe7 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -37,11 +37,10 @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception)
>      riscv_raise_exception(env, exception, 0);
>  }
>
> -target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
> -        target_ulong csr)
> +target_ulong helper_csrr(CPURISCVState *env, int csr)
>  {
>      target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, src, -1);
> +    RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> @@ -49,23 +48,20 @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
>      return val;
>  }
>
> -target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
> -        target_ulong csr, target_ulong rs1_pass)
> +void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
>  {
> -    target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
> +    RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
>      }
> -    return val;
>  }
>
> -target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
> -        target_ulong csr, target_ulong rs1_pass)
> +target_ulong helper_csrrw(CPURISCVState *env, int csr,
> +                          target_ulong src, target_ulong write_mask)
>  {
>      target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
> +    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 840187a4d6..3705aad380 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -452,80 +452,148 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
>      return true;
>  }
>
> -#define RISCV_OP_CSR_PRE do {\
> -    source1 = tcg_temp_new(); \
> -    csr_store = tcg_temp_new(); \
> -    dest = tcg_temp_new(); \
> -    rs1_pass = tcg_temp_new(); \
> -    gen_get_gpr(source1, a->rs1); \
> -    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
> -    tcg_gen_movi_tl(rs1_pass, a->rs1); \
> -    tcg_gen_movi_tl(csr_store, a->csr); \
> -    gen_io_start();\
> -} while (0)
> +static bool do_csr_post(DisasContext *ctx)
> +{
> +    /* We may have changed important cpu state -- exit to main loop. */
> +    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
> +    exit_tb(ctx);
> +    ctx->base.is_jmp = DISAS_NORETURN;
> +    return true;
> +}
>
> -#define RISCV_OP_CSR_POST do {\
> -    gen_set_gpr(a->rd, dest); \
> -    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
> -    exit_tb(ctx); \
> -    ctx->base.is_jmp = DISAS_NORETURN; \
> -    tcg_temp_free(source1); \
> -    tcg_temp_free(csr_store); \
> -    tcg_temp_free(dest); \
> -    tcg_temp_free(rs1_pass); \
> -} while (0)
> +static bool do_csrr(DisasContext *ctx, int rd, int rc)
> +{
> +    TCGv dest = gpr_dst(ctx, rd);
> +    TCGv_i32 csr = tcg_constant_i32(rc);
>
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_helper_csrr(dest, cpu_env, csr);
> +    return do_csr_post(ctx);
> +}
> +
> +static bool do_csrw(DisasContext *ctx, int rc, TCGv src)
> +{
> +    TCGv_i32 csr = tcg_constant_i32(rc);
> +
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_helper_csrw(cpu_env, csr, src);
> +    return do_csr_post(ctx);
> +}
> +
> +static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
> +{
> +    TCGv dest = gpr_dst(ctx, rd);
> +    TCGv_i32 csr = tcg_constant_i32(rc);
> +
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_helper_csrrw(dest, cpu_env, csr, src, mask);
> +    return do_csr_post(ctx);
> +}
>
>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrw(dest, cpu_env, source1, csr_store);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    TCGv src = gpr_src(ctx, a->rs1);
> +
> +    /*
> +     * If rd == 0, the insn shall not read the csr, nor cause any of the
> +     * side effects that might occur on a csr read.
> +     */
> +    if (a->rd == 0) {
> +        return do_csrw(ctx, a->csr, src);
> +    }
> +
> +    TCGv mask = tcg_constant_tl(-1);
> +    return do_csrrw(ctx, a->rd, a->csr, src, mask);
>  }
>
>  static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv ones = tcg_constant_tl(-1);
> +    TCGv mask = gpr_src(ctx, a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
>  }
>
>  static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv mask = gpr_src(ctx, a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
>  }
>
>  static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    TCGv src = tcg_constant_tl(a->rs1);
> +
> +    /*
> +     * If rd == 0, the insn shall not read the csr, nor cause any of the
> +     * side effects that might occur on a csr read.
> +     */
> +    if (a->rd == 0) {
> +        return do_csrw(ctx, a->csr, src);
> +    }
> +
> +    TCGv mask = tcg_constant_tl(-1);
> +    return do_csrrw(ctx, a->rd, a->csr, src, mask);
>  }
>
>  static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv ones = tcg_constant_tl(-1);
> +    TCGv mask = tcg_constant_tl(a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
>  }
>
>  static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv mask = tcg_constant_tl(a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 09/17] target/riscv: Reorg csr instructions
@ 2021-07-23  5:00     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-23  5:00 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:46 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Introduce csrr and csrw helpers, for read-only and write-only insns.
>
> Note that we do not properly implement this in riscv_csrrw, in that
> we cannot distinguish true read-only (rs1 == 0) from any other zero
> write_mask another source register -- this should still raise an
> exception for read-only registers.
>
> Only issue gen_io_start for CF_USE_ICOUNT.
> Use ctx->zero for csrrc.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/helper.h                   |   6 +-
>  target/riscv/op_helper.c                |  18 +--
>  target/riscv/insn_trans/trans_rvi.c.inc | 170 +++++++++++++++++-------
>  3 files changed, 129 insertions(+), 65 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 415e37bc37..460eee9988 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -65,9 +65,9 @@ DEF_HELPER_FLAGS_2(gorc, TCG_CALL_NO_RWG_SE, tl, tl, tl)
>  DEF_HELPER_FLAGS_2(gorcw, TCG_CALL_NO_RWG_SE, tl, tl, tl)
>
>  /* Special functions */
> -DEF_HELPER_3(csrrw, tl, env, tl, tl)
> -DEF_HELPER_4(csrrs, tl, env, tl, tl, tl)
> -DEF_HELPER_4(csrrc, tl, env, tl, tl, tl)
> +DEF_HELPER_2(csrr, tl, env, int)
> +DEF_HELPER_3(csrw, void, env, int, tl)
> +DEF_HELPER_4(csrrw, tl, env, int, tl, tl)
>  #ifndef CONFIG_USER_ONLY
>  DEF_HELPER_2(sret, tl, env, tl)
>  DEF_HELPER_2(mret, tl, env, tl)
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 3c48e739ac..ee7c24efe7 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -37,11 +37,10 @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception)
>      riscv_raise_exception(env, exception, 0);
>  }
>
> -target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
> -        target_ulong csr)
> +target_ulong helper_csrr(CPURISCVState *env, int csr)
>  {
>      target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, src, -1);
> +    RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> @@ -49,23 +48,20 @@ target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
>      return val;
>  }
>
> -target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
> -        target_ulong csr, target_ulong rs1_pass)
> +void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
>  {
> -    target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, -1, rs1_pass ? src : 0);
> +    RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
>      }
> -    return val;
>  }
>
> -target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
> -        target_ulong csr, target_ulong rs1_pass)
> +target_ulong helper_csrrw(CPURISCVState *env, int csr,
> +                          target_ulong src, target_ulong write_mask)
>  {
>      target_ulong val = 0;
> -    RISCVException ret = riscv_csrrw(env, csr, &val, 0, rs1_pass ? src : 0);
> +    RISCVException ret = riscv_csrrw(env, csr, &val, src, write_mask);
>
>      if (ret != RISCV_EXCP_NONE) {
>          riscv_raise_exception(env, ret, GETPC());
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 840187a4d6..3705aad380 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -452,80 +452,148 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
>      return true;
>  }
>
> -#define RISCV_OP_CSR_PRE do {\
> -    source1 = tcg_temp_new(); \
> -    csr_store = tcg_temp_new(); \
> -    dest = tcg_temp_new(); \
> -    rs1_pass = tcg_temp_new(); \
> -    gen_get_gpr(source1, a->rs1); \
> -    tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next); \
> -    tcg_gen_movi_tl(rs1_pass, a->rs1); \
> -    tcg_gen_movi_tl(csr_store, a->csr); \
> -    gen_io_start();\
> -} while (0)
> +static bool do_csr_post(DisasContext *ctx)
> +{
> +    /* We may have changed important cpu state -- exit to main loop. */
> +    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
> +    exit_tb(ctx);
> +    ctx->base.is_jmp = DISAS_NORETURN;
> +    return true;
> +}
>
> -#define RISCV_OP_CSR_POST do {\
> -    gen_set_gpr(a->rd, dest); \
> -    tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn); \
> -    exit_tb(ctx); \
> -    ctx->base.is_jmp = DISAS_NORETURN; \
> -    tcg_temp_free(source1); \
> -    tcg_temp_free(csr_store); \
> -    tcg_temp_free(dest); \
> -    tcg_temp_free(rs1_pass); \
> -} while (0)
> +static bool do_csrr(DisasContext *ctx, int rd, int rc)
> +{
> +    TCGv dest = gpr_dst(ctx, rd);
> +    TCGv_i32 csr = tcg_constant_i32(rc);
>
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_helper_csrr(dest, cpu_env, csr);
> +    return do_csr_post(ctx);
> +}
> +
> +static bool do_csrw(DisasContext *ctx, int rc, TCGv src)
> +{
> +    TCGv_i32 csr = tcg_constant_i32(rc);
> +
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_helper_csrw(cpu_env, csr, src);
> +    return do_csr_post(ctx);
> +}
> +
> +static bool do_csrrw(DisasContext *ctx, int rd, int rc, TCGv src, TCGv mask)
> +{
> +    TCGv dest = gpr_dst(ctx, rd);
> +    TCGv_i32 csr = tcg_constant_i32(rc);
> +
> +    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
> +        gen_io_start();
> +    }
> +    gen_helper_csrrw(dest, cpu_env, csr, src, mask);
> +    return do_csr_post(ctx);
> +}
>
>  static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrw(dest, cpu_env, source1, csr_store);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    TCGv src = gpr_src(ctx, a->rs1);
> +
> +    /*
> +     * If rd == 0, the insn shall not read the csr, nor cause any of the
> +     * side effects that might occur on a csr read.
> +     */
> +    if (a->rd == 0) {
> +        return do_csrw(ctx, a->csr, src);
> +    }
> +
> +    TCGv mask = tcg_constant_tl(-1);
> +    return do_csrrw(ctx, a->rd, a->csr, src, mask);
>  }
>
>  static bool trans_csrrs(DisasContext *ctx, arg_csrrs *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrs(dest, cpu_env, source1, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv ones = tcg_constant_tl(-1);
> +    TCGv mask = gpr_src(ctx, a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
>  }
>
>  static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrc(dest, cpu_env, source1, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv mask = gpr_src(ctx, a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
>  }
>
>  static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrw(dest, cpu_env, rs1_pass, csr_store);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    TCGv src = tcg_constant_tl(a->rs1);
> +
> +    /*
> +     * If rd == 0, the insn shall not read the csr, nor cause any of the
> +     * side effects that might occur on a csr read.
> +     */
> +    if (a->rd == 0) {
> +        return do_csrw(ctx, a->csr, src);
> +    }
> +
> +    TCGv mask = tcg_constant_tl(-1);
> +    return do_csrrw(ctx, a->rd, a->csr, src, mask);
>  }
>
>  static bool trans_csrrsi(DisasContext *ctx, arg_csrrsi *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrs(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv ones = tcg_constant_tl(-1);
> +    TCGv mask = tcg_constant_tl(a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ones, mask);
>  }
>
>  static bool trans_csrrci(DisasContext *ctx, arg_csrrci *a)
>  {
> -    TCGv source1, csr_store, dest, rs1_pass;
> -    RISCV_OP_CSR_PRE;
> -    gen_helper_csrrc(dest, cpu_env, rs1_pass, csr_store, rs1_pass);
> -    RISCV_OP_CSR_POST;
> -    return true;
> +    /*
> +     * If rs1 == 0, the insn shall not write to the csr at all, nor
> +     * cause any of the side effects that might occur on a csr write.
> +     * Note that if rs1 specifies a register other than x0, holding
> +     * a zero value, the instruction will still attempt to write the
> +     * unmodified value back to the csr and will cause side effects.
> +     */
> +    if (a->rs1 == 0) {
> +        return do_csrr(ctx, a->rd, a->csr);
> +    }
> +
> +    TCGv mask = tcg_constant_tl(a->rs1);
> +    return do_csrrw(ctx, a->rd, a->csr, ctx->zero, mask);
>  }
> --
> 2.25.1
>
>


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

* Re: [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc
  2021-07-09  4:26   ` Richard Henderson
@ 2021-07-23  5:02     ` Alistair Francis
  -1 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-23  5:02 UTC (permalink / raw)
  To: Richard Henderson
  Cc: open list:RISC-V, Alistair Francis, qemu-devel@nongnu.org Developers

On Fri, Jul 9, 2021 at 2:52 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Exit early if check_access fails.
> Split out do_hlv, do_hsv, do_hlvx subroutines.
> Use gpr_src, gpr_dst in the new subroutines.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn32.decode              |   1 +
>  target/riscv/insn_trans/trans_rvh.c.inc | 264 +++++-------------------
>  2 files changed, 55 insertions(+), 210 deletions(-)
>
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index f09f8d5faf..2cd921d51c 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -42,6 +42,7 @@
>  &j    imm rd
>  &r    rd rs1 rs2
>  &r2   rd rs1
> +&r2_s rs1 rs2
>  &s    imm rs1 rs2
>  &u    imm rd
>  &shift     shamt rs1 rd
> diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
> index 6b5edf82b7..dac732024b 100644
> --- a/target/riscv/insn_trans/trans_rvh.c.inc
> +++ b/target/riscv/insn_trans/trans_rvh.c.inc
> @@ -17,281 +17,137 @@
>   */
>
>  #ifndef CONFIG_USER_ONLY
> -static void check_access(DisasContext *ctx) {
> +static bool check_access(DisasContext *ctx)
> +{
>      if (!ctx->hlsx) {
>          if (ctx->virt_enabled) {
>              generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
>          } else {
>              generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
>          }
> +        return false;
>      }
> +    return true;
>  }
>  #endif
>
> +static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
> +{
> +#ifdef CONFIG_USER_ONLY
> +    return false;
> +#else
> +    if (check_access(ctx)) {
> +        TCGv dest = gpr_dst(ctx, a->rd);
> +        TCGv addr = gpr_src(ctx, a->rs1);
> +        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
> +        tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
> +    }
> +    return true;
> +#endif
> +}
> +
>  static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_SB);
>  }
>
>  static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TESW);
>  }
>
>  static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TESL);
>  }
>
>  static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_UB);
>  }
>
>  static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> +    return do_hlv(ctx, a, MO_TEUW);
> +}
>
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> +static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
> +{
> +#ifdef CONFIG_USER_ONLY
>      return false;
> +#else
> +    if (check_access(ctx)) {
> +        TCGv addr = gpr_src(ctx, a->rs1);
> +        TCGv data = gpr_src(ctx, a->rs2);
> +        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
> +        tcg_gen_qemu_ld_tl(data, addr, mem_idx, mop);
> +    }
> +    return true;
>  #endif
>  }
>
>  static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hsv(ctx, a, MO_SB);
>  }
>
>  static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hsv(ctx, a, MO_TESW);
>  }
>
>  static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hsv(ctx, a, MO_TESL);
>  }
>
>  static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
>  {
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVH);
> -
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TEUL);
>  }
>
>  static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
>  {
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVH);
> -
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TEQ);
>  }
>
>  static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
>  {
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVH);
> +    return do_hsv(ctx, a, MO_TEQ);
> +}
>
>  #ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> +static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
> +                    void (*func)(TCGv, TCGv_env, TCGv))
> +{
> +    if (check_access(ctx)) {
> +        TCGv dest = gpr_dst(ctx, a->rd);
> +        TCGv addr = gpr_src(ctx, a->rs1);
> +        func(dest, cpu_env, addr);
> +    }
>      return true;
> -#else
> -    return false;
> -#endif
>  }
> +#endif
>
>  static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
>  #ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> +    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
>  #else
>      return false;
>  #endif
> @@ -301,19 +157,7 @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
>  #ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> +    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
>  #else
>      return false;
>  #endif
> --
> 2.25.1
>
>


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

* Re: [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc
@ 2021-07-23  5:02     ` Alistair Francis
  0 siblings, 0 replies; 80+ messages in thread
From: Alistair Francis @ 2021-07-23  5:02 UTC (permalink / raw)
  To: Richard Henderson
  Cc: qemu-devel@nongnu.org Developers, Alistair Francis, open list:RISC-V

On Fri, Jul 9, 2021 at 2:52 PM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Exit early if check_access fails.
> Split out do_hlv, do_hsv, do_hlvx subroutines.
> Use gpr_src, gpr_dst in the new subroutines.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

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

Alistair

> ---
>  target/riscv/insn32.decode              |   1 +
>  target/riscv/insn_trans/trans_rvh.c.inc | 264 +++++-------------------
>  2 files changed, 55 insertions(+), 210 deletions(-)
>
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index f09f8d5faf..2cd921d51c 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -42,6 +42,7 @@
>  &j    imm rd
>  &r    rd rs1 rs2
>  &r2   rd rs1
> +&r2_s rs1 rs2
>  &s    imm rs1 rs2
>  &u    imm rd
>  &shift     shamt rs1 rd
> diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
> index 6b5edf82b7..dac732024b 100644
> --- a/target/riscv/insn_trans/trans_rvh.c.inc
> +++ b/target/riscv/insn_trans/trans_rvh.c.inc
> @@ -17,281 +17,137 @@
>   */
>
>  #ifndef CONFIG_USER_ONLY
> -static void check_access(DisasContext *ctx) {
> +static bool check_access(DisasContext *ctx)
> +{
>      if (!ctx->hlsx) {
>          if (ctx->virt_enabled) {
>              generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
>          } else {
>              generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
>          }
> +        return false;
>      }
> +    return true;
>  }
>  #endif
>
> +static bool do_hlv(DisasContext *ctx, arg_r2 *a, MemOp mop)
> +{
> +#ifdef CONFIG_USER_ONLY
> +    return false;
> +#else
> +    if (check_access(ctx)) {
> +        TCGv dest = gpr_dst(ctx, a->rd);
> +        TCGv addr = gpr_src(ctx, a->rs1);
> +        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
> +        tcg_gen_qemu_ld_tl(dest, addr, mem_idx, mop);
> +    }
> +    return true;
> +#endif
> +}
> +
>  static bool trans_hlv_b(DisasContext *ctx, arg_hlv_b *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_SB);
>  }
>
>  static bool trans_hlv_h(DisasContext *ctx, arg_hlv_h *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TESW);
>  }
>
>  static bool trans_hlv_w(DisasContext *ctx, arg_hlv_w *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TESL);
>  }
>
>  static bool trans_hlv_bu(DisasContext *ctx, arg_hlv_bu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_UB);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_UB);
>  }
>
>  static bool trans_hlv_hu(DisasContext *ctx, arg_hlv_hu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> +    return do_hlv(ctx, a, MO_TEUW);
> +}
>
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUW);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> +static bool do_hsv(DisasContext *ctx, arg_r2_s *a, MemOp mop)
> +{
> +#ifdef CONFIG_USER_ONLY
>      return false;
> +#else
> +    if (check_access(ctx)) {
> +        TCGv addr = gpr_src(ctx, a->rs1);
> +        TCGv data = gpr_src(ctx, a->rs2);
> +        int mem_idx = ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK;
> +        tcg_gen_qemu_ld_tl(data, addr, mem_idx, mop);
> +    }
> +    return true;
>  #endif
>  }
>
>  static bool trans_hsv_b(DisasContext *ctx, arg_hsv_b *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_SB);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hsv(ctx, a, MO_SB);
>  }
>
>  static bool trans_hsv_h(DisasContext *ctx, arg_hsv_h *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESW);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hsv(ctx, a, MO_TESW);
>  }
>
>  static bool trans_hsv_w(DisasContext *ctx, arg_hsv_w *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TESL);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hsv(ctx, a, MO_TESL);
>  }
>
>  static bool trans_hlv_wu(DisasContext *ctx, arg_hlv_wu *a)
>  {
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVH);
> -
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEUL);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TEUL);
>  }
>
>  static bool trans_hlv_d(DisasContext *ctx, arg_hlv_d *a)
>  {
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVH);
> -
> -#ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> -#else
> -    return false;
> -#endif
> +    return do_hlv(ctx, a, MO_TEQ);
>  }
>
>  static bool trans_hsv_d(DisasContext *ctx, arg_hsv_d *a)
>  {
>      REQUIRE_64BIT(ctx);
>      REQUIRE_EXT(ctx, RVH);
> +    return do_hsv(ctx, a, MO_TEQ);
> +}
>
>  #ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv dat = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -    gen_get_gpr(dat, a->rs2);
> -
> -    tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx | TB_FLAGS_PRIV_HYP_ACCESS_MASK, MO_TEQ);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(dat);
> +static bool do_hlvx(DisasContext *ctx, arg_r2 *a,
> +                    void (*func)(TCGv, TCGv_env, TCGv))
> +{
> +    if (check_access(ctx)) {
> +        TCGv dest = gpr_dst(ctx, a->rd);
> +        TCGv addr = gpr_src(ctx, a->rs1);
> +        func(dest, cpu_env, addr);
> +    }
>      return true;
> -#else
> -    return false;
> -#endif
>  }
> +#endif
>
>  static bool trans_hlvx_hu(DisasContext *ctx, arg_hlvx_hu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
>  #ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    gen_helper_hyp_hlvx_hu(t1, cpu_env, t0);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> +    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_hu);
>  #else
>      return false;
>  #endif
> @@ -301,19 +157,7 @@ static bool trans_hlvx_wu(DisasContext *ctx, arg_hlvx_wu *a)
>  {
>      REQUIRE_EXT(ctx, RVH);
>  #ifndef CONFIG_USER_ONLY
> -    TCGv t0 = tcg_temp_new();
> -    TCGv t1 = tcg_temp_new();
> -
> -    check_access(ctx);
> -
> -    gen_get_gpr(t0, a->rs1);
> -
> -    gen_helper_hyp_hlvx_wu(t1, cpu_env, t0);
> -    gen_set_gpr(a->rd, t1);
> -
> -    tcg_temp_free(t0);
> -    tcg_temp_free(t1);
> -    return true;
> +    return do_hlvx(ctx, a, gen_helper_hyp_hlvx_wu);
>  #else
>      return false;
>  #endif
> --
> 2.25.1
>
>


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

end of thread, other threads:[~2021-07-23  5:06 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-09  4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
2021-07-09  4:25 ` Richard Henderson
2021-07-09  4:25 ` [PATCH 01/17] " Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-09  5:41   ` Alistair Francis
2021-07-09  5:41     ` Alistair Francis
2021-07-09 16:20   ` Philippe Mathieu-Daudé
2021-07-09 16:20     ` Philippe Mathieu-Daudé
2021-07-09  4:25 ` [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-09  5:45   ` Alistair Francis
2021-07-09  5:45     ` Alistair Francis
2021-07-09  4:25 ` [PATCH 03/17] target/riscv: Use gpr_{src,dst} in shift operations Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-13  4:10   ` [PATCH 03/17] target/riscv: Use gpr_{src, dst} " Alistair Francis
2021-07-13  4:10     ` Alistair Francis
2021-07-09  4:25 ` [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-13  4:11   ` Alistair Francis
2021-07-13  4:11     ` Alistair Francis
2021-07-09  4:25 ` [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-13  4:12   ` Alistair Francis
2021-07-13  4:12     ` Alistair Francis
2021-07-09  4:25 ` [PATCH 06/17] target/riscv: Use gpr_src in branches Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-13  4:14   ` Alistair Francis
2021-07-13  4:14     ` Alistair Francis
2021-07-09  4:25 ` [PATCH 07/17] target/riscv: Use gpr_{src,dst} for integer load/store Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-13  4:18   ` [PATCH 07/17] target/riscv: Use gpr_{src, dst} " Alistair Francis
2021-07-13  4:18     ` Alistair Francis
2021-07-09  4:25 ` [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations Richard Henderson
2021-07-09  4:25   ` Richard Henderson
2021-07-15  4:49   ` Alistair Francis
2021-07-15  4:49     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 09/17] target/riscv: Reorg csr instructions Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-23  5:00   ` Alistair Francis
2021-07-23  5:00     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  4:50   ` Alistair Francis
2021-07-15  4:50     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  4:52   ` Alistair Francis
2021-07-15  4:52     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  4:58   ` Alistair Francis
2021-07-15  4:58     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  5:00   ` Alistair Francis
2021-07-15  5:00     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-23  5:02   ` Alistair Francis
2021-07-23  5:02     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  5:02   ` Alistair Francis
2021-07-15  5:02     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  5:04   ` Alistair Francis
2021-07-15  5:04     ` Alistair Francis
2021-07-09  4:26 ` [PATCH 17/17] target/riscv: Remove gen_get_gpr Richard Henderson
2021-07-09  4:26   ` Richard Henderson
2021-07-15  5:08   ` Alistair Francis
2021-07-15  5:08     ` Alistair Francis
2021-07-15 11:21 ` [PATCH 00/17] target/riscv: Use tcg_constant_* LIU Zhiwei
2021-07-15 11:21   ` LIU Zhiwei
2021-07-15 16:15   ` Richard Henderson
2021-07-15 16:15     ` Richard Henderson
2021-07-17  3:59     ` LIU Zhiwei
2021-07-17  3:59       ` LIU Zhiwei
2021-07-17 15:41       ` Richard Henderson
2021-07-17 15:41         ` Richard Henderson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.