target-alpha: Single-step properly across branches.

We were failing to generate EXC_DEBUG in the EXIT_PC_UPDATED path.
This caused us not to stop at the instruction after a branch, but
on the instruction afterward.

Signed-off-by: Richard Henderson <rth@twiddle.net>
This commit is contained in:
Richard Henderson 2011-04-25 12:52:57 -07:00 committed by Richard Henderson
parent b9bec751c8
commit bf1b03fe18
1 changed files with 20 additions and 15 deletions

View File

@ -147,17 +147,21 @@ static void alpha_translate_init(void)
done_init = 1; done_init = 1;
} }
static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code) static void gen_excp_1(int exception, int error_code)
{ {
TCGv_i32 tmp1, tmp2; TCGv_i32 tmp1, tmp2;
tcg_gen_movi_i64(cpu_pc, ctx->pc);
tmp1 = tcg_const_i32(exception); tmp1 = tcg_const_i32(exception);
tmp2 = tcg_const_i32(error_code); tmp2 = tcg_const_i32(error_code);
gen_helper_excp(tmp1, tmp2); gen_helper_excp(tmp1, tmp2);
tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp2);
tcg_temp_free_i32(tmp1); tcg_temp_free_i32(tmp1);
}
static ExitStatus gen_excp(DisasContext *ctx, int exception, int error_code)
{
tcg_gen_movi_i64(cpu_pc, ctx->pc);
gen_excp_1(exception, error_code);
return EXIT_NORETURN; return EXIT_NORETURN;
} }
@ -3211,18 +3215,15 @@ static inline void gen_intermediate_code_internal(CPUState *env,
ctx.pc += 4; ctx.pc += 4;
ret = translate_one(ctxp, insn); ret = translate_one(ctxp, insn);
if (ret == NO_EXIT) { /* If we reach a page boundary, are single stepping,
/* If we reach a page boundary, are single stepping, or exhaust instruction count, stop generation. */
or exhaust instruction count, stop generation. */ if (ret == NO_EXIT
if (env->singlestep_enabled) { && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0
gen_excp(&ctx, EXCP_DEBUG, 0); || gen_opc_ptr >= gen_opc_end
ret = EXIT_PC_UPDATED; || num_insns >= max_insns
} else if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 || singlestep
|| gen_opc_ptr >= gen_opc_end || env->singlestep_enabled)) {
|| num_insns >= max_insns ret = EXIT_PC_STALE;
|| singlestep) {
ret = EXIT_PC_STALE;
}
} }
} while (ret == NO_EXIT); } while (ret == NO_EXIT);
@ -3238,7 +3239,11 @@ static inline void gen_intermediate_code_internal(CPUState *env,
tcg_gen_movi_i64(cpu_pc, ctx.pc); tcg_gen_movi_i64(cpu_pc, ctx.pc);
/* FALLTHRU */ /* FALLTHRU */
case EXIT_PC_UPDATED: case EXIT_PC_UPDATED:
tcg_gen_exit_tb(0); if (env->singlestep_enabled) {
gen_excp_1(EXCP_DEBUG, 0);
} else {
tcg_gen_exit_tb(0);
}
break; break;
default: default:
abort(); abort();