Factorize code in translate.c

(Glauber Costa)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4274 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
aurel32 2008-04-28 00:32:32 +00:00
parent 923e5e339f
commit d2856f1ad4
11 changed files with 125 additions and 95 deletions

View File

@ -67,6 +67,9 @@ extern int loglevel;
int gen_intermediate_code(CPUState *env, struct TranslationBlock *tb);
int gen_intermediate_code_pc(CPUState *env, struct TranslationBlock *tb);
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc);
unsigned long code_gen_max_block_size(void);
void cpu_gen_init(void);
int cpu_gen_code(CPUState *env, struct TranslationBlock *tb,

View File

@ -2109,3 +2109,8 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model)
return env;
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
env->pc = gen_opc_pc[pc_pos];
}

View File

@ -8820,3 +8820,8 @@ void cpu_dump_state(CPUState *env, FILE *f,
#endif
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
env->regs[15] = gen_opc_pc[pc_pos];
}

View File

@ -2702,3 +2702,9 @@ void cpu_reset (CPUCRISState *env)
memset(env, 0, offsetof(CPUCRISState, breakpoints));
tlb_flush(env, 1);
}
void gen_pc_load(CPUState *env, struct TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
env->pregs[PR_ERP] = gen_opc_pc[pc_pos];
}

View File

@ -6888,3 +6888,26 @@ int gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
return gen_intermediate_code_internal(env, tb, 1);
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
int cc_op;
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_OP) {
int i;
fprintf(logfile, "RESTORE:\n");
for(i = 0;i <= pc_pos; i++) {
if (gen_opc_instr_start[i]) {
fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
}
}
fprintf(logfile, "spc=0x%08lx pc_pos=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
searched_pc, pc_pos, gen_opc_pc[pc_pos] - tb->cs_base,
(uint32_t)tb->cs_base);
}
#endif
env->eip = gen_opc_pc[pc_pos] - tb->cs_base;
cc_op = gen_opc_cc_op[pc_pos];
if (cc_op != CC_OP_DYNAMIC)
env->cc_op = cc_op;
}

View File

@ -3280,3 +3280,8 @@ void cpu_dump_state(CPUState *env, FILE *f,
cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
env->pc = gen_opc_pc[pc_pos];
}

View File

@ -6943,3 +6943,11 @@ void cpu_reset (CPUMIPSState *env)
#endif
cpu_mips_register(env, env->cpu_model);
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
env->PC[env->current_tc] = gen_opc_pc[pc_pos];
env->hflags &= ~MIPS_HFLAG_BMASK;
env->hflags |= gen_opc_hflags[pc_pos];
}

View File

@ -6345,3 +6345,45 @@ int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
{
return gen_intermediate_code_internal(env, tb, 1);
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
int type, c;
/* for PPC, we need to look at the micro operation to get the
* access type */
env->nip = gen_opc_pc[pc_pos];
c = gen_opc_buf[pc_pos];
switch(c) {
#if defined(CONFIG_USER_ONLY)
#define CASE3(op)\
case INDEX_op_ ## op ## _raw
#else
#define CASE3(op)\
case INDEX_op_ ## op ## _user:\
case INDEX_op_ ## op ## _kernel:\
case INDEX_op_ ## op ## _hypv
#endif
CASE3(stfd):
CASE3(stfs):
CASE3(lfd):
CASE3(lfs):
type = ACCESS_FLOAT;
break;
CASE3(lwarx):
type = ACCESS_RES;
break;
CASE3(stwcx):
type = ACCESS_RES;
break;
CASE3(eciwx):
CASE3(ecowx):
type = ACCESS_EXT;
break;
default:
type = ACCESS_INT;
break;
}
env->access_type = type;
}

View File

@ -1303,3 +1303,10 @@ int gen_intermediate_code_pc(CPUState * env, struct TranslationBlock *tb)
{
return gen_intermediate_code_internal(env, tb, 1);
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
env->pc = gen_opc_pc[pc_pos];
env->flags = gen_opc_hflags[pc_pos];
}

View File

@ -4659,3 +4659,23 @@ void gen_intermediate_code_init(CPUSPARCState *env)
gregnames[i]);
}
}
void gen_pc_load(CPUState *env, TranslationBlock *tb,
unsigned long searched_pc, int pc_pos, void *puc)
{
target_ulong npc;
env->pc = gen_opc_pc[pc_pos];
npc = gen_opc_npc[pc_pos];
if (npc == 1) {
/* dynamic NPC: already stored */
} else if (npc == 2) {
target_ulong t2 = (target_ulong)(unsigned long)puc;
/* jump PC: use T2 and the jump targets of the translation */
if (t2)
env->npc = gen_opc_jump_pc[0];
else
env->npc = gen_opc_jump_pc[1];
} else {
env->npc = npc;
}
}

View File

@ -194,102 +194,8 @@ int cpu_restore_state(TranslationBlock *tb,
/* now find start of instruction before */
while (gen_opc_instr_start[j] == 0)
j--;
#if defined(TARGET_I386)
{
int cc_op;
#ifdef DEBUG_DISAS
if (loglevel & CPU_LOG_TB_OP) {
int i;
fprintf(logfile, "RESTORE:\n");
for(i=0;i<=j; i++) {
if (gen_opc_instr_start[i]) {
fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
}
}
fprintf(logfile, "spc=0x%08lx j=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
searched_pc, j, gen_opc_pc[j] - tb->cs_base,
(uint32_t)tb->cs_base);
}
#endif
env->eip = gen_opc_pc[j] - tb->cs_base;
cc_op = gen_opc_cc_op[j];
if (cc_op != CC_OP_DYNAMIC)
env->cc_op = cc_op;
}
#elif defined(TARGET_ARM)
env->regs[15] = gen_opc_pc[j];
#elif defined(TARGET_SPARC)
{
target_ulong npc;
env->pc = gen_opc_pc[j];
npc = gen_opc_npc[j];
if (npc == 1) {
/* dynamic NPC: already stored */
} else if (npc == 2) {
target_ulong t2 = (target_ulong)(unsigned long)puc;
/* jump PC: use T2 and the jump targets of the translation */
if (t2)
env->npc = gen_opc_jump_pc[0];
else
env->npc = gen_opc_jump_pc[1];
} else {
env->npc = npc;
}
}
#elif defined(TARGET_PPC)
{
int type, c;
/* for PPC, we need to look at the micro operation to get the
access type */
env->nip = gen_opc_pc[j];
c = gen_opc_buf[j];
switch(c) {
#if defined(CONFIG_USER_ONLY)
#define CASE3(op)\
case INDEX_op_ ## op ## _raw
#else
#define CASE3(op)\
case INDEX_op_ ## op ## _user:\
case INDEX_op_ ## op ## _kernel:\
case INDEX_op_ ## op ## _hypv
#endif
CASE3(stfd):
CASE3(stfs):
CASE3(lfd):
CASE3(lfs):
type = ACCESS_FLOAT;
break;
CASE3(lwarx):
type = ACCESS_RES;
break;
CASE3(stwcx):
type = ACCESS_RES;
break;
CASE3(eciwx):
CASE3(ecowx):
type = ACCESS_EXT;
break;
default:
type = ACCESS_INT;
break;
}
env->access_type = type;
}
#elif defined(TARGET_M68K)
env->pc = gen_opc_pc[j];
#elif defined(TARGET_MIPS)
env->PC[env->current_tc] = gen_opc_pc[j];
env->hflags &= ~MIPS_HFLAG_BMASK;
env->hflags |= gen_opc_hflags[j];
#elif defined(TARGET_ALPHA)
env->pc = gen_opc_pc[j];
#elif defined(TARGET_SH4)
env->pc = gen_opc_pc[j];
env->flags = gen_opc_hflags[j];
#elif defined(TARGET_CRIS)
env->pregs[PR_ERP] = gen_opc_pc[j];
#endif
gen_pc_load(env, tb, searched_pc, j, puc);
#ifdef CONFIG_PROFILER
dyngen_restore_time += profile_getclock() - ti;