aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-18 19:46:41 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-18 19:46:41 +0000
commit6b9175478e9ad8ef2a9569fd8e2a83440747aae5 (patch)
tree2436af3fe2b5a72150f728c5b5940768e45ecd0e
parent622ed3605bf4caa5d52b407081ceb6ecce752aec (diff)
downloadqemu-6b9175478e9ad8ef2a9569fd8e2a83440747aae5.zip
qemu-6b9175478e9ad8ef2a9569fd8e2a83440747aae5.tar.gz
qemu-6b9175478e9ad8ef2a9569fd8e2a83440747aae5.tar.bz2
Refactor translation block CPU state handling (Jan Kiszka)
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"). Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5736 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--cpu-exec.c63
-rw-r--r--exec.c56
-rw-r--r--target-alpha/cpu.h8
-rw-r--r--target-arm/cpu.h13
-rw-r--r--target-cris/cpu.h9
-rw-r--r--target-i386/cpu.h8
-rw-r--r--target-m68k/cpu.h10
-rw-r--r--target-mips/cpu.h8
-rw-r--r--target-ppc/cpu.h8
-rw-r--r--target-sh4/cpu.h11
-rw-r--r--target-sparc/cpu.h16
11 files changed, 115 insertions, 95 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index 322af0d..1955d24 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -169,71 +169,12 @@ static inline TranslationBlock *tb_find_fast(void)
{
TranslationBlock *tb;
target_ulong cs_base, pc;
- uint64_t flags;
+ int flags;
/* 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
+ cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags);
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)) {
diff --git a/exec.c b/exec.c
index 1edc737..772b1c1 100644
--- a/exec.c
+++ b/exec.c
@@ -886,12 +886,19 @@ TranslationBlock *tb_gen_code(CPUState *env,
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;
+ target_ulong current_pc = 0;
+ target_ulong current_cs_base = 0;
+ int current_flags = 0;
+#endif /* TARGET_HAS_PRECISE_SMC */
p = page_find(start >> TARGET_PAGE_BITS);
if (!p)
@@ -905,12 +912,6 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t
/* 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;
@@ -947,14 +948,8 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t
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, &current_pc, &current_cs_base,
+ &current_flags);
}
#endif /* TARGET_HAS_PRECISE_SMC */
/* we need to do that to handle the case where a signal
@@ -1027,12 +1022,16 @@ static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int le
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;
+ target_ulong current_pc = 0;
+ target_ulong current_cs_base = 0;
+ int current_flags = 0;
#endif
addr &= TARGET_PAGE_MASK;
@@ -1040,11 +1039,6 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr,
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 +1058,8 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr,
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, &current_pc, &current_cs_base,
+ &current_flags);
}
#endif /* TARGET_HAS_PRECISE_SMC */
tb_phys_invalidate(tb, addr);
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index f606fac..122e2c2 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -422,4 +422,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->pc = tb->pc;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->pc;
+ *cs_base = 0;
+ *flags = env->ps;
+}
+
#endif /* !defined (__CPU_ALPHA_H__) */
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 79e51ac..d6cb116 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -423,4 +423,17 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->regs[15] = tb->pc;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->regs[15];
+ *cs_base = 0;
+ *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)
+ *flags |= (1 << 6);
+ if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30))
+ *flags |= (1 << 7);
+}
+
#endif
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 19cb209..44a98e4 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -245,4 +245,13 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->pc = tb->pc;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->pc;
+ *cs_base = 0;
+ *flags = env->dslot |
+ (env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG));
+}
+
#endif
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index ead073c..ebbf1b1 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -799,4 +799,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->eip = tb->pc - tb->cs_base;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *cs_base = env->segs[R_CS].base;
+ *pc = *cs_base + env->eip;
+ *flags = env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK));
+}
+
#endif /* CPU_I386_H */
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 48c752c..bdef9b8 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -239,4 +239,14 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->pc = tb->pc;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->pc;
+ *cs_base = 0;
+ *flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */
+ | (env->sr & SR_S) /* Bit 13 */
+ | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */
+}
+
#endif
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index a2544b1..86a7680 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -571,4 +571,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->active_tc.PC;
+ *cs_base = 0;
+ *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
+}
+
#endif /* !defined (__MIPS_CPU_H__) */
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1ffbc30..35c824a 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -1436,4 +1436,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->nip = tb->pc;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->nip;
+ *cs_base = 0;
+ *flags = env->hflags;
+}
+
#endif /* !defined (__CPU_PPC_H__) */
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index ed7c105..23ecded 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -271,4 +271,15 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->flags = tb->flags;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->pc;
+ *cs_base = 0;
+ *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 */
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 4779e34..93c1be5 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -510,4 +510,20 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
env->npc = tb->cs_base;
}
+static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
+ target_ulong *cs_base, int *flags)
+{
+ *pc = env->pc;
+ *cs_base = env->npc;
+#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
+}
+
#endif