d35d3d349a0fb5abf237c90d3f749435a5183b73
[folly.git] / folly / CpuId.h
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef FOLLY_CPUID_H_
18 #define FOLLY_CPUID_H_
19
20 #include <cstdint>
21 #include <folly/Portability.h>
22
23 namespace folly {
24
25 /**
26  * Identification of an Intel CPU.
27  * Supports CPUID feature flags (EAX=1) and extended features (EAX=7, ECX=0).
28  * Values from http://www.intel.com/content/www/us/en/processors/processor-identification-cpuid-instruction-note.html
29  */
30 class CpuId {
31  public:
32   CpuId() {
33 #ifdef _MSC_VER
34     int reg[4];
35     __cpuid(static_cast<int*>(reg), 0);
36     const int n = reg[0];
37     if (n >= 1) {
38       __cpuid(static_cast<int*>(reg), 1);
39       f1c_ = reg[2];
40       f1d_ = reg[3];
41     }
42     if (n >= 7) {
43       __cpuidex(static_cast<int*>(reg), 7, 0);
44       f7b_ = reg[1];
45       f7c_ = reg[2];
46     }
47 #elif FOLLY_X64 || defined(__i386__)
48     uint32_t n;
49     __asm__("cpuid" : "=a"(n) : "a"(0) : "ebx", "edx", "ecx");
50     if (n >= 1) {
51       __asm__("cpuid" : "=c"(f1c_), "=d"(f1d_) : "a"(1) : "ebx");
52     }
53     if (n >= 7) {
54       __asm__("cpuid" : "=b"(f7b_), "=c"(f7c_) : "a"(7), "c"(0) : "edx");
55     }
56 #endif
57   }
58
59 #define X(name, r, bit) bool name() const { return (r) & (1U << bit); }
60
61   // cpuid(1): Processor Info and Feature Bits.
62 #define C(name, bit) X(name, f1c_, bit)
63   C(sse3, 0)
64   C(pclmuldq, 1)
65   C(dtes64, 2)
66   C(monitor, 3)
67   C(dscpl, 4)
68   C(vmx, 5)
69   C(smx, 6)
70   C(eist, 7)
71   C(tm2, 8)
72   C(ssse3, 9)
73   C(cnxtid, 10)
74   C(fma, 12)
75   C(cx16, 13)
76   C(xtpr, 14)
77   C(pdcm, 15)
78   C(pcid, 17)
79   C(dca, 18)
80   C(sse41, 19)
81   C(sse42, 20)
82   C(x2apic, 21)
83   C(movbe, 22)
84   C(popcnt, 23)
85   C(tscdeadline, 24)
86   C(aes, 25)
87   C(xsave, 26)
88   C(osxsave, 27)
89   C(avx, 28)
90   C(f16c, 29)
91   C(rdrand, 30)
92 #undef C
93 #define D(name, bit) X(name, f1d_, bit)
94   D(fpu, 0)
95   D(vme, 1)
96   D(de, 2)
97   D(pse, 3)
98   D(tsc, 4)
99   D(msr, 5)
100   D(pae, 6)
101   D(mce, 7)
102   D(cx8, 8)
103   D(apic, 9)
104   D(sep, 11)
105   D(mtrr, 12)
106   D(pge, 13)
107   D(mca, 14)
108   D(cmov, 15)
109   D(pat, 16)
110   D(pse36, 17)
111   D(psn, 18)
112   D(clfsh, 19)
113   D(ds, 21)
114   D(acpi, 22)
115   D(mmx, 23)
116   D(fxsr, 24)
117   D(sse, 25)
118   D(sse2, 26)
119   D(ss, 27)
120   D(htt, 28)
121   D(tm, 29)
122   D(pbe, 31)
123 #undef D
124
125   // cpuid(7): Extended Features.
126 #define B(name, bit) X(name, f7b_, bit)
127   B(bmi1, 3)
128   B(hle, 4)
129   B(avx2, 5)
130   B(smep, 7)
131   B(bmi2, 8)
132   B(erms, 9)
133   B(invpcid, 10)
134   B(rtm, 11)
135   B(mpx, 14)
136   B(avx512f, 16)
137   B(avx512dq, 17)
138   B(rdseed, 18)
139   B(adx, 19)
140   B(smap, 20)
141   B(avx512ifma, 21)
142   B(pcommit, 22)
143   B(clflushopt, 23)
144   B(clwb, 24)
145   B(avx512pf, 26)
146   B(avx512er, 27)
147   B(avx512cd, 28)
148   B(sha, 29)
149   B(avx512bw, 30)
150   B(avx512vl, 31)
151 #undef B
152 #define C(name, bit) X(name, f7c_, bit)
153   C(prefetchwt1, 0)
154   C(avx512vbmi, 1)
155 #undef C
156
157 #undef X
158
159  private:
160   uint32_t f1c_ = 0;
161   uint32_t f1d_ = 0;
162   uint32_t f7b_ = 0;
163   uint32_t f7c_ = 0;
164 };
165
166 }  // namespace folly
167
168 #endif /* FOLLY_CPUID_H_ */