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