Message ID | 20211007174722.929993-13-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/riscv: Rationalize XLEN and operand length | expand |
On 2021/10/8 上午1:47, Richard Henderson wrote: > The count zeros instructions require a separate implementation > for RV32 when TARGET_LONG_BITS == 64. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > target/riscv/translate.c | 16 ++++++++++++ > target/riscv/insn_trans/trans_rvb.c.inc | 33 ++++++++++++------------- > 2 files changed, 32 insertions(+), 17 deletions(-) > > diff --git a/target/riscv/translate.c b/target/riscv/translate.c > index f960929c16..be458ae0c2 100644 > --- a/target/riscv/translate.c > +++ b/target/riscv/translate.c > @@ -510,6 +510,22 @@ static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext, > return true; > } > > +static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext, > + void (*f_tl)(TCGv, TCGv), > + void (*f_32)(TCGv, TCGv)) > +{ > + int olen = get_olen(ctx); > + > + if (olen != TARGET_LONG_BITS) { > + if (olen == 32) { > + f_tl = f_32; > + } else { > + g_assert_not_reached(); > + } > + } > + return gen_unary(ctx, a, ext, f_tl); > +} > + > static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) > { > DisasContext *ctx = container_of(dcbase, DisasContext, base); > diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc > index c62eea433a..adc35b6491 100644 > --- a/target/riscv/insn_trans/trans_rvb.c.inc > +++ b/target/riscv/insn_trans/trans_rvb.c.inc > @@ -47,10 +47,18 @@ static void gen_clz(TCGv ret, TCGv arg1) > tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS); > } > > +static void gen_clzw(TCGv ret, TCGv arg1) > +{ > + TCGv t = tcg_temp_new(); > + tcg_gen_shli_tl(t, arg1, 32); > + tcg_gen_clzi_tl(ret, t, 32); > + tcg_temp_free(t); > +} > + > static bool trans_clz(DisasContext *ctx, arg_clz *a) > { > REQUIRE_ZBB(ctx); > - return gen_unary(ctx, a, EXT_ZERO, gen_clz); > + return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw); > } > > static void gen_ctz(TCGv ret, TCGv arg1) > @@ -58,10 +66,15 @@ static void gen_ctz(TCGv ret, TCGv arg1) > tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS); > } > > +static void gen_ctzw(TCGv ret, TCGv arg1) > +{ > + tcg_gen_ctzi_tl(ret, ret, 32); Typo: tcg_gen_ctzi_tl(ret, arg1, 32); Otherwise, Reviewed-by: LIU Zhiwei<zhiwei_liu@c-sky.com> Thanks, Zhiwei > +} > + > static bool trans_ctz(DisasContext *ctx, arg_ctz *a) > { > REQUIRE_ZBB(ctx); > - return gen_unary(ctx, a, EXT_ZERO, gen_ctz); > + return gen_unary_per_ol(ctx, a, EXT_ZERO, gen_ctz, gen_ctzw); > } > > static bool trans_cpop(DisasContext *ctx, arg_cpop *a) > @@ -314,14 +327,6 @@ static bool trans_zext_h_64(DisasContext *ctx, arg_zext_h_64 *a) > return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl); > } > > -static void gen_clzw(TCGv ret, TCGv arg1) > -{ > - TCGv t = tcg_temp_new(); > - tcg_gen_shli_tl(t, arg1, 32); > - tcg_gen_clzi_tl(ret, t, 32); > - tcg_temp_free(t); > -} > - > static bool trans_clzw(DisasContext *ctx, arg_clzw *a) > { > REQUIRE_64BIT(ctx); > @@ -329,17 +334,11 @@ static bool trans_clzw(DisasContext *ctx, arg_clzw *a) > return gen_unary(ctx, a, EXT_NONE, gen_clzw); > } > > -static void gen_ctzw(TCGv ret, TCGv arg1) > -{ > - tcg_gen_ori_tl(ret, arg1, (target_ulong)MAKE_64BIT_MASK(32, 32)); > - tcg_gen_ctzi_tl(ret, ret, 64); > -} > - > static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a) > { > REQUIRE_64BIT(ctx); > REQUIRE_ZBB(ctx); > - return gen_unary(ctx, a, EXT_NONE, gen_ctzw); > + return gen_unary(ctx, a, EXT_ZERO, gen_ctzw); > } > > static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
diff --git a/target/riscv/translate.c b/target/riscv/translate.c index f960929c16..be458ae0c2 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -510,6 +510,22 @@ static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext, return true; } +static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext, + void (*f_tl)(TCGv, TCGv), + void (*f_32)(TCGv, TCGv)) +{ + int olen = get_olen(ctx); + + if (olen != TARGET_LONG_BITS) { + if (olen == 32) { + f_tl = f_32; + } else { + g_assert_not_reached(); + } + } + return gen_unary(ctx, a, ext, f_tl); +} + static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) { DisasContext *ctx = container_of(dcbase, DisasContext, base); diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc index c62eea433a..adc35b6491 100644 --- a/target/riscv/insn_trans/trans_rvb.c.inc +++ b/target/riscv/insn_trans/trans_rvb.c.inc @@ -47,10 +47,18 @@ static void gen_clz(TCGv ret, TCGv arg1) tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS); } +static void gen_clzw(TCGv ret, TCGv arg1) +{ + TCGv t = tcg_temp_new(); + tcg_gen_shli_tl(t, arg1, 32); + tcg_gen_clzi_tl(ret, t, 32); + tcg_temp_free(t); +} + static bool trans_clz(DisasContext *ctx, arg_clz *a) { REQUIRE_ZBB(ctx); - return gen_unary(ctx, a, EXT_ZERO, gen_clz); + return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw); } static void gen_ctz(TCGv ret, TCGv arg1) @@ -58,10 +66,15 @@ static void gen_ctz(TCGv ret, TCGv arg1) tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS); } +static void gen_ctzw(TCGv ret, TCGv arg1) +{ + tcg_gen_ctzi_tl(ret, ret, 32); +} + static bool trans_ctz(DisasContext *ctx, arg_ctz *a) { REQUIRE_ZBB(ctx); - return gen_unary(ctx, a, EXT_ZERO, gen_ctz); + return gen_unary_per_ol(ctx, a, EXT_ZERO, gen_ctz, gen_ctzw); } static bool trans_cpop(DisasContext *ctx, arg_cpop *a) @@ -314,14 +327,6 @@ static bool trans_zext_h_64(DisasContext *ctx, arg_zext_h_64 *a) return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl); } -static void gen_clzw(TCGv ret, TCGv arg1) -{ - TCGv t = tcg_temp_new(); - tcg_gen_shli_tl(t, arg1, 32); - tcg_gen_clzi_tl(ret, t, 32); - tcg_temp_free(t); -} - static bool trans_clzw(DisasContext *ctx, arg_clzw *a) { REQUIRE_64BIT(ctx); @@ -329,17 +334,11 @@ static bool trans_clzw(DisasContext *ctx, arg_clzw *a) return gen_unary(ctx, a, EXT_NONE, gen_clzw); } -static void gen_ctzw(TCGv ret, TCGv arg1) -{ - tcg_gen_ori_tl(ret, arg1, (target_ulong)MAKE_64BIT_MASK(32, 32)); - tcg_gen_ctzi_tl(ret, ret, 64); -} - static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a) { REQUIRE_64BIT(ctx); REQUIRE_ZBB(ctx); - return gen_unary(ctx, a, EXT_NONE, gen_ctzw); + return gen_unary(ctx, a, EXT_ZERO, gen_ctzw); } static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
The count zeros instructions require a separate implementation for RV32 when TARGET_LONG_BITS == 64. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/riscv/translate.c | 16 ++++++++++++ target/riscv/insn_trans/trans_rvb.c.inc | 33 ++++++++++++------------- 2 files changed, 32 insertions(+), 17 deletions(-) -- 2.25.1