#include "disas.h"
#include "tcg.h"
#include "kvm.h"
+#include "qemu-barrier.h"
#if !defined(CONFIG_SOFTMMU)
#undef EAX
tb = tb_gen_code(env, pc, cs_base, flags, 0);
found:
+ /* Move the last found TB to the head of the list */
+ if (likely(*ptb1)) {
+ *ptb1 = tb->phys_hash_next;
+ tb->phys_hash_next = tb_phys_hash[h];
+ tb_phys_hash[h] = tb;
+ }
/* we add the TB in the virtual pc hash table */
env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
return tb;
{
CPUWatchpoint *wp;
- if (!env->watchpoint_hit)
- QTAILQ_FOREACH(wp, &env->watchpoints, entry)
+ if (!env->watchpoint_hit) {
+ QTAILQ_FOREACH(wp, &env->watchpoints, entry) {
wp->flags &= ~BP_WATCHPOINT_HIT;
-
- if (debug_excp_handler)
+ }
+ }
+ if (debug_excp_handler) {
debug_excp_handler(env);
+ }
}
/* main execution loop */
uint8_t *tc_ptr;
unsigned long next_tb;
- if (cpu_halted(env1) == EXCP_HALTED)
- return EXCP_HALTED;
+ if (env1->halted) {
+ if (!cpu_has_work(env1)) {
+ return EXCP_HALTED;
+ }
+
+ env1->halted = 0;
+ }
cpu_single_env = env1;
use it. */
QEMU_BUILD_BUG_ON (sizeof (saved_env_reg) != sizeof (env));
saved_env_reg = (host_reg_t) env;
- asm("");
+ barrier();
env = env1;
- if (exit_request) {
+ if (unlikely(exit_request)) {
env->exit_request = 1;
- exit_request = 0;
}
#if defined(TARGET_I386)
- if (!kvm_enabled()) {
- /* put eflags in CPU temporary format */
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- DF = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- }
+ /* put eflags in CPU temporary format */
+ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ DF = 1 - (2 * ((env->eflags >> 10) & 1));
+ CC_OP = CC_OP_EFLAGS;
+ env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
#elif defined(TARGET_SPARC)
#elif defined(TARGET_M68K)
env->cc_op = CC_OP_FLAGS;
env->cc_x = (env->sr >> 4) & 1;
#elif defined(TARGET_ALPHA)
#elif defined(TARGET_ARM)
+#elif defined(TARGET_UNICORE32)
#elif defined(TARGET_PPC)
+#elif defined(TARGET_LM32)
#elif defined(TARGET_MICROBLAZE)
#elif defined(TARGET_MIPS)
#elif defined(TARGET_SH4)
if (setjmp(env->jmp_env) == 0) {
#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
#undef env
- env = cpu_single_env;
+ env = cpu_single_env;
#define env cpu_single_env
#endif
/* if an exception is pending, we execute it here */
if (env->exception_index >= EXCP_INTERRUPT) {
/* exit request from the cpu execution loop */
ret = env->exception_index;
- if (ret == EXCP_DEBUG)
+ if (ret == EXCP_DEBUG) {
cpu_handle_debug_exception(env);
+ }
break;
} else {
#if defined(CONFIG_USER_ONLY)
env->old_exception = -1;
#elif defined(TARGET_PPC)
do_interrupt(env);
+#elif defined(TARGET_LM32)
+ do_interrupt(env);
#elif defined(TARGET_MICROBLAZE)
do_interrupt(env);
#elif defined(TARGET_MIPS)
do_interrupt(env);
#elif defined(TARGET_ARM)
do_interrupt(env);
+#elif defined(TARGET_UNICORE32)
+ do_interrupt(env);
#elif defined(TARGET_SH4)
do_interrupt(env);
#elif defined(TARGET_ALPHA)
}
}
- if (kvm_enabled()) {
- kvm_cpu_exec(env);
- longjmp(env->jmp_env, 1);
- }
-
next_tb = 0; /* force lookup of first TB */
for(;;) {
interrupt_request = env->interrupt_request;
}
#if defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_MIPS) || \
defined(TARGET_PPC) || defined(TARGET_ALPHA) || defined(TARGET_CRIS) || \
- defined(TARGET_MICROBLAZE)
+ defined(TARGET_MICROBLAZE) || defined(TARGET_LM32) || defined(TARGET_UNICORE32)
if (interrupt_request & CPU_INTERRUPT_HALT) {
env->interrupt_request &= ~CPU_INTERRUPT_HALT;
env->halted = 1;
env->interrupt_request &= ~CPU_INTERRUPT_HARD;
next_tb = 0;
}
+#elif defined(TARGET_LM32)
+ if ((interrupt_request & CPU_INTERRUPT_HARD)
+ && (env->ie & IE_IE)) {
+ env->exception_index = EXCP_IRQ;
+ do_interrupt(env);
+ next_tb = 0;
+ }
#elif defined(TARGET_MICROBLAZE)
if ((interrupt_request & CPU_INTERRUPT_HARD)
&& (env->sregs[SR_MSR] & MSR_IE)
}
#elif defined(TARGET_MIPS)
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
- (env->CP0_Status & env->CP0_Cause & CP0Ca_IP_mask) &&
- (env->CP0_Status & (1 << CP0St_IE)) &&
- !(env->CP0_Status & (1 << CP0St_EXL)) &&
- !(env->CP0_Status & (1 << CP0St_ERL)) &&
- !(env->hflags & MIPS_HFLAG_DM)) {
+ cpu_mips_hw_interrupts_pending(env)) {
/* Raise it */
env->exception_index = EXCP_EXT_INTERRUPT;
env->error_code = 0;
do_interrupt(env);
next_tb = 0;
}
+#elif defined(TARGET_UNICORE32)
+ if (interrupt_request & CPU_INTERRUPT_HARD
+ && !(env->uncached_asr & ASR_I)) {
+ do_interrupt(env);
+ next_tb = 0;
+ }
#elif defined(TARGET_SH4)
if (interrupt_request & CPU_INTERRUPT_HARD) {
do_interrupt(env);
TB, but before it is linked into a potentially
infinite loop and becomes env->current_tb. Avoid
starting execution if there is a pending interrupt. */
- if (!unlikely (env->exit_request)) {
- env->current_tb = tb;
+ env->current_tb = tb;
+ barrier();
+ if (likely(!env->exit_request)) {
tc_ptr = tb->tc_ptr;
/* execute the generated code */
#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
#define env cpu_single_env
#endif
next_tb = tcg_qemu_tb_exec(tc_ptr);
- env->current_tb = NULL;
if ((next_tb & 3) == 2) {
/* Instruction counter expired. */
int insns_left;
}
}
}
+ env->current_tb = NULL;
/* reset soft MMU for next block (it can currently
only be set by a memory fault) */
} /* for(;;) */
env->eflags = env->eflags | helper_cc_compute_all(CC_OP) | (DF & DF_MASK);
#elif defined(TARGET_ARM)
/* XXX: Save/restore host fpu exception state?. */
+#elif defined(TARGET_UNICORE32)
#elif defined(TARGET_SPARC)
#elif defined(TARGET_PPC)
+#elif defined(TARGET_LM32)
#elif defined(TARGET_M68K)
cpu_m68k_flush_flags(env, env->cc_op);
env->cc_op = CC_OP_FLAGS;
#endif
/* restore global registers */
- asm("");
+ barrier();
env = (void *) saved_env_reg;
/* fail safe : never use cpu_single_env outside cpu_exec() */