Skip to content

Commit 8776156

Browse files
committed
Reduce x86_cpu_feature size
1 parent b5047a6 commit 8776156

File tree

1 file changed

+52
-64
lines changed

1 file changed

+52
-64
lines changed

include/xsimd/config/xsimd_cpu_features_x86.hpp

Lines changed: 52 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cassert>
1717
#include <cstdint>
1818
#include <cstring>
19+
#include <type_traits>
1920
#if __cplusplus >= 201703L
2021
#include <string_view>
2122
#endif
@@ -55,61 +56,60 @@ namespace xsimd
5556
template <typename E>
5657
using x86_reg32_bitset = utils::uint_bitset<E, x86_reg32_t>;
5758

59+
template <typename E, x86_reg32_t I>
60+
struct x86_reg_id
61+
{
62+
static constexpr x86_reg32_t index = I;
63+
using bits = E;
64+
};
65+
66+
template <x86_reg32_t K, typename... reg_ids>
67+
struct find_reg_k
68+
{
69+
using type = x86_reg_id<void, 0>;
70+
};
71+
72+
template <x86_reg32_t K, typename reg_id_head, typename... reg_id_tail>
73+
struct find_reg_k<K, reg_id_head, reg_id_tail...>
74+
{
75+
using type = std::conditional_t<
76+
reg_id_head::index == K,
77+
reg_id_head,
78+
typename find_reg_k<K, reg_id_tail...>::type>;
79+
};
80+
5881
template <x86_reg32_t leaf_num, x86_reg32_t subleaf_num,
59-
typename A, typename B, typename C, typename D>
82+
typename... reg_ids>
6083
class x86_cpuid_regs
61-
: private x86_reg32_bitset<A>,
62-
private x86_reg32_bitset<B>,
63-
private x86_reg32_bitset<C>,
64-
private x86_reg32_bitset<D>
84+
: private x86_reg32_bitset<typename reg_ids::bits>...
6585
{
6686
private:
67-
using eax_bitset = x86_reg32_bitset<A>;
68-
using ebx_bitset = x86_reg32_bitset<B>;
69-
using ecx_bitset = x86_reg32_bitset<C>;
70-
using edx_bitset = x86_reg32_bitset<D>;
71-
7287
/* Parse CPUINFO register value into individual bit components.*/
7388
constexpr explicit x86_cpuid_regs(const cpuid_reg_t& regs) noexcept
74-
: eax_bitset(regs[0])
75-
, ebx_bitset(regs[1])
76-
, ecx_bitset(regs[2])
77-
, edx_bitset(regs[3])
89+
: x86_reg32_bitset<typename reg_ids::bits>(regs[reg_ids::index])...
7890
{
7991
}
8092

8193
public:
82-
using eax = A;
83-
using ebx = B;
84-
using ecx = C;
85-
using edx = D;
8694
static constexpr x86_reg32_t leaf = leaf_num;
8795
static constexpr x86_reg32_t subleaf = subleaf_num;
8896

97+
using eax = typename find_reg_k<0, reg_ids...>::type::bits;
98+
using ebx = typename find_reg_k<1, reg_ids...>::type::bits;
99+
using ecx = typename find_reg_k<2, reg_ids...>::type::bits;
100+
using edx = typename find_reg_k<3, reg_ids...>::type::bits;
101+
89102
inline static x86_cpuid_regs read()
90103
{
91104
return x86_cpuid_regs(detail::x86_cpuid(leaf, subleaf));
92105
}
93106

94107
constexpr x86_cpuid_regs() noexcept = default;
95108

96-
using eax_bitset::all_bits_set;
97-
using eax_bitset::get_range;
98-
using ebx_bitset::all_bits_set;
99-
using ebx_bitset::get_range;
100-
using ecx_bitset::all_bits_set;
101-
using ecx_bitset::get_range;
102-
using edx_bitset::all_bits_set;
103-
using edx_bitset::get_range;
109+
using x86_reg32_bitset<typename reg_ids::bits>::all_bits_set...;
110+
using x86_reg32_bitset<typename reg_ids::bits>::get_range...;
104111
};
105112

106-
template <typename T>
107-
using make_x86_cpuid_regs = x86_cpuid_regs<T::leaf, T::subleaf,
108-
typename T::eax,
109-
typename T::ebx,
110-
typename T::ecx,
111-
typename T::edx>;
112-
113113
template <bool extended>
114114
struct x86_cpuid_highest_func
115115
{
@@ -298,12 +298,6 @@ namespace xsimd
298298
static constexpr detail::x86_reg32_t leaf = 1;
299299
static constexpr detail::x86_reg32_t subleaf = 0;
300300

301-
enum class eax
302-
{
303-
};
304-
enum class ebx
305-
{
306-
};
307301
enum class ecx
308302
{
309303
/* Streaming SIMD Extensions 3. */
@@ -328,6 +322,10 @@ namespace xsimd
328322
/* Streaming SIMD Extensions 2. */
329323
sse2 = 26,
330324
};
325+
326+
using regs_t = detail::x86_cpuid_regs<leaf, subleaf,
327+
detail::x86_reg_id<ecx, 2>,
328+
detail::x86_reg_id<edx, 3>>;
331329
};
332330

333331
/**
@@ -340,7 +338,7 @@ namespace xsimd
340338
*
341339
* @see https://en.wikipedia.org/wiki/CPUID
342340
*/
343-
using x86_cpuid_leaf1 = detail::make_x86_cpuid_regs<x86_cpuid_leaf1_traits>;
341+
using x86_cpuid_leaf1 = typename x86_cpuid_leaf1_traits::regs_t;
344342

345343
struct x86_cpuid_leaf7_traits
346344
{
@@ -386,9 +384,11 @@ namespace xsimd
386384
/* AVX-512 Vector Neural Network instructions. */
387385
avx512vnni_bw = 11,
388386
};
389-
enum class edx
390-
{
391-
};
387+
388+
using regs_t = detail::x86_cpuid_regs<leaf, subleaf,
389+
detail::x86_reg_id<eax, 0>,
390+
detail::x86_reg_id<ebx, 1>,
391+
detail::x86_reg_id<ecx, 2>>;
392392
};
393393

394394
/**
@@ -401,7 +401,7 @@ namespace xsimd
401401
*
402402
* @see https://en.wikipedia.org/wiki/CPUID
403403
*/
404-
using x86_cpuid_leaf7 = detail::make_x86_cpuid_regs<x86_cpuid_leaf7_traits>;
404+
using x86_cpuid_leaf7 = typename x86_cpuid_leaf7_traits::regs_t;
405405

406406
struct x86_cpuid_leaf7sub1_traits
407407
{
@@ -413,15 +413,9 @@ namespace xsimd
413413
/* AVX (VEX-encoded) Vector Neural Network instructions. */
414414
avxvnni = 4,
415415
};
416-
enum class ebx
417-
{
418-
};
419-
enum class ecx
420-
{
421-
};
422-
enum class edx
423-
{
424-
};
416+
417+
using regs_t = detail::x86_cpuid_regs<leaf, subleaf,
418+
detail::x86_reg_id<eax, 0>>;
425419
};
426420

427421
/**
@@ -434,7 +428,7 @@ namespace xsimd
434428
*
435429
* @see https://en.wikipedia.org/wiki/CPUID
436430
*/
437-
using x86_cpuid_leaf7sub1 = detail::make_x86_cpuid_regs<x86_cpuid_leaf7sub1_traits>;
431+
using x86_cpuid_leaf7sub1 = typename x86_cpuid_leaf7sub1_traits::regs_t;
438432

439433
/**
440434
* Highest Extended CPUID Function Parameter (EAX=0x80000000).
@@ -451,20 +445,14 @@ namespace xsimd
451445
static constexpr detail::x86_reg32_t leaf = 0x80000001;
452446
static constexpr detail::x86_reg32_t subleaf = 0;
453447

454-
enum class eax
455-
{
456-
};
457-
enum class ebx
458-
{
459-
};
460448
enum class ecx
461449
{
462450
/* AMD Fused multiply-add with 4 operands (FMA4). */
463451
fma4 = 16,
464452
};
465-
enum class edx
466-
{
467-
};
453+
454+
using regs_t = detail::x86_cpuid_regs<leaf, subleaf,
455+
detail::x86_reg_id<ecx, 2>>;
468456
};
469457

470458
/**
@@ -477,7 +465,7 @@ namespace xsimd
477465
*
478466
* @see https://en.wikipedia.org/wiki/CPUID
479467
*/
480-
using x86_cpuid_leaf80000001 = detail::make_x86_cpuid_regs<x86_cpuid_leaf80000001_traits>;
468+
using x86_cpuid_leaf80000001 = typename x86_cpuid_leaf80000001_traits::regs_t;
481469

482470
/*
483471
* Extended Control Register 0 (XCR0).

0 commit comments

Comments
 (0)