@@ -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,284 @@ 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+ // template <typename T>
158+ // struct InstructionSet: public internal::InstructionSetBase<T>
159+ struct InstructionSet : public internal ::InstructionSetBase<>
160+ {
161+ static std::string vendor (void )
162+ {
163+ return internal::InstructionSetBase<>::data.vendor_ ;
164+ }
165+ static std::string brand (void )
166+ {
167+ return internal::InstructionSetBase<>::data.brand_ ;
168+ }
169+
170+ static bool has_SSE3 (void )
171+ {
172+ return internal::InstructionSetBase<>::data.f_1_ECX_ [0 ];
173+ }
174+ static bool has_PCLMULQDQ (void )
175+ {
176+ return internal::InstructionSetBase<>::data.f_1_ECX_ [1 ];
177+ }
178+ static bool has_MONITOR (void )
179+ {
180+ return internal::InstructionSetBase<>::data.f_1_ECX_ [3 ];
181+ }
182+ static bool has_SSSE3 (void )
183+ {
184+ return internal::InstructionSetBase<>::data.f_1_ECX_ [9 ];
185+ }
186+ static bool has_FMA (void )
187+ {
188+ return internal::InstructionSetBase<>::data.f_1_ECX_ [12 ];
189+ }
190+ static bool has_CMPXCHG16B (void )
191+ {
192+ return internal::InstructionSetBase<>::data.f_1_ECX_ [13 ];
193+ }
194+ static bool has_SSE41 (void )
195+ {
196+ return internal::InstructionSetBase<>::data.f_1_ECX_ [19 ];
197+ }
198+ static bool has_SSE42 (void )
199+ {
200+ return internal::InstructionSetBase<>::data.f_1_ECX_ [20 ];
201+ }
202+ static bool has_MOVBE (void )
203+ {
204+ return internal::InstructionSetBase<>::data.f_1_ECX_ [22 ];
205+ }
206+ static bool has_POPCNT (void )
207+ {
208+ return internal::InstructionSetBase<>::data.f_1_ECX_ [23 ];
209+ }
210+ static bool has_AES (void )
211+ {
212+ return internal::InstructionSetBase<>::data.f_1_ECX_ [25 ];
213+ }
214+ static bool has_XSAVE (void )
215+ {
216+ return internal::InstructionSetBase<>::data.f_1_ECX_ [26 ];
217+ }
218+ static bool has_OSXSAVE (void )
219+ {
220+ return internal::InstructionSetBase<>::data.f_1_ECX_ [27 ];
221+ }
222+ static bool has_AVX (void )
223+ {
224+ return internal::InstructionSetBase<>::data.f_1_ECX_ [28 ];
225+ }
226+ static bool has_F16C (void )
227+ {
228+ return internal::InstructionSetBase<>::data.f_1_ECX_ [29 ];
229+ }
230+ static bool has_RDRAND (void )
231+ {
232+ return internal::InstructionSetBase<>::data.f_1_ECX_ [30 ];
233+ }
234+
235+ static bool has_MSR (void )
236+ {
237+ return internal::InstructionSetBase<>::data.f_1_EDX_ [5 ];
238+ }
239+ static bool has_CX8 (void )
240+ {
241+ return internal::InstructionSetBase<>::data.f_1_EDX_ [8 ];
242+ }
243+ static bool has_SEP (void )
244+ {
245+ return internal::InstructionSetBase<>::data.f_1_EDX_ [11 ];
246+ }
247+ static bool has_CMOV (void )
248+ {
249+ return internal::InstructionSetBase<>::data.f_1_EDX_ [15 ];
250+ }
251+ static bool has_CLFSH (void )
252+ {
253+ return internal::InstructionSetBase<>::data.f_1_EDX_ [19 ];
254+ }
255+ static bool has_MMX (void )
256+ {
257+ return internal::InstructionSetBase<>::data.f_1_EDX_ [23 ];
258+ }
259+ static bool has_FXSR (void )
260+ {
261+ return internal::InstructionSetBase<>::data.f_1_EDX_ [24 ];
262+ }
263+ static bool has_SSE (void )
264+ {
265+ return internal::InstructionSetBase<>::data.f_1_EDX_ [25 ];
266+ }
267+ static bool has_SSE2 (void )
268+ {
269+ return internal::InstructionSetBase<>::data.f_1_EDX_ [26 ];
270+ }
271+
272+ static bool has_FSGSBASE (void )
273+ {
274+ return internal::InstructionSetBase<>::data.f_7_EBX_ [0 ];
275+ }
276+ static bool has_AVX512VBMI (void )
277+ {
278+ return internal::InstructionSetBase<>::data.f_7_EBX_ [1 ];
279+ }
280+ static bool has_BMI1 (void )
281+ {
282+ return internal::InstructionSetBase<>::data.f_7_EBX_ [3 ];
283+ }
284+ static bool has_HLE (void )
285+ {
286+ return internal::InstructionSetBase<>::data.isIntel_ &&
287+ internal::InstructionSetBase<>::data.f_7_EBX_ [4 ];
288+ }
289+ static bool has_AVX2 (void )
290+ {
291+ return internal::InstructionSetBase<>::data.f_7_EBX_ [5 ];
292+ }
293+ static bool has_BMI2 (void )
294+ {
295+ return internal::InstructionSetBase<>::data.f_7_EBX_ [8 ];
296+ }
297+ static bool has_ERMS (void )
298+ {
299+ return internal::InstructionSetBase<>::data.f_7_EBX_ [9 ];
300+ }
301+ static bool has_INVPCID (void )
302+ {
303+ return internal::InstructionSetBase<>::data.f_7_EBX_ [10 ];
304+ }
305+ static bool has_RTM (void )
306+ {
307+ return internal::InstructionSetBase<>::data.isIntel_ &&
308+ internal::InstructionSetBase<>::data.f_7_EBX_ [11 ];
309+ }
310+ static bool has_AVX512F (void )
311+ {
312+ return internal::InstructionSetBase<>::data.f_7_EBX_ [16 ];
313+ }
314+ static bool has_AVX512DQ (void )
315+ {
316+ return internal::InstructionSetBase<>::data.f_7_EBX_ [17 ];
317+ }
318+ static bool has_RDSEED (void )
319+ {
320+ return internal::InstructionSetBase<>::data.f_7_EBX_ [18 ];
321+ }
322+ static bool has_ADX (void )
323+ {
324+ return internal::InstructionSetBase<>::data.f_7_EBX_ [19 ];
325+ }
326+ static bool has_AVX512IFMA (void )
327+ {
328+ return internal::InstructionSetBase<>::data.f_7_EBX_ [21 ];
329+ }
330+ static bool has_AVX512PF (void )
331+ {
332+ return internal::InstructionSetBase<>::data.f_7_EBX_ [26 ];
333+ }
334+ static bool has_AVX512ER (void )
335+ {
336+ return internal::InstructionSetBase<>::data.f_7_EBX_ [27 ];
337+ }
338+ static bool has_AVX512CD (void )
339+ {
340+ return internal::InstructionSetBase<>::data.f_7_EBX_ [28 ];
341+ }
342+ static bool has_SHA (void )
343+ {
344+ return internal::InstructionSetBase<>::data.f_7_EBX_ [29 ];
345+ }
346+ static bool has_AVX512BW (void )
347+ {
348+ return internal::InstructionSetBase<>::data.f_7_EBX_ [30 ];
349+ }
350+ static bool has_AVX512VL (void )
351+ {
352+ return internal::InstructionSetBase<>::data.f_7_EBX_ [31 ];
353+ }
354+
355+ static bool has_PREFETCHWT1 (void )
356+ {
357+ return internal::InstructionSetBase<>::data.f_7_ECX_ [0 ];
358+ }
359+
360+ static bool has_LAHF (void )
361+ {
362+ return internal::InstructionSetBase<>::data.f_81_ECX_ [0 ];
363+ }
364+ static bool has_LZCNT (void )
365+ {
366+ return internal::InstructionSetBase<>::data.isIntel_ &&
367+ internal::InstructionSetBase<>::data.f_81_ECX_ [5 ];
368+ }
369+ static bool has_ABM (void )
370+ {
371+ return internal::InstructionSetBase<>::data.isAMD_ &&
372+ internal::InstructionSetBase<>::data.f_81_ECX_ [5 ];
373+ }
374+ static bool has_SSE4a (void )
375+ {
376+ return internal::InstructionSetBase<>::data.isAMD_ &&
377+ internal::InstructionSetBase<>::data.f_81_ECX_ [6 ];
378+ }
379+ static bool has_XOP (void )
380+ {
381+ return internal::InstructionSetBase<>::data.isAMD_ &&
382+ internal::InstructionSetBase<>::data.f_81_ECX_ [11 ];
383+ }
384+ static bool has_FMA4 (void )
385+ {
386+ return internal::InstructionSetBase<>::data.isAMD_ &&
387+ internal::InstructionSetBase<>::data.f_81_ECX_ [16 ];
388+ }
389+ static bool has_TBM (void )
390+ {
391+ return internal::InstructionSetBase<>::data.isAMD_ &&
392+ internal::InstructionSetBase<>::data.f_81_ECX_ [21 ];
393+ }
394+
395+ static bool has_SYSCALL (void )
396+ {
397+ return internal::InstructionSetBase<>::data.isIntel_ &&
398+ internal::InstructionSetBase<>::data.f_81_EDX_ [11 ];
399+ }
400+ static bool has_MMXEXT (void )
401+ {
402+ return internal::InstructionSetBase<>::data.isAMD_ &&
403+ internal::InstructionSetBase<>::data.f_81_EDX_ [22 ];
404+ }
405+ static bool has_RDTSCP (void )
406+ {
407+ return internal::InstructionSetBase<>::data.isIntel_ &&
408+ internal::InstructionSetBase<>::data.f_81_EDX_ [27 ];
409+ }
410+ static bool has_x64 (void )
411+ {
412+ return internal::InstructionSetBase<>::data.isIntel_ &&
413+ internal::InstructionSetBase<>::data.f_81_EDX_ [29 ];
414+ }
415+ static bool has_3DNOWEXT (void )
416+ {
417+ return internal::InstructionSetBase<>::data.isAMD_ &&
418+ internal::InstructionSetBase<>::data.f_81_EDX_ [30 ];
419+ }
420+ static bool has_3DNOW (void )
421+ {
422+ return internal::InstructionSetBase<>::data.isAMD_ &&
423+ internal::InstructionSetBase<>::data.f_81_EDX_ [31 ];
424+ }
218425};
219426
220427} // helpers
0 commit comments