Cpu_features: remove internal FillX86BrandString usage, windows improvements, add macros for RISCV hwcaps

This commit is contained in:
Carles Fernandez 2022-07-26 08:27:20 +02:00
parent ecfbd11079
commit 9dbd24bcce
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
7 changed files with 99 additions and 88 deletions

View File

@ -82,6 +82,7 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
elseif(PROCESSOR_IS_X86)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/windows_utils.h)
elseif(PROCESSOR_IS_POWER)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h)
else()

View File

@ -362,6 +362,8 @@
// Communicates to the compiler that the function is now deprecated
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#define CPU_FEATURES_DEPRECATED(message) __attribute__((deprecated(message)))
#elif defined(CPU_FEATURES_COMPILER_MSC)
#define CPU_FEATURES_DEPRECATED(message) __declspec(deprecated(message))
#else
#define CPU_FEATURES_DEPRECATED(message)
#endif

View File

@ -164,6 +164,17 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000
#endif
// https://elixir.bootlin.com/linux/latest/source/arch/riscv/include/uapi/asm/hwcap.h
#define RISCV_HWCAP_A (1UL << ('A' - 'A'))
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
#define RISCV_HWCAP_E (1UL << ('E' - 'A'))
#define RISCV_HWCAP_F (1UL << ('F' - 'A'))
#define RISCV_HWCAP_I (1UL << ('I' - 'A'))
#define RISCV_HWCAP_M (1UL << ('M' - 'A'))
#define RISCV_HWCAP_V (1UL << ('V' - 'A'))
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
typedef struct
{
unsigned long hwcaps;

View File

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: 2022 Google LLC
// SPDX-License-Identifier: Apache-2.0
#ifndef CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_
#define CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_
#include <windows.h> // IsProcessorFeaturePresent
// modern WinSDK winnt.h contains newer features detection definitions
#if !defined(PF_SSSE3_INSTRUCTIONS_AVAILABLE)
#define PF_SSSE3_INSTRUCTIONS_AVAILABLE 36
#endif
#if !defined(PF_SSE4_1_INSTRUCTIONS_AVAILABLE)
#define PF_SSE4_1_INSTRUCTIONS_AVAILABLE 37
#endif
#if !defined(PF_SSE4_2_INSTRUCTIONS_AVAILABLE)
#define PF_SSE4_2_INSTRUCTIONS_AVAILABLE 38
#endif
#endif // CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_

View File

@ -14,7 +14,7 @@ static void OverrideOsPreserves(OsPreserves* os_preserves)
// No override
}
#include <windows.h> // IsProcessorFeaturePresent
#include "internal/windows_utils.h"
#if defined(CPU_FEATURES_MOCK_CPUID_X86)
extern bool GetWindowsIsProcessorFeaturePresent(DWORD);
@ -35,16 +35,15 @@ static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
features->sse3 =
GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
features->ssse3 =
GetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
features->sse4_1 =
GetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
features->sse4_2 =
GetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
// https://github.com/google/cpu_features/issues/200
#if (_WIN32_WINNT >= 0x0601) // Win7+
if (GetX86Microarchitecture(info) == INTEL_WSM)
{
features->ssse3 = true;
features->sse4_1 = true;
features->sse4_2 = true;
}
#endif
// do not bother checking PF_AVX*
// cause AVX enabled processor will have XCR0 be exposed and this function will be skipped at all
}
#endif // CPU_FEATURES_OS_WINDOWS

View File

@ -392,9 +392,8 @@ static Node* CreateTree(void)
char brand_string[49];
const X86Info info = GetX86Info();
const CacheInfo cache_info = GetX86CacheInfo();
FillX86BrandString(brand_string);
AddMapEntry(root, "arch", CreateString("x86"));
AddMapEntry(root, "brand", CreateString(brand_string));
AddMapEntry(root, "brand", CreateString(info.brand_string));
AddMapEntry(root, "family", CreateInt(info.family));
AddMapEntry(root, "model", CreateInt(info.model));
AddMapEntry(root, "stepping", CreateInt(info.stepping));

View File

@ -216,9 +216,8 @@ TEST_F(CpuidX86Test, Branding)
{{0x80000003, 0}, Leaf{0x37692029, 0x3035362D, 0x43205530, 0x40205550}},
{{0x80000004, 0}, Leaf{0x352E3220, 0x7A484730, 0x00000000, 0x00000000}},
});
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz");
const auto info = GetX86Info();
EXPECT_STREQ(info.brand_string, "Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz");
}
TEST_F(CpuidX86Test, KabyLakeCache)
@ -436,10 +435,6 @@ TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE)
"AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_EXCAVATOR);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F20_K15_AbuDhabi_CPUID0.txt
@ -465,9 +460,7 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI)
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_PILEDRIVER);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Opteron(tm) Processor 6376 ");
EXPECT_STREQ(info.brand_string, "AMD Opteron(tm) Processor 6376 ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F20_K15_AbuDhabi_CPUID0.txt
@ -541,10 +534,6 @@ TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS)
"AMD Opteron(TM) Processor 6238 ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_BULLDOZER);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Opteron(TM) Processor 6238 ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD0630F81_K15_Godavari_CPUID.txt
@ -571,10 +560,6 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI)
"AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_STREAMROLLER);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0700F01_K16_Kabini_CPUID.txt
@ -598,10 +583,6 @@ TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI)
EXPECT_STREQ(info.brand_string,
"AMD A4-5000 APU with Radeon(TM) HD Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A4-5000 APU with Radeon(TM) HD Graphics ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0730F01_K16_Beema_CPUID2.txt
@ -625,10 +606,6 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA)
EXPECT_STREQ(info.brand_string,
"AMD A6-6310 APU with AMD Radeon R4 Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD A6-6310 APU with AMD Radeon R4 Graphics ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0820F01_K17_Dali_CPUID.txt
@ -652,10 +629,6 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI)
EXPECT_STREQ(info.brand_string,
"AMD 3020e with Radeon Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD 3020e with Radeon Graphics ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0800F82_K17_ZenP_CPUID.txt
@ -679,10 +652,6 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE)
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 7 2700X Eight-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Ryzen 7 2700X Eight-Core Processor ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0840F70_K17_CPUID.txt
@ -705,10 +674,6 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
EXPECT_EQ(info.model, 0x47);
EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
}
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID3.txt
@ -732,10 +697,6 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
EXPECT_STREQ(info.brand_string,
"Hygon C86 3185 8-core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "Hygon C86 3185 8-core Processor ");
}
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID.txt
@ -808,10 +769,6 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER)
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 9 5900X 12-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "AMD Ryzen 9 5900X 12-Core Processor ");
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A40F41_K19_Rembrandt_03_CPUID.txt
@ -867,6 +824,9 @@ TEST_F(CpuidX86Test, Nehalem)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_MACOS)
cpu().SetDarwinSysCtlByName("hw.optional.sse");
cpu().SetDarwinSysCtlByName("hw.optional.sse2");
@ -927,20 +887,12 @@ flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
"Genuine Intel(R) CPU @ 0000 @ 1.87GHz");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "Genuine Intel(R) CPU @ 0000 @ 1.87GHz");
EXPECT_TRUE(info.features.sse);
EXPECT_TRUE(info.features.sse2);
EXPECT_TRUE(info.features.sse3);
#if !defined(CPU_FEATURES_OS_WINDOWS)
// Currently disabled on Windows as IsProcessorFeaturePresent do not support
// feature detection > sse3.
EXPECT_TRUE(info.features.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0030673_Silvermont3_CPUID.txt
@ -952,6 +904,9 @@ TEST_F(CpuidX86Test, Atom)
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
#elif defined(CPU_FEATURES_OS_MACOS)
cpu().SetDarwinSysCtlByName("hw.optional.sse");
cpu().SetDarwinSysCtlByName("hw.optional.sse2");
@ -1012,20 +967,12 @@ flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_ATOM_SMT);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, " Intel(R) Celeron(R) CPU J1900 @ 1.99GHz");
EXPECT_TRUE(info.features.sse);
EXPECT_TRUE(info.features.sse2);
EXPECT_TRUE(info.features.sse3);
#if !defined(CPU_FEATURES_OS_WINDOWS)
// Currently disabled on Windows as IsProcessorFeaturePresent do not support
// feature detection > sse3.
EXPECT_TRUE(info.features.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// https://www.felixcloutier.com/x86/cpuid#example-3-1--example-of-cache-and-tlb-interpretation
@ -1120,21 +1067,13 @@ flags : fpu mmx sse
EXPECT_STREQ(info.brand_string, "");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN);
char brand_string[49];
FillX86BrandString(brand_string);
EXPECT_STREQ(brand_string, "");
EXPECT_TRUE(info.features.mmx);
EXPECT_TRUE(info.features.sse);
EXPECT_FALSE(info.features.sse2);
EXPECT_FALSE(info.features.sse3);
#if !defined(CPU_FEATURES_OS_WINDOWS)
// Currently disabled on Windows as IsProcessorFeaturePresent do not support
// feature detection > sse3.
EXPECT_FALSE(info.features.ssse3);
EXPECT_FALSE(info.features.sse4_1);
EXPECT_FALSE(info.features.sse4_2);
#endif // !defined(CPU_FEATURES_OS_WINDOWS)
}
// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000480_486_CPUID.txt
@ -1199,11 +1138,53 @@ TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING)
X86Microarchitecture::INTEL_KNIGHTS_L);
}
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00806EC_CometLake_CPUID2.txt
TEST_F(CpuidX86Test, INTEL_CML_U)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000806EC, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x8E);
EXPECT_EQ(info.stepping, 0x0C);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_CML);
}
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00A0652_CometLake_CPUID1.txt
TEST_F(CpuidX86Test, INTEL_CML_H)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000A0652, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, "GenuineIntel");
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0xA5);
EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_CML);
}
// https://github.com/google/cpu_features/issues/200
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt
#if defined(CPU_FEATURES_OS_WINDOWS)
TEST_F(CpuidX86Test, WIN_INTEL_WESTMERE_EX)
{
// Pre AVX cpus don't have xsave
cpu().SetOsBackupsExtendedRegisters(false);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSSE3_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_1_INSTRUCTIONS_AVAILABLE);
cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000206F2, 0x00400800, 0x02BEE3FF, 0xBFEBFBFF}},
@ -1214,15 +1195,12 @@ TEST_F(CpuidX86Test, WIN_INTEL_WESTMERE_EX)
EXPECT_EQ(info.model, 0x2F);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_WSM);
#if (_WIN32_WINNT < 0x0601) // before Win7
EXPECT_FALSE(info.features.ssse3);
EXPECT_FALSE(info.features.sse4_1);
EXPECT_FALSE(info.features.sse4_2);
#else
EXPECT_TRUE(info.features.sse);
EXPECT_TRUE(info.features.sse2);
EXPECT_TRUE(info.features.sse3);
EXPECT_TRUE(info.features.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif
}
#endif // CPU_FEATURES_OS_WINDOWS