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 | ... | ... |