diff options
author | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-29 01:03:05 +0000 |
---|---|---|
committer | pbrook <pbrook@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-06-29 01:03:05 +0000 |
commit | 2e70f6efa8b960d3b5401373ad6fa98747bb9578 (patch) | |
tree | 4864a691a4d52324fe4626261e202525dd3a8659 /target-sparc | |
parent | f6e5889e7f581d286cd2153a71c386795a7070ac (diff) |
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.h | 5 | ||||
-rw-r--r-- | target-sparc/translate.c | 20 |
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) { |