Commit 6b9175478e9ad8ef2a9569fd8e2a83440747aae5
1 parent
622ed360
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
Showing
11 changed files
with
115 additions
and
95 deletions
cpu-exec.c
| ... | ... | @@ -169,71 +169,12 @@ static inline TranslationBlock *tb_find_fast(void) |
| 169 | 169 | { |
| 170 | 170 | TranslationBlock *tb; |
| 171 | 171 | target_ulong cs_base, pc; |
| 172 | - uint64_t flags; | |
| 172 | + int flags; | |
| 173 | 173 | |
| 174 | 174 | /* we record a subset of the CPU state. It will |
| 175 | 175 | always be the same before a given translated block |
| 176 | 176 | is executed. */ |
| 177 | -#if defined(TARGET_I386) | |
| 178 | - flags = env->hflags; | |
| 179 | - flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); | |
| 180 | - cs_base = env->segs[R_CS].base; | |
| 181 | - pc = cs_base + env->eip; | |
| 182 | -#elif defined(TARGET_ARM) | |
| 183 | - flags = env->thumb | (env->vfp.vec_len << 1) | |
| 184 | - | (env->vfp.vec_stride << 4); | |
| 185 | - if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) | |
| 186 | - flags |= (1 << 6); | |
| 187 | - if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) | |
| 188 | - flags |= (1 << 7); | |
| 189 | - flags |= (env->condexec_bits << 8); | |
| 190 | - cs_base = 0; | |
| 191 | - pc = env->regs[15]; | |
| 192 | -#elif defined(TARGET_SPARC) | |
| 193 | -#ifdef TARGET_SPARC64 | |
| 194 | - // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled | |
| 195 | - flags = ((env->pstate & PS_AM) << 2) | |
| 196 | - | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) | |
| 197 | - | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); | |
| 198 | -#else | |
| 199 | - // FPU enable . Supervisor | |
| 200 | - flags = (env->psref << 4) | env->psrs; | |
| 201 | -#endif | |
| 202 | - cs_base = env->npc; | |
| 203 | - pc = env->pc; | |
| 204 | -#elif defined(TARGET_PPC) | |
| 205 | - flags = env->hflags; | |
| 206 | - cs_base = 0; | |
| 207 | - pc = env->nip; | |
| 208 | -#elif defined(TARGET_MIPS) | |
| 209 | - flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK); | |
| 210 | - cs_base = 0; | |
| 211 | - pc = env->active_tc.PC; | |
| 212 | -#elif defined(TARGET_M68K) | |
| 213 | - flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */ | |
| 214 | - | (env->sr & SR_S) /* Bit 13 */ | |
| 215 | - | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ | |
| 216 | - cs_base = 0; | |
| 217 | - pc = env->pc; | |
| 218 | -#elif defined(TARGET_SH4) | |
| 219 | - flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL | |
| 220 | - | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */ | |
| 221 | - | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */ | |
| 222 | - | (env->sr & (SR_MD | SR_RB)); /* Bits 29-30 */ | |
| 223 | - cs_base = 0; | |
| 224 | - pc = env->pc; | |
| 225 | -#elif defined(TARGET_ALPHA) | |
| 226 | - flags = env->ps; | |
| 227 | - cs_base = 0; | |
| 228 | - pc = env->pc; | |
| 229 | -#elif defined(TARGET_CRIS) | |
| 230 | - flags = env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG); | |
| 231 | - flags |= env->dslot; | |
| 232 | - cs_base = 0; | |
| 233 | - pc = env->pc; | |
| 234 | -#else | |
| 235 | -#error unsupported CPU | |
| 236 | -#endif | |
| 177 | + cpu_get_tb_cpu_state(env, &pc, &cs_base, &flags); | |
| 237 | 178 | tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; |
| 238 | 179 | if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || |
| 239 | 180 | tb->flags != flags)) { | ... | ... |
exec.c
| ... | ... | @@ -886,12 +886,19 @@ TranslationBlock *tb_gen_code(CPUState *env, |
| 886 | 886 | void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, |
| 887 | 887 | int is_cpu_write_access) |
| 888 | 888 | { |
| 889 | - int n, current_tb_modified, current_tb_not_found, current_flags; | |
| 889 | + TranslationBlock *tb, *tb_next, *saved_tb; | |
| 890 | 890 | CPUState *env = cpu_single_env; |
| 891 | - PageDesc *p; | |
| 892 | - TranslationBlock *tb, *tb_next, *current_tb, *saved_tb; | |
| 893 | 891 | target_ulong tb_start, tb_end; |
| 894 | - target_ulong current_pc, current_cs_base; | |
| 892 | + PageDesc *p; | |
| 893 | + int n; | |
| 894 | +#ifdef TARGET_HAS_PRECISE_SMC | |
| 895 | + int current_tb_not_found = is_cpu_write_access; | |
| 896 | + TranslationBlock *current_tb = NULL; | |
| 897 | + int current_tb_modified = 0; | |
| 898 | + target_ulong current_pc = 0; | |
| 899 | + target_ulong current_cs_base = 0; | |
| 900 | + int current_flags = 0; | |
| 901 | +#endif /* TARGET_HAS_PRECISE_SMC */ | |
| 895 | 902 | |
| 896 | 903 | p = page_find(start >> TARGET_PAGE_BITS); |
| 897 | 904 | if (!p) |
| ... | ... | @@ -905,12 +912,6 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t |
| 905 | 912 | |
| 906 | 913 | /* we remove all the TBs in the range [start, end[ */ |
| 907 | 914 | /* XXX: see if in some cases it could be faster to invalidate all the code */ |
| 908 | - current_tb_not_found = is_cpu_write_access; | |
| 909 | - current_tb_modified = 0; | |
| 910 | - current_tb = NULL; /* avoid warning */ | |
| 911 | - current_pc = 0; /* avoid warning */ | |
| 912 | - current_cs_base = 0; /* avoid warning */ | |
| 913 | - current_flags = 0; /* avoid warning */ | |
| 914 | 915 | tb = p->first_tb; |
| 915 | 916 | while (tb != NULL) { |
| 916 | 917 | n = (long)tb & 3; |
| ... | ... | @@ -947,14 +948,8 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t |
| 947 | 948 | current_tb_modified = 1; |
| 948 | 949 | cpu_restore_state(current_tb, env, |
| 949 | 950 | env->mem_io_pc, NULL); |
| 950 | -#if defined(TARGET_I386) | |
| 951 | - current_flags = env->hflags; | |
| 952 | - current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); | |
| 953 | - current_cs_base = (target_ulong)env->segs[R_CS].base; | |
| 954 | - current_pc = current_cs_base + env->eip; | |
| 955 | -#else | |
| 956 | -#error unsupported CPU | |
| 957 | -#endif | |
| 951 | + cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, | |
| 952 | + ¤t_flags); | |
| 958 | 953 | } |
| 959 | 954 | #endif /* TARGET_HAS_PRECISE_SMC */ |
| 960 | 955 | /* 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 |
| 1027 | 1022 | static void tb_invalidate_phys_page(target_phys_addr_t addr, |
| 1028 | 1023 | unsigned long pc, void *puc) |
| 1029 | 1024 | { |
| 1030 | - int n, current_flags, current_tb_modified; | |
| 1031 | - target_ulong current_pc, current_cs_base; | |
| 1025 | + TranslationBlock *tb; | |
| 1032 | 1026 | PageDesc *p; |
| 1033 | - TranslationBlock *tb, *current_tb; | |
| 1027 | + int n; | |
| 1034 | 1028 | #ifdef TARGET_HAS_PRECISE_SMC |
| 1029 | + TranslationBlock *current_tb = NULL; | |
| 1035 | 1030 | CPUState *env = cpu_single_env; |
| 1031 | + int current_tb_modified = 0; | |
| 1032 | + target_ulong current_pc = 0; | |
| 1033 | + target_ulong current_cs_base = 0; | |
| 1034 | + int current_flags = 0; | |
| 1036 | 1035 | #endif |
| 1037 | 1036 | |
| 1038 | 1037 | addr &= TARGET_PAGE_MASK; |
| ... | ... | @@ -1040,11 +1039,6 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, |
| 1040 | 1039 | if (!p) |
| 1041 | 1040 | return; |
| 1042 | 1041 | tb = p->first_tb; |
| 1043 | - current_tb_modified = 0; | |
| 1044 | - current_tb = NULL; | |
| 1045 | - current_pc = 0; /* avoid warning */ | |
| 1046 | - current_cs_base = 0; /* avoid warning */ | |
| 1047 | - current_flags = 0; /* avoid warning */ | |
| 1048 | 1042 | #ifdef TARGET_HAS_PRECISE_SMC |
| 1049 | 1043 | if (tb && pc != 0) { |
| 1050 | 1044 | current_tb = tb_find_pc(pc); |
| ... | ... | @@ -1064,14 +1058,8 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, |
| 1064 | 1058 | |
| 1065 | 1059 | current_tb_modified = 1; |
| 1066 | 1060 | cpu_restore_state(current_tb, env, pc, puc); |
| 1067 | -#if defined(TARGET_I386) | |
| 1068 | - current_flags = env->hflags; | |
| 1069 | - current_flags |= (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); | |
| 1070 | - current_cs_base = (target_ulong)env->segs[R_CS].base; | |
| 1071 | - current_pc = current_cs_base + env->eip; | |
| 1072 | -#else | |
| 1073 | -#error unsupported CPU | |
| 1074 | -#endif | |
| 1061 | + cpu_get_tb_cpu_state(env, ¤t_pc, ¤t_cs_base, | |
| 1062 | + ¤t_flags); | |
| 1075 | 1063 | } |
| 1076 | 1064 | #endif /* TARGET_HAS_PRECISE_SMC */ |
| 1077 | 1065 | tb_phys_invalidate(tb, addr); | ... | ... |
target-alpha/cpu.h
| ... | ... | @@ -422,4 +422,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 422 | 422 | env->pc = tb->pc; |
| 423 | 423 | } |
| 424 | 424 | |
| 425 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 426 | + target_ulong *cs_base, int *flags) | |
| 427 | +{ | |
| 428 | + *pc = env->pc; | |
| 429 | + *cs_base = 0; | |
| 430 | + *flags = env->ps; | |
| 431 | +} | |
| 432 | + | |
| 425 | 433 | #endif /* !defined (__CPU_ALPHA_H__) */ | ... | ... |
target-arm/cpu.h
| ... | ... | @@ -423,4 +423,17 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 423 | 423 | env->regs[15] = tb->pc; |
| 424 | 424 | } |
| 425 | 425 | |
| 426 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 427 | + target_ulong *cs_base, int *flags) | |
| 428 | +{ | |
| 429 | + *pc = env->regs[15]; | |
| 430 | + *cs_base = 0; | |
| 431 | + *flags = env->thumb | (env->vfp.vec_len << 1) | |
| 432 | + | (env->vfp.vec_stride << 4) | (env->condexec_bits << 8); | |
| 433 | + if ((env->uncached_cpsr & CPSR_M) != ARM_CPU_MODE_USR) | |
| 434 | + *flags |= (1 << 6); | |
| 435 | + if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) | |
| 436 | + *flags |= (1 << 7); | |
| 437 | +} | |
| 438 | + | |
| 426 | 439 | #endif | ... | ... |
target-cris/cpu.h
| ... | ... | @@ -245,4 +245,13 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 245 | 245 | env->pc = tb->pc; |
| 246 | 246 | } |
| 247 | 247 | |
| 248 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 249 | + target_ulong *cs_base, int *flags) | |
| 250 | +{ | |
| 251 | + *pc = env->pc; | |
| 252 | + *cs_base = 0; | |
| 253 | + *flags = env->dslot | | |
| 254 | + (env->pregs[PR_CCS] & (S_FLAG | P_FLAG | U_FLAG | X_FLAG)); | |
| 255 | +} | |
| 256 | + | |
| 248 | 257 | #endif | ... | ... |
target-i386/cpu.h
| ... | ... | @@ -799,4 +799,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 799 | 799 | env->eip = tb->pc - tb->cs_base; |
| 800 | 800 | } |
| 801 | 801 | |
| 802 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 803 | + target_ulong *cs_base, int *flags) | |
| 804 | +{ | |
| 805 | + *cs_base = env->segs[R_CS].base; | |
| 806 | + *pc = *cs_base + env->eip; | |
| 807 | + *flags = env->hflags | (env->eflags & (IOPL_MASK | TF_MASK | VM_MASK)); | |
| 808 | +} | |
| 809 | + | |
| 802 | 810 | #endif /* CPU_I386_H */ | ... | ... |
target-m68k/cpu.h
| ... | ... | @@ -239,4 +239,14 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 239 | 239 | env->pc = tb->pc; |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 243 | + target_ulong *cs_base, int *flags) | |
| 244 | +{ | |
| 245 | + *pc = env->pc; | |
| 246 | + *cs_base = 0; | |
| 247 | + *flags = (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */ | |
| 248 | + | (env->sr & SR_S) /* Bit 13 */ | |
| 249 | + | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ | |
| 250 | +} | |
| 251 | + | |
| 242 | 252 | #endif | ... | ... |
target-mips/cpu.h
| ... | ... | @@ -571,4 +571,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 571 | 571 | env->hflags |= tb->flags & MIPS_HFLAG_BMASK; |
| 572 | 572 | } |
| 573 | 573 | |
| 574 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 575 | + target_ulong *cs_base, int *flags) | |
| 576 | +{ | |
| 577 | + *pc = env->active_tc.PC; | |
| 578 | + *cs_base = 0; | |
| 579 | + *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK); | |
| 580 | +} | |
| 581 | + | |
| 574 | 582 | #endif /* !defined (__MIPS_CPU_H__) */ | ... | ... |
target-ppc/cpu.h
| ... | ... | @@ -1436,4 +1436,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 1436 | 1436 | env->nip = tb->pc; |
| 1437 | 1437 | } |
| 1438 | 1438 | |
| 1439 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 1440 | + target_ulong *cs_base, int *flags) | |
| 1441 | +{ | |
| 1442 | + *pc = env->nip; | |
| 1443 | + *cs_base = 0; | |
| 1444 | + *flags = env->hflags; | |
| 1445 | +} | |
| 1446 | + | |
| 1439 | 1447 | #endif /* !defined (__CPU_PPC_H__) */ | ... | ... |
target-sh4/cpu.h
| ... | ... | @@ -271,4 +271,15 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 271 | 271 | env->flags = tb->flags; |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 275 | + target_ulong *cs_base, int *flags) | |
| 276 | +{ | |
| 277 | + *pc = env->pc; | |
| 278 | + *cs_base = 0; | |
| 279 | + *flags = (env->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL | |
| 280 | + | DELAY_SLOT_TRUE | DELAY_SLOT_CLEARME)) /* Bits 0- 3 */ | |
| 281 | + | (env->fpscr & (FPSCR_FR | FPSCR_SZ | FPSCR_PR)) /* Bits 19-21 */ | |
| 282 | + | (env->sr & (SR_MD | SR_RB)); /* Bits 29-30 */ | |
| 283 | +} | |
| 284 | + | |
| 274 | 285 | #endif /* _CPU_SH4_H */ | ... | ... |
target-sparc/cpu.h
| ... | ... | @@ -510,4 +510,20 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) |
| 510 | 510 | env->npc = tb->cs_base; |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | +static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc, | |
| 514 | + target_ulong *cs_base, int *flags) | |
| 515 | +{ | |
| 516 | + *pc = env->pc; | |
| 517 | + *cs_base = env->npc; | |
| 518 | +#ifdef TARGET_SPARC64 | |
| 519 | + // AM . Combined FPU enable bits . PRIV . DMMU enabled . IMMU enabled | |
| 520 | + *flags = ((env->pstate & PS_AM) << 2) | |
| 521 | + | (((env->pstate & PS_PEF) >> 1) | ((env->fprs & FPRS_FEF) << 2)) | |
| 522 | + | (env->pstate & PS_PRIV) | ((env->lsu & (DMMU_E | IMMU_E)) >> 2); | |
| 523 | +#else | |
| 524 | + // FPU enable . Supervisor | |
| 525 | + *flags = (env->psref << 4) | env->psrs; | |
| 526 | +#endif | |
| 527 | +} | |
| 528 | + | |
| 513 | 529 | #endif | ... | ... |