void cpu_loop(CPUX86State *env)

{

    CPUState *cs = CPU(x86_env_get_cpu(env));

    int trapnr;

    abi_ulong pc;

    target_siginfo_t info;



    for(;;) {

        cpu_exec_start(cs);

        trapnr = cpu_x86_exec(cs);

        cpu_exec_end(cs);

        switch(trapnr) {

        case 0x80:

            /* linux syscall from int $0x80 */

            env->regs[R_EAX] = do_syscall(env,

                                          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],

                                          0, 0);

            break;

#ifndef TARGET_ABI32

        case EXCP_SYSCALL:

            /* linux syscall from syscall instruction */

            env->regs[R_EAX] = do_syscall(env,

                                          env->regs[R_EAX],

                                          env->regs[R_EDI],

                                          env->regs[R_ESI],

                                          env->regs[R_EDX],

                                          env->regs[10],

                                          env->regs[8],

                                          env->regs[9],

                                          0, 0);

            break;

#endif

        case EXCP0B_NOSEG:

        case EXCP0C_STACK:

            info.si_signo = TARGET_SIGBUS;

            info.si_errno = 0;

            info.si_code = TARGET_SI_KERNEL;

            info._sifields._sigfault._addr = 0;

            queue_signal(env, info.si_signo, &info);

            break;

        case EXCP0D_GPF:

            /* XXX: potential problem if ABI32 */

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_fault(env);

            } else

#endif

            {

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SI_KERNEL;

                info._sifields._sigfault._addr = 0;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP0E_PAGE:

            info.si_signo = TARGET_SIGSEGV;

            info.si_errno = 0;

            if (!(env->error_code & 1))

                info.si_code = TARGET_SEGV_MAPERR;

            else

                info.si_code = TARGET_SEGV_ACCERR;

            info._sifields._sigfault._addr = env->cr[2];

            queue_signal(env, info.si_signo, &info);

            break;

        case EXCP00_DIVZ:

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_trap(env, trapnr);

            } else

#endif

            {

                /* division by zero */

                info.si_signo = TARGET_SIGFPE;

                info.si_errno = 0;

                info.si_code = TARGET_FPE_INTDIV;

                info._sifields._sigfault._addr = env->eip;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP01_DB:

        case EXCP03_INT3:

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_trap(env, trapnr);

            } else

#endif

            {

                info.si_signo = TARGET_SIGTRAP;

                info.si_errno = 0;

                if (trapnr == EXCP01_DB) {

                    info.si_code = TARGET_TRAP_BRKPT;

                    info._sifields._sigfault._addr = env->eip;

                } else {

                    info.si_code = TARGET_SI_KERNEL;

                    info._sifields._sigfault._addr = 0;

                }

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP04_INTO:

        case EXCP05_BOUND:

#ifndef TARGET_X86_64

            if (env->eflags & VM_MASK) {

                handle_vm86_trap(env, trapnr);

            } else

#endif

            {

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SI_KERNEL;

                info._sifields._sigfault._addr = 0;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP06_ILLOP:

            info.si_signo = TARGET_SIGILL;

            info.si_errno = 0;

            info.si_code = TARGET_ILL_ILLOPN;

            info._sifields._sigfault._addr = env->eip;

            queue_signal(env, info.si_signo, &info);

            break;

        case EXCP_INTERRUPT:

            /* just indicate that signals should be handled asap */

            break;

        case EXCP_DEBUG:

            {

                int sig;



                sig = gdb_handlesig(cs, TARGET_SIGTRAP);

                if (sig)

                  {

                    info.si_signo = sig;

                    info.si_errno = 0;

                    info.si_code = TARGET_TRAP_BRKPT;

                    queue_signal(env, info.si_signo, &info);

                  }

            }

            break;

        default:

            pc = env->segs[R_CS].base + env->eip;

            EXCP_DUMP(env, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",

                      (long)pc, trapnr);

            abort();

        }

        process_pending_signals(env);

    }

}
