void cpu_x86_cpuid(CPUX86State *env, uint32_t index,

                   uint32_t *eax, uint32_t *ebx,

                   uint32_t *ecx, uint32_t *edx)

{

    /* test if maximum index reached */

    if (index & 0x80000000) {

        if (index > env->cpuid_xlevel)

            index = env->cpuid_level;

    } else {

        if (index > env->cpuid_level)

            index = env->cpuid_level;

    }



    switch(index) {

    case 0:

        *eax = env->cpuid_level;

        *ebx = env->cpuid_vendor1;

        *edx = env->cpuid_vendor2;

        *ecx = env->cpuid_vendor3;



        /* sysenter isn't supported on compatibility mode on AMD.  and syscall

         * isn't supported in compatibility mode on Intel.  so advertise the

         * actuall cpu, and say goodbye to migration between different vendors

         * is you use compatibility mode. */

        if (kvm_enabled())

            host_cpuid(0, NULL, ebx, ecx, edx);

        break;

    case 1:

        *eax = env->cpuid_version;

        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; /* CLFLUSH size in quad words, Linux wants it. */

        *ecx = env->cpuid_ext_features;

        *edx = env->cpuid_features;



        /* "Hypervisor present" bit required for Microsoft SVVP */

        if (kvm_enabled())

            *ecx |= (1 << 31);

        break;

    case 2:

        /* cache info: needed for Pentium Pro compatibility */

        *eax = 1;

        *ebx = 0;

        *ecx = 0;

        *edx = 0x2c307d;

        break;

    case 4:

        /* cache info: needed for Core compatibility */

        switch (*ecx) {

            case 0: /* L1 dcache info */

                *eax = 0x0000121;

                *ebx = 0x1c0003f;

                *ecx = 0x000003f;

                *edx = 0x0000001;

                break;

            case 1: /* L1 icache info */

                *eax = 0x0000122;

                *ebx = 0x1c0003f;

                *ecx = 0x000003f;

                *edx = 0x0000001;

                break;

            case 2: /* L2 cache info */

                *eax = 0x0000143;

                *ebx = 0x3c0003f;

                *ecx = 0x0000fff;

                *edx = 0x0000001;

                break;

            default: /* end of info */

                *eax = 0;

                *ebx = 0;

                *ecx = 0;

                *edx = 0;

                break;

        }



        break;

    case 5:

        /* mwait info: needed for Core compatibility */

        *eax = 0; /* Smallest monitor-line size in bytes */

        *ebx = 0; /* Largest monitor-line size in bytes */

        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;

        *edx = 0;

        break;

    case 6:

        /* Thermal and Power Leaf */

        *eax = 0;

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 9:

        /* Direct Cache Access Information Leaf */

        *eax = 0; /* Bits 0-31 in DCA_CAP MSR */

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 0xA:

        /* Architectural Performance Monitoring Leaf */

        *eax = 0;

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 0x80000000:

        *eax = env->cpuid_xlevel;

        *ebx = env->cpuid_vendor1;

        *edx = env->cpuid_vendor2;

        *ecx = env->cpuid_vendor3;

        break;

    case 0x80000001:

        *eax = env->cpuid_features;

        *ebx = 0;

        *ecx = env->cpuid_ext3_features;

        *edx = env->cpuid_ext2_features;



        if (kvm_enabled()) {

            uint32_t h_eax, h_edx;



            host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);



            /* disable CPU features that the host does not support */



            /* long mode */

            if ((h_edx & 0x20000000) == 0 /* || !lm_capable_kernel */)

                *edx &= ~0x20000000;

            /* syscall */

            if ((h_edx & 0x00000800) == 0)

                *edx &= ~0x00000800;

            /* nx */

            if ((h_edx & 0x00100000) == 0)

                *edx &= ~0x00100000;



            /* disable CPU features that KVM cannot support */



            /* svm */

            *ecx &= ~4UL;

            /* 3dnow */

            *edx = ~0xc0000000;

        }

        break;

    case 0x80000002:

    case 0x80000003:

    case 0x80000004:

        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];

        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];

        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];

        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];

        break;

    case 0x80000005:

        /* cache info (L1 cache) */

        *eax = 0x01ff01ff;

        *ebx = 0x01ff01ff;

        *ecx = 0x40020140;

        *edx = 0x40020140;

        break;

    case 0x80000006:

        /* cache info (L2 cache) */

        *eax = 0;

        *ebx = 0x42004200;

        *ecx = 0x02008140;

        *edx = 0;

        break;

    case 0x80000008:

        /* virtual & phys address size in low 2 bytes. */

/* XXX: This value must match the one used in the MMU code. */ 

        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {

            /* 64 bit processor */

#if defined(USE_KQEMU)

            *eax = 0x00003020;	/* 48 bits virtual, 32 bits physical */

#else

/* XXX: The physical address space is limited to 42 bits in exec.c. */

            *eax = 0x00003028;	/* 48 bits virtual, 40 bits physical */

#endif

        } else {

#if defined(USE_KQEMU)

            *eax = 0x00000020;	/* 32 bits physical */

#else

            if (env->cpuid_features & CPUID_PSE36)

                *eax = 0x00000024; /* 36 bits physical */

            else

                *eax = 0x00000020; /* 32 bits physical */

#endif

        }

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 0x8000000A:

        *eax = 0x00000001; /* SVM Revision */

        *ebx = 0x00000010; /* nr of ASIDs */

        *ecx = 0;

        *edx = 0; /* optional features */

        break;

    default:

        /* reserved values: zero */

        *eax = 0;

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    }

}

void cpu_x86_cpuid(CPUX86State *env, uint32_t index,

                   uint32_t *eax, uint32_t *ebx,

                   uint32_t *ecx, uint32_t *edx)

{

    

    if (index & 0x80000000) {

        if (index > env->cpuid_xlevel)

            index = env->cpuid_level;

    } else {

        if (index > env->cpuid_level)

            index = env->cpuid_level;

    }



    switch(index) {

    case 0:

        *eax = env->cpuid_level;

        *ebx = env->cpuid_vendor1;

        *edx = env->cpuid_vendor2;

        *ecx = env->cpuid_vendor3;



        







        if (kvm_enabled())

            host_cpuid(0, NULL, ebx, ecx, edx);

        break;

    case 1:

        *eax = env->cpuid_version;

        *ebx = (env->cpuid_apic_id << 24) | 8 << 8; 

        *ecx = env->cpuid_ext_features;

        *edx = env->cpuid_features;



        

        if (kvm_enabled())

            *ecx |= (1 << 31);

        break;

    case 2:

        

        *eax = 1;

        *ebx = 0;

        *ecx = 0;

        *edx = 0x2c307d;

        break;

    case 4:

        

        switch (*ecx) {

            case 0: 

                *eax = 0x0000121;

                *ebx = 0x1c0003f;

                *ecx = 0x000003f;

                *edx = 0x0000001;

                break;

            case 1: 

                *eax = 0x0000122;

                *ebx = 0x1c0003f;

                *ecx = 0x000003f;

                *edx = 0x0000001;

                break;

            case 2: 

                *eax = 0x0000143;

                *ebx = 0x3c0003f;

                *ecx = 0x0000fff;

                *edx = 0x0000001;

                break;

            default: 

                *eax = 0;

                *ebx = 0;

                *ecx = 0;

                *edx = 0;

                break;

        }



        break;

    case 5:

        

        *eax = 0; 

        *ebx = 0; 

        *ecx = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;

        *edx = 0;

        break;

    case 6:

        

        *eax = 0;

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 9:

        

        *eax = 0; 

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 0xA:

        

        *eax = 0;

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 0x80000000:

        *eax = env->cpuid_xlevel;

        *ebx = env->cpuid_vendor1;

        *edx = env->cpuid_vendor2;

        *ecx = env->cpuid_vendor3;

        break;

    case 0x80000001:

        *eax = env->cpuid_features;

        *ebx = 0;

        *ecx = env->cpuid_ext3_features;

        *edx = env->cpuid_ext2_features;



        if (kvm_enabled()) {

            uint32_t h_eax, h_edx;



            host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);



            



            

            if ((h_edx & 0x20000000) == 0 )

                *edx &= ~0x20000000;

            

            if ((h_edx & 0x00000800) == 0)

                *edx &= ~0x00000800;

            

            if ((h_edx & 0x00100000) == 0)

                *edx &= ~0x00100000;



            



            

            *ecx &= ~4UL;

            

            *edx = ~0xc0000000;

        }

        break;

    case 0x80000002:

    case 0x80000003:

    case 0x80000004:

        *eax = env->cpuid_model[(index - 0x80000002) * 4 + 0];

        *ebx = env->cpuid_model[(index - 0x80000002) * 4 + 1];

        *ecx = env->cpuid_model[(index - 0x80000002) * 4 + 2];

        *edx = env->cpuid_model[(index - 0x80000002) * 4 + 3];

        break;

    case 0x80000005:

        

        *eax = 0x01ff01ff;

        *ebx = 0x01ff01ff;

        *ecx = 0x40020140;

        *edx = 0x40020140;

        break;

    case 0x80000006:

        

        *eax = 0;

        *ebx = 0x42004200;

        *ecx = 0x02008140;

        *edx = 0;

        break;

    case 0x80000008:

        

 

        if (env->cpuid_ext2_features & CPUID_EXT2_LM) {

            

#if defined(USE_KQEMU)

            *eax = 0x00003020;	

#else



            *eax = 0x00003028;	

#endif

        } else {

#if defined(USE_KQEMU)

            *eax = 0x00000020;	

#else

            if (env->cpuid_features & CPUID_PSE36)

                *eax = 0x00000024; 

            else

                *eax = 0x00000020; 

#endif

        }

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    case 0x8000000A:

        *eax = 0x00000001; 

        *ebx = 0x00000010; 

        *ecx = 0;

        *edx = 0; 

        break;

    default:

        

        *eax = 0;

        *ebx = 0;

        *ecx = 0;

        *edx = 0;

        break;

    }

}

void FUNC_0(CPUX86State *VAR_0, uint32_t VAR_1,

                   uint32_t *VAR_2, uint32_t *VAR_3,

                   uint32_t *VAR_4, uint32_t *VAR_5)

{

    

    if (VAR_1 & 0x80000000) {

        if (VAR_1 > VAR_0->cpuid_xlevel)

            VAR_1 = VAR_0->cpuid_level;

    } else {

        if (VAR_1 > VAR_0->cpuid_level)

            VAR_1 = VAR_0->cpuid_level;

    }



    switch(VAR_1) {

    case 0:

        *VAR_2 = VAR_0->cpuid_level;

        *VAR_3 = VAR_0->cpuid_vendor1;

        *VAR_5 = VAR_0->cpuid_vendor2;

        *VAR_4 = VAR_0->cpuid_vendor3;



        







        if (kvm_enabled())

            host_cpuid(0, NULL, VAR_3, VAR_4, VAR_5);

        break;

    case 1:

        *VAR_2 = VAR_0->cpuid_version;

        *VAR_3 = (VAR_0->cpuid_apic_id << 24) | 8 << 8; 

        *VAR_4 = VAR_0->cpuid_ext_features;

        *VAR_5 = VAR_0->cpuid_features;



        

        if (kvm_enabled())

            *VAR_4 |= (1 << 31);

        break;

    case 2:

        

        *VAR_2 = 1;

        *VAR_3 = 0;

        *VAR_4 = 0;

        *VAR_5 = 0x2c307d;

        break;

    case 4:

        

        switch (*VAR_4) {

            case 0: 

                *VAR_2 = 0x0000121;

                *VAR_3 = 0x1c0003f;

                *VAR_4 = 0x000003f;

                *VAR_5 = 0x0000001;

                break;

            case 1: 

                *VAR_2 = 0x0000122;

                *VAR_3 = 0x1c0003f;

                *VAR_4 = 0x000003f;

                *VAR_5 = 0x0000001;

                break;

            case 2: 

                *VAR_2 = 0x0000143;

                *VAR_3 = 0x3c0003f;

                *VAR_4 = 0x0000fff;

                *VAR_5 = 0x0000001;

                break;

            default: 

                *VAR_2 = 0;

                *VAR_3 = 0;

                *VAR_4 = 0;

                *VAR_5 = 0;

                break;

        }



        break;

    case 5:

        

        *VAR_2 = 0; 

        *VAR_3 = 0; 

        *VAR_4 = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE;

        *VAR_5 = 0;

        break;

    case 6:

        

        *VAR_2 = 0;

        *VAR_3 = 0;

        *VAR_4 = 0;

        *VAR_5 = 0;

        break;

    case 9:

        

        *VAR_2 = 0; 

        *VAR_3 = 0;

        *VAR_4 = 0;

        *VAR_5 = 0;

        break;

    case 0xA:

        

        *VAR_2 = 0;

        *VAR_3 = 0;

        *VAR_4 = 0;

        *VAR_5 = 0;

        break;

    case 0x80000000:

        *VAR_2 = VAR_0->cpuid_xlevel;

        *VAR_3 = VAR_0->cpuid_vendor1;

        *VAR_5 = VAR_0->cpuid_vendor2;

        *VAR_4 = VAR_0->cpuid_vendor3;

        break;

    case 0x80000001:

        *VAR_2 = VAR_0->cpuid_features;

        *VAR_3 = 0;

        *VAR_4 = VAR_0->cpuid_ext3_features;

        *VAR_5 = VAR_0->cpuid_ext2_features;



        if (kvm_enabled()) {

            uint32_t h_eax, h_edx;



            host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx);



            



            

            if ((h_edx & 0x20000000) == 0 )

                *VAR_5 &= ~0x20000000;

            

            if ((h_edx & 0x00000800) == 0)

                *VAR_5 &= ~0x00000800;

            

            if ((h_edx & 0x00100000) == 0)

                *VAR_5 &= ~0x00100000;



            



            

            *VAR_4 &= ~4UL;

            

            *VAR_5 = ~0xc0000000;

        }

        break;

    case 0x80000002:

    case 0x80000003:

    case 0x80000004:

        *VAR_2 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 0];

        *VAR_3 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 1];

        *VAR_4 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 2];

        *VAR_5 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 3];

        break;

    case 0x80000005:

        

        *VAR_2 = 0x01ff01ff;

        *VAR_3 = 0x01ff01ff;

        *VAR_4 = 0x40020140;

        *VAR_5 = 0x40020140;

        break;

    case 0x80000006:

        

        *VAR_2 = 0;

        *VAR_3 = 0x42004200;

        *VAR_4 = 0x02008140;

        *VAR_5 = 0;

        break;

    case 0x80000008:

        

 

        if (VAR_0->cpuid_ext2_features & CPUID_EXT2_LM) {

            

#if defined(USE_KQEMU)

            *VAR_2 = 0x00003020;	

#else



            *VAR_2 = 0x00003028;	

#endif

        } else {

#if defined(USE_KQEMU)

            *VAR_2 = 0x00000020;	

#else

            if (VAR_0->cpuid_features & CPUID_PSE36)

                *VAR_2 = 0x00000024; 

            else

                *VAR_2 = 0x00000020; 

#endif

        }

        *VAR_3 = 0;

        *VAR_4 = 0;

        *VAR_5 = 0;

        break;

    case 0x8000000A:

        *VAR_2 = 0x00000001; 

        *VAR_3 = 0x00000010; 

        *VAR_4 = 0;

        *VAR_5 = 0; 

        break;

    default:

        

        *VAR_2 = 0;

        *VAR_3 = 0;

        *VAR_4 = 0;

        *VAR_5 = 0;

        break;

    }

}

void FUNC_0(CPUX86State *VAR_0, uint32_t VAR_1,
uint32_t *VAR_2, uint32_t *VAR_3,
uint32_t *VAR_4, uint32_t *VAR_5)
{ if (VAR_1 & 0x80000000) { if (VAR_1 > VAR_0->cpuid_xlevel)
VAR_1 = VAR_0->cpuid_level; } else { if (VAR_1 > VAR_0->cpuid_level)
VAR_1 = VAR_0->cpuid_level; } switch(VAR_1) { case 0:
*VAR_2 = VAR_0->cpuid_level; *VAR_3 = VAR_0->cpuid_vendor1; *VAR_5 = VAR_0->cpuid_vendor2; *VAR_4 = VAR_0->cpuid_vendor3; if (kvm_enabled())
host_cpuid(0, NULL, VAR_3, VAR_4, VAR_5); break; case 1:
*VAR_2 = VAR_0->cpuid_version; *VAR_3 = (VAR_0->cpuid_apic_id << 24) | 8 << 8; *VAR_4 = VAR_0->cpuid_ext_features; *VAR_5 = VAR_0->cpuid_features; if (kvm_enabled())
*VAR_4 |= (1 << 31); break; case 2:
*VAR_2 = 1; *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0x2c307d; break; case 4:
switch (*VAR_4) { case 0:
*VAR_2 = 0x0000121; *VAR_3 = 0x1c0003f; *VAR_4 = 0x000003f; *VAR_5 = 0x0000001; break; case 1:
*VAR_2 = 0x0000122; *VAR_3 = 0x1c0003f; *VAR_4 = 0x000003f; *VAR_5 = 0x0000001; break; case 2:
*VAR_2 = 0x0000143; *VAR_3 = 0x3c0003f; *VAR_4 = 0x0000fff; *VAR_5 = 0x0000001; break; default:
*VAR_2 = 0; *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0; break; } break; case 5:
*VAR_2 = 0; *VAR_3 = 0; *VAR_4 = CPUID_MWAIT_EMX | CPUID_MWAIT_IBE; *VAR_5 = 0; break; case 6:
*VAR_2 = 0; *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0; break; case 9:
*VAR_2 = 0; *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0; break; case 0xA:
*VAR_2 = 0; *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0; break; case 0x80000000:
*VAR_2 = VAR_0->cpuid_xlevel; *VAR_3 = VAR_0->cpuid_vendor1; *VAR_5 = VAR_0->cpuid_vendor2; *VAR_4 = VAR_0->cpuid_vendor3; break; case 0x80000001:
*VAR_2 = VAR_0->cpuid_features; *VAR_3 = 0; *VAR_4 = VAR_0->cpuid_ext3_features; *VAR_5 = VAR_0->cpuid_ext2_features; if (kvm_enabled()) { uint32_t h_eax, h_edx; host_cpuid(0x80000001, &h_eax, NULL, NULL, &h_edx); if ((h_edx & 0x20000000) == 0 )
*VAR_5 &= ~0x20000000; if ((h_edx & 0x00000800) == 0)
*VAR_5 &= ~0x00000800; if ((h_edx & 0x00100000) == 0)
*VAR_5 &= ~0x00100000; *VAR_4 &= ~4UL; *VAR_5 = ~0xc0000000; } break; case 0x80000002:
case 0x80000003:
case 0x80000004:
*VAR_2 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 0]; *VAR_3 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 1]; *VAR_4 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 2]; *VAR_5 = VAR_0->cpuid_model[(VAR_1 - 0x80000002) * 4 + 3]; break; case 0x80000005:
*VAR_2 = 0x01ff01ff; *VAR_3 = 0x01ff01ff; *VAR_4 = 0x40020140; *VAR_5 = 0x40020140; break; case 0x80000006:
*VAR_2 = 0; *VAR_3 = 0x42004200; *VAR_4 = 0x02008140; *VAR_5 = 0; break; case 0x80000008:
if (VAR_0->cpuid_ext2_features & CPUID_EXT2_LM) { #if defined(USE_KQEMU)
*VAR_2 = 0x00003020; #else
*VAR_2 = 0x00003028; #endif
} else { #if defined(USE_KQEMU)
*VAR_2 = 0x00000020; #else
if (VAR_0->cpuid_features & CPUID_PSE36)
*VAR_2 = 0x00000024; else
*VAR_2 = 0x00000020; #endif
} *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0; break; case 0x8000000A:
*VAR_2 = 0x00000001; *VAR_3 = 0x00000010; *VAR_4 = 0; *VAR_5 = 0; break; default:
*VAR_2 = 0; *VAR_3 = 0; *VAR_4 = 0; *VAR_5 = 0; break; } }