Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/google/cpu_features.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMykola Hohsadze <Mykola_Hohsadze@epam.com>2022-07-28 13:22:16 +0300
committerGitHub <noreply@github.com>2022-07-28 13:22:16 +0300
commit601471d527cfddfe76002baba13795576ba0eb72 (patch)
tree9e37b430d2f98d504b5c2476a8b5cf84d04a885f
parent677d6419b29a33e25cfba24a2220b7f97aacb7de (diff)
Add detection LZCNT (#254)
Fixes #253
-rw-r--r--include/cpuinfo_x86.h2
-rw-r--r--src/impl_x86__base_implementation.inl33
-rw-r--r--test/cpuinfo_x86_test.cc48
3 files changed, 63 insertions, 20 deletions
diff --git a/include/cpuinfo_x86.h b/include/cpuinfo_x86.h
index 9cb56e5..a7ca2c6 100644
--- a/include/cpuinfo_x86.h
+++ b/include/cpuinfo_x86.h
@@ -97,6 +97,7 @@ typedef struct {
int dca : 1;
int ss : 1;
int adx : 1;
+ int lzcnt : 1; // Note: this flag is called ABM for AMD, LZCNT for Intel.
// Make sure to update X86FeaturesEnum below if you add a field here.
} X86Features;
@@ -247,6 +248,7 @@ typedef enum {
X86_DCA,
X86_SS,
X86_ADX,
+ X86_LZCNT,
X86_LAST_,
} X86FeaturesEnum;
diff --git a/src/impl_x86__base_implementation.inl b/src/impl_x86__base_implementation.inl
index fb29547..8b97449 100644
--- a/src/impl_x86__base_implementation.inl
+++ b/src/impl_x86__base_implementation.inl
@@ -254,6 +254,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info,
const Leaf leaf_1 = leaves->leaf_1;
const Leaf leaf_7 = leaves->leaf_7;
const Leaf leaf_7_1 = leaves->leaf_7_1;
+ const Leaf leaf_80000001 = leaves->leaf_80000001;
const bool have_xsave = IsBitSet(leaf_1.ecx, 26);
const bool have_osxsave = IsBitSet(leaf_1.ecx, 27);
@@ -312,6 +313,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info,
features->vaes = IsBitSet(leaf_7.ecx, 9);
features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10);
features->adx = IsBitSet(leaf_7.ebx, 19);
+ features->lzcnt = IsBitSet(leaf_80000001.ecx, 5);
/////////////////////////////////////////////////////////////////////////////
// The following section is devoted to Vector Extensions.
@@ -406,8 +408,8 @@ X86Info GetX86Info(void) {
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
const bool is_hygon =
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE);
- const bool is_zhaoxin =
- (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) ||
+ const bool is_zhaoxin =
+ (IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_CENTAUR_HAULS) ||
IsVendor(leaves.leaf_0, CPU_FEATURES_VENDOR_SHANGHAI));
SetVendor(leaves.leaf_0, info.vendor);
if (is_intel || is_amd || is_hygon || is_zhaoxin) {
@@ -585,15 +587,15 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) {
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang
return ZHAOXIN_ZHANGJIANG;
case CPUID(0x07, 0x1B):
- // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
- return ZHAOXIN_WUDAOKOU;
+ // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
+ return ZHAOXIN_WUDAOKOU;
case CPUID(0x07, 0x3B):
- // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
- return ZHAOXIN_LUJIAZUI;
+ // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
+ return ZHAOXIN_LUJIAZUI;
case CPUID(0x07, 0x5B):
- return ZHAOXIN_YONGFENG;
+ return ZHAOXIN_YONGFENG;
default:
- return X86_UNKNOWN;
+ return X86_UNKNOWN;
}
}
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_SHANGHAI)) {
@@ -603,15 +605,15 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) {
// https://en.wikichip.org/wiki/zhaoxin/microarchitectures/zhangjiang
return ZHAOXIN_ZHANGJIANG;
case CPUID(0x07, 0x1B):
- // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
- return ZHAOXIN_WUDAOKOU;
+ // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/wudaokou
+ return ZHAOXIN_WUDAOKOU;
case CPUID(0x07, 0x3B):
- // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
- return ZHAOXIN_LUJIAZUI;
+ // https://en.wikichip.org/wiki/zhaoxin/microarchitectures/lujiazui
+ return ZHAOXIN_LUJIAZUI;
case CPUID(0x07, 0x5B):
- return ZHAOXIN_YONGFENG;
+ return ZHAOXIN_YONGFENG;
default:
- return X86_UNKNOWN;
+ return X86_UNKNOWN;
}
}
if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD)) {
@@ -1755,7 +1757,8 @@ CacheInfo GetX86CacheInfo(void) {
LINE(X86_RDRND, rdrnd, , , ) \
LINE(X86_DCA, dca, , , ) \
LINE(X86_SS, ss, , , ) \
- LINE(X86_ADX, adx, , , )
+ LINE(X86_ADX, adx, , , ) \
+ LINE(X86_LZCNT, lzcnt, , , )
#define INTROSPECTION_PREFIX X86
#define INTROSPECTION_ENUM_PREFIX X86
#include "define_introspection.inl"
diff --git a/test/cpuinfo_x86_test.cc b/test/cpuinfo_x86_test.cc
index 97a4beb..7814a02 100644
--- a/test/cpuinfo_x86_test.cc
+++ b/test/cpuinfo_x86_test.cc
@@ -20,7 +20,7 @@
#include <set>
#if defined(CPU_FEATURES_OS_WINDOWS)
#include "internal/windows_utils.h"
-#endif // CPU_FEATURES_OS_WINDOWS
+#endif // CPU_FEATURES_OS_WINDOWS
#include "filesystem_for_testing.h"
#include "gtest/gtest.h"
@@ -540,6 +540,27 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI) {
X86Microarchitecture::AMD_STREAMROLLER);
}
+// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F12_K15_Zambezi8C_CPUID.txt
+TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_ZAMBEZI_ABM) {
+ cpu().SetLeaves({
+ {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}},
+ {{0x00000001, 0}, Leaf{0x00600F12, 0x00080800, 0x1E98220B, 0x178BFBFF}},
+ {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}},
+ {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}},
+ {{0x80000001, 0}, Leaf{0x00600F12, 0x10000000, 0x01C9BFFF, 0x2FD3FBFF}},
+ });
+ const auto info = GetX86Info();
+
+ EXPECT_STREQ(info.vendor, "AuthenticAMD");
+ EXPECT_EQ(info.family, 0x15);
+ EXPECT_EQ(info.model, 0x01);
+
+ EXPECT_EQ(GetX86Microarchitecture(&info),
+ X86Microarchitecture::AMD_BULLDOZER);
+
+ EXPECT_TRUE(info.features.lzcnt);
+}
+
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0700F01_K16_Kabini_CPUID.txt
TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI) {
cpu().SetLeaves({
@@ -1110,8 +1131,7 @@ TEST_F(CpuidX86Test, INTEL_CML_U) {
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x8E);
EXPECT_EQ(info.stepping, 0x0C);
- EXPECT_EQ(GetX86Microarchitecture(&info),
- X86Microarchitecture::INTEL_CML);
+ EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML);
}
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00A0652_CometLake_CPUID1.txt
@@ -1125,8 +1145,26 @@ TEST_F(CpuidX86Test, INTEL_CML_H) {
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0xA5);
- EXPECT_EQ(GetX86Microarchitecture(&info),
- X86Microarchitecture::INTEL_CML);
+ EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML);
+}
+
+// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00306F2_HaswellEP2_CPUID.txt
+TEST_F(CpuidX86Test, INTEL_HASWELL_LZCNT) {
+ cpu().SetLeaves({
+ {{0x00000000, 0}, Leaf{0x0000000F, 0x756E6547, 0x6C65746E, 0x49656E69}},
+ {{0x00000001, 0}, Leaf{0x000306F2, 0x00200800, 0x7FFEFBFF, 0xBFEBFBFF}},
+ {{0x00000007, 0}, Leaf{0x00000000, 0x000037AB, 0x00000000, 0x00000000}},
+ {{0x80000000, 0}, Leaf{0x80000008, 0x00000000, 0x00000000, 0x00000000}},
+ {{0x80000001, 0}, Leaf{0x00000000, 0x00000000, 0x00000021, 0x2C100000}},
+ });
+ const auto info = GetX86Info();
+
+ EXPECT_STREQ(info.vendor, "GenuineIntel");
+ EXPECT_EQ(info.family, 0x06);
+ EXPECT_EQ(info.model, 0x3F);
+ EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_HSW);
+
+ EXPECT_TRUE(info.features.lzcnt);
}
// https://github.com/google/cpu_features/issues/200