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 "../utility/utility.hpp"
8#include "../macros.hpp"
9#include <array>
10
11#if HI_COMPILER == HI_CC_MSVC
12#include <intrin.h>
13#elif HI_COMPILER == HI_CC_GCC || HI_COMPILER == HI_CC_CLANG
14#include <cpuid.h>
15#else
16#error "Unsuported compiler for x64 cpu_id"
17#endif
18
19hi_export_module(hikogui.settings.cpu_id);
20
21namespace hi {
22inline namespace v1 {
23
24class cpu_id {
25public:
26 constexpr static uint32_t processor_type_OEM = 0;
27 constexpr static uint32_t processor_type_Intel_overdrive = 1;
28 constexpr static uint32_t processor_type_dual_processor = 2;
29
30 std::string vendor_id = {};
31 std::string brand_name = {};
32
33 uint32_t stepping_id:4 = 0;
34 uint32_t model_id:8 = 0;
35 uint32_t family_id:9 = 0;
36 uint32_t processor_type:2 = 0;
37
38 uint64_t features = 0;
39
40
41 size_t cache_flush_size = 0;
42
45 uint8_t APIC_id = 0;
46
47 cpu_id(cpu_id const &) noexcept = default;
51
53 {
54 hilet leaf0 = get_leaf(0);
55 hilet max_leaf = leaf0.a;
56
57 // vendor_id are 12 characters from ebx, edx, ecx in that order.
58 vendor_id.resize(12);
59 std::memcpy(vendor_id.data() + 0, leaf0.b, 4);
60 std::memcpy(vendor_id.data() + 4, leaf0.d, 4);
61 std::memcpy(vendor_id.data() + 8, leaf0.c, 4);
62
63 size_t brand_index = 0;
64 if (max_leaf >= 1) {
65 hilet leaf1 = get_leaf(1);
66
67 stepping_id = leaf1.a & 0xf;
68 model_id = (leaf1.a >> 4) & 0xf;
69 family_id = (leaf1.a >> 8) & 0xf;
70 processor_type = (leaf1.a >> 12) & 0x3;
71
72 if (family_id == 0x6 or family_id == 0xf) {
73 // Extended model is concatenated.
74 model_id |= ((leaf1.a >> 16) & 0xf) << 4;
75 }
76 if (family_id == 0xf) {
77 // Extended family is simply added.
78 family_id += (leaf1.a >> 20) & 0xff;
79 }
80
81 brand_index = leaf1.b & 0xff;
82 cache_flush_size = ((leaf1.b >> 8) & 0xff) * 8;
83 APIC_id = (leaf1.b >> 24) & 0xff;
84
85
86
87 }
88 }
89
90
91 [[nodiscard]] bool has_aesni() const noexcept
92 {
93 return to_bool(instruction_set & instruction_set_aesni);
94 }
95
96 [[nodiscard]] bool has_avx() const noexcept
97 {
98 return to_bool(instruction_set & instruction_set_avx);
99 }
100
101 [[nodiscard]] bool has_cmpxchg16b() const noexcept
102 {
103 return to_bool(instruction_set & instruction_set_cmpxchg16b);
104 }
105
106 [[nodiscard]] bool has_clfsh() const noexcept
107 {
108 return to_bool(instruction_set & instruction_set_clfsh);
109 }
110
111 [[nodiscard]] bool has_cmov() const noexcept
112 {
113 return to_bool(instruction_set & instruction_set_cmov);
114 }
115
116 [[nodiscard]] bool has_cx8() const noexcept
117 {
118 return to_bool(instruction_set & instruction_set_cx8);
119 }
120
121 [[nodiscard]] bool has_fma() const noexcept
122 {
123 return to_bool(instruction_set & instruction_set_fma);
124 }
125
126 [[nodiscard]] bool has_f16c() const noexcept
127 {
128 return to_bool(instruction_set & instruction_set_f16c);
129 }
130
131 [[nodiscard]] bool has_fxsr() const noexcept
132 {
133 return to_bool(instruction_set & instruction_set_fxsr);
134 }
135
136 [[nodiscard]] bool has_sse() const noexcept
137 {
138 return to_bool(instruction_set & instruction_set_sse);
139 }
140
141 [[nodiscard]] bool has_sse2() const noexcept
142 {
143 return to_bool(instruction_set & instruction_set_sse2);
144 }
145
146 [[nodiscard]] bool has_sse3() const noexcept
147 {
148 return to_bool(instruction_set & instruction_set_sse3);
149 }
150
151 [[nodiscard]] bool has_ssse3() const noexcept
152 {
153 return to_bool(instruction_set & instruction_set_ssse3);
154 }
155
156 [[nodiscard]] bool has_sse4_1() const noexcept
157 {
158 return to_bool(instruction_set & instruction_set_sse4_1);
159 }
160
161 [[nodiscard]] bool has_sse4_2() const noexcept
162 {
163 return to_bool(instruction_set & instruction_set_sse4_2);
164 }
165
166 [[nodiscard]] bool has_movbe() const noexcept
167 {
168 return to_bool(instruction_set & instruction_set_movbe);
169 }
170
171 [[nodiscard]] bool has_mmx() const noexcept
172 {
173 return to_bool(instruction_set & instruction_set_mmx);
174 }
175
176 [[nodiscard]] bool has_msr() const noexcept
177 {
178 return to_bool(instruction_set & instruction_set_msr);
179 }
180
181 [[nodiscard]] bool has_osxsave() const noexcept
182 {
183 return to_bool(instruction_set & instruction_set_osxsave);
184 }
185
186 [[nodiscard]] bool has_pclmulqdq() const noexcept
187 {
188 return to_bool(instruction_set & instruction_set_pclmulqdq);
189 }
190
191 [[nodiscard]] bool has_popcnt() const noexcept
192 {
193 return to_bool(instruction_set & instruction_set_popcnt);
194 }
195
196 [[nodiscard]] bool has_rdrand() const noexcept
197 {
198 return to_bool(instruction_set & instruction_set_rdrand);
199 }
200
201 [[nodiscard]] bool has_sep() const noexcept
202 {
203 return to_bool(instruction_set & instruction_set_sep);
204 }
205
206 [[nodiscard]] bool has_tsc() const noexcept
207 {
208 return to_bool(instruction_set & instruction_set_tsc);
209 }
210
211 [[nodiscard]] bool has_xsave() const noexcept
212 {
213 return to_bool(instruction_set & instruction_set_xsave);
214 }
215
216 [[nodiscard]] bool has_acpi() const noexcept
217 {
218 return to_bool(features & features_acpi);
219 }
220
221 [[nodiscard]] bool has_apic() const noexcept
222 {
223 return to_bool(features & features_apic);
224 }
225
226 [[nodiscard]] bool has_cnxt_id() const noexcept
227 {
228 return to_bool(features & features_cnxt_id);
229 }
230
231 [[nodiscard]] bool has_dca() const noexcept
232 {
233 return to_bool(features & features_dca);
234 }
235
236 [[nodiscard]] bool has_de() const noexcept
237 {
238 return to_bool(features & features_de);
239 }
240
241 [[nodiscard]] bool has_ds() const noexcept
242 {
243 return to_bool(features & features_ds);
244 }
245
246 [[nodiscard]] bool has_ds_cpl() const noexcept
247 {
248 return to_bool(features & features_ds_cpl);
249 }
250
251 [[nodiscard]] bool has_dtes64() const noexcept
252 {
253 return to_bool(features & features_dtes64);
254 }
255
256 [[nodiscard]] bool has_eist() const noexcept
257 {
258 return to_bool(features & features_eist);
259 }
260
261 [[nodiscard]] bool has_fpu() const noexcept
262 {
263 return to_bool(features & features_fpu);
264 }
265
266 [[nodiscard]] bool has_htt() const noexcept
267 {
268 return to_bool(features & features_htt);
269 }
270
271 [[nodiscard]] bool has_mca() const noexcept
272 {
273 return to_bool(features & features_mca);
274 }
275
276 [[nodiscard]] bool has_mce() const noexcept
277 {
278 return to_bool(features & features_mce);
279 }
280
281 [[nodiscard]] bool has_monitor() const noexcept
282 {
283 return to_bool(features & features_monitor);
284 }
285
286 [[nodiscard]] bool has_mttr() const noexcept
287 {
288 return to_bool(features & features_mttr);
289 }
290
291 [[nodiscard]] bool has_pae() const noexcept
292 {
293 return to_bool(features & features_pae);
294 }
295
296 [[nodiscard]] bool has_pat() const noexcept
297 {
298 return to_bool(features & features_pat);
299 }
300
301 [[nodiscard]] bool has_pbe() const noexcept
302 {
303 return to_bool(features & features_pbe);
304 }
305
306 [[nodiscard]] bool has_pcid() const noexcept
307 {
308 return to_bool(features & features_pcid);
309 }
310
311 [[nodiscard]] bool has_pdcm() const noexcept
312 {
313 return to_bool(features & features_pdcm);
314 }
315
316 [[nodiscard]] bool has_pge() const noexcept
317 {
318 return to_bool(features & features_pge);
319 }
320
321 [[nodiscard]] bool has_pse() const noexcept
322 {
323 return to_bool(features & features_pse);
324 }
325
326 [[nodiscard]] bool has_pse_36() const noexcept
327 {
328 return to_bool(features & features_pse_36);
329 }
330
331 [[nodiscard]] bool has_psn() const noexcept
332 {
333 return to_bool(features & features_psm);
334 }
335
336 [[nodiscard]] bool has_sdbg() const noexcept
337 {
338 return to_bool(features & features_sdbg);
339 }
340
341 [[nodiscard]] bool has_smx() const noexcept
342 {
343 return to_bool(features & features_smx);
344 }
345
346 [[nodiscard]] bool has_ss() const noexcept
347 {
348 return to_bool(features & features_ss);
349 }
350
351 [[nodiscard]] bool has_tm() const noexcept
352 {
353 return to_bool(features & features_tm);
354 }
355
356 [[nodiscard]] bool has_tm2() const noexcept
357 {
358 return to_bool(features & features_tm2);
359 }
360
361 [[nodiscard]] bool has_tsc_deadline() const noexcept
362 {
363 return to_bool(features & features_tsc_deadline);
364 }
365
366 [[nodiscard]] bool has_vme() const noexcept
367 {
368 return to_bool(features & features_vme);
369 }
370
371 [[nodiscard]] bool has_vmx() const noexcept
372 {
373 return to_bool(features & features_vmx);
374 }
375
376 [[nodiscard]] bool has_x2apic() const noexcept
377 {
378 return to_bool(features & features_x2apic);
379 }
380
381 [[nodiscard]] bool has_xtpr() const noexcept
382 {
383 return to_bool(features & features_xtpr);
384 }
385
386private:
387 // clang-format off
388 constexpr static uint64_t instruction_set_aesni = 0x0000'0000'0000'0001;
389 constexpr static uint64_t instruction_set_avx = 0x0000'0000'0000'0002;
390 constexpr static uint64_t instruction_set_cmpxchg16b = 0x0000'0000'0000'0004;
391 constexpr static uint64_t instruction_set_clfsh = 0x0000'0000'0000'0008;
392 constexpr static uint64_t instruction_set_cmov = 0x0000'0000'0000'0010;
393 constexpr static uint64_t instruction_set_cx8 = 0x0000'0000'0000'0020;
394 constexpr static uint64_t instruction_set_fma = 0x0000'0000'0000'0040;
395 constexpr static uint64_t instruction_set_f16c = 0x0000'0000'0000'0080;
396 constexpr static uint64_t instruction_set_fxsr = 0x0000'0000'0000'0100;
397 constexpr static uint64_t instruction_set_sse = 0x0000'0000'0000'0200;
398 constexpr static uint64_t instruction_set_sse2 = 0x0000'0000'0000'0300;
399 constexpr static uint64_t instruction_set_sse3 = 0x0000'0000'0000'0800;
400 constexpr static uint64_t instruction_set_ssse3 = 0x0000'0000'0000'1000;
401 constexpr static uint64_t instruction_set_sse4_1 = 0x0000'0000'0000'2000;
402 constexpr static uint64_t instruction_set_sse4_2 = 0x0000'0000'0000'4000;
403 constexpr static uint64_t instruction_set_movbe = 0x0000'0000'0000'8000;
404 constexpr static uint64_t instruction_set_mmx = 0x0000'0000'0001'0000;
405 constexpr static uint64_t instruction_set_msr = 0x0000'0000'0002'0000;
406 constexpr static uint64_t instruction_set_osxsave = 0x0000'0000'0004'0000;
407 constexpr static uint64_t instruction_set_pclmulqdq = 0x0000'0000'0008'0000;
408 constexpr static uint64_t instruction_set_popcnt = 0x0000'0000'0010'0000;
409 constexpr static uint64_t instruction_set_rdrand = 0x0000'0000'0020'0000;
410 constexpr static uint64_t instruction_set_sep = 0x0000'0000'0040'0000;
411 constexpr static uint64_t instruction_set_tsc = 0x0000'0000'0080'0000;
412 constexpr static uint64_t instruction_set_xsave = 0x0000'0000'0100'0000;
413
414 constexpr static uint64_t features_acpi = 0x0000'0000'0000'0001;
415 constexpr static uint64_t features_apic = 0x0000'0000'0000'0002;
416 constexpr static uint64_t features_cnxt_id = 0x0000'0000'0000'0004;
417 constexpr static uint64_t features_dca = 0x0000'0000'0000'0008;
418 constexpr static uint64_t features_de = 0x0000'0000'0000'0010;
419 constexpr static uint64_t features_ds = 0x0000'0000'0000'0020;
420 constexpr static uint64_t features_ds_cpl = 0x0000'0000'0000'0040;
421 constexpr static uint64_t features_dtes64 = 0x0000'0000'0000'0080;
422 constexpr static uint64_t features_eist = 0x0000'0000'0000'0100;
423 constexpr static uint64_t features_fpu = 0x0000'0000'0000'0200;
424 constexpr static uint64_t features_htt = 0x0000'0000'0000'0400;
425 constexpr static uint64_t features_mca = 0x0000'0000'0000'0800;
426 constexpr static uint64_t features_mce = 0x0000'0000'0000'1000;
427 constexpr static uint64_t features_monitor = 0x0000'0000'0000'2000;
428 constexpr static uint64_t features_mttr = 0x0000'0000'0000'4000;
429 constexpr static uint64_t features_pae = 0x0000'0000'0000'8000;
430 constexpr static uint64_t features_pat = 0x0000'0000'0001'0000;
431 constexpr static uint64_t features_pbe = 0x0000'0000'0002'0000;
432 constexpr static uint64_t features_pcid = 0x0000'0000'0004'0000;
433 constexpr static uint64_t features_pdcm = 0x0000'0000'0008'0000;
434 constexpr static uint64_t features_pge = 0x0000'0000'0010'0000;
435 constexpr static uint64_t features_pse = 0x0000'0000'0020'0000;
436 constexpr static uint64_t features_pse_36 = 0x0000'0000'0040'0000;
437 constexpr static uint64_t features_psn = 0x0000'0000'0080'0000;
438 constexpr static uint64_t features_sdbg = 0x0000'0000'0100'0000;
439 constexpr static uint64_t features_smx = 0x0000'0000'0200'0000;
440 constexpr static uint64_t features_ss = 0x0000'0000'0400'0000;
441 constexpr static uint64_t features_tm = 0x0000'0000'0800'0000;
442 constexpr static uint64_t features_tm2 = 0x0000'0000'1000'0000;
443 constexpr static uint64_t features_tsc_deadline = 0x0000'0000'2000'0000;
444 constexpr static uint64_t features_vme = 0x0000'0000'4000'0000;
445 constexpr static uint64_t features_vmx = 0x0000'0000'8000'0000;
446 constexpr static uint64_t features_x2apic = 0x0000'0001'0000'0000;
447 constexpr static uint64_t features_xtpr = 0x0000'0002'0000'0000;
448 // clang-format off
449
450 uint32_t instruction_set = 0;
451 uint64_t features = 0;
452
453 struct leaf_type {
454 uint32_t a; // EAX
455 uint32_t b; // EBX
456 uint32_t c; // ECX
457 uint32_t d; // EDX
458 };
459
460#if HI_COMPILER == HI_CC_MSVC
461
462 [[nodiscard]] static leaf_type get_leaf(uint32_t leaf_id, uint32_t index = 0) noexcept
463 {
465 int tmp[4];
466
468
469 std::memcpy(&r, tmp, sizeof(result_type));
470 return r;
471 }
472
473#elif HI_COMPILER == HI_CC_GCC || HI_COMPILER == HI_CC_CLANG
474
475 [[nodiscard]] static leaf_type get_leaf(uint32_t leaf_id, uint32_t index = 0) noexcept
476 {
478 __cpuid_count(leaf_id, index, r.a, r.b, r.c, r.d);
479 return r;
480 }
481
482#else
483#error "Unsuported compiler for x64 cpu_id"
484#endif
485};
486
487}}
488
DOXYGEN BUG.
Definition algorithm.hpp:16
geometry/margins.hpp
Definition lookahead_iterator.hpp:5
constexpr Out narrow_cast(In const &rhs) noexcept
Cast numeric values without loss of precision.
Definition cast.hpp:377
Definition cpu_id.hpp:24
uint8_t APIC_id
Local processor id.
Definition cpu_id.hpp:45
T data(T... args)
T memcpy(T... args)
T resize(T... args)