mirror of https://github.com/proxmox/mirror_qemu
target/mips: Fix single stepping
As per an ancient comment in mips_tr_translate_insn about the
expectations of gdb, when restarting the insn in a delay slot
we also re-execute the branch. Which means that we are
expected to execute two insns in this case.
This has been broken since 8b86d6d258
, where we forced max_insns
to 1 while single-stepping. This resulted in an exit from the
translator loop after the branch but before the delay slot is
translated.
Increase the max_insns to 2 for this case. In addition, bypass
the end-of-page check, for when the branch itself ends the page.
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
master
parent
6634558025
commit
ef00cd4a22
|
@ -16016,6 +16016,16 @@ static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
|
|||
ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
|
||||
INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
|
||||
|
||||
/*
|
||||
* Execute a branch and its delay slot as a single instruction.
|
||||
* This is what GDB expects and is consistent with what the
|
||||
* hardware does (e.g. if a delay slot instruction faults, the
|
||||
* reported PC is the PC of the branch).
|
||||
*/
|
||||
if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
|
||||
ctx->base.max_insns = 2;
|
||||
}
|
||||
|
||||
LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
|
||||
ctx->hflags);
|
||||
}
|
||||
|
@ -16085,17 +16095,14 @@ static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
|
|||
if (ctx->base.is_jmp != DISAS_NEXT) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute a branch and its delay slot as a single instruction.
|
||||
* This is what GDB expects and is consistent with what the
|
||||
* hardware does (e.g. if a delay slot instruction faults, the
|
||||
* reported PC is the PC of the branch).
|
||||
* End the TB on (most) page crossings.
|
||||
* See mips_tr_init_disas_context about single-stepping a branch
|
||||
* together with its delay slot.
|
||||
*/
|
||||
if (ctx->base.singlestep_enabled &&
|
||||
(ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
|
||||
ctx->base.is_jmp = DISAS_TOO_MANY;
|
||||
}
|
||||
if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
|
||||
if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
|
||||
&& !ctx->base.singlestep_enabled) {
|
||||
ctx->base.is_jmp = DISAS_TOO_MANY;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue