diff --git a/CMakeLists.txt b/CMakeLists.txt index 1fb98188c..4b3aeb7e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index 8aa84429c..8a8f2e76e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -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) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt index acb748a3c..cde0a4668 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt @@ -16,12 +16,13 @@ if(CMAKE_VERSION LESS "3.1") add_compile_options("$<$,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 $) 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) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md index ce13d72e6..3421040c5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md @@ -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 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h index 2eb11e264..ace763248 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h @@ -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 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_s390x.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_s390x.h new file mode 100644 index 000000000..aad885e50 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_s390x.h @@ -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_ \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h index 3a968a862..4db5efa4c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_x86.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_ \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h index 94f5f43e2..29da4837a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/hwcaps.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')) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/windows_utils.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/windows_utils.h index 246bb20c9..1790adc9c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/windows_utils.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/windows_utils.h @@ -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 // 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_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c index 3303be405..9f9b3eef5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c @@ -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" diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_s390x_linux.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_s390x_linux.c new file mode 100644 index 000000000..f161009dd --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_s390x_linux.c @@ -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 + +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 \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl index 29ad4b76c..e18b7cbba 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl @@ -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) \ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c index 859ef6954..38489640c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/utils/list_cpu_features.c @@ -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; } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt index f5330653c..e887cbb55 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt @@ -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() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_s390x_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_s390x_test.cc new file mode 100644 index 000000000..44a50cb4b --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_s390x_test.cc @@ -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(S390_ZARCH); i != static_cast(S390X_LAST_); ++i) + { + const auto feature = static_cast(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 \ No newline at end of file diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc index 15f2e3217..f83df2efa 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_x86_test.cc @@ -7,8 +7,8 @@ #include #include #if defined(CPU_FEATURES_OS_WINDOWS) -#include // 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