@@ -41,81 +41,11 @@ cpuidex(std::array<int, 4>& cpui, int level, int count)
4141 __cpuidex (cpui.data (), level, count);
4242#endif
4343}
44- }
4544
46- // Adapted from
47- // https://docs.microsoft.com/fr-fr/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
48- struct InstructionSet
45+ template <typename T = void >
46+ struct InstructionSetBase
4947{
50- static std::string vendor (void ) { return data.vendor_ ; }
51- static std::string brand (void ) { return data.brand_ ; }
52-
53- static bool has_SSE3 (void ) { return data.f_1_ECX_ [0 ]; }
54- static bool has_PCLMULQDQ (void ) { return data.f_1_ECX_ [1 ]; }
55- static bool has_MONITOR (void ) { return data.f_1_ECX_ [3 ]; }
56- static bool has_SSSE3 (void ) { return data.f_1_ECX_ [9 ]; }
57- static bool has_FMA (void ) { return data.f_1_ECX_ [12 ]; }
58- static bool has_CMPXCHG16B (void ) { return data.f_1_ECX_ [13 ]; }
59- static bool has_SSE41 (void ) { return data.f_1_ECX_ [19 ]; }
60- static bool has_SSE42 (void ) { return data.f_1_ECX_ [20 ]; }
61- static bool has_MOVBE (void ) { return data.f_1_ECX_ [22 ]; }
62- static bool has_POPCNT (void ) { return data.f_1_ECX_ [23 ]; }
63- static bool has_AES (void ) { return data.f_1_ECX_ [25 ]; }
64- static bool has_XSAVE (void ) { return data.f_1_ECX_ [26 ]; }
65- static bool has_OSXSAVE (void ) { return data.f_1_ECX_ [27 ]; }
66- static bool has_AVX (void ) { return data.f_1_ECX_ [28 ]; }
67- static bool has_F16C (void ) { return data.f_1_ECX_ [29 ]; }
68- static bool has_RDRAND (void ) { return data.f_1_ECX_ [30 ]; }
69-
70- static bool has_MSR (void ) { return data.f_1_EDX_ [5 ]; }
71- static bool has_CX8 (void ) { return data.f_1_EDX_ [8 ]; }
72- static bool has_SEP (void ) { return data.f_1_EDX_ [11 ]; }
73- static bool has_CMOV (void ) { return data.f_1_EDX_ [15 ]; }
74- static bool has_CLFSH (void ) { return data.f_1_EDX_ [19 ]; }
75- static bool has_MMX (void ) { return data.f_1_EDX_ [23 ]; }
76- static bool has_FXSR (void ) { return data.f_1_EDX_ [24 ]; }
77- static bool has_SSE (void ) { return data.f_1_EDX_ [25 ]; }
78- static bool has_SSE2 (void ) { return data.f_1_EDX_ [26 ]; }
79-
80- static bool has_FSGSBASE (void ) { return data.f_7_EBX_ [0 ]; }
81- static bool has_AVX512VBMI (void ) { return data.f_7_EBX_ [1 ]; }
82- static bool has_BMI1 (void ) { return data.f_7_EBX_ [3 ]; }
83- static bool has_HLE (void ) { return data.isIntel_ && data.f_7_EBX_ [4 ]; }
84- static bool has_AVX2 (void ) { return data.f_7_EBX_ [5 ]; }
85- static bool has_BMI2 (void ) { return data.f_7_EBX_ [8 ]; }
86- static bool has_ERMS (void ) { return data.f_7_EBX_ [9 ]; }
87- static bool has_INVPCID (void ) { return data.f_7_EBX_ [10 ]; }
88- static bool has_RTM (void ) { return data.isIntel_ && data.f_7_EBX_ [11 ]; }
89- static bool has_AVX512F (void ) { return data.f_7_EBX_ [16 ]; }
90- static bool has_AVX512DQ (void ) { return data.f_7_EBX_ [17 ]; }
91- static bool has_RDSEED (void ) { return data.f_7_EBX_ [18 ]; }
92- static bool has_ADX (void ) { return data.f_7_EBX_ [19 ]; }
93- static bool has_AVX512IFMA (void ) { return data.f_7_EBX_ [21 ]; }
94- static bool has_AVX512PF (void ) { return data.f_7_EBX_ [26 ]; }
95- static bool has_AVX512ER (void ) { return data.f_7_EBX_ [27 ]; }
96- static bool has_AVX512CD (void ) { return data.f_7_EBX_ [28 ]; }
97- static bool has_SHA (void ) { return data.f_7_EBX_ [29 ]; }
98- static bool has_AVX512BW (void ) { return data.f_7_EBX_ [30 ]; }
99- static bool has_AVX512VL (void ) { return data.f_7_EBX_ [31 ]; }
100-
101- static bool has_PREFETCHWT1 (void ) { return data.f_7_ECX_ [0 ]; }
102-
103- static bool has_LAHF (void ) { return data.f_81_ECX_ [0 ]; }
104- static bool has_LZCNT (void ) { return data.isIntel_ && data.f_81_ECX_ [5 ]; }
105- static bool has_ABM (void ) { return data.isAMD_ && data.f_81_ECX_ [5 ]; }
106- static bool has_SSE4a (void ) { return data.isAMD_ && data.f_81_ECX_ [6 ]; }
107- static bool has_XOP (void ) { return data.isAMD_ && data.f_81_ECX_ [11 ]; }
108- static bool has_FMA4 (void ) { return data.isAMD_ && data.f_81_ECX_ [16 ]; }
109- static bool has_TBM (void ) { return data.isAMD_ && data.f_81_ECX_ [21 ]; }
110-
111- static bool has_SYSCALL (void ) { return data.isIntel_ && data.f_81_EDX_ [11 ]; }
112- static bool has_MMXEXT (void ) { return data.isAMD_ && data.f_81_EDX_ [22 ]; }
113- static bool has_RDTSCP (void ) { return data.isIntel_ && data.f_81_EDX_ [27 ]; }
114- static bool has_x64 (void ) { return data.isIntel_ && data.f_81_EDX_ [29 ]; }
115- static bool has_3DNOWEXT (void ) { return data.isAMD_ && data.f_81_EDX_ [30 ]; }
116- static bool has_3DNOW (void ) { return data.isAMD_ && data.f_81_EDX_ [31 ]; }
117-
118- private:
48+ protected:
11949 struct Data
12050 {
12151 Data ()
@@ -214,7 +144,129 @@ struct InstructionSet
214144 std::vector<std::array<int , 4 >> extdata_;
215145 };
216146
217- inline static const Data data = Data();
147+ static const Data data;
148+ };
149+
150+ template <>
151+ const typename InstructionSetBase<>::Data InstructionSetBase<>::data =
152+ typename InstructionSetBase<>::Data();
153+ } // namespace internal
154+
155+ // Adapted from
156+ // https://docs.microsoft.com/fr-fr/cpp/intrinsics/cpuid-cpuidex?view=msvc-170
157+ struct InstructionSet : public internal ::InstructionSetBase<>
158+ {
159+ typedef internal::InstructionSetBase<> Base;
160+
161+ static std::string vendor (void ) { return Base::data.vendor_ ; }
162+ static std::string brand (void ) { return Base::data.brand_ ; }
163+
164+ static bool has_SSE3 (void ) { return Base::data.f_1_ECX_ [0 ]; }
165+ static bool has_PCLMULQDQ (void ) { return Base::data.f_1_ECX_ [1 ]; }
166+ static bool has_MONITOR (void ) { return Base::data.f_1_ECX_ [3 ]; }
167+ static bool has_SSSE3 (void ) { return Base::data.f_1_ECX_ [9 ]; }
168+ static bool has_FMA (void ) { return Base::data.f_1_ECX_ [12 ]; }
169+ static bool has_CMPXCHG16B (void ) { return Base::data.f_1_ECX_ [13 ]; }
170+ static bool has_SSE41 (void ) { return Base::data.f_1_ECX_ [19 ]; }
171+ static bool has_SSE42 (void ) { return Base::data.f_1_ECX_ [20 ]; }
172+ static bool has_MOVBE (void ) { return Base::data.f_1_ECX_ [22 ]; }
173+ static bool has_POPCNT (void ) { return Base::data.f_1_ECX_ [23 ]; }
174+ static bool has_AES (void ) { return Base::data.f_1_ECX_ [25 ]; }
175+ static bool has_XSAVE (void ) { return Base::data.f_1_ECX_ [26 ]; }
176+ static bool has_OSXSAVE (void ) { return Base::data.f_1_ECX_ [27 ]; }
177+ static bool has_AVX (void ) { return Base::data.f_1_ECX_ [28 ]; }
178+ static bool has_F16C (void ) { return Base::data.f_1_ECX_ [29 ]; }
179+ static bool has_RDRAND (void ) { return Base::data.f_1_ECX_ [30 ]; }
180+
181+ static bool has_MSR (void ) { return Base::data.f_1_EDX_ [5 ]; }
182+ static bool has_CX8 (void ) { return Base::data.f_1_EDX_ [8 ]; }
183+ static bool has_SEP (void ) { return Base::data.f_1_EDX_ [11 ]; }
184+ static bool has_CMOV (void ) { return Base::data.f_1_EDX_ [15 ]; }
185+ static bool has_CLFSH (void ) { return Base::data.f_1_EDX_ [19 ]; }
186+ static bool has_MMX (void ) { return Base::data.f_1_EDX_ [23 ]; }
187+ static bool has_FXSR (void ) { return Base::data.f_1_EDX_ [24 ]; }
188+ static bool has_SSE (void ) { return Base::data.f_1_EDX_ [25 ]; }
189+ static bool has_SSE2 (void ) { return Base::data.f_1_EDX_ [26 ]; }
190+
191+ static bool has_FSGSBASE (void ) { return Base::data.f_7_EBX_ [0 ]; }
192+ static bool has_AVX512VBMI (void ) { return Base::data.f_7_EBX_ [1 ]; }
193+ static bool has_BMI1 (void ) { return Base::data.f_7_EBX_ [3 ]; }
194+ static bool has_HLE (void )
195+ {
196+ return Base::data.isIntel_ && Base::data.f_7_EBX_ [4 ];
197+ }
198+ static bool has_AVX2 (void ) { return Base::data.f_7_EBX_ [5 ]; }
199+ static bool has_BMI2 (void ) { return Base::data.f_7_EBX_ [8 ]; }
200+ static bool has_ERMS (void ) { return Base::data.f_7_EBX_ [9 ]; }
201+ static bool has_INVPCID (void ) { return Base::data.f_7_EBX_ [10 ]; }
202+ static bool has_RTM (void )
203+ {
204+ return Base::data.isIntel_ && Base::data.f_7_EBX_ [11 ];
205+ }
206+ static bool has_AVX512F (void ) { return Base::data.f_7_EBX_ [16 ]; }
207+ static bool has_AVX512DQ (void ) { return Base::data.f_7_EBX_ [17 ]; }
208+ static bool has_RDSEED (void ) { return Base::data.f_7_EBX_ [18 ]; }
209+ static bool has_ADX (void ) { return Base::data.f_7_EBX_ [19 ]; }
210+ static bool has_AVX512IFMA (void ) { return Base::data.f_7_EBX_ [21 ]; }
211+ static bool has_AVX512PF (void ) { return Base::data.f_7_EBX_ [26 ]; }
212+ static bool has_AVX512ER (void ) { return Base::data.f_7_EBX_ [27 ]; }
213+ static bool has_AVX512CD (void ) { return Base::data.f_7_EBX_ [28 ]; }
214+ static bool has_SHA (void ) { return Base::data.f_7_EBX_ [29 ]; }
215+ static bool has_AVX512BW (void ) { return Base::data.f_7_EBX_ [30 ]; }
216+ static bool has_AVX512VL (void ) { return Base::data.f_7_EBX_ [31 ]; }
217+
218+ static bool has_PREFETCHWT1 (void ) { return Base::data.f_7_ECX_ [0 ]; }
219+
220+ static bool has_LAHF (void ) { return Base::data.f_81_ECX_ [0 ]; }
221+ static bool has_LZCNT (void )
222+ {
223+ return Base::data.isIntel_ && Base::data.f_81_ECX_ [5 ];
224+ }
225+ static bool has_ABM (void )
226+ {
227+ return Base::data.isAMD_ && Base::data.f_81_ECX_ [5 ];
228+ }
229+ static bool has_SSE4a (void )
230+ {
231+ return Base::data.isAMD_ && Base::data.f_81_ECX_ [6 ];
232+ }
233+ static bool has_XOP (void )
234+ {
235+ return Base::data.isAMD_ && Base::data.f_81_ECX_ [11 ];
236+ }
237+ static bool has_FMA4 (void )
238+ {
239+ return Base::data.isAMD_ && Base::data.f_81_ECX_ [16 ];
240+ }
241+ static bool has_TBM (void )
242+ {
243+ return Base::data.isAMD_ && Base::data.f_81_ECX_ [21 ];
244+ }
245+
246+ static bool has_SYSCALL (void )
247+ {
248+ return Base::data.isIntel_ && Base::data.f_81_EDX_ [11 ];
249+ }
250+ static bool has_MMXEXT (void )
251+ {
252+ return Base::data.isAMD_ && Base::data.f_81_EDX_ [22 ];
253+ }
254+ static bool has_RDTSCP (void )
255+ {
256+ return Base::data.isIntel_ && Base::data.f_81_EDX_ [27 ];
257+ }
258+ static bool has_x64 (void )
259+ {
260+ return Base::data.isIntel_ && Base::data.f_81_EDX_ [29 ];
261+ }
262+ static bool has_3DNOWEXT (void )
263+ {
264+ return Base::data.isAMD_ && Base::data.f_81_EDX_ [30 ];
265+ }
266+ static bool has_3DNOW (void )
267+ {
268+ return Base::data.isAMD_ && Base::data.f_81_EDX_ [31 ];
269+ }
218270};
219271
220272} // helpers
0 commit comments