/* cannot fail at this point */
tb = tb_alloc(pc);
/* don't forget to invalidate previous TB info */
- T0 = 0;
+ tb_invalidated_flag = 1;
}
tc_ptr = code_gen_ptr;
tb->tc_ptr = tc_ptr;
tb_link_phys(tb, phys_pc, phys_page2);
found:
- if (tb_invalidated_flag) {
- /* as some TB could have been invalidated because
- of memory exceptions while generating the code, we
- must recompute the hash index here */
- T0 = 0;
- }
/* we add the TB in the virtual pc hash table */
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
spin_unlock(&tb_lock);
| (env->vfp.vec_stride << 4);
if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
flags |= (1 << 6);
+ if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
+ flags |= (1 << 7);
cs_base = 0;
pc = env->regs[15];
#elif defined(TARGET_SPARC)
cs_base = 0;
pc = env->nip;
#elif defined(TARGET_MIPS)
- flags = env->hflags & MIPS_HFLAGS_TMASK;
+ flags = env->hflags & (MIPS_HFLAGS_TMASK | MIPS_HFLAG_BMASK);
cs_base = 0;
pc = env->PC;
#else
if (__builtin_expect(!tb || tb->pc != pc || tb->cs_base != cs_base ||
tb->flags != flags, 0)) {
tb = tb_find_slow(pc, cs_base, flags);
+ /* Note: we do it here to avoid a gcc bug on Mac OS X when
+ doing it in tb_find_slow */
+ if (tb_invalidated_flag) {
+ /* as some TB could have been invalidated because
+ of memory exceptions while generating the code, we
+ must recompute the hash index here */
+ T0 = 0;
+ }
}
return tb;
}
}
}
#elif defined(TARGET_PPC)
- if (env1->msr[MSR_POW]) {
+ if (env1->halted) {
if (env1->msr[MSR_EE] &&
(env1->interrupt_request &
(CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER))) {
- env1->msr[MSR_POW] = 0;
+ env1->halted = 0;
+ } else {
+ return EXCP_HALTED;
+ }
+ }
+#elif defined(TARGET_SPARC)
+ if (env1->halted) {
+ if ((env1->interrupt_request & CPU_INTERRUPT_HARD) &&
+ (env1->psret != 0)) {
+ env1->halted = 0;
} else {
return EXCP_HALTED;
}
return EXCP_HALTED;
}
}
+#elif defined(TARGET_MIPS)
+ if (env1->halted) {
+ if (env1->interrupt_request &
+ (CPU_INTERRUPT_HARD | CPU_INTERRUPT_TIMER)) {
+ env1->halted = 0;
+ } else {
+ return EXCP_HALTED;
+ }
+ }
#endif
cpu_single_env = env1;
} else if (interrupt_request & CPU_INTERRUPT_TIMER) {
//do_interrupt(0, 0, 0, 0, 0);
env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
- }
+ } else if (interrupt_request & CPU_INTERRUPT_HALT) {
+ env1->halted = 1;
+ return EXCP_HALTED;
+ }
#elif defined(TARGET_ARM)
if (interrupt_request & CPU_INTERRUPT_FIQ
&& !(env->uncached_cpsr & CPSR_F)) {
jump. */
{
if (T0 != 0 &&
+#if USE_KQEMU
+ (env->kqemu_enabled != 2) &&
+#endif
tb->page_addr[1] == -1
#if defined(TARGET_I386) && defined(USE_CODE_COPY)
&& (tb->cflags & CF_CODE_COPY) ==
T0 = 0;
}
#endif
+#if defined(USE_KQEMU)
+#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
+ if (kqemu_is_ok(env) &&
+ (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
+ cpu_loop_exit();
+ }
+#endif
}
} else {
env_to_regs();
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
- raise_exception_err(EXCP0E_PAGE, env->error_code);
+ raise_exception_err(env->exception_index, env->error_code);
} else {
/* activate soft MMU for this block */
env->hflags |= HF_SOFTMMU_MASK;