summaryrefslogtreecommitdiff
path: root/target-cris
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-cris
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-cris')
-rw-r--r--target-cris/cpu.h2
-rw-r--r--target-cris/translate.c21
2 files changed, 22 insertions, 1 deletions
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 447e780b28..d086221d3f 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -238,5 +238,7 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
#define SFR_RW_MM_TLB_LO env->pregs[PR_SRS]][5
#define SFR_RW_MM_TLB_HI env->pregs[PR_SRS]][6
+#define CPU_PC_FROM_TB(env, tb) env->pc = tb->pc
+
#include "cpu-all.h"
#endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index cd0c2e15fa..c3b8adef87 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -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