1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 12:10:34 +00:00

Update cpu_features to commit 40e1c7158ddfbdae477751948750e0121aba55a1

This commit is contained in:
Carles Fernandez 2022-02-23 13:04:24 +01:00
parent c61cd6180e
commit c479d9cf5e
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
12 changed files with 165 additions and 77 deletions

View File

@ -16,7 +16,7 @@ For API / ABI compatibility reasons, it is recommended to build and use
cpu_features in a subdirectory of your project or as an embedded dependency. cpu_features in a subdirectory of your project or as an embedded dependency.
This is similar to the recommended usage of the googletest framework ( This is similar to the recommended usage of the googletest framework (
https://github.com/google/googletest/blob/master/googletest/README.md ) https://github.com/google/googletest/blob/main/googletest/README.md )
Build and use step-by-step Build and use step-by-step

View File

@ -223,11 +223,18 @@
// Communicates to the compiler that the block is unreachable // Communicates to the compiler that the block is unreachable
#if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC) #if defined(CPU_FEATURES_COMPILER_CLANG) || defined(CPU_FEATURES_COMPILER_GCC)
#define UNREACHABLE() __builtin_unreachable() #define CPU_FEATURES_UNREACHABLE() __builtin_unreachable()
#elif defined(CPU_FEATURES_COMPILER_MSC) #elif defined(CPU_FEATURES_COMPILER_MSC)
#define UNREACHABLE() __assume(0) #define CPU_FEATURES_UNREACHABLE() __assume(0)
#else #else
#define UNREACHABLE() #define CPU_FEATURES_UNREACHABLE()
#endif
// 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)))
#else
#define CPU_FEATURES_DEPRECATED(message)
#endif #endif
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_

View File

@ -13,6 +13,8 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define CPU_FEATURES_VENDOR_GENUINE_INTEL "GenuineIntel" #define CPU_FEATURES_VENDOR_GENUINE_INTEL "GenuineIntel"
#define CPU_FEATURES_VENDOR_AUTHENTIC_AMD "AuthenticAMD" #define CPU_FEATURES_VENDOR_AUTHENTIC_AMD "AuthenticAMD"
#define CPU_FEATURES_VENDOR_HYGON_GENUINE "HygonGenuine" #define CPU_FEATURES_VENDOR_HYGON_GENUINE "HygonGenuine"
#define CPU_FEATURES_VENDOR_CENTAUR_HAULS "CentaurHauls"
#define CPU_FEATURES_VENDOR_SHANGHAI " Shanghai "
// See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features. // See https://en.wikipedia.org/wiki/CPUID for a list of x86 cpu features.
// The field names are based on the short name provided in the wikipedia tables. // The field names are based on the short name provided in the wikipedia tables.
@ -93,7 +95,8 @@ typedef struct
int family; int family;
int model; int model;
int stepping; int stepping;
char vendor[13]; // 0 terminated string char vendor[13]; // 0 terminated string
char brand_string[49]; // 0 terminated string
} X86Info; } X86Info;
// Calls cpuid and returns an initialized X86info. // Calls cpuid and returns an initialized X86info.
@ -107,50 +110,54 @@ CacheInfo GetX86CacheInfo(void);
typedef enum typedef enum
{ {
X86_UNKNOWN, X86_UNKNOWN,
INTEL_80486, // 80486 ZHAOXIN_ZHANGJIANG, // ZhangJiang
INTEL_P5, // P5 ZHAOXIN_WUDAOKOU, // WuDaoKou
INTEL_LAKEMONT, // LAKEMONT ZHAOXIN_LUJIAZUI, // LuJiaZui
INTEL_CORE, // CORE ZHAOXIN_YONGFENG, // YongFeng
INTEL_PNR, // PENRYN INTEL_80486, // 80486
INTEL_NHM, // NEHALEM INTEL_P5, // P5
INTEL_ATOM_BNL, // BONNELL INTEL_LAKEMONT, // LAKEMONT
INTEL_WSM, // WESTMERE INTEL_CORE, // CORE
INTEL_SNB, // SANDYBRIDGE INTEL_PNR, // PENRYN
INTEL_IVB, // IVYBRIDGE INTEL_NHM, // NEHALEM
INTEL_ATOM_SMT, // SILVERMONT INTEL_ATOM_BNL, // BONNELL
INTEL_HSW, // HASWELL INTEL_WSM, // WESTMERE
INTEL_BDW, // BROADWELL INTEL_SNB, // SANDYBRIDGE
INTEL_SKL, // SKYLAKE INTEL_IVB, // IVYBRIDGE
INTEL_ATOM_GMT, // GOLDMONT INTEL_ATOM_SMT, // SILVERMONT
INTEL_KBL, // KABY LAKE INTEL_HSW, // HASWELL
INTEL_CFL, // COFFEE LAKE INTEL_BDW, // BROADWELL
INTEL_WHL, // WHISKEY LAKE INTEL_SKL, // SKYLAKE
INTEL_CNL, // CANNON LAKE INTEL_ATOM_GMT, // GOLDMONT
INTEL_ICL, // ICE LAKE INTEL_KBL, // KABY LAKE
INTEL_TGL, // TIGER LAKE INTEL_CFL, // COFFEE LAKE
INTEL_SPR, // SAPPHIRE RAPIDS INTEL_WHL, // WHISKEY LAKE
INTEL_ADL, // ALDER LAKE INTEL_CNL, // CANNON LAKE
INTEL_RCL, // ROCKET LAKE INTEL_ICL, // ICE LAKE
INTEL_KNIGHTS_M, // KNIGHTS MILL INTEL_TGL, // TIGER LAKE
INTEL_KNIGHTS_L, // KNIGHTS LANDING INTEL_SPR, // SAPPHIRE RAPIDS
INTEL_KNIGHTS_F, // KNIGHTS FERRY INTEL_ADL, // ALDER LAKE
INTEL_KNIGHTS_C, // KNIGHTS CORNER INTEL_RCL, // ROCKET LAKE
INTEL_NETBURST, // NETBURST INTEL_KNIGHTS_M, // KNIGHTS MILL
AMD_HAMMER, // K8 HAMMER INTEL_KNIGHTS_L, // KNIGHTS LANDING
AMD_K10, // K10 INTEL_KNIGHTS_F, // KNIGHTS FERRY
AMD_K11, // K11 INTEL_KNIGHTS_C, // KNIGHTS CORNER
AMD_K12, // K12 INTEL_NETBURST, // NETBURST
AMD_BOBCAT, // K14 BOBCAT AMD_HAMMER, // K8 HAMMER
AMD_PILEDRIVER, // K15 PILEDRIVER AMD_K10, // K10
AMD_STREAMROLLER, // K15 STREAMROLLER AMD_K11, // K11
AMD_EXCAVATOR, // K15 EXCAVATOR AMD_K12, // K12
AMD_BULLDOZER, // K15 BULLDOZER AMD_BOBCAT, // K14 BOBCAT
AMD_JAGUAR, // K16 JAGUAR AMD_PILEDRIVER, // K15 PILEDRIVER
AMD_PUMA, // K16 PUMA AMD_STREAMROLLER, // K15 STREAMROLLER
AMD_ZEN, // K17 ZEN AMD_EXCAVATOR, // K15 EXCAVATOR
AMD_ZEN_PLUS, // K17 ZEN+ AMD_BULLDOZER, // K15 BULLDOZER
AMD_ZEN2, // K17 ZEN 2 AMD_JAGUAR, // K16 JAGUAR
AMD_ZEN3, // K19 ZEN 3 AMD_PUMA, // K16 PUMA
AMD_ZEN, // K17 ZEN
AMD_ZEN_PLUS, // K17 ZEN+
AMD_ZEN2, // K17 ZEN 2
AMD_ZEN3, // K19 ZEN 3
X86_MICROARCHITECTURE_LAST_, X86_MICROARCHITECTURE_LAST_,
} X86Microarchitecture; } X86Microarchitecture;
@ -161,6 +168,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info);
// Calls cpuid and fills the brand_string. // Calls cpuid and fills the brand_string.
// - brand_string *must* be of size 49 (beware of array decaying). // - brand_string *must* be of size 49 (beware of array decaying).
// - brand_string will be zero terminated. // - brand_string will be zero terminated.
CPU_FEATURES_DEPRECATED("brand_string is now embedded in X86Info by default")
void FillX86BrandString(char brand_string[49]); void FillX86BrandString(char brand_string[49]);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@ -60,13 +60,7 @@ static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type)
#elif defined(HAVE_DLFCN_H) #elif defined(HAVE_DLFCN_H)
// On Android we probe the system's C library for a 'getauxval' function and // On Android we probe the system's C library for a 'getauxval' function and
// call it if it exits, or return 0 for failure. This function is available // call it if it exits, or return 0 for failure. This function is available
// since API level 20. // since API level 18.
//
// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the edge
// case where some NDK developers use headers for a platform that is newer than
// the one really targetted by their application. This is typically done to use
// newer native APIs only when running on more recent Android versions, and
// requires careful symbol management.
// //
// Note that getauxval() can't really be re-implemented here, because its // Note that getauxval() can't really be re-implemented here, because its
// implementation does not parse /proc/self/auxv. Instead it depends on values // implementation does not parse /proc/self/auxv. Instead it depends on values

View File

@ -166,13 +166,15 @@ static void FixErrors(ArmInfo* const info,
// https://crbug.com/341598. // https://crbug.com/341598.
info->features.neon = false; info->features.neon = false;
break; break;
case 0x510006F2: }
case 0x510006F3:
// The Nexus 4 (Qualcomm Krait) kernel configuration forgets to report // Some Qualcomm Krait kernels forget to report IDIV support.
// IDIV support. // https://github.com/torvalds/linux/commit/120ecfafabec382c4feb79ff159ef42a39b6d33b
if (info->implementer == 0x51 && info->architecture == 7 &&
(info->part == 0x4d || info->part == 0x6f))
{
info->features.idiva = true; info->features.idiva = true;
info->features.idivt = true; info->features.idivt = true;
break;
} }
// Propagate cpu features. // Propagate cpu features.

View File

@ -18,8 +18,9 @@ static void OverrideOsPreserves(OsPreserves* os_preserves)
#include "internal/stack_line_reader.h" #include "internal/stack_line_reader.h"
#include "internal/string_view.h" #include "internal/string_view.h"
static void DetectFeaturesFromOs(X86Features* features) static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
{ {
(void)info;
// Handling FreeBSD platform through parsing /var/run/dmesg.boot. // Handling FreeBSD platform through parsing /var/run/dmesg.boot.
const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot"); const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot");
if (fd >= 0) if (fd >= 0)

View File

@ -17,8 +17,9 @@ static void OverrideOsPreserves(OsPreserves* os_preserves)
#include "internal/filesystem.h" #include "internal/filesystem.h"
#include "internal/stack_line_reader.h" #include "internal/stack_line_reader.h"
#include "internal/string_view.h" #include "internal/string_view.h"
static void DetectFeaturesFromOs(X86Features* features) static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
{ {
(void)info;
// Handling Linux platform through /proc/cpuinfo. // Handling Linux platform through /proc/cpuinfo.
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
if (fd >= 0) if (fd >= 0)
@ -36,7 +37,7 @@ static void DetectFeaturesFromOs(X86Features* features)
if (!CpuFeatures_StringView_IsEquals(key, str("flags"))) continue; if (!CpuFeatures_StringView_IsEquals(key, str("flags"))) continue;
features->sse = CpuFeatures_StringView_HasWord(value, "sse", ' '); features->sse = CpuFeatures_StringView_HasWord(value, "sse", ' ');
features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2", ' '); features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2", ' ');
features->sse3 = CpuFeatures_StringView_HasWord(value, "sse3", ' '); features->sse3 = CpuFeatures_StringView_HasWord(value, "pni", ' ');
features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3", ' '); features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3", ' ');
features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1", ' '); features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1", ' ');
features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2", ' '); features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2", ' ');

View File

@ -33,8 +33,9 @@ static void OverrideOsPreserves(OsPreserves* os_preserves)
os_preserves->avx512_registers = GetDarwinSysCtlByName("hw.optional.avx512f"); os_preserves->avx512_registers = GetDarwinSysCtlByName("hw.optional.avx512f");
} }
static void DetectFeaturesFromOs(X86Features* features) static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
{ {
(void)info;
// Handling Darwin platform through sysctlbyname. // Handling Darwin platform through sysctlbyname.
features->sse = GetDarwinSysCtlByName("hw.optional.sse"); features->sse = GetDarwinSysCtlByName("hw.optional.sse");
features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2"); features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2");

View File

@ -25,7 +25,7 @@ static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature)
} }
#endif #endif
static void DetectFeaturesFromOs(X86Features* features) static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
{ {
// Handling Windows platform through IsProcessorFeaturePresent. // Handling Windows platform through IsProcessorFeaturePresent.
// https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
@ -35,6 +35,16 @@ static void DetectFeaturesFromOs(X86Features* features)
GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE);
features->sse3 = features->sse3 =
GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); GetWindowsIsProcessorFeaturePresent(PF_SSE3_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
} }
#endif // CPU_FEATURES_OS_WINDOWS #endif // CPU_FEATURES_OS_WINDOWS

View File

@ -363,7 +363,7 @@ static Node* GetCacheTypeString(CacheType cache_type)
case CPU_FEATURE_CACHE_PREFETCH: case CPU_FEATURE_CACHE_PREFETCH:
return CreateConstantString("prefetch"); return CreateConstantString("prefetch");
} }
UNREACHABLE(); CPU_FEATURES_UNREACHABLE();
} }
static void AddCacheInfo(Node* root, const CacheInfo* cache_info) static void AddCacheInfo(Node* root, const CacheInfo* cache_info)

View File

@ -103,7 +103,6 @@ CPU architecture: 7
CPU variant : 0x0 CPU variant : 0x0
CPU part : 0xb76 CPU part : 0xb76
CPU revision : 7 CPU revision : 7
Hardware : BCM2835 Hardware : BCM2835
Revision : 9000c1 Revision : 9000c1
Serial : 000000006cd946f3)"); Serial : 000000006cd946f3)");
@ -156,7 +155,6 @@ CPU architecture: 7
CPU variant : 0x4 CPU variant : 0x4
CPU part : 0xc09 CPU part : 0xc09
CPU revision : 1 CPU revision : 1
processor : 1 processor : 1
model name : ARMv7 Processor rev 1 (v7l) model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 50.00 BogoMIPS : 50.00
@ -166,7 +164,6 @@ CPU architecture: 7
CPU variant : 0x4 CPU variant : 0x4
CPU part : 0xc09 CPU part : 0xc09
CPU revision : 1 CPU revision : 1
Hardware : Marvell Armada 380/385 (Device Tree) Hardware : Marvell Armada 380/385 (Device Tree)
Revision : 0000 Revision : 0000
Serial : 0000000000000000)"); Serial : 0000000000000000)");
@ -221,7 +218,6 @@ CPU architecture: 7
CPU variant : 0x0 CPU variant : 0x0
CPU part : 0xb76 CPU part : 0xb76
CPU revision : 6 CPU revision : 6
Hardware : SPICA Hardware : SPICA
Revision : 0020 Revision : 0020
Serial : 33323613546d00ec )"); Serial : 33323613546d00ec )");
@ -267,17 +263,14 @@ TEST(CpuinfoArmTest, InvalidNeon)
R"(Processor: ARMv7 Processory rev 0 (v71) R"(Processor: ARMv7 Processory rev 0 (v71)
processor: 0 processor: 0
BogoMIPS: 13.50 BogoMIPS: 13.50
Processor: 1 Processor: 1
BogoMIPS: 13.50 BogoMIPS: 13.50
Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt Features: swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x51 CPU implementer : 0x51
CPU architecture: 7 CPU architecture: 7
CPU variant: 0x1 CPU variant: 0x1
CPU part: 0x04d CPU part: 0x04d
CPU revision: 0 CPU revision: 0
Hardware: SAMSUNG M2 Hardware: SAMSUNG M2
Revision: 0010 Revision: 0010
Serial: 00001e030000354e)"); Serial: 00001e030000354e)");
@ -324,6 +317,25 @@ CPU revision : 3)");
EXPECT_EQ(GetArmCpuId(&info), 0x510006f3); EXPECT_EQ(GetArmCpuId(&info), 0x510006f3);
} }
// The 2013 Nexus 7 (Qualcomm Krait) kernel configuration forgets to report IDIV
// support.
TEST(CpuinfoArmTest, Nexus7_2013_0x511006f0)
{
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo",
R"(CPU implementer : 0x51
CPU architecture: 7
CPU variant : 0x1
CPU part : 0x06f
CPU revision : 0)");
const auto info = GetArmInfo();
EXPECT_TRUE(info.features.idiva);
EXPECT_TRUE(info.features.idivt);
EXPECT_EQ(GetArmCpuId(&info), 0x511006f0);
}
// The emulator-specific Android 4.2 kernel fails to report support for the // The emulator-specific Android 4.2 kernel fails to report support for the
// 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual // 32-bit ARM IDIV instruction. Technically, this is a feature of the virtual
// CPU implemented by the emulator. // CPU implemented by the emulator.
@ -340,7 +352,6 @@ CPU architecture: 7
CPU variant : 0x0 CPU variant : 0x0
CPU part : 0xc08 CPU part : 0xc08
CPU revision : 0 CPU revision : 0
Hardware : Goldfish Hardware : Goldfish
Revision : 0000 Revision : 0000
Serial : 0000000000000000)"); Serial : 0000000000000000)");

View File

@ -432,6 +432,8 @@ TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x70); EXPECT_EQ(info.model, 0x70);
EXPECT_STREQ(info.brand_string,
"AMD A9-9410 RADEON R5, 5 COMPUTE CORES 2C+3G ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_EXCAVATOR); X86Microarchitecture::AMD_EXCAVATOR);
@ -458,6 +460,8 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x02); EXPECT_EQ(info.model, 0x02);
EXPECT_STREQ(info.brand_string,
"AMD Opteron(tm) Processor 6376 ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_PILEDRIVER); X86Microarchitecture::AMD_PILEDRIVER);
@ -533,6 +537,8 @@ TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x01); EXPECT_EQ(info.model, 0x01);
EXPECT_STREQ(info.brand_string,
"AMD Opteron(TM) Processor 6238 ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_BULLDOZER); X86Microarchitecture::AMD_BULLDOZER);
@ -561,6 +567,8 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI)
EXPECT_EQ(info.family, 0x15); EXPECT_EQ(info.family, 0x15);
EXPECT_EQ(info.model, 0x38); EXPECT_EQ(info.model, 0x38);
EXPECT_EQ(info.stepping, 0x01); EXPECT_EQ(info.stepping, 0x01);
EXPECT_STREQ(info.brand_string,
"AMD A8-7670K Radeon R7, 10 Compute Cores 4C+6G ");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::AMD_STREAMROLLER); X86Microarchitecture::AMD_STREAMROLLER);
@ -587,6 +595,8 @@ TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16); EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x00); EXPECT_EQ(info.model, 0x00);
EXPECT_STREQ(info.brand_string,
"AMD A4-5000 APU with Radeon(TM) HD Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR);
char brand_string[49]; char brand_string[49];
@ -612,6 +622,8 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x16); EXPECT_EQ(info.family, 0x16);
EXPECT_EQ(info.model, 0x30); EXPECT_EQ(info.model, 0x30);
EXPECT_STREQ(info.brand_string,
"AMD A6-6310 APU with AMD Radeon R4 Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA);
char brand_string[49]; char brand_string[49];
@ -637,6 +649,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x20); EXPECT_EQ(info.model, 0x20);
EXPECT_STREQ(info.brand_string,
"AMD 3020e with Radeon Graphics ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49]; char brand_string[49];
@ -662,6 +676,8 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x08); EXPECT_EQ(info.model, 0x08);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 7 2700X Eight-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN_PLUS);
char brand_string[49]; char brand_string[49];
@ -687,6 +703,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x17); EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x47); EXPECT_EQ(info.model, 0x47);
EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
char brand_string[49]; char brand_string[49];
@ -712,6 +729,8 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
EXPECT_STREQ(info.vendor, "HygonGenuine"); EXPECT_STREQ(info.vendor, "HygonGenuine");
EXPECT_EQ(info.family, 0x18); EXPECT_EQ(info.family, 0x18);
EXPECT_EQ(info.model, 0x00); EXPECT_EQ(info.model, 0x00);
EXPECT_STREQ(info.brand_string,
"Hygon C86 3185 8-core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
char brand_string[49]; char brand_string[49];
@ -786,6 +805,8 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER)
EXPECT_STREQ(info.vendor, "AuthenticAMD"); EXPECT_STREQ(info.vendor, "AuthenticAMD");
EXPECT_EQ(info.family, 0x19); EXPECT_EQ(info.family, 0x19);
EXPECT_EQ(info.model, 0x21); EXPECT_EQ(info.model, 0x21);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 9 5900X 12-Core Processor ");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3);
char brand_string[49]; char brand_string[49];
@ -822,7 +843,7 @@ real memory = 2147418112 (2047 MB)
#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) #elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(processor : fs.CreateFile("/proc/cpuinfo", R"(processor :
flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
)"); )");
#endif #endif
cpu().SetLeaves({ cpu().SetLeaves({
@ -858,6 +879,8 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x1A); EXPECT_EQ(info.model, 0x1A);
EXPECT_EQ(info.stepping, 0x02); EXPECT_EQ(info.stepping, 0x02);
EXPECT_STREQ(info.brand_string,
"Genuine Intel(R) CPU @ 0000 @ 1.87GHz");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_NHM);
char brand_string[49]; char brand_string[49];
@ -905,7 +928,7 @@ real memory = 2147418112 (2047 MB)
#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) #elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"( fs.CreateFile("/proc/cpuinfo", R"(
flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 flags : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2
)"); )");
#endif #endif
cpu().SetLeaves({ cpu().SetLeaves({
@ -940,6 +963,8 @@ flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2
EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x37); EXPECT_EQ(info.model, 0x37);
EXPECT_EQ(info.stepping, 0x03); EXPECT_EQ(info.stepping, 0x03);
EXPECT_STREQ(info.brand_string,
" Intel(R) Celeron(R) CPU J1900 @ 1.99GHz");
EXPECT_EQ(GetX86Microarchitecture(&info), EXPECT_EQ(GetX86Microarchitecture(&info),
X86Microarchitecture::INTEL_ATOM_SMT); X86Microarchitecture::INTEL_ATOM_SMT);
@ -1048,6 +1073,7 @@ flags : fpu mmx sse
EXPECT_EQ(info.family, 0x06); EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0x07); EXPECT_EQ(info.model, 0x07);
EXPECT_EQ(info.stepping, 0x03); EXPECT_EQ(info.stepping, 0x03);
EXPECT_STREQ(info.brand_string, "");
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN); EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::X86_UNKNOWN);
char brand_string[49]; char brand_string[49];
@ -1129,6 +1155,33 @@ TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING)
X86Microarchitecture::INTEL_KNIGHTS_L); X86Microarchitecture::INTEL_KNIGHTS_L);
} }
// 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)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x0000000B, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000206F2, 0x00400800, 0x02BEE3FF, 0xBFEBFBFF}},
});
const auto info = GetX86Info();
EXPECT_EQ(info.family, 0x06);
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.ssse3);
EXPECT_TRUE(info.features.sse4_1);
EXPECT_TRUE(info.features.sse4_2);
#endif
}
#endif // CPU_FEATURES_OS_WINDOWS
// TODO(user): test what happens when xsave/osxsave are not present. // TODO(user): test what happens when xsave/osxsave are not present.
// TODO(user): test what happens when xmm/ymm/zmm os support are not // TODO(user): test what happens when xmm/ymm/zmm os support are not
// present. // present.