diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-18 19:46:41 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-11-18 19:46:41 +0000 |
commit | 6b9175478e9ad8ef2a9569fd8e2a83440747aae5 (patch) | |
tree | 2436af3fe2b5a72150f728c5b5940768e45ecd0e | |
parent | 622ed3605bf4caa5d52b407081ceb6ecce752aec (diff) | |
download | qemu-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.c | 63 | ||||
-rw-r--r-- | exec.c | 56 | ||||
-rw-r--r-- | target-alpha/cpu.h | 8 | ||||
-rw-r--r-- | target-arm/cpu.h | 13 | ||||
-rw-r--r-- | target-cris/cpu.h | 9 | ||||
-rw-r--r-- | target-i386/cpu.h | 8 | ||||
-rw-r--r-- | target-m68k/cpu.h | 10 | ||||
-rw-r--r-- | target-mips/cpu.h | 8 | ||||
-rw-r--r-- | target-ppc/cpu.h | 8 | ||||
-rw-r--r-- | target-sh4/cpu.h | 11 | ||||
-rw-r--r-- | target-sparc/cpu.h | 16 |
11 files changed, 115 insertions, 95 deletions
@@ -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)) { @@ -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, ¤t_pc, ¤t_cs_base, + ¤t_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, ¤t_pc, ¤t_cs_base, + ¤t_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 |