1234287Sdim/*===---- cpuid.h - X86 cpu model detection --------------------------------=== 2234287Sdim * 3353358Sdim * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim * See https://llvm.org/LICENSE.txt for license information. 5353358Sdim * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6234287Sdim * 7234287Sdim *===-----------------------------------------------------------------------=== 8234287Sdim */ 9234287Sdim 10234287Sdim#if !(__x86_64__ || __i386__) 11234287Sdim#error this header is for x86 only 12234287Sdim#endif 13234287Sdim 14280031Sdim/* Responses identification request with %eax 0 */ 15280031Sdim/* AMD: "AuthenticAMD" */ 16280031Sdim#define signature_AMD_ebx 0x68747541 17280031Sdim#define signature_AMD_edx 0x69746e65 18280031Sdim#define signature_AMD_ecx 0x444d4163 19280031Sdim/* CENTAUR: "CentaurHauls" */ 20280031Sdim#define signature_CENTAUR_ebx 0x746e6543 21280031Sdim#define signature_CENTAUR_edx 0x48727561 22280031Sdim#define signature_CENTAUR_ecx 0x736c7561 23280031Sdim/* CYRIX: "CyrixInstead" */ 24280031Sdim#define signature_CYRIX_ebx 0x69727943 25280031Sdim#define signature_CYRIX_edx 0x736e4978 26280031Sdim#define signature_CYRIX_ecx 0x64616574 27280031Sdim/* INTEL: "GenuineIntel" */ 28280031Sdim#define signature_INTEL_ebx 0x756e6547 29280031Sdim#define signature_INTEL_edx 0x49656e69 30280031Sdim#define signature_INTEL_ecx 0x6c65746e 31280031Sdim/* TM1: "TransmetaCPU" */ 32280031Sdim#define signature_TM1_ebx 0x6e617254 33280031Sdim#define signature_TM1_edx 0x74656d73 34280031Sdim#define signature_TM1_ecx 0x55504361 35280031Sdim/* TM2: "GenuineTMx86" */ 36280031Sdim#define signature_TM2_ebx 0x756e6547 37280031Sdim#define signature_TM2_edx 0x54656e69 38280031Sdim#define signature_TM2_ecx 0x3638784d 39280031Sdim/* NSC: "Geode by NSC" */ 40280031Sdim#define signature_NSC_ebx 0x646f6547 41360784Sdim#define signature_NSC_edx 0x79622065 42360784Sdim#define signature_NSC_ecx 0x43534e20 43280031Sdim/* NEXGEN: "NexGenDriven" */ 44280031Sdim#define signature_NEXGEN_ebx 0x4778654e 45280031Sdim#define signature_NEXGEN_edx 0x72446e65 46280031Sdim#define signature_NEXGEN_ecx 0x6e657669 47280031Sdim/* RISE: "RiseRiseRise" */ 48280031Sdim#define signature_RISE_ebx 0x65736952 49280031Sdim#define signature_RISE_edx 0x65736952 50280031Sdim#define signature_RISE_ecx 0x65736952 51280031Sdim/* SIS: "SiS SiS SiS " */ 52280031Sdim#define signature_SIS_ebx 0x20536953 53280031Sdim#define signature_SIS_edx 0x20536953 54280031Sdim#define signature_SIS_ecx 0x20536953 55280031Sdim/* UMC: "UMC UMC UMC " */ 56280031Sdim#define signature_UMC_ebx 0x20434d55 57280031Sdim#define signature_UMC_edx 0x20434d55 58280031Sdim#define signature_UMC_ecx 0x20434d55 59280031Sdim/* VIA: "VIA VIA VIA " */ 60280031Sdim#define signature_VIA_ebx 0x20414956 61280031Sdim#define signature_VIA_edx 0x20414956 62280031Sdim#define signature_VIA_ecx 0x20414956 63280031Sdim/* VORTEX: "Vortex86 SoC" */ 64280031Sdim#define signature_VORTEX_ebx 0x74726f56 65280031Sdim#define signature_VORTEX_edx 0x36387865 66280031Sdim#define signature_VORTEX_ecx 0x436f5320 67280031Sdim 68321369Sdim/* Features in %ecx for leaf 1 */ 69253802Sdim#define bit_SSE3 0x00000001 70253802Sdim#define bit_PCLMULQDQ 0x00000002 71309124Sdim#define bit_PCLMUL bit_PCLMULQDQ /* for gcc compat */ 72253802Sdim#define bit_DTES64 0x00000004 73253802Sdim#define bit_MONITOR 0x00000008 74253802Sdim#define bit_DSCPL 0x00000010 75253802Sdim#define bit_VMX 0x00000020 76253802Sdim#define bit_SMX 0x00000040 77253802Sdim#define bit_EIST 0x00000080 78253802Sdim#define bit_TM2 0x00000100 79253802Sdim#define bit_SSSE3 0x00000200 80253802Sdim#define bit_CNXTID 0x00000400 81253802Sdim#define bit_FMA 0x00001000 82253802Sdim#define bit_CMPXCHG16B 0x00002000 83253802Sdim#define bit_xTPR 0x00004000 84253802Sdim#define bit_PDCM 0x00008000 85253802Sdim#define bit_PCID 0x00020000 86253802Sdim#define bit_DCA 0x00040000 87253802Sdim#define bit_SSE41 0x00080000 88309124Sdim#define bit_SSE4_1 bit_SSE41 /* for gcc compat */ 89253802Sdim#define bit_SSE42 0x00100000 90309124Sdim#define bit_SSE4_2 bit_SSE42 /* for gcc compat */ 91253802Sdim#define bit_x2APIC 0x00200000 92253802Sdim#define bit_MOVBE 0x00400000 93253802Sdim#define bit_POPCNT 0x00800000 94253802Sdim#define bit_TSCDeadline 0x01000000 95253802Sdim#define bit_AESNI 0x02000000 96309124Sdim#define bit_AES bit_AESNI /* for gcc compat */ 97253802Sdim#define bit_XSAVE 0x04000000 98253802Sdim#define bit_OSXSAVE 0x08000000 99253802Sdim#define bit_AVX 0x10000000 100309124Sdim#define bit_F16C 0x20000000 101280031Sdim#define bit_RDRND 0x40000000 102253802Sdim 103321369Sdim/* Features in %edx for leaf 1 */ 104253802Sdim#define bit_FPU 0x00000001 105253802Sdim#define bit_VME 0x00000002 106253802Sdim#define bit_DE 0x00000004 107253802Sdim#define bit_PSE 0x00000008 108253802Sdim#define bit_TSC 0x00000010 109253802Sdim#define bit_MSR 0x00000020 110253802Sdim#define bit_PAE 0x00000040 111253802Sdim#define bit_MCE 0x00000080 112253802Sdim#define bit_CX8 0x00000100 113309124Sdim#define bit_CMPXCHG8B bit_CX8 /* for gcc compat */ 114253802Sdim#define bit_APIC 0x00000200 115253802Sdim#define bit_SEP 0x00000800 116253802Sdim#define bit_MTRR 0x00001000 117253802Sdim#define bit_PGE 0x00002000 118253802Sdim#define bit_MCA 0x00004000 119253802Sdim#define bit_CMOV 0x00008000 120253802Sdim#define bit_PAT 0x00010000 121253802Sdim#define bit_PSE36 0x00020000 122253802Sdim#define bit_PSN 0x00040000 123253802Sdim#define bit_CLFSH 0x00080000 124253802Sdim#define bit_DS 0x00200000 125253802Sdim#define bit_ACPI 0x00400000 126253802Sdim#define bit_MMX 0x00800000 127253802Sdim#define bit_FXSR 0x01000000 128309124Sdim#define bit_FXSAVE bit_FXSR /* for gcc compat */ 129253802Sdim#define bit_SSE 0x02000000 130253802Sdim#define bit_SSE2 0x04000000 131253802Sdim#define bit_SS 0x08000000 132253802Sdim#define bit_HTT 0x10000000 133253802Sdim#define bit_TM 0x20000000 134253802Sdim#define bit_PBE 0x80000000 135253802Sdim 136321369Sdim/* Features in %ebx for leaf 7 sub-leaf 0 */ 137253802Sdim#define bit_FSGSBASE 0x00000001 138321369Sdim#define bit_SGX 0x00000004 139321369Sdim#define bit_BMI 0x00000008 140321369Sdim#define bit_HLE 0x00000010 141321369Sdim#define bit_AVX2 0x00000020 142253802Sdim#define bit_SMEP 0x00000080 143321369Sdim#define bit_BMI2 0x00000100 144253802Sdim#define bit_ENH_MOVSB 0x00000200 145341825Sdim#define bit_INVPCID 0x00000400 146321369Sdim#define bit_RTM 0x00000800 147321369Sdim#define bit_MPX 0x00004000 148321369Sdim#define bit_AVX512F 0x00010000 149321369Sdim#define bit_AVX512DQ 0x00020000 150321369Sdim#define bit_RDSEED 0x00040000 151321369Sdim#define bit_ADX 0x00080000 152321369Sdim#define bit_AVX512IFMA 0x00200000 153321369Sdim#define bit_CLFLUSHOPT 0x00800000 154321369Sdim#define bit_CLWB 0x01000000 155321369Sdim#define bit_AVX512PF 0x04000000 156341825Sdim#define bit_AVX512ER 0x08000000 157321369Sdim#define bit_AVX512CD 0x10000000 158321369Sdim#define bit_SHA 0x20000000 159321369Sdim#define bit_AVX512BW 0x40000000 160321369Sdim#define bit_AVX512VL 0x80000000 161253802Sdim 162321369Sdim/* Features in %ecx for leaf 7 sub-leaf 0 */ 163327952Sdim#define bit_PREFTCHWT1 0x00000001 164327952Sdim#define bit_AVX512VBMI 0x00000002 165327952Sdim#define bit_PKU 0x00000004 166327952Sdim#define bit_OSPKE 0x00000010 167341825Sdim#define bit_WAITPKG 0x00000020 168327952Sdim#define bit_AVX512VBMI2 0x00000040 169327952Sdim#define bit_SHSTK 0x00000080 170327952Sdim#define bit_GFNI 0x00000100 171327952Sdim#define bit_VAES 0x00000200 172327952Sdim#define bit_VPCLMULQDQ 0x00000400 173327952Sdim#define bit_AVX512VNNI 0x00000800 174327952Sdim#define bit_AVX512BITALG 0x00001000 175321369Sdim#define bit_AVX512VPOPCNTDQ 0x00004000 176327952Sdim#define bit_RDPID 0x00400000 177341825Sdim#define bit_CLDEMOTE 0x02000000 178341825Sdim#define bit_MOVDIRI 0x08000000 179341825Sdim#define bit_MOVDIR64B 0x10000000 180353358Sdim#define bit_ENQCMD 0x20000000 181321369Sdim 182321369Sdim/* Features in %edx for leaf 7 sub-leaf 0 */ 183321369Sdim#define bit_AVX5124VNNIW 0x00000004 184321369Sdim#define bit_AVX5124FMAPS 0x00000008 185341825Sdim#define bit_PCONFIG 0x00040000 186327952Sdim#define bit_IBT 0x00100000 187321369Sdim 188353358Sdim/* Features in %eax for leaf 7 sub-leaf 1 */ 189353358Sdim#define bit_AVX512BF16 0x00000020 190353358Sdim 191321369Sdim/* Features in %eax for leaf 13 sub-leaf 1 */ 192321369Sdim#define bit_XSAVEOPT 0x00000001 193321369Sdim#define bit_XSAVEC 0x00000002 194321369Sdim#define bit_XSAVES 0x00000008 195321369Sdim 196341825Sdim/* Features in %eax for leaf 0x14 sub-leaf 0 */ 197341825Sdim#define bit_PTWRITE 0x00000010 198341825Sdim 199321369Sdim/* Features in %ecx for leaf 0x80000001 */ 200321369Sdim#define bit_LAHF_LM 0x00000001 201321369Sdim#define bit_ABM 0x00000020 202327952Sdim#define bit_LZCNT bit_ABM /* for gcc compat */ 203321369Sdim#define bit_SSE4a 0x00000040 204321369Sdim#define bit_PRFCHW 0x00000100 205321369Sdim#define bit_XOP 0x00000800 206321369Sdim#define bit_LWP 0x00008000 207321369Sdim#define bit_FMA4 0x00010000 208321369Sdim#define bit_TBM 0x00200000 209321369Sdim#define bit_MWAITX 0x20000000 210321369Sdim 211321369Sdim/* Features in %edx for leaf 0x80000001 */ 212321369Sdim#define bit_MMXEXT 0x00400000 213321369Sdim#define bit_LM 0x20000000 214321369Sdim#define bit_3DNOWP 0x40000000 215321369Sdim#define bit_3DNOW 0x80000000 216321369Sdim 217341825Sdim/* Features in %ebx for leaf 0x80000008 */ 218321369Sdim#define bit_CLZERO 0x00000001 219341825Sdim#define bit_WBNOINVD 0x00000200 220321369Sdim 221321369Sdim 222253802Sdim#if __i386__ 223321369Sdim#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \ 224280031Sdim __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ 225321369Sdim : "0"(__leaf)) 226280031Sdim 227321369Sdim#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \ 228280031Sdim __asm("cpuid" : "=a"(__eax), "=b" (__ebx), "=c"(__ecx), "=d"(__edx) \ 229321369Sdim : "0"(__leaf), "2"(__count)) 230280031Sdim#else 231280031Sdim/* x86-64 uses %rbx as the base register, so preserve it. */ 232321369Sdim#define __cpuid(__leaf, __eax, __ebx, __ecx, __edx) \ 233280031Sdim __asm(" xchgq %%rbx,%q1\n" \ 234253802Sdim " cpuid\n" \ 235280031Sdim " xchgq %%rbx,%q1" \ 236253802Sdim : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ 237321369Sdim : "0"(__leaf)) 238253802Sdim 239321369Sdim#define __cpuid_count(__leaf, __count, __eax, __ebx, __ecx, __edx) \ 240280031Sdim __asm(" xchgq %%rbx,%q1\n" \ 241253802Sdim " cpuid\n" \ 242280031Sdim " xchgq %%rbx,%q1" \ 243253802Sdim : "=a"(__eax), "=r" (__ebx), "=c"(__ecx), "=d"(__edx) \ 244321369Sdim : "0"(__leaf), "2"(__count)) 245253802Sdim#endif 246253802Sdim 247321369Sdimstatic __inline int __get_cpuid_max (unsigned int __leaf, unsigned int *__sig) 248253802Sdim{ 249253802Sdim unsigned int __eax, __ebx, __ecx, __edx; 250253802Sdim#if __i386__ 251253802Sdim int __cpuid_supported; 252253802Sdim 253253802Sdim __asm(" pushfl\n" 254253802Sdim " popl %%eax\n" 255253802Sdim " movl %%eax,%%ecx\n" 256253802Sdim " xorl $0x00200000,%%eax\n" 257253802Sdim " pushl %%eax\n" 258253802Sdim " popfl\n" 259253802Sdim " pushfl\n" 260253802Sdim " popl %%eax\n" 261253802Sdim " movl $0,%0\n" 262253802Sdim " cmpl %%eax,%%ecx\n" 263253802Sdim " je 1f\n" 264253802Sdim " movl $1,%0\n" 265253802Sdim "1:" 266253802Sdim : "=r" (__cpuid_supported) : : "eax", "ecx"); 267253802Sdim if (!__cpuid_supported) 268253802Sdim return 0; 269253802Sdim#endif 270253802Sdim 271321369Sdim __cpuid(__leaf, __eax, __ebx, __ecx, __edx); 272253802Sdim if (__sig) 273253802Sdim *__sig = __ebx; 274253802Sdim return __eax; 275253802Sdim} 276321369Sdim 277321369Sdimstatic __inline int __get_cpuid (unsigned int __leaf, unsigned int *__eax, 278321369Sdim unsigned int *__ebx, unsigned int *__ecx, 279321369Sdim unsigned int *__edx) 280321369Sdim{ 281321369Sdim unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, 0); 282321369Sdim 283321369Sdim if (__max_leaf == 0 || __max_leaf < __leaf) 284321369Sdim return 0; 285321369Sdim 286321369Sdim __cpuid(__leaf, *__eax, *__ebx, *__ecx, *__edx); 287321369Sdim return 1; 288321369Sdim} 289321369Sdim 290321369Sdimstatic __inline int __get_cpuid_count (unsigned int __leaf, 291321369Sdim unsigned int __subleaf, 292321369Sdim unsigned int *__eax, unsigned int *__ebx, 293321369Sdim unsigned int *__ecx, unsigned int *__edx) 294321369Sdim{ 295321369Sdim unsigned int __max_leaf = __get_cpuid_max(__leaf & 0x80000000, 0); 296321369Sdim 297321369Sdim if (__max_leaf == 0 || __max_leaf < __leaf) 298321369Sdim return 0; 299321369Sdim 300321369Sdim __cpuid_count(__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx); 301321369Sdim return 1; 302321369Sdim} 303