diff options
author | Richard Henderson <rth@twiddle.net> | 2011-04-25 12:52:57 -0700 |
---|---|---|
committer | Richard Henderson <rth@anchor.twiddle.net> | 2011-05-31 10:18:04 -0700 |
commit | bf1b03fe182eb5a0df9ec6fc4121d8a36e1fdb97 (patch) | |
tree | 63abb2aaabe344fe367636b6f2ac02fd2d92ab42 /target-alpha | |
parent | b9bec751c8c8b08d8055da32306eb105db03031b (diff) | |
download | qemu-bf1b03fe182eb5a0df9ec6fc4121d8a36e1fdb97.tar.gz qemu-bf1b03fe182eb5a0df9ec6fc4121d8a36e1fdb97.tar.bz2 qemu-bf1b03fe182eb5a0df9ec6fc4121d8a36e1fdb97.zip |
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>
Diffstat (limited to 'target-alpha')
-rw-r--r-- | target-alpha/translate.c | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 456ba51ac6..194a286999 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -147,17 +147,21 @@ static void alpha_translate_init(void) 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; - tcg_gen_movi_i64(cpu_pc, ctx->pc); tmp1 = tcg_const_i32(exception); tmp2 = tcg_const_i32(error_code); gen_helper_excp(tmp1, tmp2); tcg_temp_free_i32(tmp2); 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; } @@ -3211,18 +3215,15 @@ static inline void gen_intermediate_code_internal(CPUState *env, ctx.pc += 4; ret = translate_one(ctxp, insn); - if (ret == NO_EXIT) { - /* If we reach a page boundary, are single stepping, - or exhaust instruction count, stop generation. */ - if (env->singlestep_enabled) { - gen_excp(&ctx, EXCP_DEBUG, 0); - ret = EXIT_PC_UPDATED; - } else if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 - || gen_opc_ptr >= gen_opc_end - || num_insns >= max_insns - || singlestep) { - ret = EXIT_PC_STALE; - } + /* If we reach a page boundary, are single stepping, + or exhaust instruction count, stop generation. */ + if (ret == NO_EXIT + && ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0 + || gen_opc_ptr >= gen_opc_end + || num_insns >= max_insns + || singlestep + || env->singlestep_enabled)) { + ret = EXIT_PC_STALE; } } 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); /* FALLTHRU */ 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; default: abort(); |