188 |
raise_exception_err(exception_index, 0); |
raise_exception_err(exception_index, 0); |
189 |
} |
} |
190 |
|
|
|
#if defined(DEBUG_EXEC) |
|
|
static const char *cc_op_str[] = { |
|
|
"DYNAMIC", |
|
|
"EFLAGS", |
|
|
"MUL", |
|
|
"ADDB", |
|
|
"ADDW", |
|
|
"ADDL", |
|
|
"ADCB", |
|
|
"ADCW", |
|
|
"ADCL", |
|
|
"SUBB", |
|
|
"SUBW", |
|
|
"SUBL", |
|
|
"SBBB", |
|
|
"SBBW", |
|
|
"SBBL", |
|
|
"LOGICB", |
|
|
"LOGICW", |
|
|
"LOGICL", |
|
|
"INCB", |
|
|
"INCW", |
|
|
"INCL", |
|
|
"DECB", |
|
|
"DECW", |
|
|
"DECL", |
|
|
"SHLB", |
|
|
"SHLW", |
|
|
"SHLL", |
|
|
"SARB", |
|
|
"SARW", |
|
|
"SARL", |
|
|
}; |
|
|
|
|
|
static void cpu_x86_dump_state(FILE *f) |
|
|
{ |
|
|
int eflags; |
|
|
char cc_op_name[32]; |
|
|
eflags = cc_table[CC_OP].compute_all(); |
|
|
eflags |= (DF & DF_MASK); |
|
|
if ((unsigned)env->cc_op < CC_OP_NB) |
|
|
strcpy(cc_op_name, cc_op_str[env->cc_op]); |
|
|
else |
|
|
snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op); |
|
|
fprintf(f, |
|
|
"EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n" |
|
|
"ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n" |
|
|
"CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n" |
|
|
"EIP=%08x\n", |
|
|
env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX], |
|
|
env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP], |
|
|
env->cc_src, env->cc_dst, cc_op_name, |
|
|
eflags & DF_MASK ? 'D' : '-', |
|
|
eflags & CC_O ? 'O' : '-', |
|
|
eflags & CC_S ? 'S' : '-', |
|
|
eflags & CC_Z ? 'Z' : '-', |
|
|
eflags & CC_A ? 'A' : '-', |
|
|
eflags & CC_P ? 'P' : '-', |
|
|
eflags & CC_C ? 'C' : '-', |
|
|
env->eip); |
|
|
#if 1 |
|
|
fprintf(f, "ST0=%f ST1=%f ST2=%f ST3=%f\n", |
|
|
(double)ST0, (double)ST1, (double)ST(2), (double)ST(3)); |
|
|
#endif |
|
|
} |
|
|
|
|
|
#endif |
|
|
|
|
191 |
void cpu_x86_tblocks_init(void) |
void cpu_x86_tblocks_init(void) |
192 |
{ |
{ |
193 |
if (!code_gen_ptr) { |
if (!code_gen_ptr) { |
331 |
CC_OP = CC_OP_EFLAGS; |
CC_OP = CC_OP_EFLAGS; |
332 |
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); |
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); |
333 |
env->interrupt_request = 0; |
env->interrupt_request = 0; |
334 |
|
|
335 |
/* prepare setjmp context for exception handling */ |
/* prepare setjmp context for exception handling */ |
336 |
if (setjmp(env->jmp_env) == 0) { |
if (setjmp(env->jmp_env) == 0) { |
337 |
for(;;) { |
for(;;) { |
340 |
} |
} |
341 |
#ifdef DEBUG_EXEC |
#ifdef DEBUG_EXEC |
342 |
if (loglevel) { |
if (loglevel) { |
343 |
cpu_x86_dump_state(logfile); |
/* XXX: save all volatile state in cpu state */ |
344 |
|
/* restore flags in standard format */ |
345 |
|
env->regs[R_EAX] = EAX; |
346 |
|
env->regs[R_EBX] = EBX; |
347 |
|
env->regs[R_ECX] = ECX; |
348 |
|
env->regs[R_EDX] = EDX; |
349 |
|
env->regs[R_ESI] = ESI; |
350 |
|
env->regs[R_EDI] = EDI; |
351 |
|
env->regs[R_EBP] = EBP; |
352 |
|
env->regs[R_ESP] = ESP; |
353 |
|
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); |
354 |
|
cpu_x86_dump_state(env, logfile, 0); |
355 |
|
env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); |
356 |
} |
} |
357 |
#endif |
#endif |
358 |
/* we compute the CPU state. We assume it will not |
/* we compute the CPU state. We assume it will not |
363 |
(unsigned long)env->seg_cache[R_ES].base | |
(unsigned long)env->seg_cache[R_ES].base | |
364 |
(unsigned long)env->seg_cache[R_SS].base) != 0) << |
(unsigned long)env->seg_cache[R_SS].base) != 0) << |
365 |
GEN_FLAG_ADDSEG_SHIFT; |
GEN_FLAG_ADDSEG_SHIFT; |
366 |
flags |= (env->eflags & VM_MASK) >> (17 - GEN_FLAG_VM_SHIFT); |
if (!(env->eflags & VM_MASK)) { |
367 |
|
flags |= (env->segs[R_CS] & 3) << GEN_FLAG_CPL_SHIFT; |
368 |
|
} else { |
369 |
|
/* NOTE: a dummy CPL is kept */ |
370 |
|
flags |= (1 << GEN_FLAG_VM_SHIFT); |
371 |
|
flags |= (3 << GEN_FLAG_CPL_SHIFT); |
372 |
|
} |
373 |
flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT); |
flags |= (env->eflags & IOPL_MASK) >> (12 - GEN_FLAG_IOPL_SHIFT); |
|
flags |= (env->segs[R_CS] & 3) << GEN_FLAG_CPL_SHIFT; |
|
374 |
cs_base = env->seg_cache[R_CS].base; |
cs_base = env->seg_cache[R_CS].base; |
375 |
pc = cs_base + env->eip; |
pc = cs_base + env->eip; |
376 |
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
398 |
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); |
399 |
cpu_unlock(); |
cpu_unlock(); |
400 |
} |
} |
401 |
|
#ifdef DEBUG_EXEC |
402 |
if (loglevel) { |
if (loglevel) { |
403 |
fprintf(logfile, "Trace 0x%08lx [0x%08lx] %s\n", |
fprintf(logfile, "Trace 0x%08lx [0x%08lx] %s\n", |
404 |
(long)tb->tc_ptr, (long)tb->pc, |
(long)tb->tc_ptr, (long)tb->pc, |
405 |
lookup_symbol((void *)tb->pc)); |
lookup_symbol((void *)tb->pc)); |
|
fflush(logfile); |
|
406 |
} |
} |
407 |
|
#endif |
408 |
/* execute the generated code */ |
/* execute the generated code */ |
409 |
tc_ptr = tb->tc_ptr; |
tc_ptr = tb->tc_ptr; |
410 |
gen_func = (void *)tc_ptr; |
gen_func = (void *)tc_ptr; |