diff --git a/include/internal/cpuid_x86.h b/include/internal/cpuid_x86.h index 9dcee0d..754ca38 100644 --- a/include/internal/cpuid_x86.h +++ b/include/internal/cpuid_x86.h @@ -26,8 +26,7 @@ typedef struct { uint32_t eax, ebx, ecx, edx; } Leaf; -// Retrieves the leaf for a particular cpuid. -Leaf CpuId(uint32_t leaf_id); +Leaf CpuIdEx(uint32_t leaf_id, int ecx); // Returns the eax value of the XCR0 register. uint32_t GetXCR0Eax(void); diff --git a/src/cpuinfo_x86.c b/src/cpuinfo_x86.c index 564f295..ea56c14 100644 --- a/src/cpuinfo_x86.c +++ b/src/cpuinfo_x86.c @@ -33,9 +33,9 @@ #include -Leaf CpuId(uint32_t leaf_id) { +Leaf CpuIdEx(uint32_t leaf_id, int ecx) { Leaf leaf; - __cpuid_count(leaf_id, 0, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx); + __cpuid_count(leaf_id, ecx, leaf.eax, leaf.ebx, leaf.ecx, leaf.edx); return leaf; } @@ -53,10 +53,10 @@ uint32_t GetXCR0Eax(void) { #include #include // For __cpuidex() -Leaf CpuId(uint32_t leaf_id) { +Leaf CpuIdEx(uint32_t leaf_id, int ecx) { Leaf leaf; int data[4]; - __cpuid(data, leaf_id); + __cpuidex(data, leaf_id, ecx); leaf.eax = data[0]; leaf.ebx = data[1]; leaf.ecx = data[2]; @@ -70,16 +70,24 @@ uint32_t GetXCR0Eax(void) { return _xgetbv(0); } #error "Unsupported compiler, x86 cpuid requires either GCC, Clang or MSVC." #endif +static Leaf CpuId(uint32_t leaf_id) { + return CpuIdEx(leaf_id, 0); +} + static const Leaf kEmptyLeaf; -static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) { +static Leaf SafeCpuIdEx(uint32_t max_cpuid_leaf, uint32_t leaf_id, int ecx) { if (leaf_id <= max_cpuid_leaf) { - return CpuId(leaf_id); + return CpuIdEx(leaf_id, ecx); } else { return kEmptyLeaf; } } +static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) { + return SafeCpuIdEx(max_cpuid_leaf, leaf_id, 0); +} + #define MASK_XMM 0x2 #define MASK_YMM 0x4 #define MASK_MASKREG 0x20 diff --git a/test/cpuinfo_x86_test.cc b/test/cpuinfo_x86_test.cc index 2389de9..98d26c6 100644 --- a/test/cpuinfo_x86_test.cc +++ b/test/cpuinfo_x86_test.cc @@ -25,7 +25,7 @@ namespace cpu_features { class FakeCpu { public: - Leaf CpuId(uint32_t leaf_id) const { + Leaf CpuIdEx(uint32_t leaf_id, int ecx) const { const auto itr = cpuid_leaves_.find(leaf_id); EXPECT_TRUE(itr != cpuid_leaves_.end()) << "Missing leaf " << leaf_id; return itr->second; @@ -48,7 +48,8 @@ class FakeCpu { auto* g_fake_cpu = new FakeCpu(); -extern "C" Leaf CpuId(uint32_t leaf_id) { return g_fake_cpu->CpuId(leaf_id); } +extern "C" Leaf CpuIdEx(uint32_t leaf_id, int ecx) { return g_fake_cpu->CpuIdEx(leaf_id, ecx); } + extern "C" uint32_t GetXCR0Eax(void) { return g_fake_cpu->GetXCR0Eax(); } namespace {