Move tb_jmp_cache from cpu-defs.h to qom/cpu.h

Change-Id: I0e504f1e47d39a36cb8f733d9e48840813d3dd5c
diff --git a/cpu-exec.c b/cpu-exec.c
index e0bd8d1..7984748 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -40,8 +40,6 @@
 #endif
 #endif
 
-int tb_invalidated_flag;
-
 //#define CONFIG_DEBUG_EXEC
 //#define DEBUG_SIGNAL
 
@@ -52,47 +50,27 @@
 
 void cpu_loop_exit(CPUArchState* env)
 {
-    env->current_tb = NULL;
+    CPUState *cpu = ENV_GET_CPU(env);
+    cpu->current_tb = NULL;
     longjmp(env->jmp_env, 1);
 }
 
 /* exit the current TB from a signal handler. The host registers are
    restored in a state compatible with the CPU emulator
  */
+#if defined(CONFIG_SOFTMMU)
 void cpu_resume_from_signal(CPUArchState *env, void *puc)
 {
-#if !defined(CONFIG_SOFTMMU)
-#ifdef __linux__
-    struct ucontext *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#endif
-#endif
-
-    /* XXX: restore cpu registers saved in host registers */
-
-#if !defined(CONFIG_SOFTMMU)
-    if (puc) {
-        /* XXX: use siglongjmp ? */
-#ifdef __linux__
-#ifdef __ia64
-        sigprocmask(SIG_SETMASK, (sigset_t *)&uc->uc_sigmask, NULL);
-#else
-        sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
-#endif
-#elif defined(__OpenBSD__)
-        sigprocmask(SIG_SETMASK, &uc->sc_mask, NULL);
-#endif
-    }
-#endif
     env->exception_index = -1;
     longjmp(env->jmp_env, 1);
 }
+#endif
 
 /* Execute the code without caching the generated code. An interpreter
    could be used if available. */
 static void cpu_exec_nocache(CPUArchState *env, int max_cycles, TranslationBlock *orig_tb)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     tcg_target_ulong next_tb;
     TranslationBlock *tb;
 
@@ -103,10 +81,10 @@
 
     tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
                      max_cycles);
-    env->current_tb = tb;
+    cpu->current_tb = tb;
     /* execute the generated code */
     next_tb = tcg_qemu_tb_exec(env, tb->tc_ptr);
-    env->current_tb = NULL;
+    cpu->current_tb = NULL;
 
     if ((next_tb & 3) == 2) {
         /* Restore PC.  This may happen if async event occurs before
@@ -122,16 +100,17 @@
                                       target_ulong cs_base,
                                       uint64_t flags)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     TranslationBlock *tb, **ptb1;
     unsigned int h;
-    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
+    tb_page_addr_t phys_pc, phys_page1;
+    target_ulong virt_page2;
 
-    tb_invalidated_flag = 0;
+    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
 
     /* find translated block using physical mappings */
     phys_pc = get_page_addr_code(env, pc);
     phys_page1 = phys_pc & TARGET_PAGE_MASK;
-    phys_page2 = -1;
     h = tb_phys_hash_func(phys_pc);
     ptb1 = &tcg_ctx.tb_ctx.tb_phys_hash[h];
     for(;;) {
@@ -144,6 +123,7 @@
             tb->flags == flags) {
             /* check next page if needed */
             if (tb->page_addr[1] != -1) {
+                tb_page_addr_t phys_page2;
                 virt_page2 = (pc & TARGET_PAGE_MASK) +
                     TARGET_PAGE_SIZE;
                 phys_page2 = get_page_addr_code(env, virt_page2);
@@ -167,12 +147,13 @@
         tcg_ctx.tb_ctx.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;
+    cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb;
     return tb;
 }
 
 static inline TranslationBlock *tb_find_fast(CPUArchState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     TranslationBlock *tb;
     target_ulong cs_base, pc;
     int flags;
@@ -181,7 +162,7 @@
        always be the same before a given translated block
        is executed. */
     cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
-    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
+    tb = cpu->tb_jmp_cache[tb_jmp_cache_hash_func(pc)];
     if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base ||
                  tb->flags != flags)) {
         tb = tb_find_slow(env, pc, cs_base, flags);
@@ -232,12 +213,12 @@
 #endif
 }
 
-int cpu_exec(CPUOldState *env)
+int cpu_exec(CPUArchState *env)
 {
     int ret, interrupt_request;
     TranslationBlock *tb;
     uint8_t *tc_ptr;
-    tcg_target_ulong next_tb;
+    uintptr_t next_tb;
     CPUState *cpu = ENV_GET_CPU(env);
 
     if (cpu->halted) {
@@ -272,12 +253,16 @@
 #elif defined(TARGET_ARM)
 #elif defined(TARGET_UNICORE32)
 #elif defined(TARGET_PPC)
+    env->reserve_addr = -1;
 #elif defined(TARGET_LM32)
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_MOXIE)
+#elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
+#elif defined(TARGET_XTENSA)
     /* XXXXX */
 #else
 #error unsupported target CPU
@@ -402,22 +387,21 @@
                         }
                     }
 #elif defined(TARGET_PPC)
-#if 0
                     if ((interrupt_request & CPU_INTERRUPT_RESET)) {
-                        cpu_reset(env);
+                        cpu_reset(cpu);
                     }
-#endif
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
                         ppc_hw_interrupt(env);
-                        if (env->pending_interrupts == 0)
-                            env->interrupt_request &= ~CPU_INTERRUPT_HARD;
+                        if (env->pending_interrupts == 0) {
+                            cpu->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);
+                        cpu->exception_index = EXCP_IRQ;
+                        cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
 #elif defined(TARGET_MICROBLAZE)
@@ -425,8 +409,8 @@
                         && (env->sregs[SR_MSR] & MSR_IE)
                         && !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
                         && !(env->iflags & (D_FLAG | IMM_FLAG))) {
-                        env->exception_index = EXCP_IRQ;
-                        do_interrupt(env);
+                        cpu->exception_index = EXCP_IRQ;
+                        cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
 #elif defined(TARGET_MIPS)
@@ -438,6 +422,23 @@
                         do_interrupt(env);
                         next_tb = 0;
                     }
+#elif defined(TARGET_OPENRISC)
+                    {
+                        int idx = -1;
+                        if ((interrupt_request & CPU_INTERRUPT_HARD)
+                            && (env->sr & SR_IEE)) {
+                            idx = EXCP_INT;
+                        }
+                        if ((interrupt_request & CPU_INTERRUPT_TIMER)
+                            && (env->sr & SR_TEE)) {
+                            idx = EXCP_TICK;
+                        }
+                        if (idx >= 0) {
+                            cpu->exception_index = idx;
+                            cc->do_interrupt(cpu);
+                            next_tb = 0;
+                        }
+                    }
 #elif defined(TARGET_SPARC)
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
                         if (cpu_interrupts_enabled(env) &&
@@ -448,8 +449,8 @@
                             if (((type == TT_EXTINT) &&
                                   cpu_pil_allowed(env, pil)) ||
                                   type != TT_EXTINT) {
-                                env->exception_index = env->interrupt_index;
-                                do_interrupt(env);
+                                cpu->exception_index = env->interrupt_index;
+                                cc->do_interrupt(cpu);
                                 next_tb = 0;
                             }
                         }
@@ -480,32 +481,67 @@
 #elif defined(TARGET_UNICORE32)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                         && !(env->uncached_asr & ASR_I)) {
-                        do_interrupt(env);
+                        cpu->exception_index = UC32_EXCP_INTR;
+                        cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
 #elif defined(TARGET_SH4)
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
-                        do_interrupt(env);
+                        cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
 #elif defined(TARGET_ALPHA)
+                    {
+                        int idx = -1;
+                        /* ??? This hard-codes the OSF/1 interrupt levels.  */
+                        switch (env->pal_mode ? 7 : env->ps & PS_INT_MASK) {
+                        case 0 ... 3:
                     if (interrupt_request & CPU_INTERRUPT_HARD) {
-                        do_interrupt(env);
+                                idx = EXCP_DEV_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 4:
+                            if (interrupt_request & CPU_INTERRUPT_TIMER) {
+                                idx = EXCP_CLK_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 5:
+                            if (interrupt_request & CPU_INTERRUPT_SMP) {
+                                idx = EXCP_SMP_INTERRUPT;
+                            }
+                            /* FALLTHRU */
+                        case 6:
+                            if (interrupt_request & CPU_INTERRUPT_MCHK) {
+                                idx = EXCP_MCHK;
+                            }
+                        }
+                        if (idx >= 0) {
+                            cpu->exception_index = idx;
+                            env->error_code = 0;
+                            cc->do_interrupt(cpu);
                         next_tb = 0;
+                        }
                     }
 #elif defined(TARGET_CRIS)
                     if (interrupt_request & CPU_INTERRUPT_HARD
                         && (env->pregs[PR_CCS] & I_FLAG)
                         && !env->locked_irq) {
-                        env->exception_index = EXCP_IRQ;
-                        do_interrupt(env);
+                        cpu->exception_index = EXCP_IRQ;
+                        cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
-                    if (interrupt_request & CPU_INTERRUPT_NMI
-                        && (env->pregs[PR_CCS] & M_FLAG)) {
-                        env->exception_index = EXCP_NMI;
-                        do_interrupt(env);
+                    if (interrupt_request & CPU_INTERRUPT_NMI) {
+                        unsigned int m_flag_archval;
+                        if (env->pregs[PR_VR] < 32) {
+                            m_flag_archval = M_FLAG_V10;
+                        } else {
+                            m_flag_archval = M_FLAG_V32;
+                        }
+                        if ((env->pregs[PR_CCS] & m_flag_archval)) {
+                            cpu->exception_index = EXCP_NMI;
+                            cc->do_interrupt(cpu);
                         next_tb = 0;
+                        }
                     }
 #elif defined(TARGET_M68K)
                     if (interrupt_request & CPU_INTERRUPT_HARD
@@ -516,14 +552,20 @@
                            hardware doesn't rely on this, so we
                            provide/save the vector when the interrupt is
                            first signalled.  */
-                        env->exception_index = env->pending_vector;
-                        do_interrupt_m68k_hardirq(env, 1);
+                        cpu->exception_index = env->pending_vector;
+                        do_interrupt_m68k_hardirq(env);
                         next_tb = 0;
                     }
 #elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
                     if ((interrupt_request & CPU_INTERRUPT_HARD) &&
                         (env->psw.mask & PSW_MASK_EXT)) {
-                        do_interrupt(env);
+                        cc->do_interrupt(cpu);
+                        next_tb = 0;
+                    }
+#elif defined(TARGET_XTENSA)
+                    if (interrupt_request & CPU_INTERRUPT_HARD) {
+                        cpu->exception_index = EXC_IRQ;
+                        cc->do_interrupt(cpu);
                         next_tb = 0;
                     }
 #endif
@@ -564,12 +606,12 @@
                 tb = tb_find_fast(env);
                 /* 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) {
+                if (tcg_ctx.tb_ctx.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 */
                     next_tb = 0;
-                    tb_invalidated_flag = 0;
+                    tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
                 }
 #ifdef CONFIG_DEBUG_EXEC
                 qemu_log_mask(CPU_LOG_EXEC, "Trace 0x%08lx [" TARGET_FMT_lx "] %s\n",
@@ -580,7 +622,8 @@
                    spans two pages, we cannot safely do a direct
                    jump. */
                 if (next_tb != 0 && tb->page_addr[1] == -1) {
-                    tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
+                    tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK),
+                                next_tb & TB_EXIT_MASK, tb);
                 }
                 spin_unlock(&tcg_ctx.tb_ctx.tb_lock);
 
@@ -588,16 +631,16 @@
                    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. */
-                env->current_tb = tb;
+                cpu->current_tb = tb;
                 barrier();
                 if (likely(!cpu->exit_request)) {
                     tc_ptr = tb->tc_ptr;
                 /* execute the generated code */
                     next_tb = tcg_qemu_tb_exec(env, tc_ptr);
-                    if ((next_tb & 3) == 2) {
+                    if ((next_tb & TB_EXIT_MASK) == TB_EXIT_ICOUNT_EXPIRED) {
                         /* Instruction counter expired.  */
                         int insns_left;
-                        tb = (TranslationBlock *)(long)(next_tb & ~3);
+                        tb = (TranslationBlock *)(next_tb & ~TB_EXIT_MASK);
                         /* Restore PC.  */
                         cpu_pc_from_tb(env, tb);
                         insns_left = env->icount_decr.u32;
@@ -622,7 +665,7 @@
                         }
                     }
                 }
-                env->current_tb = NULL;
+                cpu->current_tb = NULL;
 #ifdef CONFIG_HAX
                 if (hax_enabled() && hax_stop_emulation(cpu))
                     cpu_loop_exit(env);
@@ -633,7 +676,8 @@
         } else {
             /* Reload env after longjmp - the compiler may have smashed all
              * local variables as longjmp is marked 'noreturn'. */
-            env = cpu_single_env;
+            cpu = current_cpu;
+            env = cpu->env_ptr;
         }
     } /* for(;;) */
 
@@ -655,593 +699,19 @@
               | env->cc_dest | (env->cc_x << 4);
 #elif defined(TARGET_MICROBLAZE)
 #elif defined(TARGET_MIPS)
+#elif defined(TARGET_MOXIE)
+#elif defined(TARGET_OPENRISC)
 #elif defined(TARGET_SH4)
 #elif defined(TARGET_ALPHA)
 #elif defined(TARGET_CRIS)
 #elif defined(TARGET_S390X)
+#elif defined(TARGET_XTENSA)
     /* XXXXX */
 #else
 #error unsupported target CPU
 #endif
 
-    /* fail safe : never use cpu_single_env outside cpu_exec() */
+    /* fail safe : never use current_cpu outside cpu_exec() */
     current_cpu = NULL;
     return ret;
 }
-
-#if defined(TARGET_I386) && defined(CONFIG_USER_ONLY)
-
-void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector)
-{
-    CPUX86State *saved_env;
-
-    saved_env = env;
-    env = s;
-    if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
-        selector &= 0xffff;
-        cpu_x86_load_seg_cache(env, seg_reg, selector,
-                               (selector << 4), 0xffff, 0);
-    } else {
-        helper_load_seg(seg_reg, selector);
-    }
-    env = saved_env;
-}
-
-void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32)
-{
-    CPUX86State *saved_env;
-
-    saved_env = env;
-    env = s;
-
-    helper_fsave(ptr, data32);
-
-    env = saved_env;
-}
-
-void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32)
-{
-    CPUX86State *saved_env;
-
-    saved_env = env;
-    env = s;
-
-    helper_frstor(ptr, data32);
-
-    env = saved_env;
-}
-
-#endif /* TARGET_I386 */
-
-#if !defined(CONFIG_SOFTMMU)
-
-#if defined(TARGET_I386)
-#define EXCEPTION_ACTION raise_exception_err(env->exception_index, env->error_code)
-#else
-#define EXCEPTION_ACTION cpu_loop_exit(env)
-#endif
-
-/* 'pc' is the host PC at which the exception was raised. 'address' is
-   the effective address of the memory exception. 'is_write' is 1 if a
-   write caused the exception and otherwise 0'. 'old_set' is the
-   signal set which should be restored */
-static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
-                                    int is_write, sigset_t *old_set,
-                                    void *puc)
-{
-    TranslationBlock *tb;
-    int ret;
-
-    if (cpu_single_env)
-        env = cpu_single_env; /* XXX: find a correct solution for multithread */
-#if defined(DEBUG_SIGNAL)
-    qemu_printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
-                pc, address, is_write, *(unsigned long *)old_set);
-#endif
-    /* XXX: locking issue */
-    if (is_write && page_unprotect(h2g(address), pc, puc)) {
-        return 1;
-    }
-
-    /* see if it is an MMU fault */
-    ret = cpu_handle_mmu_fault(env, address, is_write, MMU_USER_IDX, 0);
-    if (ret < 0)
-        return 0; /* not an MMU fault */
-    if (ret == 0)
-        return 1; /* the MMU fault was handled without causing real CPU fault */
-    /* now we have a real cpu fault */
-    tb = tb_find_pc(pc);
-    if (tb) {
-        /* the PC is inside the translated code. It means that we have
-           a virtual CPU fault */
-        cpu_restore_state(env, pc);
-    }
-
-    /* we restore the process signal mask as the sigreturn should
-       do it (XXX: use sigsetjmp) */
-    sigprocmask(SIG_SETMASK, old_set, NULL);
-    EXCEPTION_ACTION;
-
-    /* never comes here */
-    return 1;
-}
-
-#if defined(__i386__)
-
-#if defined(__APPLE__)
-# include <sys/ucontext.h>
-
-# define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext->ss.eip))
-# define TRAP_sig(context)    ((context)->uc_mcontext->es.trapno)
-# define ERROR_sig(context)   ((context)->uc_mcontext->es.err)
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#elif defined (__NetBSD__)
-# include <ucontext.h>
-
-# define EIP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_EIP])
-# define TRAP_sig(context)    ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-# define ERROR_sig(context)   ((context)->uc_mcontext.__gregs[_REG_ERR])
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#elif defined (__FreeBSD__) || defined(__DragonFly__)
-# include <ucontext.h>
-
-# define EIP_sig(context)  (*((unsigned long*)&(context)->uc_mcontext.mc_eip))
-# define TRAP_sig(context)    ((context)->uc_mcontext.mc_trapno)
-# define ERROR_sig(context)   ((context)->uc_mcontext.mc_err)
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#elif defined(__OpenBSD__)
-# define EIP_sig(context)     ((context)->sc_eip)
-# define TRAP_sig(context)    ((context)->sc_trapno)
-# define ERROR_sig(context)   ((context)->sc_err)
-# define MASK_sig(context)    ((context)->sc_mask)
-#else
-# define EIP_sig(context)     ((context)->uc_mcontext.gregs[REG_EIP])
-# define TRAP_sig(context)    ((context)->uc_mcontext.gregs[REG_TRAPNO])
-# define ERROR_sig(context)   ((context)->uc_mcontext.gregs[REG_ERR])
-# define MASK_sig(context)    ((context)->uc_sigmask)
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
-    ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#else
-    struct ucontext *uc = puc;
-#endif
-    unsigned long pc;
-    int trapno;
-
-#ifndef REG_EIP
-/* for glibc 2.1 */
-#define REG_EIP    EIP
-#define REG_ERR    ERR
-#define REG_TRAPNO TRAPNO
-#endif
-    pc = EIP_sig(uc);
-    trapno = TRAP_sig(uc);
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             trapno == 0xe ?
-                             (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc), puc);
-}
-
-#elif defined(__x86_64__)
-
-#ifdef __NetBSD__
-#define PC_sig(context)       _UC_MACHINE_PC(context)
-#define TRAP_sig(context)     ((context)->uc_mcontext.__gregs[_REG_TRAPNO])
-#define ERROR_sig(context)    ((context)->uc_mcontext.__gregs[_REG_ERR])
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#elif defined(__OpenBSD__)
-#define PC_sig(context)       ((context)->sc_rip)
-#define TRAP_sig(context)     ((context)->sc_trapno)
-#define ERROR_sig(context)    ((context)->sc_err)
-#define MASK_sig(context)     ((context)->sc_mask)
-#elif defined (__FreeBSD__) || defined(__DragonFly__)
-#include <ucontext.h>
-
-#define PC_sig(context)  (*((unsigned long*)&(context)->uc_mcontext.mc_rip))
-#define TRAP_sig(context)     ((context)->uc_mcontext.mc_trapno)
-#define ERROR_sig(context)    ((context)->uc_mcontext.mc_err)
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#else
-#define PC_sig(context)       ((context)->uc_mcontext.gregs[REG_RIP])
-#define TRAP_sig(context)     ((context)->uc_mcontext.gregs[REG_TRAPNO])
-#define ERROR_sig(context)    ((context)->uc_mcontext.gregs[REG_ERR])
-#define MASK_sig(context)     ((context)->uc_sigmask)
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    unsigned long pc;
-#if defined(__NetBSD__) || defined (__FreeBSD__) || defined(__DragonFly__)
-    ucontext_t *uc = puc;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-#else
-    struct ucontext *uc = puc;
-#endif
-
-    pc = PC_sig(uc);
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             TRAP_sig(uc) == 0xe ?
-                             (ERROR_sig(uc) >> 1) & 1 : 0,
-                             &MASK_sig(uc), puc);
-}
-
-#elif defined(_ARCH_PPC)
-
-/***********************************************************************
- * signal context platform-specific definitions
- * From Wine
- */
-#ifdef linux
-/* All Registers access - only for local access */
-# define REG_sig(reg_name, context)		((context)->uc_mcontext.regs->reg_name)
-/* Gpr Registers access  */
-# define GPR_sig(reg_num, context)		REG_sig(gpr[reg_num], context)
-# define IAR_sig(context)			REG_sig(nip, context)	/* Program counter */
-# define MSR_sig(context)			REG_sig(msr, context)   /* Machine State Register (Supervisor) */
-# define CTR_sig(context)			REG_sig(ctr, context)   /* Count register */
-# define XER_sig(context)			REG_sig(xer, context) /* User's integer exception register */
-# define LR_sig(context)			REG_sig(link, context) /* Link register */
-# define CR_sig(context)			REG_sig(ccr, context) /* Condition register */
-/* Float Registers access  */
-# define FLOAT_sig(reg_num, context)		(((double*)((char*)((context)->uc_mcontext.regs+48*4)))[reg_num])
-# define FPSCR_sig(context)			(*(int*)((char*)((context)->uc_mcontext.regs+(48+32*2)*4)))
-/* Exception Registers access */
-# define DAR_sig(context)			REG_sig(dar, context)
-# define DSISR_sig(context)			REG_sig(dsisr, context)
-# define TRAP_sig(context)			REG_sig(trap, context)
-#endif /* linux */
-
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-#include <ucontext.h>
-# define IAR_sig(context)		((context)->uc_mcontext.mc_srr0)
-# define MSR_sig(context)		((context)->uc_mcontext.mc_srr1)
-# define CTR_sig(context)		((context)->uc_mcontext.mc_ctr)
-# define XER_sig(context)		((context)->uc_mcontext.mc_xer)
-# define LR_sig(context)		((context)->uc_mcontext.mc_lr)
-# define CR_sig(context)		((context)->uc_mcontext.mc_cr)
-/* Exception Registers access */
-# define DAR_sig(context)		((context)->uc_mcontext.mc_dar)
-# define DSISR_sig(context)		((context)->uc_mcontext.mc_dsisr)
-# define TRAP_sig(context)		((context)->uc_mcontext.mc_exc)
-#endif /* __FreeBSD__|| __FreeBSD_kernel__ */
-
-#ifdef __APPLE__
-# include <sys/ucontext.h>
-typedef struct ucontext SIGCONTEXT;
-/* All Registers access - only for local access */
-# define REG_sig(reg_name, context)		((context)->uc_mcontext->ss.reg_name)
-# define FLOATREG_sig(reg_name, context)	((context)->uc_mcontext->fs.reg_name)
-# define EXCEPREG_sig(reg_name, context)	((context)->uc_mcontext->es.reg_name)
-# define VECREG_sig(reg_name, context)		((context)->uc_mcontext->vs.reg_name)
-/* Gpr Registers access */
-# define GPR_sig(reg_num, context)		REG_sig(r##reg_num, context)
-# define IAR_sig(context)			REG_sig(srr0, context)	/* Program counter */
-# define MSR_sig(context)			REG_sig(srr1, context)  /* Machine State Register (Supervisor) */
-# define CTR_sig(context)			REG_sig(ctr, context)
-# define XER_sig(context)			REG_sig(xer, context) /* Link register */
-# define LR_sig(context)			REG_sig(lr, context)  /* User's integer exception register */
-# define CR_sig(context)			REG_sig(cr, context)  /* Condition register */
-/* Float Registers access */
-# define FLOAT_sig(reg_num, context)		FLOATREG_sig(fpregs[reg_num], context)
-# define FPSCR_sig(context)			((double)FLOATREG_sig(fpscr, context))
-/* Exception Registers access */
-# define DAR_sig(context)			EXCEPREG_sig(dar, context)     /* Fault registers for coredump */
-# define DSISR_sig(context)			EXCEPREG_sig(dsisr, context)
-# define TRAP_sig(context)			EXCEPREG_sig(exception, context) /* number of powerpc exception taken */
-#endif /* __APPLE__ */
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    ucontext_t *uc = puc;
-#else
-    struct ucontext *uc = puc;
-#endif
-    unsigned long pc;
-    int is_write;
-
-    pc = IAR_sig(uc);
-    is_write = 0;
-#if 0
-    /* ppc 4xx case */
-    if (DSISR_sig(uc) & 0x00800000)
-        is_write = 1;
-#else
-    if (TRAP_sig(uc) != 0x400 && (DSISR_sig(uc) & 0x02000000))
-        is_write = 1;
-#endif
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__alpha__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                           void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    uint32_t *pc = uc->uc_mcontext.sc_pc;
-    uint32_t insn = *pc;
-    int is_write = 0;
-
-    /* XXX: need kernel patch to get write flag faster */
-    switch (insn >> 26) {
-    case 0x0d: // stw
-    case 0x0e: // stb
-    case 0x0f: // stq_u
-    case 0x24: // stf
-    case 0x25: // stg
-    case 0x26: // sts
-    case 0x27: // stt
-    case 0x2c: // stl
-    case 0x2d: // stq
-    case 0x2e: // stl_c
-    case 0x2f: // stq_c
-	is_write = 1;
-    }
-
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask, puc);
-}
-#elif defined(__sparc__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    int is_write;
-    uint32_t insn;
-#if !defined(__arch64__) || defined(CONFIG_SOLARIS)
-    uint32_t *regs = (uint32_t *)(info + 1);
-    void *sigmask = (regs + 20);
-    /* XXX: is there a standard glibc define ? */
-    unsigned long pc = regs[1];
-#else
-#ifdef __linux__
-    struct sigcontext *sc = puc;
-    unsigned long pc = sc->sigc_regs.tpc;
-    void *sigmask = (void *)sc->sigc_mask;
-#elif defined(__OpenBSD__)
-    struct sigcontext *uc = puc;
-    unsigned long pc = uc->sc_pc;
-    void *sigmask = (void *)(long)uc->sc_mask;
-#endif
-#endif
-
-    /* XXX: need kernel patch to get write flag faster */
-    is_write = 0;
-    insn = *(uint32_t *)pc;
-    if ((insn >> 30) == 3) {
-      switch((insn >> 19) & 0x3f) {
-      case 0x05: // stb
-      case 0x15: // stba
-      case 0x06: // sth
-      case 0x16: // stha
-      case 0x04: // st
-      case 0x14: // sta
-      case 0x07: // std
-      case 0x17: // stda
-      case 0x0e: // stx
-      case 0x1e: // stxa
-      case 0x24: // stf
-      case 0x34: // stfa
-      case 0x27: // stdf
-      case 0x37: // stdfa
-      case 0x26: // stqf
-      case 0x36: // stqfa
-      case 0x25: // stfsr
-      case 0x3c: // casa
-      case 0x3e: // casxa
-	is_write = 1;
-	break;
-      }
-    }
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, sigmask, NULL);
-}
-
-#elif defined(__arm__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    unsigned long pc;
-    int is_write;
-
-#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
-    pc = uc->uc_mcontext.gregs[R15];
-#else
-    pc = uc->uc_mcontext.arm_pc;
-#endif
-    /* XXX: compute is_write */
-    is_write = 0;
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write,
-                             &uc->uc_sigmask, puc);
-}
-
-#elif defined(__mc68000)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    unsigned long pc;
-    int is_write;
-
-    pc = uc->uc_mcontext.gregs[16];
-    /* XXX: compute is_write */
-    is_write = 0;
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write,
-                             &uc->uc_sigmask, puc);
-}
-
-#elif defined(__ia64)
-
-#ifndef __ISR_VALID
-  /* This ought to be in <bits/siginfo.h>... */
-# define __ISR_VALID	1
-#endif
-
-int cpu_signal_handler(int host_signum, void *pinfo, void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    unsigned long ip;
-    int is_write = 0;
-
-    ip = uc->uc_mcontext.sc_ip;
-    switch (host_signum) {
-      case SIGILL:
-      case SIGFPE:
-      case SIGSEGV:
-      case SIGBUS:
-      case SIGTRAP:
-	  if (info->si_code && (info->si_segvflags & __ISR_VALID))
-	      /* ISR.W (write-access) is bit 33:  */
-	      is_write = (info->si_isr >> 33) & 1;
-	  break;
-
-      default:
-	  break;
-    }
-    return handle_cpu_signal(ip, (unsigned long)info->si_addr,
-                             is_write,
-                             (sigset_t *)&uc->uc_sigmask, puc);
-}
-
-#elif defined(__s390__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    unsigned long pc;
-    uint16_t *pinsn;
-    int is_write = 0;
-
-    pc = uc->uc_mcontext.psw.addr;
-
-    /* ??? On linux, the non-rt signal handler has 4 (!) arguments instead
-       of the normal 2 arguments.  The 3rd argument contains the "int_code"
-       from the hardware which does in fact contain the is_write value.
-       The rt signal handler, as far as I can tell, does not give this value
-       at all.  Not that we could get to it from here even if it were.  */
-    /* ??? This is not even close to complete, since it ignores all
-       of the read-modify-write instructions.  */
-    pinsn = (uint16_t *)pc;
-    switch (pinsn[0] >> 8) {
-    case 0x50: /* ST */
-    case 0x42: /* STC */
-    case 0x40: /* STH */
-        is_write = 1;
-        break;
-    case 0xc4: /* RIL format insns */
-        switch (pinsn[0] & 0xf) {
-        case 0xf: /* STRL */
-        case 0xb: /* STGRL */
-        case 0x7: /* STHRL */
-            is_write = 1;
-        }
-        break;
-    case 0xe3: /* RXY format insns */
-        switch (pinsn[2] & 0xff) {
-        case 0x50: /* STY */
-        case 0x24: /* STG */
-        case 0x72: /* STCY */
-        case 0x70: /* STHY */
-        case 0x8e: /* STPQ */
-        case 0x3f: /* STRVH */
-        case 0x3e: /* STRV */
-        case 0x2f: /* STRVG */
-            is_write = 1;
-        }
-        break;
-    }
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__mips__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    siginfo_t *info = pinfo;
-    struct ucontext *uc = puc;
-    greg_t pc = uc->uc_mcontext.pc;
-    int is_write;
-
-    /* XXX: compute is_write */
-    is_write = 0;
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask, puc);
-}
-
-#elif defined(__hppa__)
-
-int cpu_signal_handler(int host_signum, void *pinfo,
-                       void *puc)
-{
-    struct siginfo *info = pinfo;
-    struct ucontext *uc = puc;
-    unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
-    uint32_t insn = *(uint32_t *)pc;
-    int is_write = 0;
-
-    /* XXX: need kernel patch to get write flag faster.  */
-    switch (insn >> 26) {
-    case 0x1a: /* STW */
-    case 0x19: /* STH */
-    case 0x18: /* STB */
-    case 0x1b: /* STWM */
-        is_write = 1;
-        break;
-
-    case 0x09: /* CSTWX, FSTWX, FSTWS */
-    case 0x0b: /* CSTDX, FSTDX, FSTDS */
-        /* Distinguish from coprocessor load ... */
-        is_write = (insn >> 9) & 1;
-        break;
-
-    case 0x03:
-        switch ((insn >> 6) & 15) {
-        case 0xa: /* STWS */
-        case 0x9: /* STHS */
-        case 0x8: /* STBS */
-        case 0xe: /* STWAS */
-        case 0xc: /* STBYS */
-            is_write = 1;
-        }
-        break;
-    }
-
-    return handle_cpu_signal(pc, (unsigned long)info->si_addr,
-                             is_write, &uc->uc_sigmask, puc);
-}
-
-#else
-
-#error host CPU specific signal handler needed
-
-#endif
-
-#endif /* !defined(CONFIG_SOFTMMU) */
diff --git a/cpus.c b/cpus.c
index f97720a..8c5d617 100644
--- a/cpus.c
+++ b/cpus.c
@@ -298,11 +298,12 @@
 int64_t cpu_get_icount(void)
 {
     int64_t icount;
-    CPUOldState *env = cpu_single_env;;
+    CPUState *cpu = current_cpu;
+    CPUOldState *env = cpu->env_ptr;
 
     icount = qemu_icount;
     if (env) {
-        if (!can_do_io(env)) {
+        if (!cpu_can_do_io(cpu)) {
             fprintf(stderr, "Bad clock read\n");
         }
         icount -= (env->icount_decr.u16.low + env->icount_extra);
diff --git a/cputlb.c b/cputlb.c
index 220e7f9..d7d5da2 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -26,12 +26,6 @@
 /* statistics */
 int tlb_flush_count;
 
-static const CPUTLBEntry s_cputlb_empty_entry = {
-    .addr_read  = -1,
-    .addr_write = -1,
-    .addr_code  = -1,
-    .addend     = -1,
-};
 
 /* NOTE:
  * If flush_global is true (the usual case), flush all tlb entries.
@@ -47,24 +41,17 @@
  */
 void tlb_flush(CPUArchState *env, int flush_global)
 {
-    int i;
+    CPUState *cpu = ENV_GET_CPU(env);
 
 #if defined(DEBUG_TLB)
     printf("tlb_flush:\n");
 #endif
     /* must reset current TB so that interrupts cannot modify the
        links while we are modifying them */
-    env->current_tb = NULL;
+    cpu->current_tb = NULL;
 
-    for (i = 0; i < CPU_TLB_SIZE; i++) {
-        int mmu_idx;
-
-        for (mmu_idx = 0; mmu_idx < NB_MMU_MODES; mmu_idx++) {
-            env->tlb_table[mmu_idx][i] = s_cputlb_empty_entry;
-        }
-    }
-
-    memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
+    memset(env->tlb_table, -1, sizeof(env->tlb_table));
+    memset(cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
 
     env->tlb_flush_addr = -1;
     env->tlb_flush_mask = 0;
@@ -79,12 +66,13 @@
                  (TARGET_PAGE_MASK | TLB_INVALID_MASK)) ||
         addr == (tlb_entry->addr_code &
                  (TARGET_PAGE_MASK | TLB_INVALID_MASK))) {
-        *tlb_entry = s_cputlb_empty_entry;
+        memset(tlb_entry, -1, sizeof(*tlb_entry));
     }
 }
 
 void tlb_flush_page(CPUArchState *env, target_ulong addr)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     int i;
     int mmu_idx;
 
@@ -103,7 +91,7 @@
     }
     /* must reset current TB so that interrupts cannot modify the
        links while we are modifying them */
-    env->current_tb = NULL;
+    cpu->current_tb = NULL;
 
     addr &= TARGET_PAGE_MASK;
     i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
diff --git a/exec.c b/exec.c
index 83c28d1..6bd2d3c 100644
--- a/exec.c
+++ b/exec.c
@@ -437,8 +437,9 @@
     cpu_set_log(loglevel);
 }
 
-void cpu_unlink_tb(CPUOldState *env)
+void cpu_unlink_tb(CPUArchState *env)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     /* FIXME: TB unchaining isn't SMP safe.  For now just ignore the
        problem and hope the cpu will stop of its own accord.  For userspace
        emulation this often isn't actually as bad as it sounds.  Often
@@ -447,11 +448,11 @@
     static spinlock_t interrupt_lock = SPIN_LOCK_UNLOCKED;
 
     spin_lock(&interrupt_lock);
-    tb = env->current_tb;
+    tb = cpu->current_tb;
     /* if the cpu is currently executing code, we must unlink it and
        all the potentially executing TB */
     if (tb) {
-        env->current_tb = NULL;
+        cpu->current_tb = NULL;
         tb_reset_jump_recursive(tb);
     }
     spin_unlock(&interrupt_lock);
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 4f36369..3273695 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -150,7 +150,6 @@
 
 #define CPU_TEMP_BUF_NLONGS 128
 #define CPU_COMMON                                                      \
-    struct TranslationBlock *current_tb; /* currently executing TB  */  \
     /* soft mmu support */                                              \
     /* in order to avoid passing too many arguments to the MMIO         \
        helpers, we store some rarely used information in the CPU        \
@@ -160,7 +159,6 @@
     target_ulong mem_io_vaddr; /* target virtual addr at which the      \
                                      memory was accessed */             \
     CPU_COMMON_TLB                                                      \
-    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];           \
                                                                         \
     int64_t icount_extra; /* Instructions until next timer event.  */   \
     /* Number of cycles left, with interrupt flag in high bit.          \
@@ -170,7 +168,6 @@
         uint32_t u32;                                                   \
         icount_decr_u16 u16;                                            \
     } icount_decr;                                                      \
-    uint32_t can_do_io; /* nonzero if memory mapped IO is safe.  */     \
                                                                         \
     /* from this point: preserved by CPU reset */                       \
     /* ice debug support */                                             \
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index 6939cb4..4a03c01 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -406,18 +406,25 @@
 /* cpu-exec.c */
 extern volatile sig_atomic_t exit_request;
 
-/* Deterministic execution requires that IO only be performed on the last
-   instruction of a TB so that interrupts take effect immediately.  */
-static inline int can_do_io(CPUArchState *env)
+/**
+ * cpu_can_do_io:
+ * @cpu: The CPU for which to check IO.
+ *
+ * Deterministic execution requires that IO only be performed on the last
+ * instruction of a TB so that interrupts take effect immediately.
+ *
+ * Returns: %true if memory-mapped IO is safe, %false otherwise.
+ */
+static inline bool cpu_can_do_io(CPUState *cpu)
 {
     if (!use_icount) {
-        return 1;
+        return true;
     }
     /* If not executing code then assume we are ok.  */
-    if (env->current_tb == NULL) {
-        return 1;
+    if (cpu->current_tb == NULL) {
+        return true;
     }
-    return env->can_do_io != 0;
+    return cpu->can_do_io != 0;
 }
 
 #endif
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 97f01d1..b231d0f 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -32,21 +32,21 @@
     if (use_icount) {
         *icount_arg = num_insns;
         gen_set_label(icount_label);
-        tcg_gen_exit_tb((uintptr_t)tb + 2);
+        tcg_gen_exit_tb((uintptr_t)tb + TB_EXIT_ICOUNT_EXPIRED);
     }
 }
 
 static inline void gen_io_start(void)
 {
     TCGv_i32 tmp = tcg_const_i32(1);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
+    tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
     tcg_temp_free_i32(tmp);
 }
 
 static inline void gen_io_end(void)
 {
     TCGv_i32 tmp = tcg_const_i32(0);
-    tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUArchState, can_do_io));
+    tcg_gen_st_i32(tmp, cpu_env, -ENV_OFFSET + offsetof(CPUState, can_do_io));
     tcg_temp_free_i32(tmp);
 }
 
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 0b4ea36..1ee6add 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -165,4 +165,4 @@
                                    hwaddr end_addr);
 
 #endif
-#endif
\ No newline at end of file
+#endif
diff --git a/include/exec/softmmu_template.h b/include/exec/softmmu_template.h
index 5ddf5ae..fb0cb4d 100644
--- a/include/exec/softmmu_template.h
+++ b/include/exec/softmmu_template.h
@@ -122,7 +122,7 @@
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
     env->mem_io_pc = retaddr;
     if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT)
-            && !can_do_io(env)) {
+            && !cpu_can_do_io(ENV_GET_CPU(env))) {
         cpu_io_recompile(env, retaddr);
     }
 
@@ -337,7 +337,7 @@
     int index = (physaddr >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
     physaddr = (physaddr & TARGET_PAGE_MASK) + addr;
     if (index > (IO_MEM_NOTDIRTY >> IO_MEM_SHIFT)
-            && !can_do_io(env)) {
+            && !cpu_can_do_io(ENV_GET_CPU(env))) {
         cpu_io_recompile(env, retaddr);
     }
 
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index ea5a370..67cf35b 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -75,16 +75,17 @@
     struct QemuCond *halt_cond;
     struct qemu_work_item *queued_work_first, *queued_work_last;
 
-    uint32_t created;
-    uint32_t stop;   /* Stop request */
-    uint32_t stopped; /* Artificially stopped */
+    bool created;
+    bool stop;
+    bool stopped;
 
     volatile sig_atomic_t exit_request;
     uint32_t interrupt_request;
+    int singlestep_enabled;
 
     void *env_ptr; /* CPUArchState */
-    struct TranslationBlock *current_tb; /* currently executing TB  */
-    int singlestep_enabled;
+    struct TranslationBlock *current_tb;
+    struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE];
     struct GDBRegisterState *gdb_regs;
     QTAILQ_ENTRY(CPUState) node;   /* next CPU sharing TB cache */
 
@@ -100,6 +101,7 @@
     /* TODO Move common fields from CPUArchState here. */
     int cpu_index; /* used by alpha TCG */
     uint32_t halted; /* used by alpha, cris, ppc TCG */
+    uint32_t can_do_io;
 };
 
 QTAILQ_HEAD(CPUTailQ, CPUState);
diff --git a/translate-all.c b/translate-all.c
index d6c5d37..132479e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -198,6 +198,7 @@
 static int cpu_restore_state_from_tb(TranslationBlock *tb, CPUArchState *env,
                                      uintptr_t searched_pc)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     TCGContext *s = &tcg_ctx;
     int j;
     uintptr_t tc_ptr;
@@ -216,7 +217,7 @@
         /* Reset the cycle counter to the start of the block.  */
         env->icount_decr.u16.low += tb->icount;
         /* Clear the IO flag.  */
-        env->can_do_io = 0;
+        cpu->can_do_io = 0;
     }
 
     /* find opc index corresponding to search_pc */
@@ -638,6 +639,7 @@
     cpu_gen_init();
     code_gen_alloc(tb_size);
     tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
+    tcg_register_jit(tcg_ctx.code_gen_buffer, tcg_ctx.code_gen_buffer_size);
     page_init();
 #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
     /* There's no guest base to take into account, so go ahead and
@@ -741,12 +743,10 @@
     tcg_ctx.tb_ctx.nb_tbs = 0;
 
     CPU_FOREACH(cpu) {
-        CPUArchState *env = cpu->env_ptr;
-        memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
+        memset (cpu->tb_jmp_cache, 0, sizeof(cpu->tb_jmp_cache));
     }
 
-    memset(tcg_ctx.tb_ctx.tb_phys_hash, 0,
-            CODE_GEN_PHYS_HASH_SIZE * sizeof(void *));
+    memset(tcg_ctx.tb_ctx.tb_phys_hash, 0, sizeof(tcg_ctx.tb_ctx.tb_phys_hash));
     page_flush_tb();
 
     tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
@@ -894,9 +894,8 @@
     /* remove the TB from the hash list */
     h = tb_jmp_cache_hash_func(tb->pc);
     CPU_FOREACH(cpu) {
-        CPUArchState *env = cpu->env_ptr;
-        if (env->tb_jmp_cache[h] == tb) {
-            env->tb_jmp_cache[h] = NULL;
+        if (cpu->tb_jmp_cache[h] == tb) {
+            cpu->tb_jmp_cache[h] = NULL;
         }
     }
 
@@ -1115,14 +1114,14 @@
             /* we need to do that to handle the case where a signal
                occurs while doing tb_phys_invalidate() */
             saved_tb = NULL;
-            if (env) {
-                saved_tb = env->current_tb;
-                env->current_tb = NULL;
+            if (cpu != NULL) {
+                saved_tb = cpu->current_tb;
+                cpu->current_tb = NULL;
             }
             tb_phys_invalidate(tb, -1);
-            if (env) {
-                env->current_tb = saved_tb;
-                if (cpu->interrupt_request && env->current_tb) {
+            if (cpu != NULL) {
+                cpu->current_tb = saved_tb;
+                if (cpu->interrupt_request && cpu->current_tb) {
                     cpu_interrupt(cpu, cpu->interrupt_request);
                 }
             }
@@ -1143,7 +1142,7 @@
         /* we generate a block containing just the instruction
            modifying the memory. It will ensure that it cannot modify
            itself */
-        env->current_tb = NULL;
+        cpu->current_tb = NULL;
         tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
         cpu_resume_from_signal(env, NULL);
     }
@@ -1195,7 +1194,8 @@
     int n;
 #ifdef TARGET_HAS_PRECISE_SMC
     TranslationBlock *current_tb = NULL;
-    CPUArchState *env = cpu_single_env;
+    CPUState *cpu = current_cpu;
+    CPUArchState *env = NULL;
     int current_tb_modified = 0;
     target_ulong current_pc = 0;
     target_ulong current_cs_base = 0;
@@ -1212,6 +1212,9 @@
     if (tb && pc != 0) {
         current_tb = tb_find_pc(pc);
     }
+    if (cpu != NULL) {
+        env = cpu->env_ptr;
+    }
 #endif
     while (tb != NULL) {
         n = (uintptr_t)tb & 3;
@@ -1240,7 +1243,7 @@
         /* we generate a block containing just the instruction
            modifying the memory. It will ensure that it cannot modify
            itself */
-        env->current_tb = NULL;
+        cpu->current_tb = NULL;
         tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
         if (locked) {
             mmap_unlock();
@@ -1388,13 +1391,13 @@
 
 #ifndef CONFIG_ANDROID
 #if defined(TARGET_HAS_ICE) && !defined(CONFIG_USER_ONLY)
-void tb_invalidate_phys_addr(hwaddr addr)
+void tb_invalidate_phys_addr(AddressSpace *as, hwaddr addr)
 {
     ram_addr_t ram_addr;
     MemoryRegion *mr;
     hwaddr l = 1;
 
-    mr = address_space_translate(&address_space_memory, addr, &addr, &l, false);
+    mr = address_space_translate(as, addr, &addr, &l, false);
     if (!(memory_region_is_ram(mr)
           || memory_region_is_romd(mr))) {
         return;
@@ -1441,7 +1444,7 @@
 
     if (use_icount) {
         env->icount_decr.u16.high = 0xffff;
-        if (!can_do_io(env)
+        if (!cpu_can_do_io(cpu)
             && (mask & ~old_mask) != 0) {
             cpu_abort(cpu, "Raised interrupt while not in I/O function");
         }
@@ -1559,16 +1562,17 @@
 
 void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr)
 {
+    CPUState *cpu = ENV_GET_CPU(env);
     unsigned int i;
 
     /* Discard jump cache entries for any tb which might potentially
        overlap the flushed page.  */
     i = tb_jmp_cache_hash_page(addr - TARGET_PAGE_SIZE);
-    memset(&env->tb_jmp_cache[i], 0,
+    memset(&cpu->tb_jmp_cache[i], 0,
            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
 
     i = tb_jmp_cache_hash_page(addr);
-    memset(&env->tb_jmp_cache[i], 0,
+    memset(&cpu->tb_jmp_cache[i], 0,
            TB_JMP_PAGE_SIZE * sizeof(TranslationBlock *));
 }
 
@@ -1855,7 +1859,6 @@
                     return -1;
                 }
             }
-            return 0;
         }
     }
     return 0;