When UXLEN is 32 on 64-bit CPU, only use the LSB 32 bits of source registers and sign-extend or zero-extend it according to different operations.
Signed-off-by: LIU Zhiwei <zhiwei_...@c-sky.com> --- target/riscv/insn_trans/trans_rvi.c.inc | 38 ++++++++++++++++++++----- target/riscv/translate.c | 22 ++++++++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 3705aad380..ea41d1de2d 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -84,11 +84,11 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) return true; } -static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) +static bool gen_branch_internal(DisasContext *ctx, arg_b *a, + TCGCond cond, + TCGv src1, TCGv src2) { TCGLabel *l = gen_new_label(); - TCGv src1 = gpr_src(ctx, a->rs1); - TCGv src2 = gpr_src(ctx, a->rs2); tcg_gen_brcond_tl(cond, src1, src2, l); gen_goto_tb(ctx, 1, ctx->pc_succ_insn); @@ -106,6 +106,30 @@ static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) return true; } +static bool gen_branch_s(DisasContext *ctx, arg_b *a, TCGCond cond) +{ + TCGv src1 = gpr_src_s(ctx, a->rs1); + TCGv src2 = gpr_src_s(ctx, a->rs2); + + return gen_branch_internal(ctx, a, cond, src1, src2); +} + +static bool gen_branch_u(DisasContext *ctx, arg_b *a, TCGCond cond) +{ + TCGv src1 = gpr_src_u(ctx, a->rs1); + TCGv src2 = gpr_src_u(ctx, a->rs2); + + return gen_branch_internal(ctx, a, cond, src1, src2); +} + +static bool gen_branch(DisasContext *ctx, arg_b *a, TCGCond cond) +{ + TCGv src1 = gpr_src(ctx, a->rs1); + TCGv src2 = gpr_src(ctx, a->rs2); + + return gen_branch_internal(ctx, a, cond, src1, src2); +} + static bool trans_beq(DisasContext *ctx, arg_beq *a) { return gen_branch(ctx, a, TCG_COND_EQ); @@ -118,22 +142,22 @@ static bool trans_bne(DisasContext *ctx, arg_bne *a) static bool trans_blt(DisasContext *ctx, arg_blt *a) { - return gen_branch(ctx, a, TCG_COND_LT); + return gen_branch_s(ctx, a, TCG_COND_LT); } static bool trans_bge(DisasContext *ctx, arg_bge *a) { - return gen_branch(ctx, a, TCG_COND_GE); + return gen_branch_s(ctx, a, TCG_COND_GE); } static bool trans_bltu(DisasContext *ctx, arg_bltu *a) { - return gen_branch(ctx, a, TCG_COND_LTU); + return gen_branch_u(ctx, a, TCG_COND_LTU); } static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a) { - return gen_branch(ctx, a, TCG_COND_GEU); + return gen_branch_u(ctx, a, TCG_COND_GEU); } static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index ac4a545da8..d334a9db86 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -176,6 +176,28 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) } } +static TCGv gpr_src_u(DisasContext *ctx, int reg_num) +{ + if (reg_num == 0) { + return ctx->zero; + } + if (ctx->uxl32) { + tcg_gen_ext32u_tl(cpu_gpr[reg_num], cpu_gpr[reg_num]); + } + return cpu_gpr[reg_num]; +} + +static TCGv gpr_src_s(DisasContext *ctx, int reg_num) +{ + if (reg_num == 0) { + return ctx->zero; + } + if (ctx->uxl32) { + tcg_gen_ext32s_tl(cpu_gpr[reg_num], cpu_gpr[reg_num]); + } + return cpu_gpr[reg_num]; +} + /* Wrapper for getting reg values - need to check of reg is zero since * cpu_gpr[0] is not actually allocated */ -- 2.17.1