* [PATCH 00/17] target/riscv: Use tcg_constant_*
@ 2021-07-09 4:25 Richard Henderson
2021-07-09 4:25 ` [PATCH 01/17] " Richard Henderson
` (17 more replies)
0 siblings, 18 replies; 40+ 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] 40+ messages in thread
* [PATCH 01/17] target/riscv: Use tcg_constant_*
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 5:41 ` Alistair Francis
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
` (16 subsequent siblings)
17 siblings, 2 replies; 40+ 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] 40+ messages in thread
* [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
2021-07-09 4:25 ` [PATCH 01/17] " Richard Henderson
@ 2021-07-09 4:25 ` Richard Henderson
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
` (15 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 03/17] target/riscv: Use gpr_{src,dst} in shift operations
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
2021-07-09 4:25 ` [PATCH 01/17] " Richard Henderson
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-13 4:10 ` [PATCH 03/17] target/riscv: Use gpr_{src, dst} " Alistair Francis
2021-07-09 4:25 ` [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations Richard Henderson
` (14 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (2 preceding siblings ...)
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: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
` (13 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (3 preceding siblings ...)
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:12 ` Alistair Francis
2021-07-09 4:25 ` [PATCH 06/17] target/riscv: Use gpr_src in branches Richard Henderson
` (12 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 06/17] target/riscv: Use gpr_src in branches
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (4 preceding siblings ...)
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:14 ` Alistair Francis
2021-07-09 4:25 ` [PATCH 07/17] target/riscv: Use gpr_{src,dst} for integer load/store Richard Henderson
` (11 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 07/17] target/riscv: Use gpr_{src,dst} for integer load/store
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (5 preceding siblings ...)
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:18 ` [PATCH 07/17] target/riscv: Use gpr_{src, dst} " Alistair Francis
2021-07-09 4:25 ` [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations Richard Henderson
` (10 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (6 preceding siblings ...)
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-15 4:49 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 09/17] target/riscv: Reorg csr instructions Richard Henderson
` (9 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 09/17] target/riscv: Reorg csr instructions
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (7 preceding siblings ...)
2021-07-09 4:25 ` [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations Richard Henderson
@ 2021-07-09 4:26 ` Richard Henderson
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
` (8 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (8 preceding siblings ...)
2021-07-09 4:26 ` [PATCH 09/17] target/riscv: Reorg csr instructions Richard Henderson
@ 2021-07-09 4:26 ` Richard Henderson
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
` (7 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (9 preceding siblings ...)
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:52 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF Richard Henderson
` (6 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (10 preceding siblings ...)
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:58 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD Richard Henderson
` (5 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (11 preceding siblings ...)
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 5:00 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc Richard Henderson
` (4 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (12 preceding siblings ...)
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-23 5:02 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu Richard Henderson
` (3 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (13 preceding siblings ...)
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-15 5:02 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV Richard Henderson
` (2 subsequent siblings)
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (14 preceding siblings ...)
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:04 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 17/17] target/riscv: Remove gen_get_gpr Richard Henderson
2021-07-15 11:21 ` [PATCH 00/17] target/riscv: Use tcg_constant_* LIU Zhiwei
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* [PATCH 17/17] target/riscv: Remove gen_get_gpr
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (15 preceding siblings ...)
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:08 ` Alistair Francis
2021-07-15 11:21 ` [PATCH 00/17] target/riscv: Use tcg_constant_* LIU Zhiwei
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* Re: [PATCH 01/17] target/riscv: Use tcg_constant_*
2021-07-09 4:25 ` [PATCH 01/17] " Richard Henderson
@ 2021-07-09 5:41 ` Alistair Francis
2021-07-09 16:20 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst
2021-07-09 4:25 ` [PATCH 02/17] target/riscv: Introduce gpr_src, gpr_dst Richard Henderson
@ 2021-07-09 5:45 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 01/17] target/riscv: Use tcg_constant_*
2021-07-09 4:25 ` [PATCH 01/17] " Richard Henderson
2021-07-09 5:41 ` Alistair Francis
@ 2021-07-09 16:20 ` Philippe Mathieu-Daudé
1 sibling, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 03/17] target/riscv: Use gpr_{src, dst} in shift operations
2021-07-09 4:25 ` [PATCH 03/17] target/riscv: Use gpr_{src,dst} in shift operations Richard Henderson
@ 2021-07-13 4:10 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations
2021-07-09 4:25 ` [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations Richard Henderson
@ 2021-07-13 4:11 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ 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 ` [PATCH 05/17] target/riscv: Use gpr_{src, dst} and tcg_constant_tl in gen_grevi Richard Henderson
@ 2021-07-13 4:12 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 06/17] target/riscv: Use gpr_src in branches
2021-07-09 4:25 ` [PATCH 06/17] target/riscv: Use gpr_src in branches Richard Henderson
@ 2021-07-13 4:14 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 07/17] target/riscv: Use gpr_{src, dst} for integer load/store
2021-07-09 4:25 ` [PATCH 07/17] target/riscv: Use gpr_{src,dst} for integer load/store Richard Henderson
@ 2021-07-13 4:18 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations
2021-07-09 4:25 ` [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations Richard Henderson
@ 2021-07-15 4:49 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA
2021-07-09 4:26 ` [PATCH 10/17] target/riscv: Use gpr_{src,dst} for RVA Richard Henderson
@ 2021-07-15 4:50 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB
2021-07-09 4:26 ` [PATCH 11/17] target/riscv: Use gpr_{src,dst} for RVB Richard Henderson
@ 2021-07-15 4:52 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF
2021-07-09 4:26 ` [PATCH 12/17] target/riscv: Use gpr_{src,dst} for RVF Richard Henderson
@ 2021-07-15 4:58 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD
2021-07-09 4:26 ` [PATCH 13/17] target/riscv: Use gpr_{src,dst} for RVD Richard Henderson
@ 2021-07-15 5:00 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu
2021-07-09 4:26 ` [PATCH 15/17] target/riscv: Use gen_arith for mulh and mulhu Richard Henderson
@ 2021-07-15 5:02 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV
2021-07-09 4:26 ` [PATCH 16/17] target/riscv: Use gpr_{src,dst} for RVV Richard Henderson
@ 2021-07-15 5:04 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 17/17] target/riscv: Remove gen_get_gpr
2021-07-09 4:26 ` [PATCH 17/17] target/riscv: Remove gen_get_gpr Richard Henderson
@ 2021-07-15 5:08 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
2021-07-09 4:25 [PATCH 00/17] target/riscv: Use tcg_constant_* Richard Henderson
` (16 preceding siblings ...)
2021-07-09 4:26 ` [PATCH 17/17] target/riscv: Remove gen_get_gpr Richard Henderson
@ 2021-07-15 11:21 ` LIU Zhiwei
2021-07-15 16:15 ` Richard Henderson
17 siblings, 1 reply; 40+ 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] 40+ messages in thread
* Re: [PATCH 00/17] target/riscv: Use tcg_constant_*
2021-07-15 11:21 ` [PATCH 00/17] target/riscv: Use tcg_constant_* LIU Zhiwei
@ 2021-07-15 16:15 ` Richard Henderson
2021-07-17 3:59 ` LIU Zhiwei
0 siblings, 1 reply; 40+ 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] 40+ 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
2021-07-17 15:41 ` Richard Henderson
0 siblings, 1 reply; 40+ 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] 40+ 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
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 09/17] target/riscv: Reorg csr instructions
2021-07-09 4:26 ` [PATCH 09/17] target/riscv: Reorg csr instructions Richard Henderson
@ 2021-07-23 5:00 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
* Re: [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc
2021-07-09 4:26 ` [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc Richard Henderson
@ 2021-07-23 5:02 ` Alistair Francis
0 siblings, 0 replies; 40+ 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] 40+ messages in thread
end of thread, other threads:[~2021-07-23 5:06 UTC | newest]
Thread overview: 40+ 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 ` [PATCH 01/17] " Richard Henderson
2021-07-09 5:41 ` Alistair Francis
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 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-13 4:10 ` [PATCH 03/17] target/riscv: Use gpr_{src, dst} " Alistair Francis
2021-07-09 4:25 ` [PATCH 04/17] target/riscv: Use gpr_{src, dst} in word division operations Richard Henderson
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-13 4:12 ` Alistair Francis
2021-07-09 4:25 ` [PATCH 06/17] target/riscv: Use gpr_src in branches Richard Henderson
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-13 4:18 ` [PATCH 07/17] target/riscv: Use gpr_{src, dst} " Alistair Francis
2021-07-09 4:25 ` [PATCH 08/17] target/riscv: Use gpr_{src, dst} for word shift operations Richard Henderson
2021-07-15 4:49 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 09/17] target/riscv: Reorg csr instructions Richard Henderson
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-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-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-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-15 5:00 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 14/17] target/riscv: Tidy trans_rvh.c.inc Richard Henderson
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-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-15 5:04 ` Alistair Francis
2021-07-09 4:26 ` [PATCH 17/17] target/riscv: Remove gen_get_gpr Richard Henderson
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 16:15 ` Richard Henderson
2021-07-17 3:59 ` LIU Zhiwei
2021-07-17 15:41 ` Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).