aboutsummaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorRichard Henderson <rth@twiddle.net>2010-04-26 10:17:24 -0700
committerBlue Swirl <blauwirbel@gmail.com>2010-04-26 17:23:58 +0000
commit060718c19423fd1b24fa3a232bf99c5c97a7d61b (patch)
tree561d95a51db553b13a1e65bd1199347727872368 /target-sparc
parenta303f9e37b87ced34e966dc2c0b7f86bc5e74035 (diff)
downloadqemu-060718c19423fd1b24fa3a232bf99c5c97a7d61b.zip
qemu-060718c19423fd1b24fa3a232bf99c5c97a7d61b.tar.gz
qemu-060718c19423fd1b24fa3a232bf99c5c97a7d61b.tar.bz2
target-sparc: Fix -singlestep.
Single-stepping was not properly updating npc, resulting in some instructions being executed twice. In addition, we were emitting dead code at the end of the TB. Fix both by teaching gen_goto_tb to avoid goto_tb for single-step and removing the special-case code in gen_intermediate_code_internal. Signed-off-by: Richard Henderson <rth@twiddle.net> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/translate.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index b54c520..be2a116 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -79,6 +79,7 @@ typedef struct DisasContext {
int mem_idx;
int fpu_enabled;
int address_mask_32bit;
+ int singlestep;
uint32_t cc_op; /* current CC operation */
struct TranslationBlock *tb;
sparc_def_t *def;
@@ -234,7 +235,8 @@ static inline void gen_goto_tb(DisasContext *s, int tb_num,
tb = s->tb;
if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
- (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK)) {
+ (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
+ !s->singlestep) {
/* jump to same page: we can use a direct jump */
tcg_gen_goto_tb(tb_num);
tcg_gen_movi_tl(cpu_pc, pc);
@@ -4694,6 +4696,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
#ifdef TARGET_SPARC64
dc->address_mask_32bit = env->pstate & PS_AM;
#endif
+ dc->singlestep = (env->singlestep_enabled || singlestep);
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
cpu_tmp0 = tcg_temp_new();
@@ -4754,9 +4757,7 @@ static inline void gen_intermediate_code_internal(TranslationBlock * tb,
break;
/* if single step mode, we generate only one instruction and
generate an exception */
- if (env->singlestep_enabled || singlestep) {
- tcg_gen_movi_tl(cpu_pc, dc->pc);
- tcg_gen_exit_tb(0);
+ if (dc->singlestep) {
break;
}
} while ((gen_opc_ptr < gen_opc_end) &&