diff --git a/qemu/target/riscv/insn_trans/trans_rvm.inc.c b/qemu/target/riscv/insn_trans/trans_rvm.inc.c index 3d8b06f2..090cd821 100644 --- a/qemu/target/riscv/insn_trans/trans_rvm.inc.c +++ b/qemu/target/riscv/insn_trans/trans_rvm.inc.c @@ -106,7 +106,7 @@ static bool trans_divw(DisasContext *ctx, arg_divw *a) static bool trans_divuw(DisasContext *ctx, arg_divuw *a) { REQUIRE_EXT(ctx, RVM); - return gen_arith_div_w(ctx, a, &gen_divu); + return gen_arith_div_uw(ctx, a, &gen_divu); } static bool trans_remw(DisasContext *ctx, arg_remw *a) @@ -118,6 +118,6 @@ static bool trans_remw(DisasContext *ctx, arg_remw *a) static bool trans_remuw(DisasContext *ctx, arg_remuw *a) { REQUIRE_EXT(ctx, RVM); - return gen_arith_div_w(ctx, a, &gen_remu); + return gen_arith_div_uw(ctx, a, &gen_remu); } #endif diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index 1b78323a..036210a6 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -620,6 +620,29 @@ static bool gen_arith_div_w(DisasContext *ctx, arg_r *a, tcg_temp_free(tcg_ctx, source2); return true; } + +static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a, + void(*func)(TCGContext *, TCGv, TCGv, TCGv)) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + TCGv source1, source2; + source1 = tcg_temp_new(tcg_ctx); + source2 = tcg_temp_new(tcg_ctx); + + gen_get_gpr(ctx, source1, a->rs1); + gen_get_gpr(ctx, source2, a->rs2); + tcg_gen_ext32u_tl(tcg_ctx, source1, source1); + tcg_gen_ext32u_tl(tcg_ctx, source2, source2); + + (*func)(tcg_ctx, source1, source1, source2); + + tcg_gen_ext32s_tl(tcg_ctx, source1, source1); + gen_set_gpr(ctx, a->rd, source1); + tcg_temp_free(tcg_ctx, source1); + tcg_temp_free(tcg_ctx, source2); + return true; +} + #endif static bool gen_arith(DisasContext *ctx, arg_r *a,