diff options
Diffstat (limited to 'target-m68k/translate.c')
-rw-r--r-- | target-m68k/translate.c | 27 |
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(); |