On 10/18/21 7:24 PM, LIU Zhiwei wrote:
@@ -223,10 +238,15 @@ static TCGv dest_gpr(DisasContext *ctx, int reg_num)
static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
{
if (reg_num != 0) {
- if (ctx->w) {
+ switch (get_ol(ctx)) {
+ case MXL_RV32:
tcg_gen_ext32s_tl(cpu_gpr[reg_num], t);
- } else {
+ break;
+ case MXL_RV64:
tcg_gen_mov_tl(cpu_gpr[reg_num], t);
+ break;
+ default:
+ g_assert_not_reached();
}
}
}
The dest_gpr currently will force call gen_set_gpr. However, many cases for MXL_RV64,
dest_gpr will return a global TCG variable and don't need to call gen_set_gpr.
In the MXL_RV64 case to which you refer, tcg_gen_mov_tl will be presented with a nop move,
and will emit no code. Similarly for TARGET_RISCV32 and the use of tcg_gen_ext32s_tl,
which will expand to tcg_gen_mov_i32.
And even x0 can avoid to call gen_set_gpr. I don't find a good way to utilize
this point.
You shouldn't special case x0 unless absolutely necessary. We check for it here so that
we do not have to scatter many checks across the code base.
r~