Commit d2856f1ad4c259e5766847c49acbb4e390731bd4
1 parent
923e5e33
Factorize code in translate.c
(Glauber Costa) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4274 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
11 changed files
with
125 additions
and
95 deletions
exec-all.h
| ... | ... | @@ -67,6 +67,9 @@ extern int loglevel; |
| 67 | 67 | |
| 68 | 68 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); |
| 69 | 69 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); |
| 70 | +void gen_pc_load(CPUState *env, struct TranslationBlock *tb, | |
| 71 | + unsigned long searched_pc, int pc_pos, void *puc); | |
| 72 | + | |
| 70 | 73 | unsigned long code_gen_max_block_size(void); |
| 71 | 74 | void cpu_gen_init(void); |
| 72 | 75 | int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, | ... | ... |
target-alpha/translate.c
| ... | ... | @@ -2109,3 +2109,8 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) |
| 2109 | 2109 | return env; |
| 2110 | 2110 | } |
| 2111 | 2111 | |
| 2112 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 2113 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 2114 | +{ | |
| 2115 | + env->pc = gen_opc_pc[pc_pos]; | |
| 2116 | +} | ... | ... |
target-arm/translate.c
target-cris/translate.c
| ... | ... | @@ -2702,3 +2702,9 @@ void cpu_reset (CPUCRISState *env) |
| 2702 | 2702 | memset(env, 0, offsetof(CPUCRISState, breakpoints)); |
| 2703 | 2703 | tlb_flush(env, 1); |
| 2704 | 2704 | } |
| 2705 | + | |
| 2706 | +void gen_pc_load(CPUState *env, struct TranslationBlock *tb, | |
| 2707 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 2708 | +{ | |
| 2709 | + env->pregs[PR_ERP] = gen_opc_pc[pc_pos]; | |
| 2710 | +} | ... | ... |
target-i386/translate.c
| ... | ... | @@ -6888,3 +6888,26 @@ int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb) |
| 6888 | 6888 | return gen_intermediate_code_internal(env, tb, 1); |
| 6889 | 6889 | } |
| 6890 | 6890 | |
| 6891 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 6892 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 6893 | +{ | |
| 6894 | + int cc_op; | |
| 6895 | +#ifdef DEBUG_DISAS | |
| 6896 | + if (loglevel & CPU_LOG_TB_OP) { | |
| 6897 | + int i; | |
| 6898 | + fprintf(logfile, "RESTORE:\n"); | |
| 6899 | + for(i = 0;i <= pc_pos; i++) { | |
| 6900 | + if (gen_opc_instr_start[i]) { | |
| 6901 | + fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]); | |
| 6902 | + } | |
| 6903 | + } | |
| 6904 | + fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n", | |
| 6905 | + searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base, | |
| 6906 | + (uint32_t)tb->cs_base); | |
| 6907 | + } | |
| 6908 | +#endif | |
| 6909 | + env->eip = gen_opc_pc[pc_pos] - tb->cs_base; | |
| 6910 | + cc_op = gen_opc_cc_op[pc_pos]; | |
| 6911 | + if (cc_op != CC_OP_DYNAMIC) | |
| 6912 | + env->cc_op = cc_op; | |
| 6913 | +} | ... | ... |
target-m68k/translate.c
| ... | ... | @@ -3280,3 +3280,8 @@ void cpu_dump_state(CPUState *env, FILE *f, |
| 3280 | 3280 | cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result); |
| 3281 | 3281 | } |
| 3282 | 3282 | |
| 3283 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 3284 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 3285 | +{ | |
| 3286 | + env->pc = gen_opc_pc[pc_pos]; | |
| 3287 | +} | ... | ... |
target-mips/translate.c
| ... | ... | @@ -6943,3 +6943,11 @@ void cpu_reset (CPUMIPSState *env) |
| 6943 | 6943 | #endif |
| 6944 | 6944 | cpu_mips_register(env, env->cpu_model); |
| 6945 | 6945 | } |
| 6946 | + | |
| 6947 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 6948 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 6949 | +{ | |
| 6950 | + env->PC[env->current_tc] = gen_opc_pc[pc_pos]; | |
| 6951 | + env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 6952 | + env->hflags |= gen_opc_hflags[pc_pos]; | |
| 6953 | +} | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -6345,3 +6345,45 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) |
| 6345 | 6345 | { |
| 6346 | 6346 | return gen_intermediate_code_internal(env, tb, 1); |
| 6347 | 6347 | } |
| 6348 | + | |
| 6349 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 6350 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 6351 | +{ | |
| 6352 | + int type, c; | |
| 6353 | + /* for PPC, we need to look at the micro operation to get the | |
| 6354 | + * access type */ | |
| 6355 | + env->nip = gen_opc_pc[pc_pos]; | |
| 6356 | + c = gen_opc_buf[pc_pos]; | |
| 6357 | + switch(c) { | |
| 6358 | +#if defined(CONFIG_USER_ONLY) | |
| 6359 | +#define CASE3(op)\ | |
| 6360 | + case INDEX_op_ ## op ## _raw | |
| 6361 | +#else | |
| 6362 | +#define CASE3(op)\ | |
| 6363 | + case INDEX_op_ ## op ## _user:\ | |
| 6364 | + case INDEX_op_ ## op ## _kernel:\ | |
| 6365 | + case INDEX_op_ ## op ## _hypv | |
| 6366 | +#endif | |
| 6367 | + | |
| 6368 | + CASE3(stfd): | |
| 6369 | + CASE3(stfs): | |
| 6370 | + CASE3(lfd): | |
| 6371 | + CASE3(lfs): | |
| 6372 | + type = ACCESS_FLOAT; | |
| 6373 | + break; | |
| 6374 | + CASE3(lwarx): | |
| 6375 | + type = ACCESS_RES; | |
| 6376 | + break; | |
| 6377 | + CASE3(stwcx): | |
| 6378 | + type = ACCESS_RES; | |
| 6379 | + break; | |
| 6380 | + CASE3(eciwx): | |
| 6381 | + CASE3(ecowx): | |
| 6382 | + type = ACCESS_EXT; | |
| 6383 | + break; | |
| 6384 | + default: | |
| 6385 | + type = ACCESS_INT; | |
| 6386 | + break; | |
| 6387 | + } | |
| 6388 | + env->access_type = type; | |
| 6389 | +} | ... | ... |
target-sh4/translate.c
| ... | ... | @@ -1303,3 +1303,10 @@ int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) |
| 1303 | 1303 | { |
| 1304 | 1304 | return gen_intermediate_code_internal(env, tb, 1); |
| 1305 | 1305 | } |
| 1306 | + | |
| 1307 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 1308 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 1309 | +{ | |
| 1310 | + env->pc = gen_opc_pc[pc_pos]; | |
| 1311 | + env->flags = gen_opc_hflags[pc_pos]; | |
| 1312 | +} | ... | ... |
target-sparc/translate.c
| ... | ... | @@ -4659,3 +4659,23 @@ void gen_intermediate_code_init(CPUSPARCState *env) |
| 4659 | 4659 | gregnames[i]); |
| 4660 | 4660 | } |
| 4661 | 4661 | } |
| 4662 | + | |
| 4663 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | |
| 4664 | + unsigned long searched_pc, int pc_pos, void *puc) | |
| 4665 | +{ | |
| 4666 | + target_ulong npc; | |
| 4667 | + env->pc = gen_opc_pc[pc_pos]; | |
| 4668 | + npc = gen_opc_npc[pc_pos]; | |
| 4669 | + if (npc == 1) { | |
| 4670 | + /* dynamic NPC: already stored */ | |
| 4671 | + } else if (npc == 2) { | |
| 4672 | + target_ulong t2 = (target_ulong)(unsigned long)puc; | |
| 4673 | + /* jump PC: use T2 and the jump targets of the translation */ | |
| 4674 | + if (t2) | |
| 4675 | + env->npc = gen_opc_jump_pc[0]; | |
| 4676 | + else | |
| 4677 | + env->npc = gen_opc_jump_pc[1]; | |
| 4678 | + } else { | |
| 4679 | + env->npc = npc; | |
| 4680 | + } | |
| 4681 | +} | ... | ... |
translate-all.c
| ... | ... | @@ -194,102 +194,8 @@ int cpu_restore_state(TranslationBlock *tb, |
| 194 | 194 | /* now find start of instruction before */ |
| 195 | 195 | while (gen_opc_instr_start[j] == 0) |
| 196 | 196 | j--; |
| 197 | -#if defined(TARGET_I386) | |
| 198 | - { | |
| 199 | - int cc_op; | |
| 200 | -#ifdef DEBUG_DISAS | |
| 201 | - if (loglevel & CPU_LOG_TB_OP) { | |
| 202 | - int i; | |
| 203 | - fprintf(logfile, "RESTORE:\n"); | |
| 204 | - for(i=0;i<=j; i++) { | |
| 205 | - if (gen_opc_instr_start[i]) { | |
| 206 | - fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]); | |
| 207 | - } | |
| 208 | - } | |
| 209 | - fprintf(logfile, "spc=0x%08lx j=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n", | |
| 210 | - searched_pc, j, gen_opc_pc[j] - tb->cs_base, | |
| 211 | - (uint32_t)tb->cs_base); | |
| 212 | - } | |
| 213 | -#endif | |
| 214 | - env->eip = gen_opc_pc[j] - tb->cs_base; | |
| 215 | - cc_op = gen_opc_cc_op[j]; | |
| 216 | - if (cc_op != CC_OP_DYNAMIC) | |
| 217 | - env->cc_op = cc_op; | |
| 218 | - } | |
| 219 | -#elif defined(TARGET_ARM) | |
| 220 | - env->regs[15] = gen_opc_pc[j]; | |
| 221 | -#elif defined(TARGET_SPARC) | |
| 222 | - { | |
| 223 | - target_ulong npc; | |
| 224 | - env->pc = gen_opc_pc[j]; | |
| 225 | - npc = gen_opc_npc[j]; | |
| 226 | - if (npc == 1) { | |
| 227 | - /* dynamic NPC: already stored */ | |
| 228 | - } else if (npc == 2) { | |
| 229 | - target_ulong t2 = (target_ulong)(unsigned long)puc; | |
| 230 | - /* jump PC: use T2 and the jump targets of the translation */ | |
| 231 | - if (t2) | |
| 232 | - env->npc = gen_opc_jump_pc[0]; | |
| 233 | - else | |
| 234 | - env->npc = gen_opc_jump_pc[1]; | |
| 235 | - } else { | |
| 236 | - env->npc = npc; | |
| 237 | - } | |
| 238 | - } | |
| 239 | -#elif defined(TARGET_PPC) | |
| 240 | - { | |
| 241 | - int type, c; | |
| 242 | - /* for PPC, we need to look at the micro operation to get the | |
| 243 | - access type */ | |
| 244 | - env->nip = gen_opc_pc[j]; | |
| 245 | - c = gen_opc_buf[j]; | |
| 246 | - switch(c) { | |
| 247 | -#if defined(CONFIG_USER_ONLY) | |
| 248 | -#define CASE3(op)\ | |
| 249 | - case INDEX_op_ ## op ## _raw | |
| 250 | -#else | |
| 251 | -#define CASE3(op)\ | |
| 252 | - case INDEX_op_ ## op ## _user:\ | |
| 253 | - case INDEX_op_ ## op ## _kernel:\ | |
| 254 | - case INDEX_op_ ## op ## _hypv | |
| 255 | -#endif | |
| 256 | 197 | |
| 257 | - CASE3(stfd): | |
| 258 | - CASE3(stfs): | |
| 259 | - CASE3(lfd): | |
| 260 | - CASE3(lfs): | |
| 261 | - type = ACCESS_FLOAT; | |
| 262 | - break; | |
| 263 | - CASE3(lwarx): | |
| 264 | - type = ACCESS_RES; | |
| 265 | - break; | |
| 266 | - CASE3(stwcx): | |
| 267 | - type = ACCESS_RES; | |
| 268 | - break; | |
| 269 | - CASE3(eciwx): | |
| 270 | - CASE3(ecowx): | |
| 271 | - type = ACCESS_EXT; | |
| 272 | - break; | |
| 273 | - default: | |
| 274 | - type = ACCESS_INT; | |
| 275 | - break; | |
| 276 | - } | |
| 277 | - env->access_type = type; | |
| 278 | - } | |
| 279 | -#elif defined(TARGET_M68K) | |
| 280 | - env->pc = gen_opc_pc[j]; | |
| 281 | -#elif defined(TARGET_MIPS) | |
| 282 | - env->PC[env->current_tc] = gen_opc_pc[j]; | |
| 283 | - env->hflags &= ~MIPS_HFLAG_BMASK; | |
| 284 | - env->hflags |= gen_opc_hflags[j]; | |
| 285 | -#elif defined(TARGET_ALPHA) | |
| 286 | - env->pc = gen_opc_pc[j]; | |
| 287 | -#elif defined(TARGET_SH4) | |
| 288 | - env->pc = gen_opc_pc[j]; | |
| 289 | - env->flags = gen_opc_hflags[j]; | |
| 290 | -#elif defined(TARGET_CRIS) | |
| 291 | - env->pregs[PR_ERP] = gen_opc_pc[j]; | |
| 292 | -#endif | |
| 198 | + gen_pc_load(env, tb, searched_pc, j, puc); | |
| 293 | 199 | |
| 294 | 200 | #ifdef CONFIG_PROFILER |
| 295 | 201 | dyngen_restore_time += profile_getclock() - ti; | ... | ... |