Message ID | 20210517205025.3777947-6-matheus.ferst@eldorado.org.br (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Base for adding PowerPC 64-bit instructions | expand |
On Mon, May 17, 2021 at 05:50:07PM -0300, matheus.ferst@eldorado.org.br wrote: > From: Richard Henderson <richard.henderson@linaro.org> > > When single-stepping, force max_insns to 1 in init_disas > so that we exit the translation loop immediately. > > Combine the single-step checks in tb_stop, and give the > gdb exception priority over the cpu exception, just as > we already do in gen_lookup_and_goto_ptr. > > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br> Applied to ppc-for-6.1, thanks. > --- > target/ppc/translate.c | 33 +++++++++++++++++++-------------- > 1 file changed, 19 insertions(+), 14 deletions(-) > > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index 80cd11b3f8..05e3c0417a 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -8992,7 +8992,6 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) > DisasContext *ctx = container_of(dcbase, DisasContext, base); > CPUPPCState *env = cs->env_ptr; > uint32_t hflags = ctx->base.tb->flags; > - int bound; > > ctx->spr_cb = env->spr_cb; > ctx->pr = (hflags >> HFLAGS_PR) & 1; > @@ -9032,8 +9031,12 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) > ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP; > } > > - bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; > - ctx->base.max_insns = MIN(ctx->base.max_insns, bound); > + if (ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP)) { > + ctx->base.max_insns = 1; > + } else { > + int bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; > + ctx->base.max_insns = MIN(ctx->base.max_insns, bound); > + } > } > > static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs) > @@ -9087,14 +9090,6 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) > handler->count++; > #endif > > - /* Check trace mode exceptions */ > - if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP && > - (ctx->base.pc_next <= 0x100 || ctx->base.pc_next > 0xF00) && > - ctx->base.is_jmp != DISAS_NORETURN)) { > - uint32_t excp = gen_prep_dbgex(ctx); > - gen_exception_nip(ctx, excp, ctx->base.pc_next); > - } > - > if (tcg_check_temp_count()) { > qemu_log("Opcode %02x %02x %02x %02x (%08x) leaked " > "temporaries\n", opc1(ctx->opcode), opc2(ctx->opcode), > @@ -9107,6 +9102,7 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) > DisasContext *ctx = container_of(dcbase, DisasContext, base); > DisasJumpType is_jmp = ctx->base.is_jmp; > target_ulong nip = ctx->base.pc_next; > + int sse; > > if (is_jmp == DISAS_NORETURN) { > /* We have already exited the TB. */ > @@ -9114,7 +9110,8 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) > } > > /* Honor single stepping. */ > - if (unlikely(ctx->base.singlestep_enabled)) { > + sse = ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP); > + if (unlikely(sse)) { > switch (is_jmp) { > case DISAS_TOO_MANY: > case DISAS_EXIT_UPDATE: > @@ -9127,8 +9124,16 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) > default: > g_assert_not_reached(); > } > - gen_debug_exception(ctx); > - return; > + > + if (sse & GDBSTUB_SINGLE_STEP) { > + gen_debug_exception(ctx); > + return; > + } > + /* else CPU_SINGLE_STEP... */ > + if (nip <= 0x100 || nip > 0xf00) { > + gen_exception(ctx, gen_prep_dbgex(ctx)); > + return; > + } > } > > switch (is_jmp) {
diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 80cd11b3f8..05e3c0417a 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -8992,7 +8992,6 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) DisasContext *ctx = container_of(dcbase, DisasContext, base); CPUPPCState *env = cs->env_ptr; uint32_t hflags = ctx->base.tb->flags; - int bound; ctx->spr_cb = env->spr_cb; ctx->pr = (hflags >> HFLAGS_PR) & 1; @@ -9032,8 +9031,12 @@ static void ppc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->singlestep_enabled |= GDBSTUB_SINGLE_STEP; } - bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; - ctx->base.max_insns = MIN(ctx->base.max_insns, bound); + if (ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP)) { + ctx->base.max_insns = 1; + } else { + int bound = -(ctx->base.pc_first | TARGET_PAGE_MASK) / 4; + ctx->base.max_insns = MIN(ctx->base.max_insns, bound); + } } static void ppc_tr_tb_start(DisasContextBase *db, CPUState *cs) @@ -9087,14 +9090,6 @@ static void ppc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs) handler->count++; #endif - /* Check trace mode exceptions */ - if (unlikely(ctx->singlestep_enabled & CPU_SINGLE_STEP && - (ctx->base.pc_next <= 0x100 || ctx->base.pc_next > 0xF00) && - ctx->base.is_jmp != DISAS_NORETURN)) { - uint32_t excp = gen_prep_dbgex(ctx); - gen_exception_nip(ctx, excp, ctx->base.pc_next); - } - if (tcg_check_temp_count()) { qemu_log("Opcode %02x %02x %02x %02x (%08x) leaked " "temporaries\n", opc1(ctx->opcode), opc2(ctx->opcode), @@ -9107,6 +9102,7 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) DisasContext *ctx = container_of(dcbase, DisasContext, base); DisasJumpType is_jmp = ctx->base.is_jmp; target_ulong nip = ctx->base.pc_next; + int sse; if (is_jmp == DISAS_NORETURN) { /* We have already exited the TB. */ @@ -9114,7 +9110,8 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) } /* Honor single stepping. */ - if (unlikely(ctx->base.singlestep_enabled)) { + sse = ctx->singlestep_enabled & (CPU_SINGLE_STEP | GDBSTUB_SINGLE_STEP); + if (unlikely(sse)) { switch (is_jmp) { case DISAS_TOO_MANY: case DISAS_EXIT_UPDATE: @@ -9127,8 +9124,16 @@ static void ppc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs) default: g_assert_not_reached(); } - gen_debug_exception(ctx); - return; + + if (sse & GDBSTUB_SINGLE_STEP) { + gen_debug_exception(ctx); + return; + } + /* else CPU_SINGLE_STEP... */ + if (nip <= 0x100 || nip > 0xf00) { + gen_exception(ctx, gen_prep_dbgex(ctx)); + return; + } } switch (is_jmp) {