summaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
authorpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-29 01:03:05 +0000
committerpbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162>2008-06-29 01:03:05 +0000
commit2e70f6efa8b960d3b5401373ad6fa98747bb9578 (patch)
tree4864a691a4d52324fe4626261e202525dd3a8659 /target-sparc
parentf6e5889e7f581d286cd2153a71c386795a7070ac (diff)
downloadqemu-2e70f6efa8b960d3b5401373ad6fa98747bb9578.tar.gz
Add instruction counter.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4799 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/cpu.h5
-rw-r--r--target-sparc/translate.c20
2 files changed, 24 insertions, 1 deletions
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index b56dc91ff5..03bc2dfd09 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -437,6 +437,11 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
}
#endif
+#define CPU_PC_FROM_TB(env, tb) do { \
+ env->pc = tb->pc; \
+ env->npc = tb->cs_base; \
+ } while(0)
+
#include "cpu-all.h"
#endif
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 98c6291502..49f998e90b 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -48,6 +48,8 @@ static TCGv cpu_xcc;
/* local register indexes (only used inside old micro ops) */
static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64;
+#include "gen-icount.h"
+
typedef struct DisasContext {
target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */
target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */
@@ -4719,6 +4721,8 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
uint16_t *gen_opc_end;
DisasContext dc1, *dc = &dc1;
int j, lj = -1;
+ int num_insns;
+ int max_insns;
memset(dc, 0, sizeof(DisasContext));
dc->tb = tb;
@@ -4747,6 +4751,11 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
cpu_val = tcg_temp_local_new(TCG_TYPE_TL);
cpu_addr = tcg_temp_local_new(TCG_TYPE_TL);
+ num_insns = 0;
+ max_insns = tb->cflags & CF_COUNT_MASK;
+ if (max_insns == 0)
+ max_insns = CF_COUNT_MASK;
+ gen_icount_start();
do {
if (env->nb_breakpoints > 0) {
for(j = 0; j < env->nb_breakpoints; j++) {
@@ -4771,10 +4780,14 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
gen_opc_pc[lj] = dc->pc;
gen_opc_npc[lj] = dc->npc;
gen_opc_instr_start[lj] = 1;
+ gen_opc_icount[lj] = num_insns;
}
}
+ if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
+ gen_io_start();
last_pc = dc->pc;
disas_sparc_insn(dc);
+ num_insns++;
if (dc->is_br)
break;
@@ -4793,7 +4806,8 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
break;
}
} while ((gen_opc_ptr < gen_opc_end) &&
- (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32));
+ (dc->pc - pc_start) < (TARGET_PAGE_SIZE - 32) &&
+ num_insns < max_insns);
exit_gen_loop:
tcg_temp_free(cpu_addr);
@@ -4802,6 +4816,8 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
tcg_temp_free(cpu_tmp64);
tcg_temp_free(cpu_tmp32);
tcg_temp_free(cpu_tmp0);
+ if (tb->cflags & CF_LAST_IO)
+ gen_io_end();
if (!dc->is_br) {
if (dc->pc != DYNAMIC_PC &&
(dc->npc != DYNAMIC_PC && dc->npc != JUMP_PC)) {
@@ -4814,6 +4830,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
tcg_gen_exit_tb(0);
}
}
+ gen_icount_end(tb, num_insns);
*gen_opc_ptr = INDEX_op_end;
if (spc) {
j = gen_opc_ptr - gen_opc_buf;
@@ -4829,6 +4846,7 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
gen_opc_jump_pc[1] = dc->jump_pc[1];
} else {
tb->size = last_pc + 4 - pc_start;
+ tb->icount = num_insns;
}
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_IN_ASM) {