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,71 +169,12 @@ static inline TranslationBlock *tb_find_fast(void) | ||
169 | { | 169 | { |
170 | TranslationBlock *tb; | 170 | TranslationBlock *tb; |
171 | target_ulong cs_base, pc; | 171 | target_ulong cs_base, pc; |
172 | - uint64_t flags; | 172 | + int flags; |
173 | 173 | ||
174 | /* we record a subset of the CPU state. It will | 174 | /* we record a subset of the CPU state. It will |
175 | always be the same before a given translated block | 175 | always be the same before a given translated block |
176 | is executed. */ | 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 | tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; | 178 | tb = env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)]; |
238 | if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || | 179 | if (unlikely(!tb || tb->pc != pc || tb->cs_base != cs_base || |
239 | tb->flags != flags)) { | 180 | tb->flags != flags)) { |
exec.c
@@ -886,12 +886,19 @@ TranslationBlock *tb_gen_code(CPUState *env, | @@ -886,12 +886,19 @@ TranslationBlock *tb_gen_code(CPUState *env, | ||
886 | void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, | 886 | void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t end, |
887 | int is_cpu_write_access) | 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 | CPUState *env = cpu_single_env; | 890 | CPUState *env = cpu_single_env; |
891 | - PageDesc *p; | ||
892 | - TranslationBlock *tb, *tb_next, *current_tb, *saved_tb; | ||
893 | target_ulong tb_start, tb_end; | 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 | p = page_find(start >> TARGET_PAGE_BITS); | 903 | p = page_find(start >> TARGET_PAGE_BITS); |
897 | if (!p) | 904 | if (!p) |
@@ -905,12 +912,6 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t | @@ -905,12 +912,6 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t | ||
905 | 912 | ||
906 | /* we remove all the TBs in the range [start, end[ */ | 913 | /* we remove all the TBs in the range [start, end[ */ |
907 | /* XXX: see if in some cases it could be faster to invalidate all the code */ | 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 | tb = p->first_tb; | 915 | tb = p->first_tb; |
915 | while (tb != NULL) { | 916 | while (tb != NULL) { |
916 | n = (long)tb & 3; | 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,14 +948,8 @@ void tb_invalidate_phys_page_range(target_phys_addr_t start, target_phys_addr_t | ||
947 | current_tb_modified = 1; | 948 | current_tb_modified = 1; |
948 | cpu_restore_state(current_tb, env, | 949 | cpu_restore_state(current_tb, env, |
949 | env->mem_io_pc, NULL); | 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 | #endif /* TARGET_HAS_PRECISE_SMC */ | 954 | #endif /* TARGET_HAS_PRECISE_SMC */ |
960 | /* we need to do that to handle the case where a signal | 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,12 +1022,16 @@ static inline void tb_invalidate_phys_page_fast(target_phys_addr_t start, int le | ||
1027 | static void tb_invalidate_phys_page(target_phys_addr_t addr, | 1022 | static void tb_invalidate_phys_page(target_phys_addr_t addr, |
1028 | unsigned long pc, void *puc) | 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 | PageDesc *p; | 1026 | PageDesc *p; |
1033 | - TranslationBlock *tb, *current_tb; | 1027 | + int n; |
1034 | #ifdef TARGET_HAS_PRECISE_SMC | 1028 | #ifdef TARGET_HAS_PRECISE_SMC |
1029 | + TranslationBlock *current_tb = NULL; | ||
1035 | CPUState *env = cpu_single_env; | 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 | #endif | 1035 | #endif |
1037 | 1036 | ||
1038 | addr &= TARGET_PAGE_MASK; | 1037 | addr &= TARGET_PAGE_MASK; |
@@ -1040,11 +1039,6 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, | @@ -1040,11 +1039,6 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, | ||
1040 | if (!p) | 1039 | if (!p) |
1041 | return; | 1040 | return; |
1042 | tb = p->first_tb; | 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 | #ifdef TARGET_HAS_PRECISE_SMC | 1042 | #ifdef TARGET_HAS_PRECISE_SMC |
1049 | if (tb && pc != 0) { | 1043 | if (tb && pc != 0) { |
1050 | current_tb = tb_find_pc(pc); | 1044 | current_tb = tb_find_pc(pc); |
@@ -1064,14 +1058,8 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, | @@ -1064,14 +1058,8 @@ static void tb_invalidate_phys_page(target_phys_addr_t addr, | ||
1064 | 1058 | ||
1065 | current_tb_modified = 1; | 1059 | current_tb_modified = 1; |
1066 | cpu_restore_state(current_tb, env, pc, puc); | 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 | #endif /* TARGET_HAS_PRECISE_SMC */ | 1064 | #endif /* TARGET_HAS_PRECISE_SMC */ |
1077 | tb_phys_invalidate(tb, addr); | 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,4 +422,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
422 | env->pc = tb->pc; | 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 | #endif /* !defined (__CPU_ALPHA_H__) */ | 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,4 +423,17 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
423 | env->regs[15] = tb->pc; | 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 | #endif | 439 | #endif |
target-cris/cpu.h
@@ -245,4 +245,13 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | @@ -245,4 +245,13 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
245 | env->pc = tb->pc; | 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 | #endif | 257 | #endif |
target-i386/cpu.h
@@ -799,4 +799,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | @@ -799,4 +799,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
799 | env->eip = tb->pc - tb->cs_base; | 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 | #endif /* CPU_I386_H */ | 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,4 +239,14 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
239 | env->pc = tb->pc; | 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 | #endif | 252 | #endif |
target-mips/cpu.h
@@ -571,4 +571,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | @@ -571,4 +571,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
571 | env->hflags |= tb->flags & MIPS_HFLAG_BMASK; | 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 | #endif /* !defined (__MIPS_CPU_H__) */ | 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,4 +1436,12 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
1436 | env->nip = tb->pc; | 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 | #endif /* !defined (__CPU_PPC_H__) */ | 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,4 +271,15 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
271 | env->flags = tb->flags; | 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 | #endif /* _CPU_SH4_H */ | 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,4 +510,20 @@ static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb) | ||
510 | env->npc = tb->cs_base; | 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 | #endif | 529 | #endif |