1/* 2 * Copyright (C) 2007-2022 Free Software Foundation, Inc. 3 * 4 * This file is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License as published by the 6 * Free Software Foundation; either version 3, or (at your option) any 7 * later version. 8 * 9 * This file is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 * 14 * Under Section 7 of GPL version 3, you are granted additional 15 * permissions described in the GCC Runtime Library Exception, version 16 * 3.1, as published by the Free Software Foundation. 17 * 18 * You should have received a copy of the GNU General Public License and 19 * a copy of the GCC Runtime Library Exception along with this program; 20 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 21 * <http://www.gnu.org/licenses/>. 22 */ 23 24#ifndef _CPUID_H_INCLUDED 25#define _CPUID_H_INCLUDED 26 27/* %eax */ 28#define bit_AVXVNNI (1 << 4) 29#define bit_AVX512BF16 (1 << 5) 30#define bit_HRESET (1 << 22) 31 32/* %ecx */ 33#define bit_SSE3 (1 << 0) 34#define bit_PCLMUL (1 << 1) 35#define bit_LZCNT (1 << 5) 36#define bit_SSSE3 (1 << 9) 37#define bit_FMA (1 << 12) 38#define bit_CMPXCHG16B (1 << 13) 39#define bit_SSE4_1 (1 << 19) 40#define bit_SSE4_2 (1 << 20) 41#define bit_MOVBE (1 << 22) 42#define bit_POPCNT (1 << 23) 43#define bit_AES (1 << 25) 44#define bit_XSAVE (1 << 26) 45#define bit_OSXSAVE (1 << 27) 46#define bit_AVX (1 << 28) 47#define bit_F16C (1 << 29) 48#define bit_RDRND (1 << 30) 49 50/* %edx */ 51#define bit_CMPXCHG8B (1 << 8) 52#define bit_CMOV (1 << 15) 53#define bit_MMX (1 << 23) 54#define bit_FXSAVE (1 << 24) 55#define bit_SSE (1 << 25) 56#define bit_SSE2 (1 << 26) 57 58/* Extended Features (%eax == 0x80000001) */ 59/* %ecx */ 60#define bit_LAHF_LM (1 << 0) 61#define bit_ABM (1 << 5) 62#define bit_SSE4a (1 << 6) 63#define bit_PRFCHW (1 << 8) 64#define bit_XOP (1 << 11) 65#define bit_LWP (1 << 15) 66#define bit_FMA4 (1 << 16) 67#define bit_TBM (1 << 21) 68#define bit_MWAITX (1 << 29) 69 70/* %edx */ 71#define bit_MMXEXT (1 << 22) 72#define bit_LM (1 << 29) 73#define bit_3DNOWP (1 << 30) 74#define bit_3DNOW (1u << 31) 75 76/* %ebx */ 77#define bit_CLZERO (1 << 0) 78#define bit_WBNOINVD (1 << 9) 79 80/* Extended Features (%eax == 7) */ 81/* %ebx */ 82#define bit_FSGSBASE (1 << 0) 83#define bit_SGX (1 << 2) 84#define bit_BMI (1 << 3) 85#define bit_HLE (1 << 4) 86#define bit_AVX2 (1 << 5) 87#define bit_BMI2 (1 << 8) 88#define bit_RTM (1 << 11) 89#define bit_AVX512F (1 << 16) 90#define bit_AVX512DQ (1 << 17) 91#define bit_RDSEED (1 << 18) 92#define bit_ADX (1 << 19) 93#define bit_AVX512IFMA (1 << 21) 94#define bit_CLFLUSHOPT (1 << 23) 95#define bit_CLWB (1 << 24) 96#define bit_AVX512PF (1 << 26) 97#define bit_AVX512ER (1 << 27) 98#define bit_AVX512CD (1 << 28) 99#define bit_SHA (1 << 29) 100#define bit_AVX512BW (1 << 30) 101#define bit_AVX512VL (1u << 31) 102 103/* %ecx */ 104#define bit_PREFETCHWT1 (1 << 0) 105#define bit_AVX512VBMI (1 << 1) 106#define bit_PKU (1 << 3) 107#define bit_OSPKE (1 << 4) 108#define bit_WAITPKG (1 << 5) 109#define bit_AVX512VBMI2 (1 << 6) 110#define bit_SHSTK (1 << 7) 111#define bit_GFNI (1 << 8) 112#define bit_VAES (1 << 9) 113#define bit_AVX512VNNI (1 << 11) 114#define bit_VPCLMULQDQ (1 << 10) 115#define bit_AVX512BITALG (1 << 12) 116#define bit_AVX512VPOPCNTDQ (1 << 14) 117#define bit_RDPID (1 << 22) 118#define bit_MOVDIRI (1 << 27) 119#define bit_MOVDIR64B (1 << 28) 120#define bit_ENQCMD (1 << 29) 121#define bit_CLDEMOTE (1 << 25) 122#define bit_KL (1 << 23) 123 124/* %edx */ 125#define bit_AVX5124VNNIW (1 << 2) 126#define bit_AVX5124FMAPS (1 << 3) 127#define bit_AVX512VP2INTERSECT (1 << 8) 128#define bit_AVX512FP16 (1 << 23) 129#define bit_IBT (1 << 20) 130#define bit_UINTR (1 << 5) 131#define bit_PCONFIG (1 << 18) 132#define bit_SERIALIZE (1 << 14) 133#define bit_TSXLDTRK (1 << 16) 134#define bit_AMX_BF16 (1 << 22) 135#define bit_AMX_TILE (1 << 24) 136#define bit_AMX_INT8 (1 << 25) 137 138/* Extended State Enumeration Sub-leaf (%eax == 0xd, %ecx == 1) */ 139#define bit_XSAVEOPT (1 << 0) 140#define bit_XSAVEC (1 << 1) 141#define bit_XSAVES (1 << 3) 142 143/* PT sub leaf (%eax == 0x14, %ecx == 0) */ 144/* %ebx */ 145#define bit_PTWRITE (1 << 4) 146 147/* Keylocker leaf (%eax == 0x19) */ 148/* %ebx */ 149#define bit_AESKLE ( 1<<0 ) 150#define bit_WIDEKL ( 1<<2 ) 151 152 153/* Signatures for different CPU implementations as returned in uses 154 of cpuid with level 0. */ 155#define signature_AMD_ebx 0x68747541 156#define signature_AMD_ecx 0x444d4163 157#define signature_AMD_edx 0x69746e65 158 159#define signature_CENTAUR_ebx 0x746e6543 160#define signature_CENTAUR_ecx 0x736c7561 161#define signature_CENTAUR_edx 0x48727561 162 163#define signature_CYRIX_ebx 0x69727943 164#define signature_CYRIX_ecx 0x64616574 165#define signature_CYRIX_edx 0x736e4978 166 167#define signature_INTEL_ebx 0x756e6547 168#define signature_INTEL_ecx 0x6c65746e 169#define signature_INTEL_edx 0x49656e69 170 171#define signature_TM1_ebx 0x6e617254 172#define signature_TM1_ecx 0x55504361 173#define signature_TM1_edx 0x74656d73 174 175#define signature_TM2_ebx 0x756e6547 176#define signature_TM2_ecx 0x3638784d 177#define signature_TM2_edx 0x54656e69 178 179#define signature_NSC_ebx 0x646f6547 180#define signature_NSC_ecx 0x43534e20 181#define signature_NSC_edx 0x79622065 182 183#define signature_NEXGEN_ebx 0x4778654e 184#define signature_NEXGEN_ecx 0x6e657669 185#define signature_NEXGEN_edx 0x72446e65 186 187#define signature_RISE_ebx 0x65736952 188#define signature_RISE_ecx 0x65736952 189#define signature_RISE_edx 0x65736952 190 191#define signature_SIS_ebx 0x20536953 192#define signature_SIS_ecx 0x20536953 193#define signature_SIS_edx 0x20536953 194 195#define signature_UMC_ebx 0x20434d55 196#define signature_UMC_ecx 0x20434d55 197#define signature_UMC_edx 0x20434d55 198 199#define signature_VIA_ebx 0x20414956 200#define signature_VIA_ecx 0x20414956 201#define signature_VIA_edx 0x20414956 202 203#define signature_VORTEX_ebx 0x74726f56 204#define signature_VORTEX_ecx 0x436f5320 205#define signature_VORTEX_edx 0x36387865 206 207#ifndef __x86_64__ 208/* At least one cpu (Winchip 2) does not set %ebx and %ecx 209 for cpuid leaf 1. Forcibly zero the two registers before 210 calling cpuid as a precaution. */ 211#define __cpuid(level, a, b, c, d) \ 212 do { \ 213 if (__builtin_constant_p (level) && (level) != 1) \ 214 __asm__ __volatile__ ("cpuid\n\t" \ 215 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 216 : "0" (level)); \ 217 else \ 218 __asm__ __volatile__ ("cpuid\n\t" \ 219 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 220 : "0" (level), "1" (0), "2" (0)); \ 221 } while (0) 222#else 223#define __cpuid(level, a, b, c, d) \ 224 __asm__ __volatile__ ("cpuid\n\t" \ 225 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 226 : "0" (level)) 227#endif 228 229#define __cpuid_count(level, count, a, b, c, d) \ 230 __asm__ __volatile__ ("cpuid\n\t" \ 231 : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ 232 : "0" (level), "2" (count)) 233 234 235/* Return highest supported input value for cpuid instruction. ext can 236 be either 0x0 or 0x80000000 to return highest supported value for 237 basic or extended cpuid information. Function returns 0 if cpuid 238 is not supported or whatever cpuid returns in eax register. If sig 239 pointer is non-null, then first four bytes of the signature 240 (as found in ebx register) are returned in location pointed by sig. */ 241 242static __inline unsigned int 243__get_cpuid_max (unsigned int __ext, unsigned int *__sig) 244{ 245 unsigned int __eax, __ebx, __ecx, __edx; 246 247#ifndef __x86_64__ 248 /* See if we can use cpuid. On AMD64 we always can. */ 249#if __GNUC__ >= 3 250 __asm__ ("pushf{l|d}\n\t" 251 "pushf{l|d}\n\t" 252 "pop{l}\t%0\n\t" 253 "mov{l}\t{%0, %1|%1, %0}\n\t" 254 "xor{l}\t{%2, %0|%0, %2}\n\t" 255 "push{l}\t%0\n\t" 256 "popf{l|d}\n\t" 257 "pushf{l|d}\n\t" 258 "pop{l}\t%0\n\t" 259 "popf{l|d}\n\t" 260 : "=&r" (__eax), "=&r" (__ebx) 261 : "i" (0x00200000)); 262#else 263/* Host GCCs older than 3.0 weren't supporting Intel asm syntax 264 nor alternatives in i386 code. */ 265 __asm__ ("pushfl\n\t" 266 "pushfl\n\t" 267 "popl\t%0\n\t" 268 "movl\t%0, %1\n\t" 269 "xorl\t%2, %0\n\t" 270 "pushl\t%0\n\t" 271 "popfl\n\t" 272 "pushfl\n\t" 273 "popl\t%0\n\t" 274 "popfl\n\t" 275 : "=&r" (__eax), "=&r" (__ebx) 276 : "i" (0x00200000)); 277#endif 278 279 if (!((__eax ^ __ebx) & 0x00200000)) 280 return 0; 281#endif 282 283 /* Host supports cpuid. Return highest supported cpuid input value. */ 284 __cpuid (__ext, __eax, __ebx, __ecx, __edx); 285 286 if (__sig) 287 *__sig = __ebx; 288 289 return __eax; 290} 291 292/* Return cpuid data for requested cpuid leaf, as found in returned 293 eax, ebx, ecx and edx registers. The function checks if cpuid is 294 supported and returns 1 for valid cpuid information or 0 for 295 unsupported cpuid leaf. All pointers are required to be non-null. */ 296 297static __inline int 298__get_cpuid (unsigned int __leaf, 299 unsigned int *__eax, unsigned int *__ebx, 300 unsigned int *__ecx, unsigned int *__edx) 301{ 302 unsigned int __ext = __leaf & 0x80000000; 303 unsigned int __maxlevel = __get_cpuid_max (__ext, 0); 304 305 if (__maxlevel == 0 || __maxlevel < __leaf) 306 return 0; 307 308 __cpuid (__leaf, *__eax, *__ebx, *__ecx, *__edx); 309 return 1; 310} 311 312/* Same as above, but sub-leaf can be specified. */ 313 314static __inline int 315__get_cpuid_count (unsigned int __leaf, unsigned int __subleaf, 316 unsigned int *__eax, unsigned int *__ebx, 317 unsigned int *__ecx, unsigned int *__edx) 318{ 319 unsigned int __ext = __leaf & 0x80000000; 320 unsigned int __maxlevel = __get_cpuid_max (__ext, 0); 321 322 if (__maxlevel == 0 || __maxlevel < __leaf) 323 return 0; 324 325 __cpuid_count (__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx); 326 return 1; 327} 328 329static __inline void 330__cpuidex (int __cpuid_info[4], int __leaf, int __subleaf) 331{ 332 __cpuid_count (__leaf, __subleaf, __cpuid_info[0], __cpuid_info[1], 333 __cpuid_info[2], __cpuid_info[3]); 334} 335 336#endif /* _CPUID_H_INCLUDED */ 337