mirror of
				https://github.com/gnss-sdr/gnss-sdr
				synced 2025-10-30 23:03:05 +00:00 
			
		
		
		
	Add support for s390x arch in cpu_features. Update to 4e191a4
This commit is contained in:
		| @@ -1187,7 +1187,7 @@ if(NOT VOLKGNSSSDR_FOUND) | ||||
|     include(GNUInstallDirs) | ||||
|     set(SUPPORTED_CPU_FEATURES_ARCH FALSE) | ||||
|     if(CMAKE_SYSTEM_PROCESSOR MATCHES | ||||
|         "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)") | ||||
|         "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)") | ||||
|         set(SUPPORTED_CPU_FEATURES_ARCH TRUE) | ||||
|     endif() | ||||
|     if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64) | ||||
|   | ||||
| @@ -257,7 +257,7 @@ endif() | ||||
|  | ||||
| # cpu_features - sensible defaults, user settable option | ||||
| if(CMAKE_SYSTEM_PROCESSOR MATCHES | ||||
|     "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)") | ||||
|     "(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)") | ||||
|     option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON) | ||||
| else() | ||||
|     option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF) | ||||
|   | ||||
| @@ -16,12 +16,13 @@ if(CMAKE_VERSION LESS "3.1") | ||||
|     add_compile_options("$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:-std=gnu99>") | ||||
| endif() | ||||
|  | ||||
| # Default Build Type to be Release | ||||
| # Default Build Type to be Release | ||||
| if(NOT CMAKE_BUILD_TYPE) | ||||
|   set(CMAKE_BUILD_TYPE "Release" CACHE STRING | ||||
|       "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." | ||||
|       FORCE) | ||||
| endif() | ||||
| endif(NOT CMAKE_BUILD_TYPE) | ||||
|  | ||||
| # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make | ||||
| # it prominent in the GUI. | ||||
| @@ -55,6 +56,7 @@ set(PROCESSOR_IS_ARM FALSE) | ||||
| set(PROCESSOR_IS_AARCH64 FALSE) | ||||
| set(PROCESSOR_IS_X86 FALSE) | ||||
| set(PROCESSOR_IS_POWER FALSE) | ||||
| set(PROCESSOR_IS_S390X FALSE) | ||||
|  | ||||
| if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") | ||||
|   set(PROCESSOR_IS_MIPS TRUE) | ||||
| @@ -66,6 +68,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") | ||||
|   set(PROCESSOR_IS_X86 TRUE) | ||||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") | ||||
|   set(PROCESSOR_IS_POWER TRUE) | ||||
| elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)") | ||||
|   set(PROCESSOR_IS_S390X TRUE) | ||||
| endif() | ||||
|  | ||||
| macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) | ||||
| @@ -85,6 +89,8 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) | ||||
|       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) | ||||
|   elseif(PROCESSOR_IS_S390X) | ||||
|       list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h) | ||||
|   else() | ||||
|     message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") | ||||
|   endif() | ||||
| @@ -128,8 +134,8 @@ endif() | ||||
| # | ||||
| # library : cpu_features | ||||
| # | ||||
| set(CPU_FEATURES_HDRS) | ||||
| set(CPU_FEATURES_SRCS) | ||||
| set (CPU_FEATURES_HDRS) | ||||
| set (CPU_FEATURES_SRCS) | ||||
| add_cpu_features_headers_and_sources(CPU_FEATURES_HDRS CPU_FEATURES_SRCS) | ||||
| list(APPEND CPU_FEATURES_SRCS $<TARGET_OBJECTS:utils>) | ||||
| if(NOT PROCESSOR_IS_X86 AND UNIX) | ||||
| @@ -211,8 +217,8 @@ if(BUILD_TESTING) | ||||
|     # Add googletest directly to our build. This defines the gtest and | ||||
|     # gtest_main targets. | ||||
|     add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src | ||||
|         ${CMAKE_BINARY_DIR}/googletest-build | ||||
|         EXCLUDE_FROM_ALL) | ||||
|                      ${CMAKE_BINARY_DIR}/googletest-build | ||||
|                      EXCLUDE_FROM_ALL) | ||||
|   endif() | ||||
|  | ||||
|   add_subdirectory(test) | ||||
|   | ||||
| @@ -158,21 +158,21 @@ flags           : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3 | ||||
|  | ||||
| ## What's supported | ||||
|  | ||||
| |         | x86³ |   ARM   | AArch64 |  MIPS⁴  |  POWER  | | ||||
| | ------- | :--: | :-----: | :-----: | :-----: | :-----: | | ||||
| | Android | yes² |  yes¹   |  yes¹   |  yes¹   |   N/A   | | ||||
| | iOS     | N/A  | not yet | not yet |   N/A   |   N/A   | | ||||
| | Linux   | yes² |  yes¹   |  yes¹   |  yes¹   |  yes¹   | | ||||
| | MacOS   | yes² |   N/A   |  yes²   |   N/A   |   no    | | ||||
| | Windows | yes² | not yet | not yet |   N/A   |   N/A   | | ||||
| | FreeBSD | yes² | not yet | not yet | not yet | not yet | | ||||
| |         | x86³  | AArch64 |   ARM   |  MIPS⁴  |  s390x  |  POWER  | | ||||
| | ------- | :---: | :-----: | :-----: | :-----: | :-----: | :-----: | | ||||
| | Linux   | yes²  |  yes¹   |  yes¹   |  yes¹   |  yes¹   |  yes¹   | | ||||
| | FreeBSD | yes²  | not yet | not yet | not yet | not yet | not yet | | ||||
| | MacOs   | yes²  | not yet |   N/A   |   N/A   |   no    |   no    | | ||||
| | Windows | yes²  | not yet | not yet |   N/A   |   N/A   |   N/A   | | ||||
| | Android | yes²  |  yes¹   |  yes¹   |  yes¹   |   N/A   |   N/A   | | ||||
| | iOS     |  N/A  | not yet | not yet |   N/A   |   N/A   |   N/A   | | ||||
|  | ||||
| 1.  **Features revealed from Linux.** We gather data from several sources | ||||
|     depending on availability: | ||||
|     - from glibc's | ||||
|       [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html) | ||||
|     - by parsing `/proc/self/auxv` | ||||
|     - by parsing `/proc/cpuinfo` | ||||
|     +   from glibc's | ||||
|         [getauxval](https://www.gnu.org/software/libc/manual/html_node/Auxiliary-Vector.html) | ||||
|     +   by parsing `/proc/self/auxv` | ||||
|     +   by parsing `/proc/cpuinfo` | ||||
| 2.  **Features revealed from CPU.** features are retrieved by using the `cpuid` | ||||
|     instruction. | ||||
| 3.  **Microarchitecture detection.** On x86 some features are not always | ||||
|   | ||||
| @@ -56,6 +56,10 @@ | ||||
| #define CPU_FEATURES_ARCH_RISCV | ||||
| #endif | ||||
|  | ||||
| #if defined(__s390x__) | ||||
| #define CPU_FEATURES_ARCH_S390X | ||||
| #endif | ||||
|  | ||||
| #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32 | ||||
| #define CPU_FEATURES_ARCH_RISCV32 | ||||
| #endif | ||||
|   | ||||
| @@ -0,0 +1,102 @@ | ||||
| // SPDX-FileCopyrightText: 2022 IBM | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
|  | ||||
| #ifndef CPU_FEATURES_INCLUDE_CPUINFO_S390X_H_ | ||||
| #define CPU_FEATURES_INCLUDE_CPUINFO_S390X_H_ | ||||
|  | ||||
| #include "cpu_features_cache_info.h" | ||||
| #include "cpu_features_macros.h" | ||||
|  | ||||
| CPU_FEATURES_START_CPP_NAMESPACE | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     int esan3 : 1;     // instructions named N3, "backported" to esa-mode | ||||
|     int zarch : 1;     // z/Architecture mode active | ||||
|     int stfle : 1;     // store-facility-list-extended | ||||
|     int msa : 1;       // message-security assist | ||||
|     int ldisp : 1;     // long-displacement | ||||
|     int eimm : 1;      // extended-immediate | ||||
|     int dfp : 1;       // decimal floating point & perform floating point operation | ||||
|     int edat : 1;      // huge page support | ||||
|     int etf3eh : 1;    // extended-translation facility 3 enhancement | ||||
|     int highgprs : 1;  // 64-bit register support for 31-bit processes | ||||
|     int te : 1;        // transactional execution | ||||
|     int vx : 1;        // vector extension facility | ||||
|     int vxd : 1;       // vector-packed-decimal facility | ||||
|     int vxe : 1;       // vector-enhancement facility 1 | ||||
|     int gs : 1;        // guarded-storage facility | ||||
|     int vxe2 : 1;      // vector-enhancements facility 2 | ||||
|     int vxp : 1;       // vector-packed-decimal-enhancement facility | ||||
|     int sort : 1;      // enhanced-sort facility | ||||
|     int dflt : 1;      // deflate-conversion facility | ||||
|     int vxp2 : 1;      // vector-packed-decimal-enhancement facility 2 | ||||
|     int nnpa : 1;      // neural network processing assist facility | ||||
|     int pcimio : 1;    // PCI mio facility | ||||
|     int sie : 1;       // virtualization support | ||||
|  | ||||
|     // Make sure to update S390XFeaturesEnum below if you add a field here. | ||||
| } S390XFeatures; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     S390XFeatures features; | ||||
| } S390XInfo; | ||||
|  | ||||
| S390XInfo GetS390XInfo(void); | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     char platform[64];  // 0 terminated string | ||||
| } S390XPlatformTypeStrings; | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     int num_processors;  // -1 if N/A | ||||
|     S390XPlatformTypeStrings type; | ||||
| } S390XPlatformStrings; | ||||
|  | ||||
| S390XPlatformStrings GetS390XPlatformStrings(void); | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Introspection functions | ||||
|  | ||||
| typedef enum | ||||
| { | ||||
|     S390_ESAN3, | ||||
|     S390_ZARCH, | ||||
|     S390_STFLE, | ||||
|     S390_MSA, | ||||
|     S390_LDISP, | ||||
|     S390_EIMM, | ||||
|     S390_DFP, | ||||
|     S390_EDAT, | ||||
|     S390_ETF3EH, | ||||
|     S390_HIGHGPRS, | ||||
|     S390_TE, | ||||
|     S390_VX, | ||||
|     S390_VXD, | ||||
|     S390_VXE, | ||||
|     S390_GS, | ||||
|     S390_VXE2, | ||||
|     S390_VXP, | ||||
|     S390_SORT, | ||||
|     S390_DFLT, | ||||
|     S390_VXP2, | ||||
|     S390_NNPA, | ||||
|     S390_PCIMIO, | ||||
|     S390_SIE, | ||||
|     S390X_LAST_, | ||||
| } S390XFeaturesEnum; | ||||
|  | ||||
| int GetS390XFeaturesEnumValue(const S390XFeatures* features, S390XFeaturesEnum value); | ||||
|  | ||||
| const char* GetS390XFeaturesEnumName(S390XFeaturesEnum); | ||||
|  | ||||
| CPU_FEATURES_END_CPP_NAMESPACE | ||||
|  | ||||
| #if !defined(CPU_FEATURES_ARCH_S390X) | ||||
| #error "Including cpuinfo_s390x.h from a non-s390x target." | ||||
| #endif | ||||
|  | ||||
| #endif  // CPU_FEATURES_INCLUDE_CPUINFO_S390X_H_ | ||||
| @@ -49,6 +49,7 @@ typedef struct | ||||
|     int sse4a : 1; | ||||
|  | ||||
|     int avx : 1; | ||||
|     int avx_vnni : 1; | ||||
|     int avx2 : 1; | ||||
|  | ||||
|     int avx512f : 1; | ||||
| @@ -70,6 +71,7 @@ typedef struct | ||||
|     int avx512_4fmaps : 1; | ||||
|     int avx512_bf16 : 1; | ||||
|     int avx512_vp2intersect : 1; | ||||
|     int avx512_fp16 : 1; | ||||
|     int amx_bf16 : 1; | ||||
|     int amx_tile : 1; | ||||
|     int amx_int8 : 1; | ||||
| @@ -86,7 +88,15 @@ typedef struct | ||||
|     int dca : 1; | ||||
|     int ss : 1; | ||||
|     int adx : 1; | ||||
|     // Make sure to update X86FeaturesEnum below if you add a field here. | ||||
|     int lzcnt : 1;  // Note: this flag is called ABM for AMD, LZCNT for Intel. | ||||
|     int gfni : 1; | ||||
|     int movdiri : 1; | ||||
|     int movdir64b : 1; | ||||
|     int fs_rep_mov : 1;          // Fast short REP MOV | ||||
|     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 | ||||
|                                  // Make sure to update X86FeaturesEnum below if you add a field here. | ||||
| } X86Features; | ||||
|  | ||||
| typedef struct | ||||
| @@ -110,56 +120,60 @@ CacheInfo GetX86CacheInfo(void); | ||||
| typedef enum | ||||
| { | ||||
|     X86_UNKNOWN, | ||||
|     ZHAOXIN_ZHANGJIANG,  // ZhangJiang | ||||
|     ZHAOXIN_WUDAOKOU,    // WuDaoKou | ||||
|     ZHAOXIN_LUJIAZUI,    // LuJiaZui | ||||
|     ZHAOXIN_YONGFENG,    // YongFeng | ||||
|     INTEL_80486,         // 80486 | ||||
|     INTEL_P5,            // P5 | ||||
|     INTEL_LAKEMONT,      // LAKEMONT | ||||
|     INTEL_CORE,          // CORE | ||||
|     INTEL_PNR,           // PENRYN | ||||
|     INTEL_NHM,           // NEHALEM | ||||
|     INTEL_ATOM_BNL,      // BONNELL | ||||
|     INTEL_WSM,           // WESTMERE | ||||
|     INTEL_SNB,           // SANDYBRIDGE | ||||
|     INTEL_IVB,           // IVYBRIDGE | ||||
|     INTEL_ATOM_SMT,      // SILVERMONT | ||||
|     INTEL_HSW,           // HASWELL | ||||
|     INTEL_BDW,           // BROADWELL | ||||
|     INTEL_SKL,           // SKYLAKE | ||||
|     INTEL_ATOM_GMT,      // GOLDMONT | ||||
|     INTEL_KBL,           // KABY LAKE | ||||
|     INTEL_CFL,           // COFFEE LAKE | ||||
|     INTEL_WHL,           // WHISKEY LAKE | ||||
|     INTEL_CML,           // COMET LAKE | ||||
|     INTEL_CNL,           // CANNON LAKE | ||||
|     INTEL_ICL,           // ICE LAKE | ||||
|     INTEL_TGL,           // TIGER LAKE | ||||
|     INTEL_SPR,           // SAPPHIRE RAPIDS | ||||
|     INTEL_ADL,           // ALDER LAKE | ||||
|     INTEL_RCL,           // ROCKET LAKE | ||||
|     INTEL_KNIGHTS_M,     // KNIGHTS MILL | ||||
|     INTEL_KNIGHTS_L,     // KNIGHTS LANDING | ||||
|     INTEL_KNIGHTS_F,     // KNIGHTS FERRY | ||||
|     INTEL_KNIGHTS_C,     // KNIGHTS CORNER | ||||
|     INTEL_NETBURST,      // NETBURST | ||||
|     AMD_HAMMER,          // K8  HAMMER | ||||
|     AMD_K10,             // K10 | ||||
|     AMD_K11,             // K11 | ||||
|     AMD_K12,             // K12 | ||||
|     AMD_BOBCAT,          // K14 BOBCAT | ||||
|     AMD_PILEDRIVER,      // K15 PILEDRIVER | ||||
|     AMD_STREAMROLLER,    // K15 STREAMROLLER | ||||
|     AMD_EXCAVATOR,       // K15 EXCAVATOR | ||||
|     AMD_BULLDOZER,       // K15 BULLDOZER | ||||
|     AMD_JAGUAR,          // K16 JAGUAR | ||||
|     AMD_PUMA,            // K16 PUMA | ||||
|     AMD_ZEN,             // K17 ZEN | ||||
|     AMD_ZEN_PLUS,        // K17 ZEN+ | ||||
|     AMD_ZEN2,            // K17 ZEN 2 | ||||
|     AMD_ZEN3,            // K19 ZEN 3 | ||||
|     AMD_ZEN4,            // K19 ZEN 4 | ||||
|     ZHAOXIN_ZHANGJIANG,   // ZhangJiang | ||||
|     ZHAOXIN_WUDAOKOU,     // WuDaoKou | ||||
|     ZHAOXIN_LUJIAZUI,     // LuJiaZui | ||||
|     ZHAOXIN_YONGFENG,     // YongFeng | ||||
|     INTEL_80486,          // 80486 | ||||
|     INTEL_P5,             // P5 | ||||
|     INTEL_LAKEMONT,       // LAKEMONT | ||||
|     INTEL_CORE,           // CORE | ||||
|     INTEL_PNR,            // PENRYN | ||||
|     INTEL_NHM,            // NEHALEM | ||||
|     INTEL_ATOM_BNL,       // BONNELL | ||||
|     INTEL_WSM,            // WESTMERE | ||||
|     INTEL_SNB,            // SANDYBRIDGE | ||||
|     INTEL_IVB,            // IVYBRIDGE | ||||
|     INTEL_ATOM_SMT,       // SILVERMONT | ||||
|     INTEL_HSW,            // HASWELL | ||||
|     INTEL_BDW,            // BROADWELL | ||||
|     INTEL_SKL,            // SKYLAKE | ||||
|     INTEL_CCL,            // CASCADELAKE | ||||
|     INTEL_ATOM_GMT,       // GOLDMONT | ||||
|     INTEL_ATOM_GMT_PLUS,  // GOLDMONT+ | ||||
|     INTEL_ATOM_TMT,       // TREMONT | ||||
|     INTEL_KBL,            // KABY LAKE | ||||
|     INTEL_CFL,            // COFFEE LAKE | ||||
|     INTEL_WHL,            // WHISKEY LAKE | ||||
|     INTEL_CML,            // COMET LAKE | ||||
|     INTEL_CNL,            // CANNON LAKE | ||||
|     INTEL_ICL,            // ICE LAKE | ||||
|     INTEL_TGL,            // TIGER LAKE | ||||
|     INTEL_SPR,            // SAPPHIRE RAPIDS | ||||
|     INTEL_ADL,            // ALDER LAKE | ||||
|     INTEL_RCL,            // ROCKET LAKE | ||||
|     INTEL_RPL,            // RAPTOR LAKE | ||||
|     INTEL_KNIGHTS_M,      // KNIGHTS MILL | ||||
|     INTEL_KNIGHTS_L,      // KNIGHTS LANDING | ||||
|     INTEL_KNIGHTS_F,      // KNIGHTS FERRY | ||||
|     INTEL_KNIGHTS_C,      // KNIGHTS CORNER | ||||
|     INTEL_NETBURST,       // NETBURST | ||||
|     AMD_HAMMER,           // K8  HAMMER | ||||
|     AMD_K10,              // K10 | ||||
|     AMD_K11,              // K11 | ||||
|     AMD_K12,              // K12 LLANO | ||||
|     AMD_BOBCAT,           // K14 BOBCAT | ||||
|     AMD_PILEDRIVER,       // K15 PILEDRIVER | ||||
|     AMD_STREAMROLLER,     // K15 STREAMROLLER | ||||
|     AMD_EXCAVATOR,        // K15 EXCAVATOR | ||||
|     AMD_BULLDOZER,        // K15 BULLDOZER | ||||
|     AMD_JAGUAR,           // K16 JAGUAR | ||||
|     AMD_PUMA,             // K16 PUMA | ||||
|     AMD_ZEN,              // K17 ZEN | ||||
|     AMD_ZEN_PLUS,         // K17 ZEN+ | ||||
|     AMD_ZEN2,             // K17 ZEN 2 | ||||
|     AMD_ZEN3,             // K19 ZEN 3 | ||||
|     AMD_ZEN4,             // K19 ZEN 4 | ||||
|     X86_MICROARCHITECTURE_LAST_, | ||||
| } X86Microarchitecture; | ||||
|  | ||||
| @@ -205,6 +219,7 @@ typedef enum | ||||
|     X86_SSE4_2, | ||||
|     X86_SSE4A, | ||||
|     X86_AVX, | ||||
|     X86_AVX_VNNI, | ||||
|     X86_AVX2, | ||||
|     X86_AVX512F, | ||||
|     X86_AVX512CD, | ||||
| @@ -225,6 +240,7 @@ typedef enum | ||||
|     X86_AVX512_4FMAPS, | ||||
|     X86_AVX512_BF16, | ||||
|     X86_AVX512_VP2INTERSECT, | ||||
|     X86_AVX512_FP16, | ||||
|     X86_AMX_BF16, | ||||
|     X86_AMX_TILE, | ||||
|     X86_AMX_INT8, | ||||
| @@ -239,6 +255,14 @@ typedef enum | ||||
|     X86_DCA, | ||||
|     X86_SS, | ||||
|     X86_ADX, | ||||
|     X86_LZCNT, | ||||
|     X86_GFNI, | ||||
|     X86_MOVDIRI, | ||||
|     X86_MOVDIR64B, | ||||
|     X86_FS_REP_MOV, | ||||
|     X86_FZ_REP_MOVSB, | ||||
|     X86_FS_REP_STOSB, | ||||
|     X86_FS_REP_CMPSB_SCASB, | ||||
|     X86_LAST_, | ||||
| } X86FeaturesEnum; | ||||
|  | ||||
| @@ -254,4 +278,4 @@ CPU_FEATURES_END_CPP_NAMESPACE | ||||
| #error "Including cpuinfo_x86.h from a non-x86 target." | ||||
| #endif | ||||
|  | ||||
| #endif  // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ | ||||
| #endif  // CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ | ||||
| @@ -164,6 +164,34 @@ CPU_FEATURES_START_CPP_NAMESPACE | ||||
| #define PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000 | ||||
| #endif | ||||
|  | ||||
| // https://elixir.bootlin.com/linux/v6.0-rc6/source/arch/s390/include/asm/elf.h | ||||
| #define HWCAP_S390_ESAN3 1 | ||||
| #define HWCAP_S390_ZARCH 2 | ||||
| #define HWCAP_S390_STFLE 4 | ||||
| #define HWCAP_S390_MSA 8 | ||||
| #define HWCAP_S390_LDISP 16 | ||||
| #define HWCAP_S390_EIMM 32 | ||||
| #define HWCAP_S390_DFP 64 | ||||
| #define HWCAP_S390_HPAGE 128 | ||||
| #define HWCAP_S390_ETF3EH 256 | ||||
| #define HWCAP_S390_HIGH_GPRS 512 | ||||
| #define HWCAP_S390_TE 1024 | ||||
| #define HWCAP_S390_VX 2048 | ||||
| #define HWCAP_S390_VXRS HWCAP_S390_VX | ||||
| #define HWCAP_S390_VXD 4096 | ||||
| #define HWCAP_S390_VXRS_BCD HWCAP_S390_VXD | ||||
| #define HWCAP_S390_VXE 8192 | ||||
| #define HWCAP_S390_VXRS_EXT HWCAP_S390_VXE | ||||
| #define HWCAP_S390_GS 16384 | ||||
| #define HWCAP_S390_VXRS_EXT2 32768 | ||||
| #define HWCAP_S390_VXRS_PDE 65536 | ||||
| #define HWCAP_S390_SORT 131072 | ||||
| #define HWCAP_S390_DFLT 262144 | ||||
| #define HWCAP_S390_VXRS_PDE2 524288 | ||||
| #define HWCAP_S390_NNPA 1048576 | ||||
| #define HWCAP_S390_PCI_MIO 2097152 | ||||
| #define HWCAP_S390_SIE 4194304 | ||||
|  | ||||
| // 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')) | ||||
|   | ||||
| @@ -3,6 +3,10 @@ | ||||
| #ifndef CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_ | ||||
| #define CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_ | ||||
|  | ||||
| #include "cpu_features_macros.h" | ||||
|  | ||||
| #ifdef CPU_FEATURES_OS_WINDOWS | ||||
|  | ||||
| #include <windows.h>  // IsProcessorFeaturePresent | ||||
|  | ||||
| // modern WinSDK winnt.h contains newer features detection definitions | ||||
| @@ -18,4 +22,5 @@ | ||||
| #define PF_SSE4_2_INSTRUCTIONS_AVAILABLE 38 | ||||
| #endif | ||||
|  | ||||
| #endif  // CPU_FEATURES_OS_WINDOWS | ||||
| #endif  // CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_ | ||||
|   | ||||
| @@ -58,6 +58,7 @@ | ||||
|     LINE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV)                               \ | ||||
|     LINE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0,                \ | ||||
|         PPC_FEATURE2_HTM_NO_SUSPEND) | ||||
| #undef PPC  // Remove conflict with compiler generated preprocessor | ||||
| #define INTROSPECTION_PREFIX PPC | ||||
| #define INTROSPECTION_ENUM_PREFIX PPC | ||||
| #include "define_introspection_and_hwcaps.inl" | ||||
|   | ||||
| @@ -0,0 +1,119 @@ | ||||
| // SPDX-FileCopyrightText: 2022 IBM | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
|  | ||||
| #include "cpu_features_macros.h" | ||||
|  | ||||
| #ifdef CPU_FEATURES_ARCH_S390X | ||||
| #ifdef CPU_FEATURES_OS_LINUX | ||||
|  | ||||
| #include "cpuinfo_s390x.h" | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Definitions for introspection. | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| #define INTROSPECTION_TABLE                                            \ | ||||
|     LINE(S390_ESAN3, esan3, "esan3", HWCAP_S390_ESAN3, 0)              \ | ||||
|     LINE(S390_ZARCH, zarch, "zarch", HWCAP_S390_ZARCH, 0)              \ | ||||
|     LINE(S390_STFLE, stfle, "stfle", HWCAP_S390_STFLE, 0)              \ | ||||
|     LINE(S390_MSA, msa, "msa", HWCAP_S390_MSA, 0)                      \ | ||||
|     LINE(S390_LDISP, ldisp, "ldisp", HWCAP_S390_LDISP, 0)              \ | ||||
|     LINE(S390_EIMM, eimm, "eimm", HWCAP_S390_EIMM, 0)                  \ | ||||
|     LINE(S390_DFP, dfp, "dfp", HWCAP_S390_DFP, 0)                      \ | ||||
|     LINE(S390_EDAT, edat, "edat", HWCAP_S390_HPAGE, 0)                 \ | ||||
|     LINE(S390_ETF3EH, etf3eh, "etf3eh", HWCAP_S390_ETF3EH, 0)          \ | ||||
|     LINE(S390_HIGHGPRS, highgprs, "highgprs", HWCAP_S390_HIGH_GPRS, 0) \ | ||||
|     LINE(S390_TE, te, "te", HWCAP_S390_TE, 0)                          \ | ||||
|     LINE(S390_VX, vx, "vx", HWCAP_S390_VXRS, 0)                        \ | ||||
|     LINE(S390_VXD, vxd, "vxd", HWCAP_S390_VXRS_BCD, 0)                 \ | ||||
|     LINE(S390_VXE, vxe, "vxe", HWCAP_S390_VXRS_EXT, 0)                 \ | ||||
|     LINE(S390_GS, gs, "gs", HWCAP_S390_GS, 0)                          \ | ||||
|     LINE(S390_VXE2, vxe2, "vxe2", HWCAP_S390_VXRS_EXT2, 0)             \ | ||||
|     LINE(S390_VXP, vxp, "vxp", HWCAP_S390_VXRS_PDE, 0)                 \ | ||||
|     LINE(S390_SORT, sort, "sort", HWCAP_S390_SORT, 0)                  \ | ||||
|     LINE(S390_DFLT, dflt, "dflt", HWCAP_S390_DFLT, 0)                  \ | ||||
|     LINE(S390_VXP2, vxp2, "vxp2", HWCAP_S390_VXRS_PDE2, 0)             \ | ||||
|     LINE(S390_NNPA, nnpa, "nnpa", HWCAP_S390_NNPA, 0)                  \ | ||||
|     LINE(S390_PCIMIO, pcimio, "pcimio", HWCAP_S390_PCI_MIO, 0)         \ | ||||
|     LINE(S390_SIE, sie, "sie", HWCAP_S390_SIE, 0) | ||||
| #define INTROSPECTION_PREFIX S390X | ||||
| #define INTROSPECTION_ENUM_PREFIX S390X | ||||
| #include "define_introspection_and_hwcaps.inl" | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Implementation. | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| #include "internal/bit_utils.h" | ||||
| #include "internal/filesystem.h" | ||||
| #include "internal/hwcaps.h" | ||||
| #include "internal/stack_line_reader.h" | ||||
| #include "internal/string_view.h" | ||||
| #include <stdbool.h> | ||||
|  | ||||
| static bool HandleS390XLine(const LineResult result, | ||||
|     S390XPlatformStrings* const strings) | ||||
| { | ||||
|     StringView line = result.line; | ||||
|     StringView key, value; | ||||
|     if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) | ||||
|         { | ||||
|             if (CpuFeatures_StringView_IsEquals(key, str("# processors"))) | ||||
|                 { | ||||
|                     strings->num_processors = CpuFeatures_StringView_ParsePositiveNumber(value); | ||||
|                 } | ||||
|         } | ||||
|     return !result.eof; | ||||
| } | ||||
|  | ||||
| static void FillProcCpuInfoData(S390XPlatformStrings* const strings) | ||||
| { | ||||
|     const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); | ||||
|     if (fd >= 0) | ||||
|         { | ||||
|             StackLineReader reader; | ||||
|             StackLineReader_Initialize(&reader, fd); | ||||
|             for (;;) | ||||
|                 { | ||||
|                     if (!HandleS390XLine(StackLineReader_NextLine(&reader), strings)) | ||||
|                         { | ||||
|                             break; | ||||
|                         } | ||||
|                 } | ||||
|             CpuFeatures_CloseFile(fd); | ||||
|         } | ||||
| } | ||||
|  | ||||
| static const S390XInfo kEmptyS390XInfo; | ||||
|  | ||||
| S390XInfo GetS390XInfo(void) | ||||
| { | ||||
|     S390XInfo info = kEmptyS390XInfo; | ||||
|     const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); | ||||
|     for (size_t i = 0; i < S390X_LAST_; ++i) | ||||
|         { | ||||
|             if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) | ||||
|                 { | ||||
|                     kSetters[i](&info.features, true); | ||||
|                 } | ||||
|         } | ||||
|     return info; | ||||
| } | ||||
|  | ||||
| static const S390XPlatformStrings kEmptyS390XPlatformStrings; | ||||
|  | ||||
| S390XPlatformStrings GetS390XPlatformStrings(void) | ||||
| { | ||||
|     S390XPlatformStrings strings = kEmptyS390XPlatformStrings; | ||||
|     const char* platform = CpuFeatures_GetPlatformPointer(); | ||||
|  | ||||
|     FillProcCpuInfoData(&strings); | ||||
|  | ||||
|     if (platform != NULL) | ||||
|         CpuFeatures_StringView_CopyString(str(platform), strings.type.platform, | ||||
|             sizeof(strings.type.platform)); | ||||
|  | ||||
|     return strings; | ||||
| } | ||||
|  | ||||
| #endif  // CPU_FEATURES_OS_LINUX | ||||
| #endif  // CPU_FEATURES_ARCH_S390X | ||||
| @@ -266,6 +266,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); | ||||
| @@ -321,9 +322,17 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info, | ||||
|     features->clflushopt = IsBitSet(leaf_7.ebx, 23); | ||||
|     features->clwb = IsBitSet(leaf_7.ebx, 24); | ||||
|     features->sha = IsBitSet(leaf_7.ebx, 29); | ||||
|     features->gfni = IsBitSet(leaf_7.ecx, 8); | ||||
|     features->vaes = IsBitSet(leaf_7.ecx, 9); | ||||
|     features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); | ||||
|     features->movdiri = IsBitSet(leaf_7.ecx, 27); | ||||
|     features->movdir64b = IsBitSet(leaf_7.ecx, 28); | ||||
|     features->fs_rep_mov = IsBitSet(leaf_7.edx, 4); | ||||
|     features->fz_rep_movsb = IsBitSet(leaf_7_1.eax, 10); | ||||
|     features->fs_rep_stosb = IsBitSet(leaf_7_1.eax, 11); | ||||
|     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); | ||||
|  | ||||
|     ///////////////////////////////////////////////////////////////////////////// | ||||
|     // The following section is devoted to Vector Extensions. | ||||
| @@ -355,6 +364,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info, | ||||
|                 { | ||||
|                     features->fma3 = IsBitSet(leaf_1.ecx, 12); | ||||
|                     features->avx = IsBitSet(leaf_1.ecx, 28); | ||||
|                     features->avx_vnni = IsBitSet(leaf_7_1.eax, 4); | ||||
|                     features->avx2 = IsBitSet(leaf_7.ebx, 5); | ||||
|                 } | ||||
|             if (os_preserves->avx512_registers) | ||||
| @@ -378,6 +388,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info, | ||||
|                     features->avx512_4fmaps = IsBitSet(leaf_7.edx, 3); | ||||
|                     features->avx512_bf16 = IsBitSet(leaf_7_1.eax, 5); | ||||
|                     features->avx512_vp2intersect = IsBitSet(leaf_7.edx, 8); | ||||
|                     features->avx512_fp16 = IsBitSet(leaf_7.edx, 23); | ||||
|                 } | ||||
|             if (os_preserves->amx_registers) | ||||
|                 { | ||||
| @@ -491,6 +502,15 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                 case CPUID(0x06, 0x5C): | ||||
|                     // https://en.wikipedia.org/wiki/Goldmont | ||||
|                     return INTEL_ATOM_GMT; | ||||
|                 case CPUID(0x06, 0x7A): | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/goldmont_plus | ||||
|                     return INTEL_ATOM_GMT_PLUS; | ||||
|                 case CPUID(0x06, 0x8A): | ||||
|                 case CPUID(0x06, 0x96): | ||||
|                 case CPUID(0x06, 0x9C): | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/tremont | ||||
|                     return INTEL_ATOM_TMT; | ||||
|                 case CPUID(0x06, 0x0E): | ||||
|                 case CPUID(0x06, 0x0F): | ||||
|                 case CPUID(0x06, 0x16): | ||||
|                     // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) | ||||
| @@ -531,10 +551,16 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                     // https://en.wikipedia.org/wiki/Broadwell_(microarchitecture) | ||||
|                     return INTEL_BDW; | ||||
|                 case CPUID(0x06, 0x4E): | ||||
|                 case CPUID(0x06, 0x55): | ||||
|                 case CPUID(0x06, 0x5E): | ||||
|                     // https://en.wikipedia.org/wiki/Skylake_(microarchitecture) | ||||
|                     return INTEL_SKL; | ||||
|                 case CPUID(0x06, 0x55): | ||||
|                     if (info->stepping >= 6 && info->stepping <= 7) | ||||
|                         { | ||||
|                             // https://en.wikipedia.org/wiki/Cascade_Lake_(microprocessor) | ||||
|                             return INTEL_CCL; | ||||
|                         } | ||||
|                     return INTEL_SKL; | ||||
|                 case CPUID(0x06, 0x66): | ||||
|                     // https://en.wikipedia.org/wiki/Cannon_Lake_(microarchitecture) | ||||
|                     return INTEL_CNL; | ||||
| @@ -582,11 +608,15 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake | ||||
|                     return INTEL_ADL; | ||||
|                 case CPUID(0x06, 0xA5): | ||||
|                 case CPUID(0x06, 0xA6): | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/comet_lake | ||||
|                     return INTEL_CML; | ||||
|                 case CPUID(0x06, 0xA7): | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/rocket_lake | ||||
|                     return INTEL_RCL; | ||||
|                 case CPUID(0x06, 0xB7): | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/raptor_lake | ||||
|                     return INTEL_RPL; | ||||
|                 case CPUID(0x06, 0x85): | ||||
|                     // https://en.wikichip.org/wiki/intel/microarchitectures/knights_mill | ||||
|                     return INTEL_KNIGHTS_M; | ||||
| @@ -702,6 +732,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                 case CPUID(0x11, 0x03): | ||||
|                     // http://developer.amd.com/wordpress/media/2012/10/41788.pdf | ||||
|                     return AMD_K11; | ||||
|                 case CPUID(0x12, 0x00): | ||||
|                 case CPUID(0x12, 0x01): | ||||
|                     // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf | ||||
|                     return AMD_K12; | ||||
| @@ -714,9 +745,11 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                     // https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer | ||||
|                     return AMD_BULLDOZER; | ||||
|                 case CPUID(0x15, 0x02): | ||||
|                 case CPUID(0x15, 0x10): | ||||
|                 case CPUID(0x15, 0x11): | ||||
|                 case CPUID(0x15, 0x13): | ||||
|                     // https://en.wikichip.org/wiki/amd/microarchitectures/piledriver | ||||
|                     // https://www.amd.com/system/files/TechDocs/48931_15h_Mod_10h-1Fh_Rev_Guide.pdf | ||||
|                     return AMD_PILEDRIVER; | ||||
|                 case CPUID(0x15, 0x30): | ||||
|                 case CPUID(0x15, 0x38): | ||||
| @@ -728,6 +761,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                     // https://en.wikichip.org/wiki/amd/microarchitectures/excavator | ||||
|                     return AMD_EXCAVATOR; | ||||
|                 case CPUID(0x16, 0x00): | ||||
|                 case CPUID(0x16, 0x26): | ||||
|                     return AMD_JAGUAR; | ||||
|                 case CPUID(0x16, 0x30): | ||||
|                     return AMD_PUMA; | ||||
| @@ -760,6 +794,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info) | ||||
|                     // https://en.wikichip.org/wiki/amd/microarchitectures/zen_3 | ||||
|                     return AMD_ZEN3; | ||||
|                 case CPUID(0x19, 0x10): | ||||
|                 case CPUID(0x19, 0x61): | ||||
|                     // https://en.wikichip.org/wiki/amd/microarchitectures/zen_4 | ||||
|                     return AMD_ZEN4; | ||||
|                 default: | ||||
| @@ -1687,16 +1722,18 @@ static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id, | ||||
|             const Leaf leaf = SafeCpuIdEx(max_cpuid_leaf, leaf_id, index); | ||||
|             int cache_type_field = ExtractBitRange(leaf.eax, 4, 0); | ||||
|             CacheType cache_type; | ||||
|             if (cache_type_field == 0) | ||||
|                 break; | ||||
|             else if (cache_type_field == 1) | ||||
|             if (cache_type_field == 1) | ||||
|                 cache_type = CPU_FEATURE_CACHE_DATA; | ||||
|             else if (cache_type_field == 2) | ||||
|                 cache_type = CPU_FEATURE_CACHE_INSTRUCTION; | ||||
|             else if (cache_type_field == 3) | ||||
|                 cache_type = CPU_FEATURE_CACHE_UNIFIED; | ||||
|             else | ||||
|                 break;  // Should not occur as per documentation. | ||||
|                 // Intel Processor Identification and the CPUID Instruction Application | ||||
|                 // Note 485 page 37 Table 5-10. Deterministic Cache Parameters. | ||||
|                 // We skip cache parsing in case null of cache type or cache type in the | ||||
|                 // range of 4-31 according to documentation. | ||||
|                 break; | ||||
|             int level = ExtractBitRange(leaf.eax, 7, 5); | ||||
|             int line_size = ExtractBitRange(leaf.ebx, 11, 0) + 1; | ||||
|             int partitioning = ExtractBitRange(leaf.ebx, 21, 12) + 1; | ||||
| @@ -1717,6 +1754,123 @@ static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id, | ||||
|     if (info.size > 0) *old_info = info; | ||||
| } | ||||
|  | ||||
| typedef struct | ||||
| { | ||||
|     int level; | ||||
|     int cache_id; | ||||
|     CacheType cache_type; | ||||
| } CacheLevelInfoLegacyAMD; | ||||
|  | ||||
| static int GetWaysLegacyAMD(int cache_level, const uint32_t cache_id) | ||||
| { | ||||
|     // https://www.amd.com/system/files/TechDocs/25481.pdf page 23 | ||||
|     // CPUID.8000_0005_ECX[23:16] L1 data cache associativity. | ||||
|     // CPUID.8000_0005_EDX[23:16] L1 instruction cache associativity. | ||||
|     if (cache_level == 1) | ||||
|         { | ||||
|             return ExtractBitRange(cache_id, 23, 16); | ||||
|         } | ||||
|     // https://www.amd.com/system/files/TechDocs/25481.pdf page 24 | ||||
|     // See Table 4: L2/L3 Cache and TLB Associativity Field Definition. | ||||
|     // CPUID.8000_0006_ECX[15:12] L2 cache associativity. | ||||
|     // CPUID.8000_0006_EDX[15:12] L3 cache associativity. | ||||
|     const int ways = ExtractBitRange(cache_id, 15, 12); | ||||
|     switch (ways) | ||||
|         { | ||||
|         case 0x0: | ||||
|         case 0x1: | ||||
|         case 0x2: | ||||
|         case 0x4: | ||||
|             return ways; | ||||
|         case 0x6: | ||||
|             return 8; | ||||
|         case 0x8: | ||||
|             return 16; | ||||
|         case 0xA: | ||||
|             return 32; | ||||
|         case 0xB: | ||||
|             return 48; | ||||
|         case 0xC: | ||||
|             return 64; | ||||
|         case 0xD: | ||||
|             return 96; | ||||
|         case 0xE: | ||||
|             return 128; | ||||
|         case 0xF: | ||||
|             return 255; | ||||
|         default: | ||||
|             return -1;  // Reserved | ||||
|         } | ||||
| } | ||||
|  | ||||
| static int GetCacheSizeLegacyAMD(int cache_level, const uint32_t cache_id) | ||||
| { | ||||
|     switch (cache_level) | ||||
|         { | ||||
|         case 1: | ||||
|             // https://www.amd.com/system/files/TechDocs/25481.pdf page 23 | ||||
|             // CPUID.8000_0005_ECX[31:24] L1 data cache size in KB. | ||||
|             // CPUID.8000_0005_EDX[31:24] L1 instruction cache size KB. | ||||
|             return ExtractBitRange(cache_id, 31, 24); | ||||
|         case 2: | ||||
|             // https://www.amd.com/system/files/TechDocs/25481.pdf page 25 | ||||
|             // CPUID.8000_0006_ECX[31:16] L2 cache size in KB. | ||||
|             return ExtractBitRange(cache_id, 31, 16); | ||||
|         case 3: | ||||
|             // https://www.amd.com/system/files/TechDocs/25481.pdf page 25 | ||||
|             // CPUID.8000_0006_EDX[31:18] L3 cache size. | ||||
|             // Specifies the L3 cache size is within the following range: | ||||
|             // (L3Size[31:18] * 512KB) <= L3 cache size < ((L3Size[31:18]+1) * 512KB). | ||||
|             return ExtractBitRange(cache_id, 31, 18) * 512; | ||||
|         default: | ||||
|             return 0; | ||||
|         } | ||||
| } | ||||
|  | ||||
| #define LEGACY_AMD_MAX_CACHE_LEVEL 4 | ||||
|  | ||||
| // https://www.amd.com/system/files/TechDocs/25481.pdf | ||||
| // CPUID Fn8000_0005_E[A,B,C,D]X, Fn8000_0006_E[A,B,C,D]X - TLB and Cache info | ||||
| static void ParseCacheInfoLegacyAMD(const uint32_t max_ext, CacheInfo* info) | ||||
| { | ||||
|     const Leaf cache_tlb_leaf1 = SafeCpuIdEx(max_ext, 0x80000005, 0); | ||||
|     const Leaf cache_tlb_leaf2 = SafeCpuIdEx(max_ext, 0x80000006, 0); | ||||
|  | ||||
|     const CacheLevelInfoLegacyAMD legacy_cache_info[LEGACY_AMD_MAX_CACHE_LEVEL] = | ||||
|         {(CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf1.ecx, | ||||
|              .cache_type = CPU_FEATURE_CACHE_DATA, | ||||
|              .level = 1}, | ||||
|             (CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf1.edx, | ||||
|                 .cache_type = CPU_FEATURE_CACHE_INSTRUCTION, | ||||
|                 .level = 1}, | ||||
|             (CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf2.ecx, | ||||
|                 .cache_type = CPU_FEATURE_CACHE_UNIFIED, | ||||
|                 .level = 2}, | ||||
|             (CacheLevelInfoLegacyAMD){.cache_id = cache_tlb_leaf2.edx, | ||||
|                 .cache_type = CPU_FEATURE_CACHE_UNIFIED, | ||||
|                 .level = 3}}; | ||||
|  | ||||
|     const int KiB = 1024; | ||||
|     const int UNDEF = -1; | ||||
|     for (int i = 0; i < LEGACY_AMD_MAX_CACHE_LEVEL; ++i) | ||||
|         { | ||||
|             const int level = legacy_cache_info[i].level; | ||||
|             const int cache_id = legacy_cache_info[i].cache_id; | ||||
|             const CacheType cache_type = legacy_cache_info[i].cache_type; | ||||
|             const int cache_size = GetCacheSizeLegacyAMD(level, cache_id); | ||||
|             if (cache_size == 0) break; | ||||
|             info->levels[i] = | ||||
|                 (CacheLevelInfo){.level = level, | ||||
|                     .cache_type = cache_type, | ||||
|                     .cache_size = cache_size * KiB, | ||||
|                     .ways = GetWaysLegacyAMD(level, cache_id), | ||||
|                     .line_size = ExtractBitRange(cache_id, 7, 0), | ||||
|                     .tlb_entries = UNDEF, | ||||
|                     .partitioning = UNDEF}; | ||||
|             ++info->size; | ||||
|         } | ||||
| } | ||||
|  | ||||
| CacheInfo GetX86CacheInfo(void) | ||||
| { | ||||
|     CacheInfo info = kEmptyCacheInfo; | ||||
| @@ -1738,6 +1892,10 @@ CacheInfo GetX86CacheInfo(void) | ||||
|                 { | ||||
|                     ParseCacheInfo(leaves.max_cpuid_leaf_ext, 0x8000001D, &info); | ||||
|                 } | ||||
|             else | ||||
|                 { | ||||
|                     ParseCacheInfoLegacyAMD(leaves.max_cpuid_leaf_ext, &info); | ||||
|                 } | ||||
|         } | ||||
|     return info; | ||||
| } | ||||
| @@ -1773,6 +1931,7 @@ CacheInfo GetX86CacheInfo(void) | ||||
|     LINE(X86_SSE4_2, sse4_2, , , )                           \ | ||||
|     LINE(X86_SSE4A, sse4a, , , )                             \ | ||||
|     LINE(X86_AVX, avx, , , )                                 \ | ||||
|     LINE(X86_AVX_VNNI, avx_vnni, , , )                       \ | ||||
|     LINE(X86_AVX2, avx2, , , )                               \ | ||||
|     LINE(X86_AVX512F, avx512f, , , )                         \ | ||||
|     LINE(X86_AVX512CD, avx512cd, , , )                       \ | ||||
| @@ -1793,6 +1952,7 @@ CacheInfo GetX86CacheInfo(void) | ||||
|     LINE(X86_AVX512_4FMAPS, avx512_4fmaps, , , )             \ | ||||
|     LINE(X86_AVX512_BF16, avx512_bf16, , , )                 \ | ||||
|     LINE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, , , ) \ | ||||
|     LINE(X86_AVX512_FP16, avx512_fp16, , , )                 \ | ||||
|     LINE(X86_AMX_BF16, amx_bf16, , , )                       \ | ||||
|     LINE(X86_AMX_TILE, amx_tile, , , )                       \ | ||||
|     LINE(X86_AMX_INT8, amx_int8, , , )                       \ | ||||
| @@ -1806,7 +1966,15 @@ 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, , , )                             \ | ||||
|     LINE(X86_GFNI, gfni, , , )                               \ | ||||
|     LINE(X86_MOVDIRI, movdiri, , , )                         \ | ||||
|     LINE(X86_MOVDIR64B, movdir64b, , , )                     \ | ||||
|     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, , , ) | ||||
| #define INTROSPECTION_PREFIX X86 | ||||
| #define INTROSPECTION_ENUM_PREFIX X86 | ||||
| #include "define_introspection.inl" | ||||
| @@ -1831,7 +1999,10 @@ CacheInfo GetX86CacheInfo(void) | ||||
|     LINE(INTEL_HSW)                 \ | ||||
|     LINE(INTEL_BDW)                 \ | ||||
|     LINE(INTEL_SKL)                 \ | ||||
|     LINE(INTEL_CCL)                 \ | ||||
|     LINE(INTEL_ATOM_GMT)            \ | ||||
|     LINE(INTEL_ATOM_GMT_PLUS)       \ | ||||
|     LINE(INTEL_ATOM_TMT)            \ | ||||
|     LINE(INTEL_KBL)                 \ | ||||
|     LINE(INTEL_CFL)                 \ | ||||
|     LINE(INTEL_WHL)                 \ | ||||
| @@ -1842,6 +2013,7 @@ CacheInfo GetX86CacheInfo(void) | ||||
|     LINE(INTEL_SPR)                 \ | ||||
|     LINE(INTEL_ADL)                 \ | ||||
|     LINE(INTEL_RCL)                 \ | ||||
|     LINE(INTEL_RPL)                 \ | ||||
|     LINE(INTEL_KNIGHTS_M)           \ | ||||
|     LINE(INTEL_KNIGHTS_L)           \ | ||||
|     LINE(INTEL_KNIGHTS_F)           \ | ||||
|   | ||||
| @@ -23,6 +23,8 @@ | ||||
| #include "cpuinfo_mips.h" | ||||
| #elif defined(CPU_FEATURES_ARCH_PPC) | ||||
| #include "cpuinfo_ppc.h" | ||||
| #elif defined(CPU_FEATURES_ARCH_S390X) | ||||
| #include "cpuinfo_s390x.h" | ||||
| #endif | ||||
|  | ||||
| // Design principles | ||||
| @@ -212,6 +214,9 @@ DEFINE_ADD_FLAGS(GetMipsFeaturesEnumValue, GetMipsFeaturesEnumName, | ||||
| #elif defined(CPU_FEATURES_ARCH_PPC) | ||||
| DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures, | ||||
|     PPC_LAST_) | ||||
| #elif defined(CPU_FEATURES_ARCH_S390X) | ||||
| DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures, | ||||
|     S390X_LAST_) | ||||
| #endif | ||||
|  | ||||
| // Prints a json string with characters escaping. | ||||
| @@ -389,7 +394,6 @@ static Node* CreateTree(void) | ||||
| { | ||||
|     Node* root = CreateMap(); | ||||
| #if defined(CPU_FEATURES_ARCH_X86) | ||||
|     char brand_string[49]; | ||||
|     const X86Info info = GetX86Info(); | ||||
|     const CacheInfo cache_info = GetX86CacheInfo(); | ||||
|     AddMapEntry(root, "arch", CreateString("x86")); | ||||
| @@ -435,6 +439,14 @@ static Node* CreateTree(void) | ||||
|     AddMapEntry(root, "microarchitecture", | ||||
|         CreateString(strings.type.base_platform)); | ||||
|     AddFlags(root, &info.features); | ||||
| #elif defined(CPU_FEATURES_ARCH_S390X) | ||||
|     const S390XInfo info = GetS390XInfo(); | ||||
|     const S390XPlatformStrings strings = GetS390XPlatformStrings(); | ||||
|     AddMapEntry(root, "arch", CreateString("s390x")); | ||||
|     AddMapEntry(root, "platform", CreateString("zSeries")); | ||||
|     AddMapEntry(root, "model", CreateString(strings.type.platform)); | ||||
|     AddMapEntry(root, "# processors", CreateInt(strings.num_processors)); | ||||
|     AddFlags(root, &info.features); | ||||
| #endif | ||||
|     return root; | ||||
| } | ||||
|   | ||||
| @@ -92,3 +92,10 @@ if(PROCESSOR_IS_POWER) | ||||
|   target_link_libraries(cpuinfo_ppc_test all_libraries) | ||||
|   add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test) | ||||
| endif() | ||||
| ##------------------------------------------------------------------------------ | ||||
| ## cpuinfo_s390x_test | ||||
| if(PROCESSOR_IS_S390X) | ||||
|   add_executable(cpuinfo_s390x_test cpuinfo_s390x_test.cc  ../src/impl_s390x_linux.c) | ||||
|   target_link_libraries(cpuinfo_s390x_test all_libraries) | ||||
|   add_test(NAME cpuinfo_s390x_test COMMAND cpuinfo_s390x_test) | ||||
| endif() | ||||
|   | ||||
| @@ -0,0 +1,79 @@ | ||||
| // SPDX-FileCopyrightText: 2022 IBM | ||||
| // SPDX-License-Identifier: Apache-2.0 | ||||
|  | ||||
| #include "cpuinfo_s390x.h" | ||||
| #include "filesystem_for_testing.h" | ||||
| #include "gtest/gtest.h" | ||||
| #include "hwcaps_for_testing.h" | ||||
|  | ||||
| namespace cpu_features | ||||
| { | ||||
| namespace | ||||
| { | ||||
|  | ||||
| TEST(CpustringsS390XTest, S390XFeaturesEnum) | ||||
| { | ||||
|     const char* last_name = GetS390XFeaturesEnumName(S390X_LAST_); | ||||
|     EXPECT_STREQ(last_name, "unknown_feature"); | ||||
|     for (int i = static_cast<int>(S390_ZARCH); i != static_cast<int>(S390X_LAST_); ++i) | ||||
|         { | ||||
|             const auto feature = static_cast<S390XFeaturesEnum>(i); | ||||
|             const char* name = GetS390XFeaturesEnumName(feature); | ||||
|             ASSERT_FALSE(name == nullptr); | ||||
|             EXPECT_STRNE(name, ""); | ||||
|             EXPECT_STRNE(name, last_name); | ||||
|         } | ||||
| } | ||||
|  | ||||
| TEST(CpustringsS390XTest, FromHardwareCap) | ||||
| { | ||||
|     ResetHwcaps(); | ||||
|     SetHardwareCapabilities(HWCAP_S390_ESAN3 | HWCAP_S390_HPAGE | | ||||
|                                 HWCAP_S390_NNPA | HWCAP_S390_SIE, | ||||
|         0); | ||||
|     GetEmptyFilesystem();  // disabling /proc/cpuinfo | ||||
|     const auto info = GetS390XInfo(); | ||||
|     EXPECT_TRUE(info.features.esan3); | ||||
|     EXPECT_TRUE(info.features.edat); | ||||
|     EXPECT_TRUE(info.features.nnpa); | ||||
|     EXPECT_TRUE(info.features.sie); | ||||
|     EXPECT_FALSE(info.features.msa); | ||||
|     EXPECT_FALSE(info.features.stfle); | ||||
|     EXPECT_FALSE(info.features.vxp2); | ||||
|     EXPECT_FALSE(info.features.pcimio); | ||||
| } | ||||
|  | ||||
| TEST(CpustringsS390XTest, z16) | ||||
| { | ||||
|     ResetHwcaps(); | ||||
|     auto& fs = GetEmptyFilesystem(); | ||||
|     fs.CreateFile("/proc/cpuinfo", | ||||
|         R"(vendor_id       : IBM/S390 | ||||
| # processors    : 24 | ||||
| bogomips per cpu: 26315.00 | ||||
| max thread id   : 1 | ||||
| features	: esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs te vx vxd vxe gs vxe2 vxp sort dflt vxp2 nnpa pcimio sie )"); | ||||
|     SetPlatformPointer("z16"); | ||||
|     const auto strings = GetS390XPlatformStrings(); | ||||
|     EXPECT_EQ(strings.num_processors, 24); | ||||
|     ASSERT_STREQ(strings.type.platform, "z16"); | ||||
| } | ||||
|  | ||||
| TEST(CpustringsS390XTest, z15) | ||||
| { | ||||
|     ResetHwcaps(); | ||||
|     auto& fs = GetEmptyFilesystem(); | ||||
|     fs.CreateFile("/proc/cpuinfo", | ||||
|         R"(vendor_id       : IBM/S390 | ||||
| # processors    : 2 | ||||
| bogomips per cpu: 24038.00 | ||||
| max thread id   : 1 | ||||
| features    : esan3 zarch stfle msa ldisp eimm dfp edat etf3eh highgprs te vx vxd vxe gs vxe2 vxp sort dflt sie)"); | ||||
|     SetPlatformPointer("z15"); | ||||
|     const auto strings = GetS390XPlatformStrings(); | ||||
|     EXPECT_EQ(strings.num_processors, 2); | ||||
|     ASSERT_STREQ(strings.type.platform, "z15"); | ||||
| } | ||||
|  | ||||
| }  // namespace | ||||
| }  // namespace cpu_features | ||||
| @@ -7,8 +7,8 @@ | ||||
| #include <map> | ||||
| #include <set> | ||||
| #if defined(CPU_FEATURES_OS_WINDOWS) | ||||
| #include <windows.h>  // IsProcessorFeaturePresent | ||||
| #endif                // CPU_FEATURES_OS_WINDOWS | ||||
| #include "internal/windows_utils.h" | ||||
| #endif  // CPU_FEATURES_OS_WINDOWS | ||||
|  | ||||
| #include "filesystem_for_testing.h" | ||||
| #include "gtest/gtest.h" | ||||
| @@ -161,7 +161,7 @@ TEST_F(CpuidX86Test, SandyBridge) | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x02A); | ||||
|     EXPECT_EQ(info.stepping, 0x06); | ||||
| @@ -225,13 +225,39 @@ TEST_F(CpuidX86Test, SkyLake) | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0x029C67AF, 0x00000000, 0x00000000}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x04E); | ||||
|     EXPECT_EQ(info.stepping, 0x03); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel0050654_SkylakeXeon_CPUID8.txt | ||||
| TEST_F(CpuidX86Test, SkyLakeXeon) | ||||
| { | ||||
|     cpu().SetLeaves({{{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00050654, 0x00100800, 0x7FFEFBFF, 0xBFEBFBFF}}}); | ||||
|     const auto info = GetX86Info(); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x055); | ||||
|     EXPECT_EQ(info.stepping, 0x04); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_SKL); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel0050657_CascadeLakeXeon_CPUID.txt | ||||
| TEST_F(CpuidX86Test, CascadeLake) | ||||
| { | ||||
|     cpu().SetLeaves({{{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00050657, 0x00400800, 0x7FFEFBFF, 0xBFEBFBFF}}}); | ||||
|     const auto info = GetX86Info(); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x055); | ||||
|     EXPECT_EQ(info.stepping, 0x07); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CCL); | ||||
| } | ||||
|  | ||||
| TEST_F(CpuidX86Test, Branding) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
| @@ -266,7 +292,7 @@ TEST_F(CpuidX86Test, KabyLakeCache) | ||||
|     const auto info = GetX86CacheInfo(); | ||||
|     EXPECT_EQ(info.size, 4); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 32 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 8); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
| @@ -274,7 +300,8 @@ TEST_F(CpuidX86Test, KabyLakeCache) | ||||
|     EXPECT_EQ(info.levels[0].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, 2); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 32 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 8); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
| @@ -282,7 +309,7 @@ TEST_F(CpuidX86Test, KabyLakeCache) | ||||
|     EXPECT_EQ(info.levels[1].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 256 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 4); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
| @@ -290,7 +317,7 @@ TEST_F(CpuidX86Test, KabyLakeCache) | ||||
|     EXPECT_EQ(info.levels[2].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 6 * MiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 12); | ||||
|     EXPECT_EQ(info.levels[3].line_size, 64); | ||||
| @@ -316,7 +343,7 @@ TEST_F(CpuidX86Test, HSWCache) | ||||
|     const auto info = GetX86CacheInfo(); | ||||
|     EXPECT_EQ(info.size, 4); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 32 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 8); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
| @@ -324,7 +351,8 @@ TEST_F(CpuidX86Test, HSWCache) | ||||
|     EXPECT_EQ(info.levels[0].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, 2); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 32 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 8); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
| @@ -332,7 +360,7 @@ TEST_F(CpuidX86Test, HSWCache) | ||||
|     EXPECT_EQ(info.levels[1].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 256 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 8); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
| @@ -340,7 +368,7 @@ TEST_F(CpuidX86Test, HSWCache) | ||||
|     EXPECT_EQ(info.levels[2].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 6 * MiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 12); | ||||
|     EXPECT_EQ(info.levels[3].line_size, 64); | ||||
| @@ -359,7 +387,7 @@ TEST_F(CpuidX86Test, AMD_K11_GRIFFIN) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x11); | ||||
|     EXPECT_EQ(info.model, 0x03); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_K11); | ||||
| @@ -376,7 +404,7 @@ TEST_F(CpuidX86Test, AMD_K12_LLANO) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x12); | ||||
|     EXPECT_EQ(info.model, 0x01); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_K12); | ||||
| @@ -393,7 +421,7 @@ TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F01) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x14); | ||||
|     EXPECT_EQ(info.model, 0x00); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT); | ||||
| @@ -418,7 +446,7 @@ TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F10) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x14); | ||||
|     EXPECT_EQ(info.model, 0x01); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT); | ||||
| @@ -435,7 +463,7 @@ TEST_F(CpuidX86Test, AMD_K14_BOBCAT_AMD0500F20) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x14); | ||||
|     EXPECT_EQ(info.model, 0x02); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_BOBCAT); | ||||
| @@ -456,7 +484,7 @@ TEST_F(CpuidX86Test, AMD_K15_EXCAVATOR_STONEY_RIDGE) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x15); | ||||
|     EXPECT_EQ(info.model, 0x70); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -480,7 +508,7 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x15); | ||||
|     EXPECT_EQ(info.model, 0x02); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -508,7 +536,7 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO) | ||||
|  | ||||
|     EXPECT_EQ(info.size, 4); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 16 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 4); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
| @@ -516,7 +544,8 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[0].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, 2); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 2); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
| @@ -524,7 +553,7 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[1].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 2 * MiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 16); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
| @@ -532,7 +561,7 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[2].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 6 * MiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 48); | ||||
|     EXPECT_EQ(info.levels[3].line_size, 64); | ||||
| @@ -540,6 +569,30 @@ TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_ABU_DHABI_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[3].partitioning, 1); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/AuthenticAMD/AuthenticAMD0610F01_K15_Piledriver_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_K15_PILEDRIVER_A10) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00610F01, 0x00040800, 0x3E98320B, 0x178BFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}}, | ||||
|         {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000001, 0}, Leaf{0x00610F01, 0x20000000, 0x01EBBFFF, 0x2FD3FBFF}}, | ||||
|         {{0x80000002, 0}, Leaf{0x20444D41, 0x2D303141, 0x30303835, 0x5041204B}}, | ||||
|         {{0x80000003, 0}, Leaf{0x69772055, 0x52206874, 0x6F656461, 0x6D74286E}}, | ||||
|         {{0x80000004, 0}, Leaf{0x44482029, 0x61724720, 0x63696870, 0x00202073}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x15); | ||||
|     EXPECT_EQ(info.model, 0x10); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
|         "AMD A10-5800K APU with Radeon(tm) HD Graphics  "); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), | ||||
|         X86Microarchitecture::AMD_PILEDRIVER); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0600F12_K15_Interlagos_CPUID3.txt | ||||
| TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS) | ||||
| { | ||||
| @@ -555,7 +608,7 @@ TEST_F(CpuidX86Test, AMD_K15_BULLDOZER_INTERLAGOS) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x15); | ||||
|     EXPECT_EQ(info.model, 0x01); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -580,7 +633,7 @@ TEST_F(CpuidX86Test, AMD_K15_STREAMROLLER_GODAVARI) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x15); | ||||
|     EXPECT_EQ(info.model, 0x38); | ||||
|     EXPECT_EQ(info.stepping, 0x01); | ||||
| @@ -590,6 +643,28 @@ 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, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     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) | ||||
| { | ||||
| @@ -605,7 +680,7 @@ TEST_F(CpuidX86Test, AMD_K16_JAGUAR_KABINI) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x16); | ||||
|     EXPECT_EQ(info.model, 0x00); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -628,7 +703,7 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x16); | ||||
|     EXPECT_EQ(info.model, 0x30); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -636,6 +711,29 @@ TEST_F(CpuidX86Test, AMD_K16_PUMA_BEEMA) | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_PUMA); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/AuthenticAMD/AuthenticAMD0720F61_K16_Cato_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_K16_CATO) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000000D, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00720F61, 0x00080800, 0x3ED8220B, 0x178BFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0x00000008, 0x00000000, 0x00000000}}, | ||||
|         {{0x80000000, 0}, Leaf{0x8000001E, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000001, 0}, Leaf{0x00720F61, 0x00000000, 0x154837FF, 0x2FD3FBFF}}, | ||||
|         {{0x80000002, 0}, Leaf{0x20444D41, 0x392D3941, 0x20303238, 0x636F7250}}, | ||||
|         {{0x80000003, 0}, Leaf{0x6F737365, 0x00000072, 0x00000000, 0x00000000}}, | ||||
|         {{0x80000004, 0}, Leaf{0x00000000, 0x00000000, 0x00000000, 0x00000000}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x16); | ||||
|     EXPECT_EQ(info.model, 0x26); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
|         "AMD A9-9820 Processor"); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_JAGUAR); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0820F01_K17_Dali_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI) | ||||
| { | ||||
| @@ -651,7 +749,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_DALI) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x17); | ||||
|     EXPECT_EQ(info.model, 0x20); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -674,7 +772,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN_PLUS_PINNACLE_RIDGE) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x17); | ||||
|     EXPECT_EQ(info.model, 0x08); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -697,7 +795,7 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x17); | ||||
|     EXPECT_EQ(info.model, 0x47); | ||||
|     EXPECT_STREQ(info.brand_string, "AMD 4700S 8-Core Processor Desktop Kit"); | ||||
| @@ -719,7 +817,7 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "HygonGenuine"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_HYGON_GENUINE); | ||||
|     EXPECT_EQ(info.family, 0x18); | ||||
|     EXPECT_EQ(info.model, 0x00); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -744,7 +842,7 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_CACHE_INFO) | ||||
|  | ||||
|     EXPECT_EQ(info.size, 4); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 32 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 8); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
| @@ -752,7 +850,8 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[0].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, 2); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 4); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
| @@ -760,7 +859,7 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[1].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 512 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 8); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
| @@ -768,7 +867,7 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_CACHE_INFO) | ||||
|     EXPECT_EQ(info.levels[2].partitioning, 1); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 8 * MiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 16); | ||||
|     EXPECT_EQ(info.levels[3].line_size, 64); | ||||
| @@ -791,7 +890,7 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3_VERMEER) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x19); | ||||
|     EXPECT_EQ(info.model, 0x21); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -813,7 +912,7 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "AuthenticAMD"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x19); | ||||
|     EXPECT_EQ(info.model, 0x44); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
| @@ -821,6 +920,28 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN3) | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN3); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A60F12_K19_Raphael_01_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00A60F12, 0x000C0800, 0x7EF8320B, 0x178BFBFF}}, | ||||
|         {{0x80000000, 0}, Leaf{0x80000028, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000001, 0}, Leaf{0x00A60F12, 0x00000000, 0x75C237FF, 0x2FD3FBFF}}, | ||||
|         {{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2035206E, 0x30303637}}, | ||||
|         {{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}}, | ||||
|         {{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); | ||||
|     EXPECT_EQ(info.family, 0x19); | ||||
|     EXPECT_EQ(info.model, 0x61); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
|         "AMD Ryzen 5 7600X 6-Core Processor             "); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F11_Hygon_01_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250) | ||||
| { | ||||
| @@ -837,12 +958,274 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250) | ||||
|  | ||||
|     EXPECT_EQ(info.model, 0x01); | ||||
|     EXPECT_EQ(info.family, 0x18); | ||||
|     EXPECT_STREQ(info.vendor, "HygonGenuine"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_HYGON_GENUINE); | ||||
|     EXPECT_STREQ(info.brand_string, | ||||
|         "Hygon C86 3250  8-core Processor               "); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906A4_AlderLakeP_00_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX_VNNI) | ||||
| { | ||||
|     cpu().SetOsBackupsExtendedRegisters(true); | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000906A4, 0x00400800, 0x7FFAFBBF, 0xBFEBFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000001, 0x239CA7EB, 0x984007AC, 0xFC18C410}}, | ||||
|         {{0x00000007, 1}, Leaf{0x00400810, 0x00000000, 0x00000000, 0x00000000}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x9A); | ||||
|     EXPECT_TRUE(info.features.avx_vnni); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0090672_AlderLake_BC_AVX512_CPUID01.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX512) | ||||
| { | ||||
|     cpu().SetOsBackupsExtendedRegisters(true); | ||||
| #if defined(CPU_FEATURES_OS_MACOS) | ||||
|     cpu().SetDarwinSysCtlByName("hw.optional.avx512f"); | ||||
| #endif | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000906A4, 0x00400800, 0x7FFAFBBF, 0xBFEBFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000001, 0xF3BFA7EB, 0x98C07FEE, 0xFC9CC510}}, | ||||
|         {{0x00000007, 1}, Leaf{0x00401C30, 0x00000000, 0x00000000, 0x00000000}}, | ||||
|     }); | ||||
|  | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x9A); | ||||
|     EXPECT_TRUE(info.features.avx512f); | ||||
|     EXPECT_TRUE(info.features.avx512bw); | ||||
|     EXPECT_TRUE(info.features.avx512dq); | ||||
|     EXPECT_TRUE(info.features.avx512cd); | ||||
|     EXPECT_TRUE(info.features.avx512vl); | ||||
|     EXPECT_TRUE(info.features.avx512_vp2intersect); | ||||
|     EXPECT_TRUE(info.features.avx512vbmi); | ||||
|     EXPECT_TRUE(info.features.avx512vbmi2); | ||||
|     EXPECT_TRUE(info.features.avx512bitalg); | ||||
|     EXPECT_TRUE(info.features.avx512vpopcntdq); | ||||
|     EXPECT_TRUE(info.features.avx512ifma); | ||||
|     EXPECT_TRUE(info.features.avx512_bf16); | ||||
|     EXPECT_TRUE(info.features.avx512_fp16); | ||||
|  | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00806C1_TigerLake_CPUID3.txt | ||||
| TEST_F(CpuidX86Test, INTEL_TIGER_LAKE_AVX512) | ||||
| { | ||||
|     cpu().SetOsBackupsExtendedRegisters(true); | ||||
| #if defined(CPU_FEATURES_OS_MACOS) | ||||
|     cpu().SetDarwinSysCtlByName("hw.optional.avx512f"); | ||||
| #endif | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000806C1, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0xF3BFA7EB, 0x18C05FCE, 0xFC100510}}, | ||||
|     }); | ||||
|  | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x8C); | ||||
|     EXPECT_TRUE(info.features.avx512f); | ||||
|     EXPECT_TRUE(info.features.avx512bw); | ||||
|     EXPECT_TRUE(info.features.avx512dq); | ||||
|     EXPECT_TRUE(info.features.avx512cd); | ||||
|     EXPECT_TRUE(info.features.avx512vl); | ||||
|     EXPECT_TRUE(info.features.avx512_vp2intersect); | ||||
|     EXPECT_TRUE(info.features.avx512vbmi); | ||||
|     EXPECT_TRUE(info.features.avx512vbmi2); | ||||
|     EXPECT_TRUE(info.features.avx512bitalg); | ||||
|     EXPECT_TRUE(info.features.avx512vpopcntdq); | ||||
|     EXPECT_TRUE(info.features.avx512ifma); | ||||
|  | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_TGL); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00706E5_IceLakeY_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ICE_LAKE_GFNI) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000706E5, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0xF2BF27EF, 0x40405F4E, 0xBC000410}}, | ||||
|     }); | ||||
|  | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x7E); | ||||
|     EXPECT_TRUE(info.features.gfni); | ||||
|  | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ICL); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906C0_JasperLake_CPUID01.txt | ||||
| TEST_F(CpuidX86Test, INTEL_TREMONT_JASPER_LAKE_MOVDR) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00090661, 0x00800800, 0x4FF8EBBF, 0xBFEBFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000000, 0x2394A2C3, 0x18400124, 0xFC000400}}, | ||||
|     }); | ||||
|  | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x96); | ||||
|     EXPECT_TRUE(info.features.movdiri); | ||||
|     EXPECT_TRUE(info.features.movdir64b); | ||||
|  | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel0090672_AlderLake_LC_BC_CPUID01.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_REP) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00090672, 0x00800800, 0x7FFAFBFF, 0xBFEBFBFF}}, | ||||
|         {{0x00000007, 0}, Leaf{0x00000001, 0x239CA7EB, 0x98C027AC, 0xFC1CC410}}, | ||||
|         {{0x00000007, 1}, Leaf{0x00400810, 0x00000000, 0x00000000, 0x00000000}}, | ||||
|     }); | ||||
|  | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x97); | ||||
|     EXPECT_TRUE(info.features.erms); | ||||
|     EXPECT_TRUE(info.features.fs_rep_mov); | ||||
|     EXPECT_FALSE(info.features.fz_rep_movsb); | ||||
|     EXPECT_TRUE(info.features.fs_rep_stosb); | ||||
|     EXPECT_FALSE(info.features.fs_rep_cmpsb_scasb); | ||||
|  | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0100FA0_K10_Thuban_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_THUBAN_CACHE_INFO) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000006, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000000, 0}, Leaf{0x8000001B, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000001, 0}, Leaf{0x00100FA0, 0x10000050, 0x000037FF, 0xEFD3FBFF}}, | ||||
|         {{0x80000005, 0}, Leaf{0xFF30FF10, 0xFF30FF20, 0x40020140, 0x40020140}}, | ||||
|         {{0x80000006, 0}, Leaf{0x20800000, 0x42004200, 0x02008140, 0x0030B140}}, | ||||
|     }); | ||||
|     const auto info = GetX86CacheInfo(); | ||||
|  | ||||
|     EXPECT_EQ(info.size, 4); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 2); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 2); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 512 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 16); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 6 * MiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 48); | ||||
|     EXPECT_EQ(info.levels[3].line_size, 64); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0020FB1_K8_Manchester_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_MANCHESTER_CACHE_INFO) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000001, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000000, 0}, Leaf{0x80000018, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000001, 0}, Leaf{0x00020FB1, 0x00000150, 0x00000003, 0xE3D3FBFF}}, | ||||
|         {{0x80000005, 0}, Leaf{0xFF08FF08, 0xFF20FF20, 0x40020140, 0x40020140}}, | ||||
|         {{0x80000006, 0}, Leaf{0x00000000, 0x42004200, 0x02008140, 0x00000000}}, | ||||
|     }); | ||||
|     const auto info = GetX86CacheInfo(); | ||||
|  | ||||
|     EXPECT_EQ(info.size, 3); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 2); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 2); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 512 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 16); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0100F22_K10_Agena_CPUID.txt | ||||
| TEST_F(CpuidX86Test, AMD_AGENA_CACHE_INFO) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000005, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000000, 0}, Leaf{0x8000001A, 0x68747541, 0x444D4163, 0x69746E65}}, | ||||
|         {{0x80000001, 0}, Leaf{0x00100F22, 0x10000000, 0x000007FF, 0xEFD3FBFF}}, | ||||
|         {{0x80000005, 0}, Leaf{0xFF30FF10, 0xFF30FF20, 0x40020140, 0x40020140}}, | ||||
|         {{0x80000006, 0}, Leaf{0x20800000, 0x42004200, 0x02008140, 0x0010A140}}, | ||||
|     }); | ||||
|     const auto info = GetX86CacheInfo(); | ||||
|  | ||||
|     EXPECT_EQ(info.size, 4); | ||||
|     EXPECT_EQ(info.levels[0].level, 1); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, 2); | ||||
|     EXPECT_EQ(info.levels[0].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, 1); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 64 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, 2); | ||||
|     EXPECT_EQ(info.levels[1].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 2); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 512 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 16); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 3); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CacheType::CPU_FEATURE_CACHE_UNIFIED); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 2 * MiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 32); | ||||
|     EXPECT_EQ(info.levels[3].line_size, 64); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00106A1_Nehalem_CPUID.txt | ||||
| TEST_F(CpuidX86Test, Nehalem) | ||||
| { | ||||
| @@ -907,7 +1290,7 @@ flags           : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2 | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x1A); | ||||
|     EXPECT_EQ(info.stepping, 0x02); | ||||
| @@ -986,7 +1369,7 @@ flags           : fpu mmx sse sse2 pni ssse3 sse4_1 sse4_2 | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x37); | ||||
|     EXPECT_EQ(info.stepping, 0x03); | ||||
| @@ -1016,7 +1399,7 @@ TEST_F(CpuidX86Test, P4_CacheInfo) | ||||
|     EXPECT_EQ(info.size, 5); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[0].level, UNDEF); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CPU_FEATURE_CACHE_TLB); | ||||
|     EXPECT_EQ(info.levels[0].cache_type, CacheType::CPU_FEATURE_CACHE_TLB); | ||||
|     EXPECT_EQ(info.levels[0].cache_size, 4 * KiB); | ||||
|     EXPECT_EQ(info.levels[0].ways, UNDEF); | ||||
|     EXPECT_EQ(info.levels[0].line_size, UNDEF); | ||||
| @@ -1024,7 +1407,7 @@ TEST_F(CpuidX86Test, P4_CacheInfo) | ||||
|     EXPECT_EQ(info.levels[0].partitioning, 0); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[1].level, UNDEF); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, CPU_FEATURE_CACHE_TLB); | ||||
|     EXPECT_EQ(info.levels[1].cache_type, CacheType::CPU_FEATURE_CACHE_TLB); | ||||
|     EXPECT_EQ(info.levels[1].cache_size, 4 * KiB); | ||||
|     EXPECT_EQ(info.levels[1].ways, UNDEF); | ||||
|     EXPECT_EQ(info.levels[1].line_size, UNDEF); | ||||
| @@ -1032,7 +1415,7 @@ TEST_F(CpuidX86Test, P4_CacheInfo) | ||||
|     EXPECT_EQ(info.levels[1].partitioning, 0); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[2].level, 1); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[2].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[2].cache_size, 8 * KiB); | ||||
|     EXPECT_EQ(info.levels[2].ways, 4); | ||||
|     EXPECT_EQ(info.levels[2].line_size, 64); | ||||
| @@ -1040,7 +1423,8 @@ TEST_F(CpuidX86Test, P4_CacheInfo) | ||||
|     EXPECT_EQ(info.levels[2].partitioning, 0); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[3].level, 1); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[3].cache_type, | ||||
|         CacheType::CPU_FEATURE_CACHE_INSTRUCTION); | ||||
|     EXPECT_EQ(info.levels[3].cache_size, 12 * KiB); | ||||
|     EXPECT_EQ(info.levels[3].ways, 8); | ||||
|     EXPECT_EQ(info.levels[3].line_size, UNDEF); | ||||
| @@ -1048,7 +1432,7 @@ TEST_F(CpuidX86Test, P4_CacheInfo) | ||||
|     EXPECT_EQ(info.levels[3].partitioning, 0); | ||||
|  | ||||
|     EXPECT_EQ(info.levels[4].level, 2); | ||||
|     EXPECT_EQ(info.levels[4].cache_type, CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[4].cache_type, CacheType::CPU_FEATURE_CACHE_DATA); | ||||
|     EXPECT_EQ(info.levels[4].cache_size, 256 * KiB); | ||||
|     EXPECT_EQ(info.levels[4].ways, 8); | ||||
|     EXPECT_EQ(info.levels[4].line_size, 64); | ||||
| @@ -1088,7 +1472,7 @@ flags           : fpu mmx sse | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x07); | ||||
|     EXPECT_EQ(info.stepping, 0x03); | ||||
| @@ -1113,7 +1497,7 @@ TEST_F(CpuidX86Test, INTEL_80486) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x04); | ||||
|     EXPECT_EQ(info.model, 0x08); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_80486); | ||||
| @@ -1128,7 +1512,7 @@ TEST_F(CpuidX86Test, INTEL_P54C) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x05); | ||||
|     EXPECT_EQ(info.model, 0x02); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_P5); | ||||
| @@ -1143,13 +1527,44 @@ TEST_F(CpuidX86Test, INTEL_LAKEMONT) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x05); | ||||
|     EXPECT_EQ(info.model, 0x09); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), | ||||
|         X86Microarchitecture::INTEL_LAKEMONT); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00006E8_PM_Yonah_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_CORE_YONAH) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000000A, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000006E8, 0x00010800, 0x0000C109, 0xAFE9FBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x0E); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CORE); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00706A8_GoldmontPlus_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_GOLDMONT_PLUS) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000018, 0x756E6547, 0x6c65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000706A8, 0x00400800, 0x4FF8EBBF, 0xBFEBFBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x7A); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), | ||||
|         X86Microarchitecture::INTEL_ATOM_GMT_PLUS); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0050670_KnightsLanding_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING) | ||||
| { | ||||
| @@ -1159,7 +1574,7 @@ TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x57); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), | ||||
| @@ -1175,12 +1590,11 @@ TEST_F(CpuidX86Test, INTEL_CML_U) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     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 | ||||
| @@ -1192,11 +1606,106 @@ TEST_F(CpuidX86Test, INTEL_CML_H) | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, "GenuineIntel"); | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0xA5); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), | ||||
|         X86Microarchitecture::INTEL_CML); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00A0660_CometLake_CPUID1.txt | ||||
| TEST_F(CpuidX86Test, INTEL_CML_U2) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000016, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000A0660, 0x00100800, 0x7FFAFBBF, 0xBFEBFBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0xA6); | ||||
|     EXPECT_EQ(info.stepping, 0x00); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_CML); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00806A1_Lakefield_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ATOM_TMT_LAKEFIELD) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000806A1, 0x00100800, 0x4FD8EBBF, 0xBFEBFBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x8A); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0090661_ElkhartLake_CPUID01.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ATOM_TMT_ELKHART_LAKE) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x00090661, 0x00800800, 0x4FF8EBBF, 0xBFEBFBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x96); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT); | ||||
| } | ||||
|  | ||||
| // https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel00906C0_JasperLake_01_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_ATOM_TMT_JASPER_LAKE) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x0000001B, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000906C0, 0x00800800, 0x4FF8EBBF, 0xBFEBFBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0x9C); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ATOM_TMT); | ||||
| } | ||||
|  | ||||
| // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B0671_RaptorLake_02_CPUID.txt | ||||
| TEST_F(CpuidX86Test, INTEL_RAPTOR_LAKE) | ||||
| { | ||||
|     cpu().SetLeaves({ | ||||
|         {{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}}, | ||||
|         {{0x00000001, 0}, Leaf{0x000B0671, 0x00800800, 0x7FFAFBBF, 0xBFEBFBFF}}, | ||||
|     }); | ||||
|     const auto info = GetX86Info(); | ||||
|  | ||||
|     EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     EXPECT_EQ(info.family, 0x06); | ||||
|     EXPECT_EQ(info.model, 0xB7); | ||||
|     EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_RPL); | ||||
| } | ||||
|  | ||||
| // 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, CPU_FEATURES_VENDOR_GENUINE_INTEL); | ||||
|     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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Carles Fernandez
					Carles Fernandez