aboutsummaryrefslogtreecommitdiff
path: root/target-m68k
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-m68k
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-m68k')
-rw-r--r--target-m68k/cpu.h2
-rw-r--r--target-m68k/translate.c21
2 files changed, 22 insertions, 1 deletions
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index cfeafc003e..aaf9e42632 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -235,6 +235,8 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
}
#endif
+#define CPU_PC_FROM_TB(env, tb) env->pc = tb->pc
+
#include "cpu-all.h"
#endif
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0d603bdf58..a920d213b0 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -63,6 +63,8 @@ static TCGv NULL_QREG;
/* Used to distinguish stores from bad addressing modes. */
static TCGv store_dummy;
+#include "gen-icount.h"
+
void m68k_tcg_init(void)
{
char *p;
@@ -2919,6 +2921,8 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
target_ulong pc_start;
int pc_offset;
int last_cc_op;
+ int num_insns;
+ int max_insns;
/* generate intermediate code */
pc_start = tb->pc;
@@ -2937,6 +2941,12 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
dc->is_mem = 0;
dc->mactmp = NULL_QREG;
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 {
pc_offset = dc->pc - pc_start;
gen_throws_exception = NULL;
@@ -2960,10 +2970,14 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
}
gen_opc_pc[lj] = dc->pc;
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_cc_op = dc->cc_op;
dc->insn_pc = dc->pc;
disas_m68k_insn(env, dc);
+ num_insns++;
/* Terminate the TB on memory ops if watchpoints are present. */
/* FIXME: This should be replacd by the deterministic execution
@@ -2972,8 +2986,11 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
break;
} while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
!env->singlestep_enabled &&
- (pc_offset) < (TARGET_PAGE_SIZE - 32));
+ (pc_offset) < (TARGET_PAGE_SIZE - 32) &&
+ num_insns < max_insns);
+ if (tb->cflags & CF_LAST_IO)
+ gen_io_end();
if (__builtin_expect(env->singlestep_enabled, 0)) {
/* Make sure the pc is updated, and raise a debug exception. */
if (!dc->is_jmp) {
@@ -2999,6 +3016,7 @@ gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb,
break;
}
}
+ gen_icount_end(tb, num_insns);
*gen_opc_ptr = INDEX_op_end;
#ifdef DEBUG_DISAS
@@ -3016,6 +3034,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;
}
//optimize_flags();