HikoGUI
A low latency retained GUI
Loading...
Searching...
No Matches
cpu_id.hpp
1// Copyright Take Vos 2019, 2021.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
4
5#pragma once
6
7#include "architecture.hpp"
8#include <array>
9
10#if HI_COMPILER == HI_CC_MSVC
11#include <intrin.h>
12#elif HI_COMPILER == HI_CC_GCC || HI_COMPILER == HI_CC_CLANG
13#include <cpuid.h>
14#else
15#error "Unsuported compiler for x64 cpu_id"
16#endif
17
18namespace hi::inline v1 {
19
20#if HI_COMPILER == HI_CC_MSVC
21std::array<uint32_t, 4> cpu_id_x64_result cpu_id_x64(uint32_t cpu_id_leaf)
22{
24 __cpuid(info.data(), static_cast<int>(cpu_id_leaf));
25
27 r[0] = static_cast<uint32_t> info[0];
28 r[1] = static_cast<uint32_t> info[1];
29 r[2] = static_cast<uint32_t> info[2];
30 r[3] = static_cast<uint32_t> info[3];
31 return r;
32}
33
34#elif HI_COMPILER == HI_CC_GCC || HI_COMPILER == HI_CC_CLANG
35std::array<uint32_t, 4> cpu_id_x64_result cpu_id_x64(uint32_t cpu_id_leaf)
36{
38 __cpuid(cpu_id_leaf, r[0], r[1], r[2], r[3]);
39 return r;
40}
41
42#else
43#error "Unsuported compiler for x64 cpu_id"
44#endif
45
46inline std::array<uint32_t, 4> cpu_id_leaf1 = cpu_id_x64(1);
47inline std::array<uint32_t, 4> cpu_id_leaf7 = cpu_id_x64(7);
48
49template<int Bit>
50bool cpu_id_leaf1_ecx()
51{
52 constexpr uint32_t mask = 1 << Bit;
53 return (cpu_id_leaf1[2] & mask) != 0;
54}
55
56template<int Bit>
57bool cpu_id_leaf1_edx()
58{
59 constexpr uint32_t mask = 1 << Bit;
60 return (cpu_id_leaf1[3] & mask) != 0;
61}
62
63template<int Bit>
64bool cpu_id_leaf7_ebx()
65{
66 constexpr uint32_t mask = 1 << Bit;
67 return (cpu_id_leaf7[1] & mask) != 0;
68}
69
70template<int Bit>
71bool cpu_id_leaf7_ecx()
72{
73 constexpr uint32_t mask = 1 << Bit;
74 return (cpu_id_leaf7[2] & mask) != 0;
75}
76
77template<int Bit>
78bool cpu_id_leaf7_edx()
79{
80 constexpr uint32_t mask = 1 << Bit;
81 return (cpu_id_leaf7[3] & mask) != 0;
82}
83
84// LEAF1.0: EDX
85bool cpu_has_fpu()
86{
87 return cpu_id_leaf1_edx<0>();
88}
89bool cpu_has_vme()
90{
91 return cpu_id_leaf1_edx<1>();
92}
93bool cpu_has_de()
94{
95 return cpu_id_leaf1_edx<2>();
96}
97bool cpu_has_pse()
98{
99 return cpu_id_leaf1_edx<3>();
100}
101bool cpu_has_tsc()
102{
103 return cpu_id_leaf1_edx<4>();
104}
105bool cpu_has_msr()
106{
107 return cpu_id_leaf1_edx<5>();
108}
109bool cpu_has_pae()
110{
111 return cpu_id_leaf1_edx<6>();
112}
113bool cpu_has_mce()
114{
115 return cpu_id_leaf1_edx<7>();
116}
117bool cpu_has_cx8()
118{
119 return cpu_id_leaf1_edx<8>();
120}
121bool cpu_has_apic()
122{
123 return cpu_id_leaf1_edx<9>();
124}
125// reserved
126bool cpu_has_sep()
127{
128 return cpu_id_leaf1_edx<11>();
129}
130bool cpu_has_mtrr()
131{
132 return cpu_id_leaf1_edx<12>();
133}
134bool cpu_has_pge()
135{
136 return cpu_id_leaf1_edx<13>();
137}
138bool cpu_has_mca()
139{
140 return cpu_id_leaf1_edx<14>();
141}
142bool cpu_has_cmov()
143{
144 return cpu_id_leaf1_edx<15>();
145}
146bool cpu_has_pat()
147{
148 return cpu_id_leaf1_edx<16>();
149}
150bool cpu_has_pse_36()
151{
152 return cpu_id_leaf1_edx<17>();
153}
154bool cpu_has_psn()
155{
156 return cpu_id_leaf1_edx<18>();
157}
158bool cpu_has_clfsh()
159{
160 return cpu_id_leaf1_edx<19>();
161}
162// reserved
163bool cpu_has_ds()
164{
165 return cpu_id_leaf1_edx<21>();
166}
167bool cpu_has_acpi()
168{
169 return cpu_id_leaf1_edx<22>();
170}
171bool cpu_has_mmx()
172{
173 return cpu_id_leaf1_edx<23>();
174}
175bool cpu_has_fxsr()
176{
177 return cpu_id_leaf1_edx<24>();
178}
179bool cpu_has_sse()
180{
181 return cpu_id_leaf1_edx<25>();
182}
183bool cpu_has_sse2()
184{
185 return cpu_id_leaf1_edx<26>();
186}
187bool cpu_has_ss()
188{
189 return cpu_id_leaf1_edx<27>();
190}
191bool cpu_has_htt()
192{
193 return cpu_id_leaf1_edx<28>();
194}
195bool cpu_has_tm()
196{
197 return cpu_id_leaf1_edx<29>();
198}
199bool cpu_has_ia64()
200{
201 return cpu_id_leaf1_edx<30>();
202}
203bool cpu_has_pbe()
204{
205 return cpu_id_leaf1_edx<31>();
206}
207
208// LEAF1.0: ECX
209bool cpu_has_sse3()
210{
211 return cpu_id_leaf1_ecx<0>();
212}
213bool cpu_has_pclmulqdq()
214{
215 return cpu_id_leaf1_ecx<1>();
216}
217bool cpu_has_dtes64()
218{
219 return cpu_id_leaf1_ecx<2>();
220}
221bool cpu_has_monitor()
222{
223 return cpu_id_leaf1_ecx<3>();
224}
225bool cpu_has_ds_cpl()
226{
227 return cpu_id_leaf1_ecx<4>();
228}
229bool cpu_has_vmx()
230{
231 return cpu_id_leaf1_ecx<5>();
232}
233bool cpu_has_smx()
234{
235 return cpu_id_leaf1_ecx<6>();
236}
237bool cpu_has_est()
238{
239 return cpu_id_leaf1_ecx<7>();
240}
241bool cpu_has_tm2()
242{
243 return cpu_id_leaf1_ecx<8>();
244}
245bool cpu_has_ssse3()
246{
247 return cpu_id_leaf1_ecx<9>();
248}
249bool cpu_has_cnxt_id()
250{
251 return cpu_id_leaf1_ecx<10>();
252}
253bool cpu_has_sdbg()
254{
255 return cpu_id_leaf1_ecx<11>();
256}
257bool cpu_has_fma()
258{
259 return cpu_id_leaf1_ecx<12>();
260}
261bool cpu_has_cx16()
262{
263 return cpu_id_leaf1_ecx<13>();
264}
265bool cpu_has_xtpr()
266{
267 return cpu_id_leaf1_ecx<14>();
268}
269bool cpu_has_pdcm()
270{
271 return cpu_id_leaf1_ecx<15>();
272}
273// reserved
274bool cpu_has_pcid()
275{
276 return cpu_id_leaf1_ecx<17>();
277}
278bool cpu_has_dca()
279{
280 return cpu_id_leaf1_ecx<18>();
281}
282bool cpu_has_sse4_1()
283{
284 return cpu_id_leaf1_ecx<19>();
285}
286bool cpu_has_sse4_2()
287{
288 return cpu_id_leaf1_ecx<20>();
289}
290bool cpu_has_x2apic()
291{
292 return cpu_id_leaf1_ecx<21>();
293}
294bool cpu_has_movbe()
295{
296 return cpu_id_leaf1_ecx<22>();
297}
298bool cpu_has_popcnt()
299{
300 return cpu_id_leaf1_ecx<23>();
301}
302bool cpu_has_tsc_deadline()
303{
304 return cpu_id_leaf1_ecx<24>();
305}
306bool cpu_has_aes()
307{
308 return cpu_id_leaf1_ecx<25>();
309}
310bool cpu_has_xsave()
311{
312 return cpu_id_leaf1_ecx<26>();
313}
314bool cpu_has_osxsave()
315{
316 return cpu_id_leaf1_ecx<27>();
317}
318bool cpu_has_avx()
319{
320 return cpu_id_leaf1_ecx<28>();
321}
322bool cpu_has_f16c()
323{
324 return cpu_id_leaf1_ecx<29>();
325}
326bool cpu_has_rdrnd()
327{
328 return cpu_id_leaf1_ecx<30>();
329}
330bool cpu_has_hypervisor()
331{
332 return cpu_id_leaf1_ecx<31>();
333}
334
335// LEAF1.0: EBX
336
337// LEAF1.0: EAX
338bool cpu_stepping()
339{
340 return cpu_id_leaf1[0] & 0xf;
341}
342bool cpu_model_id()
343{
344 uint32_t family_id = (cpu_id_leaf1[0] >> 8) & 0xf;
345 uint32_t model_id = (cpu_id_leaf1[0] >> 4) & 0xf;
346 if (family_id == 6 || family_id == 15) {
347 uint32_t extended_model_id = (cpu_id_leaf1[0] >> 16) & 0xf;
348 return (extended_model_id << 4) | model_id;
349 } else {
350 return model_id;
351 }
352}
353bool cpu_family_id()
354{
355 uint32_t family_id = (cpu_id_leaf1[0] >> 8) & 0xf;
356 if (family_id == 15) {
357 uint32_t extended_family_id = (cpu_id_leaf1[0] >> 20) & 0xff;
358 return family_id + extended_family_id;
359 } else {
360 return extended_family_id;
361 }
362}
363
364// LEAF7.0: EBX
365bool cpu_has_fsgsbase()
366{
367 return cpu_id_leaf7_ebx<0>();
368}
369bool cpu_has_tsc_adjust()
370{
371 return cpu_id_leaf7_ebx<1>();
372}
373bool cpu_has_sgx()
374{
375 return cpu_id_leaf7_ebx<2>();
376}
377bool cpu_has_bmi1()
378{
379 return cpu_id_leaf7_ebx<3>();
380}
381bool cpu_has_hle()
382{
383 return cpu_id_leaf7_ebx<4>();
384}
385bool cpu_has_avx2()
386{
387 return cpu_id_leaf7_ebx<5>();
388}
389// reserved
390bool cpu_has_smep()
391{
392 return cpu_id_leaf7_ebx<7>();
393}
394bool cpu_has_bmi2()
395{
396 return cpu_id_leaf7_ebx<8>();
397}
398bool cpu_has_erms()
399{
400 return cpu_id_leaf7_ebx<9>();
401}
402bool cpu_has_invpcid()
403{
404 return cpu_id_leaf7_ebx<10>();
405}
406bool cpu_has_rtm()
407{
408 return cpu_id_leaf7_ebx<11>();
409}
410bool cpu_has_pqm()
411{
412 return cpu_id_leaf7_ebx<12>();
413}
414bool cpu_has_deprecated_fpu_cs_ds()
415{
416 return cpu_id_leaf7_ebx<13>();
417}
418bool cpu_has_mpx()
419{
420 return cpu_id_leaf7_ebx<14>();
421}
422bool cpu_has_pqe()
423{
424 return cpu_id_leaf7_ebx<15>();
425}
426bool cpu_has_avx512_f()
427{
428 return cpu_id_leaf7_ebx<16>();
429}
430bool cpu_has_avx512_dq()
431{
432 return cpu_id_leaf7_ebx<17>();
433}
434bool cpu_has_rdseed()
435{
436 return cpu_id_leaf7_ebx<18>();
437}
438bool cpu_has_adx()
439{
440 return cpu_id_leaf7_ebx<19>();
441}
442bool cpu_has_smap()
443{
444 return cpu_id_leaf7_ebx<20>();
445}
446bool cpu_has_avx512_ifma()
447{
448 return cpu_id_leaf7_ebx<21>();
449}
450bool cpu_has_pcommit()
451{
452 return cpu_id_leaf7_ebx<22>();
453}
454bool cpu_has_clflushopt()
455{
456 return cpu_id_leaf7_ebx<23>();
457}
458bool cpu_has_clwb()
459{
460 return cpu_id_leaf7_ebx<24>();
461}
462bool cpu_has_intelpt()
463{
464 return cpu_id_leaf7_ebx<25>();
465}
466bool cpu_has_avx512_pf()
467{
468 return cpu_id_leaf7_ebx<26>();
469}
470bool cpu_has_avx512_er()
471{
472 return cpu_id_leaf7_ebx<27>();
473}
474bool cpu_has_avx512_cd()
475{
476 return cpu_id_leaf7_ebx<28>();
477}
478bool cpu_has_sha()
479{
480 return cpu_id_leaf7_ebx<29>();
481}
482bool cpu_has_avx512_bw()
483{
484 return cpu_id_leaf7_ebx<30>();
485}
486bool cpu_has_avx512_vl()
487{
488 return cpu_id_leaf7_ebx<31>();
489}
490
491// LEAF7.0: ECX
492bool cpu_has_prefetchwt1()
493{
494 return cpu_id_leaf7_ecx<0>();
495}
496bool cpu_has_avx512_vbmi()
497{
498 return cpu_id_leaf7_ecx<1>();
499}
500bool cpu_has_umip()
501{
502 return cpu_id_leaf7_ecx<2>();
503}
504bool cpu_has_pku()
505{
506 return cpu_id_leaf7_ecx<3>();
507}
508bool cpu_has_ospke()
509{
510 return cpu_id_leaf7_ecx<4>();
511}
512bool cpu_has_waitpkg()
513{
514 return cpu_id_leaf7_ecx<5>();
515}
516bool cpu_has_avx512_vmbi2()
517{
518 return cpu_id_leaf7_ecx<6>();
519}
520bool cpu_has_shstk()
521{
522 return cpu_id_leaf7_ecx<7>();
523}
524bool cpu_has_gfni()
525{
526 return cpu_id_leaf7_ecx<8>();
527}
528bool cpu_has_vaes()
529{
530 return cpu_id_leaf7_ecx<9>();
531}
532bool cpu_has_vpclmulqdq()
533{
534 return cpu_id_leaf7_ecx<10>();
535}
536bool cpu_has_avx512_vnni()
537{
538 return cpu_id_leaf7_ecx<11>();
539}
540bool cpu_has_avx512_bitalg()
541{
542 return cpu_id_leaf7_ecx<12>();
543}
544// reserved
545bool cpu_has_avx512_vpopcntdq()
546{
547 return cpu_id_leaf7_ecx<14>();
548}
549// reserved
550bool cpu_has_5level_paging()
551{
552 return cpu_id_leaf7_ecx<16>();
553}
554int cpu_has_mawau() {}
555bool cpu_has_rdpid()
556{
557 return cpu_id_leaf7_ecx<22>();
558}
559// reserved
560// reserved
561bool cpu_has_cldemote()
562{
563 return cpu_id_leaf7_ecx<25>();
564}
565// reserved
566bool cpu_has_movdir()
567{
568 return cpu_id_leaf7_ecx<27>();
569}
570bool cpu_has_movdir64b()
571{
572 return cpu_id_leaf7_ecx<28>();
573}
574// reserved
575bool cpu_has_sgx_lc()
576{
577 return cpu_id_leaf7_ecx<30>();
578}
579// reserved
580
581// LEAF7.0: EDX
582// reserved
583// reserved
584bool cpu_has_avx512_4vnniw()
585{
586 return cpu_id_leaf7_edx<2>();
587}
588bool cpu_has_avx512_4fmaps()
589{
590 return cpu_id_leaf7_edx<3>();
591}
592bool cpu_has_fsrm()
593{
594 return cpu_id_leaf7_edx<4>();
595}
596bool cpu_has_pconfig()
597{
598 return cpu_id_leaf7_edx<18>();
599}
600// reserved
601bool cpu_has_ibt()
602{
603 return cpu_id_leaf7_edx<20>();
604}
605// reserved 5
606bool cpu_has_spec_ctrl()
607{
608 return cpu_id_leaf7_edx<26>();
609}
610bool cpu_has_stibp()
611{
612 return cpu_id_leaf7_edx<27>();
613}
614// reserved
615bool cpu_has_capabilities()
616{
617 return cpu_id_leaf7_edx<29>();
618}
619// reserved
620bool cpu_has_ssbd()
621{
622 return cpu_id_leaf7_edx<31>();
623}
624} // namespace hi::inline v1
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
DOXYGEN BUG.
Definition algorithm.hpp:15
T data(T... args)