Revision ec6338ba cpu-exec.c
b/cpu-exec.c | ||
---|---|---|
612 | 612 |
#if USE_KQEMU |
613 | 613 |
(env->kqemu_enabled != 2) && |
614 | 614 |
#endif |
615 |
tb->page_addr[1] == -1 |
|
616 |
#if defined(TARGET_I386) && defined(USE_CODE_COPY) |
|
617 |
&& (tb->cflags & CF_CODE_COPY) == |
|
618 |
(((TranslationBlock *)(T0 & ~3))->cflags & CF_CODE_COPY) |
|
619 |
#endif |
|
620 |
) { |
|
615 |
tb->page_addr[1] == -1) { |
|
621 | 616 |
spin_lock(&tb_lock); |
622 | 617 |
tb_add_jump((TranslationBlock *)(long)(T0 & ~3), T0 & 3, tb); |
623 |
#if defined(USE_CODE_COPY) |
|
624 |
/* propagates the FP use info */ |
|
625 |
((TranslationBlock *)(T0 & ~3))->cflags |= |
|
626 |
(tb->cflags & CF_FP_USED); |
|
627 |
#endif |
|
628 | 618 |
spin_unlock(&tb_lock); |
629 | 619 |
} |
630 | 620 |
} |
... | ... | |
648 | 638 |
: /* no outputs */ |
649 | 639 |
: "r" (gen_func) |
650 | 640 |
: "r1", "r2", "r3", "r8", "r9", "r10", "r12", "r14"); |
651 |
#elif defined(TARGET_I386) && defined(USE_CODE_COPY) |
|
652 |
{ |
|
653 |
if (!(tb->cflags & CF_CODE_COPY)) { |
|
654 |
if ((tb->cflags & CF_FP_USED) && env->native_fp_regs) { |
|
655 |
save_native_fp_state(env); |
|
656 |
} |
|
657 |
gen_func(); |
|
658 |
} else { |
|
659 |
if ((tb->cflags & CF_FP_USED) && !env->native_fp_regs) { |
|
660 |
restore_native_fp_state(env); |
|
661 |
} |
|
662 |
/* we work with native eflags */ |
|
663 |
CC_SRC = cc_table[CC_OP].compute_all(); |
|
664 |
CC_OP = CC_OP_EFLAGS; |
|
665 |
asm(".globl exec_loop\n" |
|
666 |
"\n" |
|
667 |
"debug1:\n" |
|
668 |
" pushl %%ebp\n" |
|
669 |
" fs movl %10, %9\n" |
|
670 |
" fs movl %11, %%eax\n" |
|
671 |
" andl $0x400, %%eax\n" |
|
672 |
" fs orl %8, %%eax\n" |
|
673 |
" pushl %%eax\n" |
|
674 |
" popf\n" |
|
675 |
" fs movl %%esp, %12\n" |
|
676 |
" fs movl %0, %%eax\n" |
|
677 |
" fs movl %1, %%ecx\n" |
|
678 |
" fs movl %2, %%edx\n" |
|
679 |
" fs movl %3, %%ebx\n" |
|
680 |
" fs movl %4, %%esp\n" |
|
681 |
" fs movl %5, %%ebp\n" |
|
682 |
" fs movl %6, %%esi\n" |
|
683 |
" fs movl %7, %%edi\n" |
|
684 |
" fs jmp *%9\n" |
|
685 |
"exec_loop:\n" |
|
686 |
" fs movl %%esp, %4\n" |
|
687 |
" fs movl %12, %%esp\n" |
|
688 |
" fs movl %%eax, %0\n" |
|
689 |
" fs movl %%ecx, %1\n" |
|
690 |
" fs movl %%edx, %2\n" |
|
691 |
" fs movl %%ebx, %3\n" |
|
692 |
" fs movl %%ebp, %5\n" |
|
693 |
" fs movl %%esi, %6\n" |
|
694 |
" fs movl %%edi, %7\n" |
|
695 |
" pushf\n" |
|
696 |
" popl %%eax\n" |
|
697 |
" movl %%eax, %%ecx\n" |
|
698 |
" andl $0x400, %%ecx\n" |
|
699 |
" shrl $9, %%ecx\n" |
|
700 |
" andl $0x8d5, %%eax\n" |
|
701 |
" fs movl %%eax, %8\n" |
|
702 |
" movl $1, %%eax\n" |
|
703 |
" subl %%ecx, %%eax\n" |
|
704 |
" fs movl %%eax, %11\n" |
|
705 |
" fs movl %9, %%ebx\n" /* get T0 value */ |
|
706 |
" popl %%ebp\n" |
|
707 |
: |
|
708 |
: "m" (*(uint8_t *)offsetof(CPUState, regs[0])), |
|
709 |
"m" (*(uint8_t *)offsetof(CPUState, regs[1])), |
|
710 |
"m" (*(uint8_t *)offsetof(CPUState, regs[2])), |
|
711 |
"m" (*(uint8_t *)offsetof(CPUState, regs[3])), |
|
712 |
"m" (*(uint8_t *)offsetof(CPUState, regs[4])), |
|
713 |
"m" (*(uint8_t *)offsetof(CPUState, regs[5])), |
|
714 |
"m" (*(uint8_t *)offsetof(CPUState, regs[6])), |
|
715 |
"m" (*(uint8_t *)offsetof(CPUState, regs[7])), |
|
716 |
"m" (*(uint8_t *)offsetof(CPUState, cc_src)), |
|
717 |
"m" (*(uint8_t *)offsetof(CPUState, tmp0)), |
|
718 |
"a" (gen_func), |
|
719 |
"m" (*(uint8_t *)offsetof(CPUState, df)), |
|
720 |
"m" (*(uint8_t *)offsetof(CPUState, saved_esp)) |
|
721 |
: "%ecx", "%edx" |
|
722 |
); |
|
723 |
} |
|
724 |
} |
|
725 | 641 |
#elif defined(__ia64) |
726 | 642 |
struct fptr { |
727 | 643 |
void *ip; |
... | ... | |
759 | 675 |
|
760 | 676 |
|
761 | 677 |
#if defined(TARGET_I386) |
762 |
#if defined(USE_CODE_COPY) |
|
763 |
if (env->native_fp_regs) { |
|
764 |
save_native_fp_state(env); |
|
765 |
} |
|
766 |
#endif |
|
767 | 678 |
/* restore flags in standard format */ |
768 | 679 |
env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); |
769 | 680 |
#elif defined(TARGET_ARM) |
... | ... | |
1275 | 1186 |
# define ERROR_sig(context) ((context)->uc_mcontext.gregs[REG_ERR]) |
1276 | 1187 |
#endif |
1277 | 1188 |
|
1278 |
#if defined(USE_CODE_COPY) |
|
1279 |
static void cpu_send_trap(unsigned long pc, int trap, |
|
1280 |
struct ucontext *uc) |
|
1281 |
{ |
|
1282 |
TranslationBlock *tb; |
|
1283 |
|
|
1284 |
if (cpu_single_env) |
|
1285 |
env = cpu_single_env; /* XXX: find a correct solution for multithread */ |
|
1286 |
/* now we have a real cpu fault */ |
|
1287 |
tb = tb_find_pc(pc); |
|
1288 |
if (tb) { |
|
1289 |
/* the PC is inside the translated code. It means that we have |
|
1290 |
a virtual CPU fault */ |
|
1291 |
cpu_restore_state(tb, env, pc, uc); |
|
1292 |
} |
|
1293 |
sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL); |
|
1294 |
raise_exception_err(trap, env->error_code); |
|
1295 |
} |
|
1296 |
#endif |
|
1297 |
|
|
1298 | 1189 |
int cpu_signal_handler(int host_signum, void *pinfo, |
1299 | 1190 |
void *puc) |
1300 | 1191 |
{ |
... | ... | |
1311 | 1202 |
#endif |
1312 | 1203 |
pc = EIP_sig(uc); |
1313 | 1204 |
trapno = TRAP_sig(uc); |
1314 |
#if defined(TARGET_I386) && defined(USE_CODE_COPY) |
|
1315 |
if (trapno == 0x00 || trapno == 0x05) { |
|
1316 |
/* send division by zero or bound exception */ |
|
1317 |
cpu_send_trap(pc, trapno, uc); |
|
1318 |
return 1; |
|
1319 |
} else |
|
1320 |
#endif |
|
1321 |
return handle_cpu_signal(pc, (unsigned long)info->si_addr, |
|
1322 |
trapno == 0xe ? |
|
1323 |
(ERROR_sig(uc) >> 1) & 1 : 0, |
|
1324 |
&uc->uc_sigmask, puc); |
|
1205 |
return handle_cpu_signal(pc, (unsigned long)info->si_addr, |
|
1206 |
trapno == 0xe ? |
|
1207 |
(ERROR_sig(uc) >> 1) & 1 : 0, |
|
1208 |
&uc->uc_sigmask, puc); |
|
1325 | 1209 |
} |
1326 | 1210 |
|
1327 | 1211 |
#elif defined(__x86_64__) |
Also available in: Unified diff