2 * mono-hwcap-x86.c: x86 hardware feature detection
5 * Alex Rønne Petersen (alexrp@xamarin.com)
6 * Elijah Taylor (elijahtaylor@google.com)
7 * Miguel de Icaza (miguel@xamarin.com)
8 * Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
9 * Paolo Molaro (lupus@xamarin.com)
10 * Rodrigo Kumpera (kumpera@gmail.com)
11 * Sebastien Pouliot (sebastien@xamarin.com)
12 * Zoltan Varga (vargaz@xamarin.com)
14 * Copyright 2003 Ximian, Inc.
15 * Copyright 2003-2011 Novell, Inc
16 * Copyright 2006 Broadcom
17 * Copyright 2007-2008 Andreas Faerber
18 * Copyright 2011-2013 Xamarin Inc
19 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
22 #include "mono/utils/mono-hwcap.h"
24 #if defined(HAVE_UNISTD_H)
32 cpuid (int id
, int *p_eax
, int *p_ebx
, int *p_ecx
, int *p_edx
)
38 /* First, make sure we can use cpuid if we're on 32-bit. */
39 #if defined(TARGET_X86)
40 gboolean have_cpuid
= FALSE
;
57 __asm__
__volatile__ (
60 "movl\t%%eax, %%edx\n\t"
61 "xorl\t$0x200000, %%eax\n\t"
66 "xorl\t%%edx, %%eax\n\t"
67 "andl\t$0x200000, %%eax\n\t"
79 /* Now issue the actual cpuid instruction. We can use
80 MSVC's __cpuid on both 32-bit and 64-bit. */
87 #elif defined(TARGET_X86)
88 /* This complicated stuff is necessary because EBX
89 may be used by the compiler in PIC mode. */
90 __asm__
__volatile__ (
91 "xchgl\t%%ebx, %k1\n\t"
93 "xchgl\t%%ebx, %k1\n\t"
94 : "=a" (*p_eax
), "=&r" (*p_ebx
), "=c" (*p_ecx
), "=d" (*p_edx
)
98 __asm__
__volatile__ (
100 : "=a" (*p_eax
), "=b" (*p_ebx
), "=c" (*p_ecx
), "=d" (*p_edx
)
109 mono_hwcap_arch_init (void)
111 int eax
, ebx
, ecx
, edx
;
113 if (cpuid (1, &eax
, &ebx
, &ecx
, &edx
)) {
114 if (edx
& (1 << 15)) {
115 mono_hwcap_x86_has_cmov
= TRUE
;
118 mono_hwcap_x86_has_fcmov
= TRUE
;
122 mono_hwcap_x86_has_sse1
= TRUE
;
125 mono_hwcap_x86_has_sse2
= TRUE
;
128 mono_hwcap_x86_has_sse3
= TRUE
;
131 mono_hwcap_x86_has_ssse3
= TRUE
;
134 mono_hwcap_x86_has_sse41
= TRUE
;
137 mono_hwcap_x86_has_sse42
= TRUE
;
140 if (cpuid (0x80000000, &eax
, &ebx
, &ecx
, &edx
)) {
141 if ((unsigned int) eax
>= 0x80000001 && ebx
== 0x68747541 && ecx
== 0x444D4163 && edx
== 0x69746E65) {
142 if (cpuid (0x80000001, &eax
, &ebx
, &ecx
, &edx
)) {
144 mono_hwcap_x86_has_sse4a
= TRUE
;
149 #if defined(HAVE_UNISTD_H)
150 mono_hwcap_x86_is_xen
= !access ("/proc/xen", F_OK
);