qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 01/12] Refactor translation block CPU state handling


From: Jan Kiszka
Subject: [Qemu-devel] [PATCH 01/12] Refactor translation block CPU state handling
Date: Mon, 03 Nov 2008 11:35:59 +0100
User-agent: quilt/0.46_cvs20080326-19.1

This patch refactors the way the CPU state is handled that is associated
with a TB. The basic motivation is to move more arch specific code out
of generic files. Specifically the long #ifdef clutter in tb_find_fast()
has to be overcome in order to avoid duplicating it for the gdb
watchpoint fixes (patch "Restore pc on watchpoint hits").

The approach taken here is to encapsulate the relevant CPU state in a
new structure called TBCPUState which is kept inside TranslationBlock
but also passed around when setting up new TBs. To fill a TBCPUState
based on the current CPUState, each arch has to provide
cpu_get_tb_cpu_state(CPUState *, TBCPUState *).

At this chance, the patch also converts the not really beautiful macro
CPU_PC_FROM_TB into a clean static inline function.

Signed-off-by: Jan Kiszka <address@hidden>
---
 cpu-exec.c               |   96 ++++++++---------------------------------------
 exec-all.h               |   11 +++--
 exec.c                   |   89 ++++++++++++++++---------------------------
 target-alpha/cpu.h       |   14 +++++-
 target-alpha/translate.c |    2 
 target-arm/cpu.h         |   19 ++++++++-
 target-arm/translate.c   |    4 -
 target-cris/cpu.h        |   16 ++++++-
 target-cris/translate.c  |   22 +++++-----
 target-i386/cpu.h        |   16 ++++++-
 target-i386/translate.c  |   22 +++++-----
 target-m68k/cpu.h        |   16 ++++++-
 target-m68k/translate.c  |    5 +-
 target-mips/cpu.h        |   18 ++++++--
 target-mips/translate.c  |    6 +-
 target-ppc/cpu.h         |   14 +++++-
 target-ppc/translate.c   |    4 -
 target-sh4/cpu.h         |   21 +++++++---
 target-sh4/translate.c   |    6 +-
 target-sparc/cpu.h       |   26 ++++++++++--
 target-sparc/translate.c |    8 +--
 21 files changed, 232 insertions(+), 203 deletions(-)

Index: b/cpu-exec.c
===================================================================
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -39,6 +39,8 @@
 #endif
 #endif
 
+#include <string.h>
+
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
 // Work around ugly bugs in glibc that mangle global register contents
 #undef env
@@ -100,8 +102,7 @@ static void cpu_exec_nocache(int max_cyc
     if (max_cycles > CF_COUNT_MASK)
         max_cycles = CF_COUNT_MASK;
 
-    tb = tb_gen_code(env, orig_tb->pc, orig_tb->cs_base, orig_tb->flags,
-                     max_cycles);
+    tb = tb_gen_code(env, &orig_tb->cpu_state, max_cycles);
     env->current_tb = tb;
     /* execute the generated code */
     next_tb = tcg_qemu_tb_exec(tb->tc_ptr);
@@ -109,20 +110,19 @@ static void cpu_exec_nocache(int max_cyc
     if ((next_tb & 3) == 2) {
         /* Restore PC.  This may happen if async event occurs before
            the TB starts executing.  */
-        CPU_PC_FROM_TB(env, tb);
+        cpu_pc_from_tb(env, tb);
     }
     tb_phys_invalidate(tb, -1);
     tb_free(tb);
 }
 
-static TranslationBlock *tb_find_slow(target_ulong pc,
-                                      target_ulong cs_base,
-                                      uint64_t flags)
+static TranslationBlock *tb_find_slow(TBCPUState *cpu_state)
 {
     TranslationBlock *tb, **ptb1;
     unsigned int h;
-    target_ulong phys_pc, phys_page1, phys_page2, virt_page2;
+    target_ulong pc, phys_pc, phys_page1, phys_page2, virt_page2;
 
+    pc = cpu_state->pc;
     tb_invalidated_flag = 0;
 
     regs_to_env(); /* XXX: do it just before cpu_gen_code() */
@@ -137,10 +137,10 @@ static TranslationBlock *tb_find_slow(ta
         tb = *ptb1;
         if (!tb)
             goto not_found;
-        if (tb->pc == pc &&
+        if (tb->cpu_state.pc == pc &&
             tb->page_addr[0] == phys_page1 &&
-            tb->cs_base == cs_base &&
-            tb->flags == flags) {
+            tb->cpu_state.cs_base == cpu_state->cs_base &&
+            tb->cpu_state.flags == cpu_state->flags) {
             /* check next page if needed */
             if (tb->page_addr[1] != -1) {
                 virt_page2 = (pc & TARGET_PAGE_MASK) +
@@ -156,7 +156,7 @@ static TranslationBlock *tb_find_slow(ta
     }
  not_found:
    /* if no translated code available, then translate it now */
-    tb = tb_gen_code(env, pc, cs_base, flags, 0);
+    tb = tb_gen_code(env, cpu_state, 0);
 
  found:
     /* we add the TB in the virtual pc hash table */
@@ -167,76 +167,16 @@ static TranslationBlock *tb_find_slow(ta
 static inline TranslationBlock *tb_find_fast(void)
 {
     TranslationBlock *tb;
-    target_ulong cs_base, pc;
-    uint64_t flags;
+    TBCPUState cpu_state;
 
     /* we record a subset of the CPU state. It will
        always be the same before a given translated block
        is executed. */
-#if defined(TARGET_I386)
-    flags = env->hflags;
-    flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
-    cs_base = env->segs[R_CS].base;
-    pc = cs_base + env->eip;
-#elif defined(TARGET_ARM)
-    flags = env->thumb | (env->vfp.vec_len << 1)
-            | (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);
-    flags |= (env->condexec_bits << 8);
-    cs_base = 0;
-    pc = env->regs[15];
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
-    // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
-    flags = ((env->pstate & PS_AM) << 2)
-        | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
-        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
-#else
-    // FPU enable . Supervisor
-    flags = (env->psref << 4) | env->psrs;
-#endif
-    cs_base = env->npc;
-    pc = env->pc;
-#elif defined(TARGET_PPC)
-    flags = env->hflags;
-    cs_base = 0;
-    pc = env->nip;
-#elif defined(TARGET_MIPS)
-    flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
-    cs_base = 0;
-    pc = env->active_tc.PC;
-#elif defined(TARGET_M68K)
-    flags = (env->fpcr & M68K_FPCR_PREC)  /* Bit  6 */
-            | (env->sr & SR_S)            /* Bit  13 */
-            | ((env->macsr >> 4) & 0xf);  /* Bits 0-3 */
-    cs_base = 0;
-    pc = env->pc;
-#elif defined(TARGET_SH4)
-    flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
-                    | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME))   /* Bits  0- 3 */
-            | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR))  /* Bits 19-21 */
-            | (env->sr & (SR_MD | SR_RB));                     /* Bits 29-30 */
-    cs_base = 0;
-    pc = env->pc;
-#elif defined(TARGET_ALPHA)
-    flags = env->ps;
-    cs_base = 0;
-    pc = env->pc;
-#elif defined(TARGET_CRIS)
-    flags = env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
-    flags |= env->dslot;
-    cs_base = 0;
-    pc = env->pc;
-#else
-#error unsupported CPU
-#endif
-    tb = env->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(pc, cs_base, flags);
+    cpu_get_tb_cpu_state(env, &cpu_state);
+    tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(cpu_state.pc)];
+    if (unlikely(!tb ||
+                 memcmp(&tb->cpu_state, &cpu_state, sizeof(cpu_state)))) {
+        tb = tb_find_slow(&cpu_state);
     }
     return tb;
 }
@@ -634,7 +574,7 @@ int cpu_exec(CPUState *env1)
                         int insns_left;
                         tb = (TranslationBlock *)(long)(next_tb & ~3);
                         /* Restore PC.  */
-                        CPU_PC_FROM_TB(env, tb);
+                        cpu_pc_from_tb(env, tb);
                         insns_left = env->icount_decr.u32;
                         if (env->icount_extra && insns_left >= 0) {
                             /* Refill decrementer and continue execution.  */
Index: b/exec-all.h
===================================================================
--- a/exec-all.h
+++ b/exec-all.h
@@ -29,6 +29,7 @@
 #define DISAS_UPDATE  2 /* cpu state was modified dynamically */
 #define DISAS_TB_JUMP 3 /* only pc was modified statically */
 
+typedef struct TBCPUState TBCPUState;
 typedef struct TranslationBlock TranslationBlock;
 
 /* XXX: make safe guess about sizes */
@@ -78,9 +79,7 @@ int cpu_restore_state_copy(struct Transl
                            void *puc);
 void cpu_resume_from_signal(CPUState *env1, void *puc);
 void cpu_io_recompile(CPUState *env, void *retaddr);
-TranslationBlock *tb_gen_code(CPUState *env, 
-                              target_ulong pc, target_ulong cs_base, int flags,
-                              int cflags);
+TranslationBlock *tb_gen_code(CPUState *env, TBCPUState *cpu_state, int 
cflags);
 void cpu_exec_init(CPUState *env);
 int page_unprotect(target_ulong address, unsigned long pc, void *puc);
 void tb_invalidate_phys_page_range(target_phys_addr_t start, 
target_phys_addr_t end,
@@ -123,10 +122,14 @@ static inline int tlb_set_page(CPUState
 #define USE_DIRECT_JUMP
 #endif
 
-struct TranslationBlock {
+struct TBCPUState {
     target_ulong pc;   /* simulated PC corresponding to this block (EIP + CS 
base) */
     target_ulong cs_base; /* CS base for this block */
     uint64_t flags; /* flags defining in which context the code was generated 
*/
+};
+
+struct TranslationBlock {
+    TBCPUState cpu_state;
     uint16_t size;      /* size of target code for this block (1 <=
                            size <= TARGET_PAGE_SIZE) */
     uint16_t cflags;    /* compile flags */
Index: b/exec.c
===================================================================
--- a/exec.c
+++ b/exec.c
@@ -737,7 +737,7 @@ void tb_phys_invalidate(TranslationBlock
     TranslationBlock *tb1, *tb2;
 
     /* remove the TB from the hash list */
-    phys_pc = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
+    phys_pc = tb->page_addr[0] + (tb->cpu_state.pc & ~TARGET_PAGE_MASK);
     h = tb_phys_hash_func(phys_pc);
     tb_remove(&tb_phys_hash[h], tb,
               offsetof(TranslationBlock, phys_hash_next));
@@ -757,7 +757,7 @@ void tb_phys_invalidate(TranslationBlock
     tb_invalidated_flag = 1;
 
     /* remove the TB from the hash list */
-    h = tb_jmp_cache_hash_func(tb->pc);
+    h = tb_jmp_cache_hash_func(tb->cpu_state.pc);
     for(env = first_cpu; env != NULL; env = env->next_cpu) {
         if (env->tb_jmp_cache[h] == tb)
             env->tb_jmp_cache[h] = NULL;
@@ -828,28 +828,27 @@ static void build_page_bitmap(PageDesc *
         if (n == 0) {
             /* NOTE: tb_end may be after the end of the page, but
                it is not a problem */
-            tb_start = tb->pc & ~TARGET_PAGE_MASK;
+            tb_start = tb->cpu_state.pc & ~TARGET_PAGE_MASK;
             tb_end = tb_start + tb->size;
             if (tb_end > TARGET_PAGE_SIZE)
                 tb_end = TARGET_PAGE_SIZE;
         } else {
             tb_start = 0;
-            tb_end = ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
+            tb_end = ((tb->cpu_state.pc + tb->size) & ~TARGET_PAGE_MASK);
         }
         set_bits(p->code_bitmap, tb_start, tb_end - tb_start);
         tb = tb->page_next[n];
     }
 }
 
-TranslationBlock *tb_gen_code(CPUState *env,
-                              target_ulong pc, target_ulong cs_base,
-                              int flags, int cflags)
+TranslationBlock *tb_gen_code(CPUState *env, TBCPUState *cpu_state, int cflags)
 {
     TranslationBlock *tb;
     uint8_t *tc_ptr;
-    target_ulong phys_pc, phys_page2, virt_page2;
+    target_ulong pc, phys_pc, phys_page2, virt_page2;
     int code_gen_size;
 
+    pc = cpu_state->pc;
     phys_pc = get_phys_addr_code(env, pc);
     tb = tb_alloc(pc);
     if (!tb) {
@@ -862,8 +861,7 @@ TranslationBlock *tb_gen_code(CPUState *
     }
     tc_ptr = code_gen_ptr;
     tb->tc_ptr = tc_ptr;
-    tb->cs_base = cs_base;
-    tb->flags = flags;
+    tb->cpu_state = *cpu_state;
     tb->cflags = cflags;
     cpu_gen_code(env, tb, &code_gen_size);
     code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + 
CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
@@ -886,12 +884,17 @@ TranslationBlock *tb_gen_code(CPUState *
 void tb_invalidate_phys_page_range(target_phys_addr_t start, 
target_phys_addr_t end,
                                    int is_cpu_write_access)
 {
-    int n, current_tb_modified, current_tb_not_found, current_flags;
+    TranslationBlock *tb, *tb_next, *saved_tb;
     CPUState *env = cpu_single_env;
-    PageDesc *p;
-    TranslationBlock *tb, *tb_next, *current_tb, *saved_tb;
     target_ulong tb_start, tb_end;
-    target_ulong current_pc, current_cs_base;
+    PageDesc *p;
+    int n;
+#ifdef TARGET_HAS_PRECISE_SMC
+    int current_tb_not_found = is_cpu_write_access;
+    TranslationBlock *current_tb = NULL;
+    int current_tb_modified = 0;
+    TBCPUState cpu_state;
+#endif /* TARGET_HAS_PRECISE_SMC */
 
     p = page_find(start >> TARGET_PAGE_BITS);
     if (!p)
@@ -905,12 +908,6 @@ void tb_invalidate_phys_page_range(targe
 
     /* we remove all the TBs in the range [start, end[ */
     /* XXX: see if in some cases it could be faster to invalidate all the code 
*/
-    current_tb_not_found = is_cpu_write_access;
-    current_tb_modified = 0;
-    current_tb = NULL; /* avoid warning */
-    current_pc = 0; /* avoid warning */
-    current_cs_base = 0; /* avoid warning */
-    current_flags = 0; /* avoid warning */
     tb = p->first_tb;
     while (tb != NULL) {
         n = (long)tb & 3;
@@ -920,11 +917,13 @@ void tb_invalidate_phys_page_range(targe
         if (n == 0) {
             /* NOTE: tb_end may be after the end of the page, but
                it is not a problem */
-            tb_start = tb->page_addr[0] + (tb->pc & ~TARGET_PAGE_MASK);
+            tb_start = tb->page_addr[0] +
+                    (tb->cpu_state.pc & ~TARGET_PAGE_MASK);
             tb_end = tb_start + tb->size;
         } else {
             tb_start = tb->page_addr[1];
-            tb_end = tb_start + ((tb->pc + tb->size) & ~TARGET_PAGE_MASK);
+            tb_end = tb_start +
+                    ((tb->cpu_state.pc + tb->size) & ~TARGET_PAGE_MASK);
         }
         if (!(tb_end <= start || tb_start >= end)) {
 #ifdef TARGET_HAS_PRECISE_SMC
@@ -947,14 +946,7 @@ void tb_invalidate_phys_page_range(targe
                 current_tb_modified = 1;
                 cpu_restore_state(current_tb, env,
                                   env->mem_io_pc, NULL);
-#if defined(TARGET_I386)
-                current_flags = env->hflags;
-                current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | 
VM_MASK));
-                current_cs_base = (target_ulong)env->segs[R_CS].base;
-                current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
+                cpu_get_tb_cpu_state(env, &cpu_state);
             }
 #endif /* TARGET_HAS_PRECISE_SMC */
             /* we need to do that to handle the case where a signal
@@ -988,7 +980,7 @@ void tb_invalidate_phys_page_range(targe
            modifying the memory. It will ensure that it cannot modify
            itself */
         env->current_tb = NULL;
-        tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
+        tb_gen_code(env, &cpu_state, 1);
         cpu_resume_from_signal(env, NULL);
     }
 #endif
@@ -1027,12 +1019,14 @@ static inline void tb_invalidate_phys_pa
 static void tb_invalidate_phys_page(target_phys_addr_t addr,
                                     unsigned long pc, void *puc)
 {
-    int n, current_flags, current_tb_modified;
-    target_ulong current_pc, current_cs_base;
+    TranslationBlock *tb;
     PageDesc *p;
-    TranslationBlock *tb, *current_tb;
+    int n;
 #ifdef TARGET_HAS_PRECISE_SMC
+    TranslationBlock *current_tb = NULL;
     CPUState *env = cpu_single_env;
+    int current_tb_modified = 0;
+    TBCPUState cpu_state;
 #endif
 
     addr &= TARGET_PAGE_MASK;
@@ -1040,11 +1034,6 @@ static void tb_invalidate_phys_page(targ
     if (!p)
         return;
     tb = p->first_tb;
-    current_tb_modified = 0;
-    current_tb = NULL;
-    current_pc = 0; /* avoid warning */
-    current_cs_base = 0; /* avoid warning */
-    current_flags = 0; /* avoid warning */
 #ifdef TARGET_HAS_PRECISE_SMC
     if (tb && pc != 0) {
         current_tb = tb_find_pc(pc);
@@ -1064,14 +1053,7 @@ static void tb_invalidate_phys_page(targ
 
             current_tb_modified = 1;
             cpu_restore_state(current_tb, env, pc, puc);
-#if defined(TARGET_I386)
-            current_flags = env->hflags;
-            current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
-            current_cs_base = (target_ulong)env->segs[R_CS].base;
-            current_pc = current_cs_base + env->eip;
-#else
-#error unsupported CPU
-#endif
+            cpu_get_tb_cpu_state(env, &cpu_state);
         }
 #endif /* TARGET_HAS_PRECISE_SMC */
         tb_phys_invalidate(tb, addr);
@@ -1084,7 +1066,7 @@ static void tb_invalidate_phys_page(targ
            modifying the memory. It will ensure that it cannot modify
            itself */
         env->current_tb = NULL;
-        tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
+        tb_gen_code(env, &cpu_state, 1);
         cpu_resume_from_signal(env, puc);
     }
 #endif
@@ -1156,7 +1138,7 @@ TranslationBlock *tb_alloc(target_ulong
         (code_gen_ptr - code_gen_buffer) >= code_gen_buffer_max_size)
         return NULL;
     tb = &tbs[nb_tbs++];
-    tb->pc = pc;
+    tb->cpu_state.pc = pc;
     tb->cflags = 0;
     return tb;
 }
@@ -3150,9 +3132,8 @@ int cpu_memory_rw_debug(CPUState *env, t
 void cpu_io_recompile(CPUState *env, void *retaddr)
 {
     TranslationBlock *tb;
+    TBCPUState cpu_state;
     uint32_t n, cflags;
-    target_ulong pc, cs_base;
-    uint64_t flags;
 
     tb = tb_find_pc((unsigned long)retaddr);
     if (!tb) {
@@ -3189,13 +3170,11 @@ void cpu_io_recompile(CPUState *env, voi
         cpu_abort(env, "TB too big during recompile");
 
     cflags = n | CF_LAST_IO;
-    pc = tb->pc;
-    cs_base = tb->cs_base;
-    flags = tb->flags;
+    cpu_state = tb->cpu_state;
     tb_phys_invalidate(tb, -1);
     /* FIXME: In theory this could raise an exception.  In practice
        we have already translated the block once so it's probably ok.  */
-    tb_gen_code(env, pc, cs_base, flags, cflags);
+    tb_gen_code(env, &cpu_state, cflags);
     /* TODO: If env->pc != tb->pc (i.e. the faulting instruction was not
        the first in the TB) then we end up generating a whole new TB and
        repeating the fault, which is horribly inefficient.
Index: b/target-alpha/cpu.h
===================================================================
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -318,6 +318,7 @@ static inline void cpu_clone_regs(CPUSta
 #endif
 
 #include "cpu-all.h"
+#include "exec-all.h"
 
 enum {
     FEATURE_ASN    = 0x00000001,
@@ -416,6 +417,15 @@ void call_pal (CPUState *env);
 void call_pal (CPUState *env, int palcode);
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) env->pc = tb->pc
-
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->cpu_state.pc;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->pc;
+    cpu_state->cs_base = 0;
+    cpu_state->flags = env->ps;
+}
 #endif /* !defined (__CPU_ALPHA_H__) */
Index: b/target-alpha/translate.c
===================================================================
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -2245,7 +2245,7 @@ static always_inline void gen_intermedia
     int num_insns;
     int max_insns;
 
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     ctx.pc = pc_start;
     ctx.amask = env->amask;
Index: b/target-arm/cpu.h
===================================================================
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -415,8 +415,23 @@ static inline void cpu_clone_regs(CPUSta
 }
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) env->regs[15] = tb->pc
-
 #include "cpu-all.h"
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->regs[15] = tb->cpu_state.pc;
+}
 
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->regs[15];
+    cpu_state->cs_base = 0;
+    cpu_state->flags = env->thumb | (env->vfp.vec_len << 1)
+            | (env->vfp.vec_stride << 4) | (env->condexec_bits << 8);
+    if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR)
+        cpu_state->flags |= (1 << 6);
+    if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
+        cpu_state->flags |= (1 << 7);
+}
 #endif
Index: b/target-arm/translate.c
===================================================================
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -3375,7 +3375,7 @@ static inline void gen_goto_tb(DisasCont
     TranslationBlock *tb;
 
     tb = s->tb;
-    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+    if ((tb->cpu_state.pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_set_pc_im(dest);
         tcg_gen_exit_tb((long)tb + n);
@@ -8597,7 +8597,7 @@ static inline void gen_intermediate_code
     num_temps = 0;
     memset(temps, 0, sizeof(temps));
 
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
 
     dc->tb = tb;
 
Index: b/target-cris/cpu.h
===================================================================
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -237,7 +237,19 @@ static inline void cpu_clone_regs(CPUSta
 #define SFR_RW_MM_TLB_LO   env->pregs[PR_SRS]][5
 #define SFR_RW_MM_TLB_HI   env->pregs[PR_SRS]][6
 
-#define CPU_PC_FROM_TB(env, tb) env->pc = tb->pc
-
 #include "cpu-all.h"
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->cpu_state.pc;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->pc;
+    cpu_state->cs_base = 0;
+    cpu_state->flags = env->dslot |
+            (env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG));
+}
 #endif
Index: b/target-cris/translate.c
===================================================================
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -642,7 +642,8 @@ static void gen_goto_tb(DisasContext *dc
 {
        TranslationBlock *tb;
        tb = dc->tb;
-       if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+       if ((tb->cpu_state.pc & TARGET_PAGE_MASK) ==
+           (dest & TARGET_PAGE_MASK)) {
                tcg_gen_goto_tb(n);
                tcg_gen_movi_tl(env_pc, dest);
                tcg_gen_exit_tb((long)tb + n);
@@ -3241,7 +3242,7 @@ gen_intermediate_code_internal(CPUState
        /* Odd PC indicates that branch is rexecuting due to exception in the
         * delayslot, like in real hw.
         */
-       pc_start = tb->pc & ~1;
+       pc_start = tb->cpu_state.pc & ~1;
        dc->env = env;
        dc->tb = tb;
 
@@ -3253,7 +3254,7 @@ gen_intermediate_code_internal(CPUState
        dc->singlestep_enabled = env->singlestep_enabled;
        dc->flags_uptodate = 1;
        dc->flagx_known = 1;
-       dc->flags_x = tb->flags & X_FLAG;
+       dc->flags_x = tb->cpu_state.flags & X_FLAG;
        dc->cc_x_uptodate = 0;
        dc->cc_mask = 0;
        dc->update_cc = 0;
@@ -3262,8 +3263,9 @@ gen_intermediate_code_internal(CPUState
        dc->cc_size_uptodate = -1;
 
        /* Decode TB flags.  */
-       dc->tb_flags = tb->flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
-       dc->delayed_branch = !!(tb->flags & 7);
+       dc->tb_flags =
+               tb->cpu_state.flags & (S_FLAG | P_FLAG | U_FLAG | X_FLAG);
+       dc->delayed_branch = !!(tb->cpu_state.flags & 7);
        if (dc->delayed_branch)
                dc->jmp = JMP_INDIRECT;
        else
@@ -3280,8 +3282,8 @@ gen_intermediate_code_internal(CPUState
                        "%x.%x.%x.%x\n"
                        "%x.%x.%x.%x\n",
                        search_pc, dc->pc, dc->ppc,
-                       (unsigned long long)tb->flags,
-                       env->btarget, (unsigned)tb->flags & 7,
+                       (unsigned long long)tb->cpu_state.flags,
+                       env->btarget, (unsigned)tb->cpu_state.flags & 7,
                        env->pregs[PR_CCS], 
                        env->pregs[PR_PID], env->pregs[PR_USP],
                        env->regs[0], env->regs[1], env->regs[2], env->regs[3],
@@ -3342,7 +3344,7 @@ gen_intermediate_code_internal(CPUState
                        dc->delayed_branch--;
                        if (dc->delayed_branch == 0)
                        {
-                               if (tb->flags & 7)
+                               if (tb->cpu_state.flags & 7)
                                        t_gen_mov_env_TN(dslot, 
                                                tcg_const_tl(0));
                                if (dc->jmp == JMP_DIRECT) {
@@ -3358,7 +3360,7 @@ gen_intermediate_code_internal(CPUState
 
                /* If we are rexecuting a branch due to exceptions on
                   delay slots dont break.  */
-               if (!(tb->pc & 1) && env->singlestep_enabled)
+               if (!(tb->cpu_state.pc & 1) && env->singlestep_enabled)
                        break;
        } while (!dc->is_jmp && !dc->cpustate_changed
                 && gen_opc_ptr < gen_opc_end
@@ -3374,7 +3376,7 @@ gen_intermediate_code_internal(CPUState
        /* Force an update if the per-tb cpu state has changed.  */
        if (dc->is_jmp == DISAS_NEXT
            && (dc->cpustate_changed || !dc->flagx_known 
-           || (dc->flags_x != (tb->flags & X_FLAG)))) {
+           || (dc->flags_x != (tb->cpu_state.flags & X_FLAG)))) {
                dc->is_jmp = DISAS_UPDATE;
                tcg_gen_movi_tl(env_pc, npc);
        }
Index: b/target-i386/cpu.h
===================================================================
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -774,10 +774,20 @@ static inline void cpu_clone_regs(CPUSta
 }
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) env->eip = tb->pc - tb->cs_base
-
 #include "cpu-all.h"
-
+#include "exec-all.h"
 #include "svm.h"
 
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->eip = tb->cpu_state.pc - tb->cpu_state.cs_base;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->cs_base = env->segs[R_CS].base;
+    cpu_state->pc = cpu_state->cs_base + env->eip;
+    cpu_state->flags =
+            env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
+}
 #endif /* CPU_I386_H */
Index: b/target-i386/translate.c
===================================================================
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -2210,7 +2210,7 @@ static inline void gen_goto_tb(DisasCont
     pc = s->cs_base + eip;
     tb = s->tb;
     /* NOTE: we handle the case where the TB spans two pages here */
-    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) ||
+    if ((pc & TARGET_PAGE_MASK) == (tb->cpu_state.pc & TARGET_PAGE_MASK) ||
         (pc & TARGET_PAGE_MASK) == ((s->pc - 1) & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
@@ -2625,7 +2625,7 @@ static void gen_eob(DisasContext *s)
 {
     if (s->cc_op != CC_OP_DYNAMIC)
         gen_op_set_cc_op(s->cc_op);
-    if (s->tb->flags & HF_INHIBIT_IRQ_MASK) {
+    if (s->tb->cpu_state.flags & HF_INHIBIT_IRQ_MASK) {
         tcg_gen_helper_0_0(helper_reset_inhibit_irq);
     }
     if (s->singlestep_enabled) {
@@ -4921,7 +4921,7 @@ static target_ulong disas_insn(DisasCont
             /* if reg == SS, inhibit interrupts/trace. */
             /* If several instructions disable interrupts, only the
                _first_ does it */
-            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
+            if (!(s->tb->cpu_state.flags & HF_INHIBIT_IRQ_MASK))
                 tcg_gen_helper_0_0(helper_set_inhibit_irq);
             s->tf = 0;
         }
@@ -4997,7 +4997,7 @@ static target_ulong disas_insn(DisasCont
             /* if reg == SS, inhibit interrupts/trace */
             /* If several instructions disable interrupts, only the
                _first_ does it */
-            if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
+            if (!(s->tb->cpu_state.flags & HF_INHIBIT_IRQ_MASK))
                 tcg_gen_helper_0_0(helper_set_inhibit_irq);
             s->tf = 0;
         }
@@ -6597,7 +6597,7 @@ static target_ulong disas_insn(DisasCont
                 /* interruptions are enabled only the first insn after sti */
                 /* If several instructions disable interrupts, only the
                    _first_ does it */
-                if (!(s->tb->flags & HF_INHIBIT_IRQ_MASK))
+                if (!(s->tb->cpu_state.flags & HF_INHIBIT_IRQ_MASK))
                     tcg_gen_helper_0_0(helper_set_inhibit_irq);
                 /* give a chance to handle pending irqs */
                 gen_jmp_im(s->pc - s->cs_base);
@@ -7541,9 +7541,9 @@ static inline void gen_intermediate_code
     int max_insns;
 
     /* generate intermediate code */
-    pc_start = tb->pc;
-    cs_base = tb->cs_base;
-    flags = tb->flags;
+    pc_start = tb->cpu_state.pc;
+    cs_base = tb->cpu_state.cs_base;
+    flags = tb->cpu_state.flags;
     cflags = tb->cflags;
 
     dc->pe = (flags >> HF_PE_SHIFT) & 1;
@@ -7725,11 +7725,11 @@ void gen_pc_load(CPUState *env, Translat
             }
         }
         fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " 
cs_base=%x\n",
-                searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
-                (uint32_t)tb->cs_base);
+                searched_pc, pc_pos, gen_opc_pc[pc_pos] - 
tb->cpu_state.cs_base,
+                (uint32_t)tb->cpu_state.cs_base);
     }
 #endif
-    env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
+    env->eip = gen_opc_pc[pc_pos] - tb->cpu_state.cs_base;
     cc_op = gen_opc_cc_op[pc_pos];
     if (cc_op != CC_OP_DYNAMIC)
         env->cc_op = cc_op;
Index: b/target-m68k/cpu.h
===================================================================
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -231,8 +231,20 @@ static inline void cpu_clone_regs(CPUSta
 }
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) env->pc = tb->pc
-
 #include "cpu-all.h"
+#include "exec-all.h"
+
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->cpu_state.pc;
+}
 
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->pc;
+    cpu_state->cs_base = 0;
+    cpu_state->flags = (env->fpcr & M68K_FPCR_PREC)     /* Bit  6 */
+            | (env->sr & SR_S)                          /* Bit  13 */
+            | ((env->macsr >> 4) & 0xf);                /* Bits 0-3 */
+}
 #endif
Index: b/target-m68k/translate.c
===================================================================
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -874,7 +874,8 @@ static void gen_jmp_tb(DisasContext *s,
     tb = s->tb;
     if (unlikely(s->singlestep_enabled)) {
         gen_exception(s, dest, EXCP_DEBUG);
-    } else if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
+    } else if ((tb->cpu_state.pc & TARGET_PAGE_MASK) ==
+               (dest & TARGET_PAGE_MASK) ||
                (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(QREG_PC, dest);
@@ -2924,7 +2925,7 @@ gen_intermediate_code_internal(CPUState
     int max_insns;
 
     /* generate intermediate code */
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
 
     dc->tb = tb;
 
Index: b/target-mips/cpu.h
===================================================================
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -501,6 +501,7 @@ static inline void cpu_clone_regs(CPUSta
 }
 
 #include "cpu-all.h"
+#include "exec-all.h"
 
 /* Memory access type :
  * may be needed for precise access rights control and precise exceptions.
@@ -562,10 +563,17 @@ CPUMIPSState *cpu_mips_init(const char *
 uint32_t cpu_mips_get_clock (void);
 int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
 
-#define CPU_PC_FROM_TB(env, tb) do { \
-    env->active_tc.PC = tb->pc; \
-    env->hflags &= ~MIPS_HFLAG_BMASK; \
-    env->hflags |= tb->flags & MIPS_HFLAG_BMASK; \
-    } while (0)
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->active_tc.PC = tb->cpu_state.pc;
+    env->hflags &= ~MIPS_HFLAG_BMASK;
+    env->hflags |= tb->cpu_state.flags & MIPS_HFLAG_BMASK;
+}
 
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->active_tc.PC;
+    cpu_state->cs_base = 0;
+    cpu_state->flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
+}
 #endif /* !defined (__MIPS_CPU_H__) */
Index: b/target-mips/translate.c
===================================================================
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2475,7 +2475,7 @@ static inline void gen_goto_tb(DisasCont
 {
     TranslationBlock *tb;
     tb = ctx->tb;
-    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
+    if ((tb->cpu_state.pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
         tcg_gen_goto_tb(n);
         gen_save_pc(dest);
         tcg_gen_exit_tb((long)tb + n);
@@ -8449,7 +8449,7 @@ gen_intermediate_code_internal (CPUState
     if (search_pc && loglevel)
         fprintf (logfile, "search pc %d\n", search_pc);
 
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
     /* Leave some spare opc slots for branch handling. */
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
     ctx.pc = pc_start;
@@ -8457,7 +8457,7 @@ gen_intermediate_code_internal (CPUState
     ctx.tb = tb;
     ctx.bstate = BS_NONE;
     /* Restore delay slot state from the tb context.  */
-    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
+    ctx.hflags = (uint32_t)tb->cpu_state.flags; /* FIXME: maybe use 64 bits 
here? */
     restore_cpu_state(env, &ctx);
     if (env->user_mode_only)
         ctx.mem_idx = MIPS_HFLAG_UM;
Index: b/target-ppc/cpu.h
===================================================================
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -822,9 +822,8 @@ static inline void cpu_clone_regs(CPUSta
 }
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) env->nip = tb->pc
-
 #include "cpu-all.h"
+#include "exec-all.h"
 
 /*****************************************************************************/
 /* CRF definitions */
@@ -1424,4 +1423,15 @@ enum {
 
 /*****************************************************************************/
 
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->nip = tb->cpu_state.pc;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->nip;
+    cpu_state->cs_base = 0;
+    cpu_state->flags = env->hflags;
+}
 #endif /* !defined (__CPU_PPC_H__) */
Index: b/target-ppc/translate.c
===================================================================
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -3470,7 +3470,7 @@ static always_inline void gen_goto_tb (D
     if (!ctx->sf_mode)
         dest = (uint32_t) dest;
 #endif
-    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+    if ((tb->cpu_state.pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
         likely(!ctx->singlestep_enabled)) {
         tcg_gen_goto_tb(n);
         tcg_gen_movi_tl(cpu_nip, dest & ~3);
@@ -6783,7 +6783,7 @@ static always_inline void gen_intermedia
     int num_insns;
     int max_insns;
 
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
 #if defined(OPTIMIZE_FPRF_UPDATE)
     gen_fprf_ptr = gen_fprf_buf;
Index: b/target-sh4/cpu.h
===================================================================
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -173,12 +173,8 @@ static inline void cpu_clone_regs(CPUSta
 }
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) do { \
-    env->pc = tb->pc; \
-    env->flags = tb->flags; \
-    } while (0)
-
 #include "cpu-all.h"
+#include "exec-all.h"
 
 /* Memory access type */
 enum {
@@ -269,4 +265,19 @@ static inline int cpu_ptel_pr (uint32_t
 #define PTEA_TC        (1 << 3)
 #define cpu_ptea_tc(ptea) (((ptea) & PTEA_TC) >> 3)
 
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->cpu_state.pc;
+    env->flags = tb->cpu_state.flags;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->pc;
+    cpu_state->cs_base = 0;
+    cpu_state->flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL
+                    | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME))   /* Bits  0- 3 */
+            | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR))  /* Bits 19-21 */
+            | (env->sr & (SR_MD | SR_RB));                     /* Bits 29-30 */
+}
 #endif                         /* _CPU_SH4_H */
Index: b/target-sh4/translate.c
===================================================================
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -261,7 +261,7 @@ static void gen_goto_tb(DisasContext * c
     TranslationBlock *tb;
     tb = ctx->tb;
 
-    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
+    if ((tb->cpu_state.pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
        !ctx->singlestep_enabled) {
        /* Use a direct jump if in same page and singlestep not enabled */
         tcg_gen_goto_tb(n);
@@ -1803,10 +1803,10 @@ gen_intermediate_code_internal(CPUState
     int num_insns;
     int max_insns;
 
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
     ctx.pc = pc_start;
-    ctx.flags = (uint32_t)tb->flags;
+    ctx.flags = (uint32_t)tb->cpu_state.flags;
     ctx.bstate = BS_NONE;
     ctx.sr = env->sr;
     ctx.fpscr = env->fpscr;
Index: b/target-sparc/cpu.h
===================================================================
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -491,12 +491,8 @@ static inline void cpu_clone_regs(CPUSta
 }
 #endif
 
-#define CPU_PC_FROM_TB(env, tb) do { \
-    env->pc = tb->pc; \
-    env->npc = tb->cs_base; \
-    } while(0)
-
 #include "cpu-all.h"
+#include "exec-all.h"
 
 /* sum4m.c, sun4u.c */
 void cpu_check_irqs(CPUSPARCState *env);
@@ -508,4 +504,24 @@ uint64_t cpu_tick_get_count(void *opaque
 void cpu_tick_set_limit(void *opaque, uint64_t limit);
 #endif
 
+static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
+{
+    env->pc = tb->cpu_state.pc;
+    env->npc = tb->cpu_state.cs_base;
+}
+
+static inline void cpu_get_tb_cpu_state(CPUState *env, TBCPUState *cpu_state)
+{
+    cpu_state->pc = env->pc;
+    cpu_state->cs_base = env->npc;
+#ifdef TARGET_SPARC64
+    // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled
+    cpu_state->flags = ((env->pstate & PS_AM) << 2)
+        | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2))
+        | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2);
+#else
+    // FPU enable . Supervisor
+    cpu_state->flags = (env->psref << 4) | env->psrs;
+#endif
+}
 #endif
Index: b/target-sparc/translate.c
===================================================================
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -223,8 +223,8 @@ static inline void gen_goto_tb(DisasCont
     TranslationBlock *tb;
 
     tb = s->tb;
-    if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
-        (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK))  {
+    if ((pc & TARGET_PAGE_MASK) == (tb->cpu_state.pc & TARGET_PAGE_MASK) &&
+        (npc & TARGET_PAGE_MASK) == (tb->cpu_state.pc & TARGET_PAGE_MASK))  {
         /* jump to same page: we can use a direct jump */
         tcg_gen_goto_tb(tb_num);
         tcg_gen_movi_tl(cpu_pc, pc);
@@ -4783,10 +4783,10 @@ static inline void gen_intermediate_code
 
     memset(dc, 0, sizeof(DisasContext));
     dc->tb = tb;
-    pc_start = tb->pc;
+    pc_start = tb->cpu_state.pc;
     dc->pc = pc_start;
     last_pc = dc->pc;
-    dc->npc = (target_ulong) tb->cs_base;
+    dc->npc = (target_ulong) tb->cpu_state.cs_base;
     dc->mem_idx = cpu_mmu_index(env);
     dc->def = env->def;
     if ((dc->def->features & CPU_FEATURE_FLOAT))





reply via email to

[Prev in Thread] Current Thread [Next in Thread]