Add instruction counter.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4799 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2008-06-29 01:03:05 +00:00
parent f6e5889e7f
commit 2e70f6efa8
29 changed files with 830 additions and 117 deletions

View file

@ -77,6 +77,8 @@ TCGv env_btaken;
TCGv env_btarget;
TCGv env_pc;
#include "gen-icount.h"
/* This is the state at translation time. */
typedef struct DisasContext {
CPUState *env;
@ -3032,6 +3034,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
struct DisasContext *dc = &ctx;
uint32_t next_page_start;
target_ulong npc;
int num_insns;
int max_insns;
if (!logfile)
logfile = stderr;
@ -3092,6 +3096,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
lj = -1;
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
gen_icount_start();
do
{
check_breakpoint(env, dc);
@ -3108,6 +3118,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
else
gen_opc_pc[lj] = dc->pc;
gen_opc_instr_start[lj] = 1;
gen_opc_icount[lj] = num_insns;
}
/* Pretty disas. */
@ -3116,6 +3127,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
DIS(fprintf(logfile, "%x ", dc->pc));
}
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
gen_io_start();
dc->clear_x = 1;
if (unlikely(loglevel & CPU_LOG_TB_OP))
tcg_gen_debug_insn_start(dc->pc);
@ -3125,6 +3138,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
if (dc->clear_x)
cris_clear_x_flag(dc);
num_insns++;
/* Check for delayed branches here. If we do it before
actually genereating any host code, the simulator will just
loop doing nothing for on this program location. */
@ -3151,12 +3165,15 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
if (!(tb->pc & 1) && env->singlestep_enabled)
break;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end
&& (dc->pc < next_page_start));
&& (dc->pc < next_page_start)
&& num_insns < max_insns);
npc = dc->pc;
if (dc->jmp == JMP_DIRECT && !dc->delayed_branch)
npc = dc->jmp_pc;
if (tb->cflags & CF_LAST_IO)
gen_io_end();
/* Force an update if the per-tb cpu state has changed. */
if (dc->is_jmp == DISAS_NEXT
&& (dc->cpustate_changed || !dc->flagx_known
@ -3194,6 +3211,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
break;
}
}
gen_icount_end(tb, num_insns);
*gen_opc_ptr = INDEX_op_end;
if (search_pc) {
j = gen_opc_ptr - gen_opc_buf;
@ -3202,6 +3220,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
gen_opc_instr_start[lj++] = 0;
} else {
tb->size = dc->pc - pc_start;
tb->icount = num_insns;
}
#ifdef DEBUG_DISAS