Commit 6b9175478e9ad8ef2a9569fd8e2a83440747aae5

Authored by aliguori
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
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)) {
... ...
... ... @@ -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, &current_pc, &current_cs_base,
  952 + &current_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, &current_pc, &current_cs_base,
  1062 + &current_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
... ...