diff --git a/qemu/target/riscv/insn_trans/trans_privileged.inc.c b/qemu/target/riscv/insn_trans/trans_privileged.inc.c index e5c00cec..4c7a9600 100644 --- a/qemu/target/riscv/insn_trans/trans_privileged.inc.c +++ b/qemu/target/riscv/insn_trans/trans_privileged.inc.c @@ -20,20 +20,17 @@ static bool trans_ecall(DisasContext *ctx, arg_ecall *a) { - TCGContext *tcg_ctx = ctx->uc->tcg_ctx; - /* always generates U-level ECALL, fixed in do_interrupt handler */ generate_exception(ctx, RISCV_EXCP_U_ECALL); - tcg_gen_exit_tb(tcg_ctx, NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; } static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a) { - TCGContext *tcg_ctx = ctx->uc->tcg_ctx; generate_exception(ctx, RISCV_EXCP_BREAKPOINT); - tcg_gen_exit_tb(tcg_ctx, NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; } @@ -51,7 +48,7 @@ static bool trans_sret(DisasContext *ctx, arg_sret *a) if (has_ext(ctx, RVS)) { gen_helper_sret(tcg_ctx, tcg_ctx->cpu_pc_risc, tcg_ctx->cpu_env, tcg_ctx->cpu_pc_risc); - tcg_gen_exit_tb(tcg_ctx, NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; } else { return false; @@ -73,7 +70,7 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a) TCGContext *tcg_ctx = ctx->uc->tcg_ctx; tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->base.pc_next); gen_helper_mret(tcg_ctx, tcg_ctx->cpu_pc_risc, tcg_ctx->cpu_env, tcg_ctx->cpu_pc_risc); - tcg_gen_exit_tb(tcg_ctx, NULL, 0); /* no chaining */ + exit_tb(ctx); /* no chaining */ ctx->base.is_jmp = DISAS_NORETURN; return true; #else diff --git a/qemu/target/riscv/insn_trans/trans_rvi.inc.c b/qemu/target/riscv/insn_trans/trans_rvi.inc.c index 4cb798dc..7762fc12 100644 --- a/qemu/target/riscv/insn_trans/trans_rvi.inc.c +++ b/qemu/target/riscv/insn_trans/trans_rvi.inc.c @@ -63,7 +63,7 @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a) if (a->rd != 0) { tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_gpr_risc[a->rd], ctx->pc_succ_insn); } - tcg_gen_lookup_and_goto_ptr(tcg_ctx); + lookup_and_goto_ptr(ctx); if (misaligned) { gen_set_label(tcg_ctx, misaligned); @@ -503,7 +503,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a) * however we need to end the translation block */ tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->pc_succ_insn); - tcg_gen_exit_tb(tcg_ctx, NULL, 0); + exit_tb(ctx); ctx->base.is_jmp = DISAS_NORETURN; return true; } @@ -522,7 +522,7 @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a) #define RISCV_OP_CSR_POST do {\ gen_set_gpr(ctx, a->rd, dest); \ tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, ctx->pc_succ_insn); \ - tcg_gen_exit_tb(tcg_ctx, NULL, 0); \ + exit_tb(ctx); \ ctx->base.is_jmp = DISAS_NORETURN; \ tcg_temp_free(tcg_ctx, source1); \ tcg_temp_free(tcg_ctx, csr_store); \ diff --git a/qemu/target/riscv/translate.c b/qemu/target/riscv/translate.c index c34a0c00..c1c8891b 100644 --- a/qemu/target/riscv/translate.c +++ b/qemu/target/riscv/translate.c @@ -116,6 +116,30 @@ static void gen_exception_debug(const DisasContext *ctx) tcg_temp_free_i32(tcg_ctx, helper_tmp); } +/* Wrapper around tcg_gen_exit_tb that handles single stepping */ +static void exit_tb(DisasContext *ctx) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + if (ctx->base.singlestep_enabled) { + gen_exception_debug(ctx); + } else { + tcg_gen_exit_tb(tcg_ctx, NULL, 0); + } +} + +/* Wrapper around tcg_gen_lookup_and_goto_ptr that handles single stepping */ +static void lookup_and_goto_ptr(DisasContext *ctx) +{ + TCGContext *tcg_ctx = ctx->uc->tcg_ctx; + + if (ctx->base.singlestep_enabled) { + gen_exception_debug(ctx); + } else { + tcg_gen_lookup_and_goto_ptr(tcg_ctx); + } +} + static void gen_exception_illegal(DisasContext *ctx) { generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST); @@ -147,14 +171,14 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest) /* chaining is only allowed when the jump is to the same page */ tcg_gen_goto_tb(tcg_ctx, n); tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, dest); + + /* No need to check for single stepping here as use_goto_tb() will + * return false in case of single stepping. + */ tcg_gen_exit_tb(tcg_ctx, ctx->base.tb, n); } else { tcg_gen_movi_tl(tcg_ctx, tcg_ctx->cpu_pc_risc, dest); - if (ctx->base.singlestep_enabled) { - gen_exception_debug(ctx); - } else { - tcg_gen_lookup_and_goto_ptr(tcg_ctx); - } + lookup_and_goto_ptr(ctx); } }