aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomahawkd <20868632+Tomahawkd@users.noreply.github.com>2023-08-28 22:25:24 +0800
committerGitHub <noreply@github.com>2023-08-28 16:25:24 +0200
commitb5cb91b35c7b498ee44e870c077c5325acc30c11 (patch)
tree1d04176f0cac48d07b7f5ecfb7d4532cb4809c03
parenta89e3b55697d567502de0c549fc9f6703cd7e25e (diff)
downloadcpu_features-b5cb91b35c7b498ee44e870c077c5325acc30c11.tar.gz
Add Intel LAM/AMD UAI feature detection in X86_64 (#315)
* Add Intel LAM/AMD UAI features in X86 * Add AMD UAI test for AMD_K19_ZEN4_RAPHAEL * Add separate UAI for AMD
-rw-r--r--include/cpuinfo_x86.h5
-rw-r--r--src/impl_x86__base_implementation.inl10
-rw-r--r--test/cpuinfo_x86_test.cc4
3 files changed, 18 insertions, 1 deletions
diff --git a/include/cpuinfo_x86.h b/include/cpuinfo_x86.h
index e897500..6f24e4b 100644
--- a/include/cpuinfo_x86.h
+++ b/include/cpuinfo_x86.h
@@ -107,6 +107,9 @@ typedef struct {
int fz_rep_movsb : 1; // Fast zero-length REP MOVSB
int fs_rep_stosb : 1; // Fast short REP STOSB
int fs_rep_cmpsb_scasb : 1; // Fast short REP CMPSB/SCASB
+
+ int lam: 1; // Intel Linear Address Mask
+ int uai: 1; // AMD Upper Address Ignore
// Make sure to update X86FeaturesEnum below if you add a field here.
} X86Features;
@@ -270,6 +273,8 @@ typedef enum {
X86_FZ_REP_MOVSB,
X86_FS_REP_STOSB,
X86_FS_REP_CMPSB_SCASB,
+ X86_LAM,
+ X86_UAI,
X86_LAST_,
} X86FeaturesEnum;
diff --git a/src/impl_x86__base_implementation.inl b/src/impl_x86__base_implementation.inl
index 6a34bff..a7faad3 100644
--- a/src/impl_x86__base_implementation.inl
+++ b/src/impl_x86__base_implementation.inl
@@ -166,6 +166,7 @@ typedef struct {
Leaf leaf_80000002; // brand string
Leaf leaf_80000003; // brand string
Leaf leaf_80000004; // brand string
+ Leaf leaf_80000021; // AMD Extended Feature Identification 2
} Leaves;
static Leaves ReadLeaves(void) {
@@ -186,6 +187,7 @@ static Leaves ReadLeaves(void) {
.leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0),
.leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0),
.leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0),
+ .leaf_80000021 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000021, 0),
};
}
@@ -390,6 +392,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info,
features->fs_rep_cmpsb_scasb = IsBitSet(leaf_7_1.eax, 12);
features->adx = IsBitSet(leaf_7.ebx, 19);
features->lzcnt = IsBitSet(leaf_80000001.ecx, 5);
+ features->lam = IsBitSet(leaf_7_1.eax, 26);
/////////////////////////////////////////////////////////////////////////////
// The following section is devoted to Vector Extensions.
@@ -462,6 +465,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info,
static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
OsPreserves os_preserves) {
const Leaf leaf_80000001 = leaves->leaf_80000001;
+ const Leaf leaf_80000021 = leaves->leaf_80000021;
X86Features* const features = &info->features;
@@ -472,6 +476,8 @@ static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
if (os_preserves.avx_registers) {
features->fma4 = IsBitSet(leaf_80000001.ecx, 16);
}
+
+ features->uai = IsBitSet(leaf_80000021.eax, 7);
}
static const X86Info kEmptyX86Info;
@@ -1984,7 +1990,9 @@ CacheInfo GetX86CacheInfo(void) {
LINE(X86_FS_REP_MOV, fs_rep_mov, , , ) \
LINE(X86_FZ_REP_MOVSB, fz_rep_movsb, , , ) \
LINE(X86_FS_REP_STOSB, fs_rep_stosb, , , ) \
- LINE(X86_FS_REP_CMPSB_SCASB, fs_rep_cmpsb_scasb, , , )
+ LINE(X86_FS_REP_CMPSB_SCASB, fs_rep_cmpsb_scasb, , , ) \
+ LINE(X86_LAM, lam, , , ) \
+ LINE(X86_UAI, uai, , , )
#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 de271cc..c9469a7 100644
--- a/test/cpuinfo_x86_test.cc
+++ b/test/cpuinfo_x86_test.cc
@@ -184,6 +184,8 @@ TEST_F(CpuidX86Test, SandyBridge) {
EXPECT_FALSE(features.movbe);
EXPECT_FALSE(features.rdrnd);
EXPECT_FALSE(features.adx);
+ EXPECT_FALSE(features.lam);
+ EXPECT_FALSE(features.uai);
}
const int UNDEF = -1;
@@ -894,6 +896,7 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL) {
{{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2035206E, 0x30303637}},
{{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}},
{{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}},
+ {{0x80000021, 0}, Leaf{0x00062FCF, 0x0000015C, 0x00000000, 0x00000000}},
});
const auto info = GetX86Info();
@@ -902,6 +905,7 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL) {
EXPECT_EQ(info.model, 0x61);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 5 7600X 6-Core Processor ");
+ EXPECT_TRUE(info.features.uai);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
}