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