aboutsummaryrefslogtreecommitdiff
path: root/target-sh4
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-sh4
parentf6e5889e7f581d286cd2153a71c386795a7070ac (diff)
Add instruction counter.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4799 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-sh4')
-rw-r--r--target-sh4/cpu.h5
-rw-r--r--target-sh4/translate.c31
2 files changed, 36 insertions, 0 deletions
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index c349bc8862..014ecd3422 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -152,6 +152,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->flags = tb->flags; \
+ } while (0)
+
#include "cpu-all.h"
/* Memory access type */
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index 3564a67613..8e3f324f3e 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -56,6 +56,19 @@ enum {
BS_EXCP = 3, /* We reached an exception condition */
};
+static TCGv cpu_env;
+
+#include "gen-icount.h"
+
+void sh4_translate_init()
+{
+ static int done_init = 0;
+ if (done_init)
+ return;
+ cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+ done_init = 1;
+}
+
#ifdef CONFIG_USER_ONLY
#define GEN_OP_LD(width, reg) \
@@ -143,6 +156,7 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model)
if (!env)
return NULL;
cpu_exec_init(env);
+ sh4_translate_init();
cpu_sh4_reset(env);
tlb_flush(env, 1);
return env;
@@ -1189,6 +1203,8 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
target_ulong pc_start;
static uint16_t *gen_opc_end;
int i, ii;
+ int num_insns;
+ int max_insns;
pc_start = tb->pc;
gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
@@ -1213,6 +1229,11 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
#endif
ii = -1;
+ num_insns = 0;
+ max_insns = tb->cflags & CF_COUNT_MASK;
+ if (max_insns == 0)
+ max_insns = CF_COUNT_MASK;
+ gen_icount_start();
while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
if (env->nb_breakpoints > 0) {
for (i = 0; i < env->nb_breakpoints; i++) {
@@ -1235,22 +1256,30 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
gen_opc_pc[ii] = ctx.pc;
gen_opc_hflags[ii] = ctx.flags;
gen_opc_instr_start[ii] = 1;
+ gen_opc_icount[ii] = num_insns;
}
+ if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
+ gen_io_start();
#if 0
fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc);
fflush(stderr);
#endif
ctx.opcode = lduw_code(ctx.pc);
decode_opc(&ctx);
+ num_insns++;
ctx.pc += 2;
if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
break;
if (env->singlestep_enabled)
break;
+ if (num_insns >= max_insns)
+ break;
#ifdef SH4_SINGLE_STEP
break;
#endif
}
+ if (tb->cflags & CF_LAST_IO)
+ gen_io_end();
if (env->singlestep_enabled) {
gen_op_debug();
} else {
@@ -1274,6 +1303,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
}
}
+ gen_icount_end(tb, num_insns);
*gen_opc_ptr = INDEX_op_end;
if (search_pc) {
i = gen_opc_ptr - gen_opc_buf;
@@ -1282,6 +1312,7 @@ gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb,
gen_opc_instr_start[ii++] = 0;
} else {
tb->size = ctx.pc - pc_start;
+ tb->icount = num_insns;
}
#ifdef DEBUG_DISAS