For slitu, the imm is sign-extend before unsigned compare. Thus we should only use the LSB 32 bits of the imm for UXL32.
Signed-off-by: LIU Zhiwei <zhiwei_...@c-sky.com> --- target/riscv/insn_trans/trans_rvi.c.inc | 8 ++--- target/riscv/translate.c | 44 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc index 6823a6b3e0..6201c07795 100644 --- a/target/riscv/insn_trans/trans_rvi.c.inc +++ b/target/riscv/insn_trans/trans_rvi.c.inc @@ -276,12 +276,12 @@ static void gen_sltu(TCGv ret, TCGv s1, TCGv s2) static bool trans_slti(DisasContext *ctx, arg_slti *a) { - return gen_arith_imm_tl(ctx, a, &gen_slt); + return gen_arith_simm_tl(ctx, a, &gen_slt); } static bool trans_sltiu(DisasContext *ctx, arg_sltiu *a) { - return gen_arith_imm_tl(ctx, a, &gen_sltu); + return gen_arith_uimm_tl(ctx, a, &gen_sltu); } static bool trans_xori(DisasContext *ctx, arg_xori *a) @@ -328,12 +328,12 @@ static bool trans_sll(DisasContext *ctx, arg_sll *a) static bool trans_slt(DisasContext *ctx, arg_slt *a) { - return gen_arith(ctx, a, &gen_slt); + return gen_arith_s(ctx, a, &gen_slt); } static bool trans_sltu(DisasContext *ctx, arg_sltu *a) { - return gen_arith(ctx, a, &gen_sltu); + return gen_arith_u(ctx, a, &gen_sltu); } static bool trans_xor(DisasContext *ctx, arg_xor *a) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index d334a9db86..912e5f1061 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -494,6 +494,28 @@ static bool gen_arith_imm_tl(DisasContext *ctx, arg_i *a, return true; } +static bool gen_arith_simm_tl(DisasContext *ctx, arg_i *a, + void (*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd); + TCGv src1 = gpr_src_s(ctx, a->rs1); + TCGv src2 = tcg_constant_tl(a->imm); + + (*func)(dest, src1, src2); + return true; +} + +static bool gen_arith_uimm_tl(DisasContext *ctx, arg_i *a, + void (*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd); + TCGv src1 = gpr_src_u(ctx, a->rs1); + TCGv src2 = tcg_constant_tl(ctx->uxl32 ? a->imm & UINT32_MAX : a->imm); + + (*func)(dest, src1, src2); + return true; +} + static void gen_addw(TCGv ret, TCGv arg1, TCGv arg2) { tcg_gen_add_tl(ret, arg1, arg2); @@ -779,6 +801,28 @@ static bool gen_arith(DisasContext *ctx, arg_r *a, return true; } +static bool gen_arith_u(DisasContext *ctx, arg_r *a, + void(*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd); + TCGv src1 = gpr_src_u(ctx, a->rs1); + TCGv src2 = gpr_src_u(ctx, a->rs2); + + (*func)(dest, src1, src2); + return true; +} + +static bool gen_arith_s(DisasContext *ctx, arg_r *a, + void(*func)(TCGv, TCGv, TCGv)) +{ + TCGv dest = gpr_dst(ctx, a->rd); + TCGv src1 = gpr_src_s(ctx, a->rs1); + TCGv src2 = gpr_src_s(ctx, a->rs2); + + (*func)(dest, src1, src2); + return true; +} + static bool gen_shift(DisasContext *ctx, arg_r *a, void(*func)(TCGv, TCGv, TCGv)) { -- 2.17.1