aboutsummaryrefslogtreecommitdiff
path: root/target-m68k/translate.c
diff options
context:
space:
mode:
Diffstat (limited to 'target-m68k/translate.c')
-rw-r--r--target-m68k/translate.c27
1 files changed, 23 insertions, 4 deletions
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 0d603bdf5..9486c31d7 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;
@@ -871,7 +873,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest)
TranslationBlock *tb;
tb = s->tb;
- if (__builtin_expect (s->singlestep_enabled, 0)) {
+ if (unlikely(s->singlestep_enabled)) {
gen_exception(s, dest, EXCP_DEBUG);
} else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
(s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
@@ -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,21 +2970,28 @@ 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
+ /* FIXME: This should be replaced by the deterministic execution
* IRQ raising bits. */
if (dc->is_mem && env->nb_watchpoints)
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 (__builtin_expect(env->singlestep_enabled, 0)) {
+ if (tb->cflags & CF_LAST_IO)
+ gen_io_end();
+ if (unlikely(env->singlestep_enabled)) {
/* Make sure the pc is updated, and raise a debug exception. */
if (!dc->is_jmp) {
gen_flush_cc_op(dc);
@@ -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();