diff --git a/mono/utils/mono-hwcap-x86.c b/mono/utils/mono-hwcap-x86.c index cc36bd927e93..642613ba53c7 100644 --- a/mono/utils/mono-hwcap-x86.c +++ b/mono/utils/mono-hwcap-x86.c @@ -24,63 +24,8 @@ #include #endif -#if defined(TARGET_X86) -#include "mono/utils/mono-codeman.h" - -typedef void (* CpuidFunc) (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx); - -static MonoCodeManager *code_man; -static CpuidFunc func; - -#if defined(__native_client__) -static const guchar cpuid_impl [] = { - 0x55, /* push %ebp */ - 0x89, 0xe5, /* mov %esp, %ebp */ - 0x53, /* push %ebx */ - 0x8b, 0x45, 0x08, /* mov 0x8 (%ebp), %eax */ - 0x0f, 0xa2, /* cpuid */ - 0x50, /* push %eax */ - 0x8b, 0x45, 0x10, /* mov 0x10 (%ebp), %eax */ - 0x89, 0x18, /* mov %ebx, (%eax) */ - 0x8b, 0x45, 0x14, /* mov 0x14 (%ebp), %eax */ - 0x89, 0x08, /* mov %ecx, (%eax) */ - 0x8b, 0x45, 0x18, /* mov 0x18 (%ebp), %eax */ - 0x89, 0x10, /* mov %edx, (%eax) */ - 0x58, /* pop %eax */ - 0x8b, 0x55, 0x0c, /* mov 0xc (%ebp), %edx */ - 0x89, 0x02, /* mov %eax, (%edx) */ - 0x5b, /* pop %ebx */ - 0xc9, /* leave */ - 0x59, 0x83, 0xe1, 0xe0, 0xff, 0xe1, /* naclret */ - 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, /* padding, to provide bundle aligned version */ - 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, 0xf4, - 0xf4, -}; -#else -static const guchar cpuid_impl [] = { - 0x55, /* push %ebp */ - 0x89, 0xe5, /* mov %esp, %ebp */ - 0x53, /* push %ebx */ - 0x8b, 0x45, 0x08, /* mov 0x8 (%ebp), %eax */ - 0x0f, 0xa2, /* cpuid */ - 0x50, /* push %eax */ - 0x8b, 0x45, 0x10, /* mov 0x10 (%ebp), %eax */ - 0x89, 0x18, /* mov %ebx, (%eax) */ - 0x8b, 0x45, 0x14, /* mov 0x14 (%ebp), %eax */ - 0x89, 0x08, /* mov %ecx, (%eax) */ - 0x8b, 0x45, 0x18, /* mov 0x18 (%ebp), %eax */ - 0x89, 0x10, /* mov %edx, (%eax) */ - 0x58, /* pop %eax */ - 0x8b, 0x55, 0x0c, /* mov 0xc (%ebp), %edx */ - 0x89, 0x02, /* mov %eax, (%edx) */ - 0x5b, /* pop %ebx */ - 0xc9, /* leave */ - 0xc3, /* ret */ -}; -#endif - +#if defined(_MSC_VER) +#include #endif gboolean mono_hwcap_x86_is_xen = FALSE; @@ -97,13 +42,8 @@ gboolean mono_hwcap_x86_has_sse4a = FALSE; static gboolean cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx) { + /* First, make sure we can use cpuid if we're on 32-bit. */ #if defined(TARGET_X86) - -#if defined(__native_client__) - func (id, p_eax, p_ebx, p_ecx, p_edx); - - return TRUE; -#else gboolean have_cpuid = FALSE; #if defined(_MSC_VER) @@ -122,34 +62,29 @@ cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx) } #else __asm__ __volatile__ ( - "pushfl\n" - "popl %%eax\n" - "movl %%eax, %%edx\n" - "xorl $0x200000, %%eax\n" - "pushl %%eax\n" - "popfl\n" - "pushfl\n" - "popl %%eax\n" - "xorl %%edx, %%eax\n" - "andl $0x200000, %%eax\n" - "movl %%eax, %0" + "pushfl\n\t" + "popl\t%%eax\n\t" + "movl\t%%eax, %%edx\n\t" + "xorl\t$0x200000, %%eax\n\t" + "pushl\t%%eax\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl\t%%eax\n\t" + "xorl\t%%edx, %%eax\n\t" + "andl\t$0x200000, %%eax\n\t" + "movl\t%%eax, %0\n\t" : "=r" (have_cpuid) : : "%eax", "%edx" ); #endif - if (have_cpuid) { - func (id, p_eax, p_ebx, p_ecx, p_edx); - - return TRUE; - } - - return FALSE; + if (!have_cpuid) + return FALSE; #endif -#else - + /* Now issue the actual cpuid instruction. We can use + MSVC's __cpuid on both 32-bit and 64-bit. */ #if defined(_MSC_VER) int info [4]; __cpuid (info, id); @@ -157,42 +92,30 @@ cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx) *p_ebx = info [1]; *p_ecx = info [2]; *p_edx = info [3]; +#elif defined(TARGET_X86) + /* This complicated stuff is necessary because EBX + may be used by the compiler in PIC mode. */ + __asm__ __volatile__ ( + "xchgl\t%%ebx, %k1\n\t" + "cpuid\n\t" + "xchgl\t%%ebx, %k1\n\t" + : "=a" (*p_eax), "=&r" (*p_ebx), "=c" (*p_ecx), "=d" (*p_edx) + : "0" (id) + ); #else __asm__ __volatile__ ( - "cpuid" + "cpuid\n\t" : "=a" (*p_eax), "=b" (*p_ebx), "=c" (*p_ecx), "=d" (*p_edx) : "a" (id) ); #endif return TRUE; -#endif } void mono_hwcap_arch_init (void) { -#if defined(TARGET_X86) - code_man = mono_code_manager_new (); - -#if defined(__native_client__) - gpointer ptr = mono_code_manager_reserve (code_man, sizeof (cpuid_impl)); - memcpy (ptr, cpuid_impl, sizeof (cpuid_impl)); - gpointer end_ptr = ptr + sizeof (cpuid_impl); - - guint8 *code = nacl_code_manager_get_dest (code_man, ptr); - mono_code_manager_commit (code_man, ptr, sizeof (cpuid_impl), end_ptr - ptr); - - func = (CpuidFunc) code; -#else - gpointer ptr = mono_code_manager_reserve (code_man, sizeof (cpuid_impl)); - memcpy (ptr, cpuid_impl, sizeof (cpuid_impl)); - - func = (CpuidFunc) ptr; -#endif - -#endif - int eax, ebx, ecx, edx; if (cpuid (1, &eax, &ebx, &ecx, &edx)) { @@ -231,10 +154,6 @@ mono_hwcap_arch_init (void) } } -#if defined(TARGET_X86) - mono_code_manager_destroy (code_man); -#endif - #if defined(HAVE_UNISTD_H) mono_hwcap_x86_is_xen = !access ("/proc/xen", F_OK); #endif