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,6 +67,9 @@ extern int loglevel; | ||
| 67 | 67 | ||
| 68 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); | 68 | int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb); |
| 69 | int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb); | 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 | unsigned long code_gen_max_block_size(void); | 73 | unsigned long code_gen_max_block_size(void); |
| 71 | void cpu_gen_init(void); | 74 | void cpu_gen_init(void); |
| 72 | int cpu_gen_code(CPUState *env, struct TranslationBlock *tb, | 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,3 +2109,8 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) | ||
| 2109 | return env; | 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
| @@ -8820,3 +8820,8 @@ void cpu_dump_state(CPUState *env, FILE *f, | @@ -8820,3 +8820,8 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
| 8820 | #endif | 8820 | #endif |
| 8821 | } | 8821 | } |
| 8822 | 8822 | ||
| 8823 | +void gen_pc_load(CPUState *env, TranslationBlock *tb, | ||
| 8824 | + unsigned long searched_pc, int pc_pos, void *puc) | ||
| 8825 | +{ | ||
| 8826 | + env->regs[15] = gen_opc_pc[pc_pos]; | ||
| 8827 | +} |
target-cris/translate.c
| @@ -2702,3 +2702,9 @@ void cpu_reset (CPUCRISState *env) | @@ -2702,3 +2702,9 @@ void cpu_reset (CPUCRISState *env) | ||
| 2702 | memset(env, 0, offsetof(CPUCRISState, breakpoints)); | 2702 | memset(env, 0, offsetof(CPUCRISState, breakpoints)); |
| 2703 | tlb_flush(env, 1); | 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,3 +6888,26 @@ int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb) | ||
| 6888 | return gen_intermediate_code_internal(env, tb, 1); | 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,3 +3280,8 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
| 3280 | cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result); | 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,3 +6943,11 @@ void cpu_reset (CPUMIPSState *env) | ||
| 6943 | #endif | 6943 | #endif |
| 6944 | cpu_mips_register(env, env->cpu_model); | 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,3 +6345,45 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) | ||
| 6345 | { | 6345 | { |
| 6346 | return gen_intermediate_code_internal(env, tb, 1); | 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,3 +1303,10 @@ int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb) | ||
| 1303 | { | 1303 | { |
| 1304 | return gen_intermediate_code_internal(env, tb, 1); | 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,3 +4659,23 @@ void gen_intermediate_code_init(CPUSPARCState *env) | ||
| 4659 | gregnames[i]); | 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,102 +194,8 @@ int cpu_restore_state(TranslationBlock *tb, | ||
| 194 | /* now find start of instruction before */ | 194 | /* now find start of instruction before */ |
| 195 | while (gen_opc_instr_start[j] == 0) | 195 | while (gen_opc_instr_start[j] == 0) |
| 196 | j--; | 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 | #ifdef CONFIG_PROFILER | 200 | #ifdef CONFIG_PROFILER |
| 295 | dyngen_restore_time += profile_getclock() - ti; | 201 | dyngen_restore_time += profile_getclock() - ti; |