27 std::int32_t eax, ebx, ecx, edx;
35 cpuid_t cpuid(std::int32_t eax, std::int32_t ecx)
noexcept;
60 std::uint32_t max_basic_leaf = 0;
61 std::uint32_t leaf1_ecx = 0, leaf1_edx = 0, leaf7_ebx = 0;
98 constexpr std::array<char,13> vendor_identifier(
cpuid_t leaf)
noexcept {
99 std::array<char,13> result{};
100 std::uint32_t words[]{std::uint32_t(leaf.ebx),std::uint32_t(leaf.edx),std::uint32_t(leaf.ecx)};
101 for(
unsigned word=0;word!=3;++word)
102 for(
unsigned byte=0;
byte!=4;++byte)
103 result[4*word+
byte]=
char((words[word]>>(8*
byte))&0xff);
106 constexpr enum cpu_vendor identify_vendor(std::array<char,13>
const &
id)
noexcept {
107 std::string_view name{
id.data(),12};
112 static_assert(identify_vendor(vendor_identifier({0,0x756e6547,0x6c65746e,0x49656e69}))==
cpu_vendor::intel);
113 static_assert(identify_vendor(vendor_identifier({0,0x68747541,0x444d4163,0x69746e65}))==
cpu_vendor::amd);
120 __cpuidex(registers, eax, ecx);
121 return {registers[0], registers[1], registers[2], registers[3]};
124 __cpuid_count(eax, ecx, result.eax, result.ebx, result.ecx, result.edx);
132 auto identity=
cpuid(0,0);
133 result.
raw.max_basic_leaf = std::uint32_t(identity.eax);
134 result.
vendor_id=detail::vendor_identifier(identity);
136 if (result.
raw.max_basic_leaf >= 1) {
137 auto leaf =
cpuid(1, 0);
138 result.
raw.leaf1_ecx = std::uint32_t(leaf.ecx);
139 result.
raw.leaf1_edx = std::uint32_t(leaf.edx);
140 constexpr auto xsave = (1u << 26) | (1u << 27);
141 if ((result.
raw.leaf1_ecx & xsave) == xsave) {
143 result.
xcr0 = _xgetbv(0);
145 std::uint32_t low, high;
146 __asm__(
"xgetbv" :
"=a"(low),
"=d"(high) :
"c"(0));
147 result.
xcr0 = std::uint64_t(low) | (std::uint64_t(high) << 32);
152 if (result.
raw.max_basic_leaf >= 7) {
153 auto leaf =
cpuid(7, 0);
154 result.
raw.leaf7_ebx = std::uint32_t(leaf.ebx);
159 auto subleaf =
cpuid(7, 1);
166 result.
raw.extended1_ecx=std::uint32_t(
cpuid(std::int32_t(0x80000001u),0).ecx);
167 auto features=detail::decode_x86_features(result.
raw);
168 result.
present=features.present;
174 return detail::identify_vendor(detail::vendor_identifier(
cpuid(0,0)));
Compiler attributes for host code, with shader-safe shared modifiers.
cpuid_t cpuid(std::int32_t eax, std::int32_t ecx) noexcept
#define native_nodiscard
C++17 [[nodiscard]].
Architecture-tagged vectors, register packs and supporting value types. Native arithmetic follows its...
x86_capabilities observe_x86_capabilities() noexcept
Capture CPUID and, only with XSAVE and OSXSAVE, XCR0. No ISA profile required.
cpu_vendor
Recognized CPUID vendor strings; vendor identity alone does not imply features.
@ intel
CPUID reports GenuineIntel.
@ amd
CPUID reports AuthenticAMD.
@ unknown
Any other vendor string.
A structural set of one family's features, without prerequisite closure.
CPUID query inputs retained for diagnostics, not a second admission source.
std::uint32_t leaf7_1_edx
std::uint32_t max_leaf7_subleaf
std::uint32_t leaf7_1_eax
std::uint32_t max_extended_leaf
std::uint32_t leaf7_edx
CPUID.7.0 EDX; bit 23 reports AVX512_FP16. Zero without leaf 7.
enum cpu_vendor vendor
Classification of vendor_id; it does not establish instruction support.
std::array< char, 13 > vendor_id
Exact CPUID vendor identifier, followed by a zero terminator.
std::uint64_t xcr0
OS-enabled vector state. Used only when xcr0_observed is true.
isa< x86 > present
Features whose queries succeeded and reported support; no compiler closure.
bool xcr0_observed
True after XSAVE/OSXSAVE permit XGETBV and its result was captured.
raw_observations raw
Diagnostic snapshot; editing it does not update present/observed or XCR0.
isa< x86 > observed
Features whose CPUID leaves were available, whether present or absent.