From e373a7c8606054f0ccfd9390d50157f54259fc67 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Fri, 24 Dec 2021 15:14:26 +0100 Subject: [PATCH] Update cpu_features code layout to https://github.com/google/cpu_features/commit/69d39934e83be9a0133d2850f15f5debd5eba06f --- .../volk_gnsssdr/CMakeLists.txt | 1 + .../volk_gnsssdr/cpu_features/CMakeLists.txt | 18 +- .../volk_gnsssdr/cpu_features/cmake/README.md | 16 +- .../cmake/googletest.CMakeLists.txt.in | 2 +- .../include/cpu_features_macros.h | 24 +- .../cpu_features/include/cpuinfo_aarch64.h | 1 - .../cpu_features/include/cpuinfo_arm.h | 1 - .../cpu_features/include/cpuinfo_mips.h | 1 - .../cpu_features/include/cpuinfo_ppc.h | 4 +- .../cpu_features/include/cpuinfo_x86.h | 17 +- .../cpu_features/include/internal/bit_utils.h | 1 - .../cpu_features/include/internal/cpuid_x86.h | 1 - .../include/internal/filesystem.h | 1 - .../cpu_features/include/internal/hwcaps.h | 1 - .../include/internal/stack_line_reader.h | 1 - .../include/internal/string_view.h | 1 - .../cpu_features/scripts/run_integration.sh | 433 ++++-- .../cpu_features/scripts/test_integration.sh | 59 +- .../volk_gnsssdr/cpu_features/src/copy.inl | 9 + .../cpu_features/src/cpuinfo_aarch64.c | 210 --- .../cpu_features/src/cpuinfo_ppc.c | 175 --- .../cpu_features/src/define_introspection.inl | 79 + .../src/define_introspection_and_hwcaps.inl | 15 + .../cpu_features/src/define_tables.h | 58 - .../volk_gnsssdr/cpu_features/src/equals.inl | 12 + .../src/impl_aarch64_linux_or_android.c | 157 ++ ...info_arm.c => impl_arm_linux_or_android.c} | 98 +- ...fo_mips.c => impl_mips_linux_or_android.c} | 48 +- .../cpu_features/src/impl_ppc_linux.c | 167 ++ ...86.c => impl_x86__base_implementation.inl} | 1378 ++++++++--------- .../cpu_features/src/impl_x86_freebsd.c | 60 + .../src/impl_x86_linux_or_android.c | 50 + .../cpu_features/src/impl_x86_macos.c | 48 + .../cpu_features/src/impl_x86_windows.c | 41 + .../src/utils/list_cpu_features.c | 2 +- .../cpu_features/test/CMakeLists.txt | 20 +- .../cpu_features/test/cpuinfo_x86_test.cc | 88 +- 37 files changed, 1793 insertions(+), 1505 deletions(-) create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl delete mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c delete mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl delete mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c rename src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/{cpuinfo_arm.c => impl_arm_linux_or_android.c} (72%) rename src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/{cpuinfo_mips.c => impl_mips_linux_or_android.c} (71%) create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c rename src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/{cpuinfo_x86.c => impl_x86__base_implementation.inl} (79%) create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c create mode 100644 src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c 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 66b4ac603..4cd801af8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -270,6 +270,7 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") endif() if(CMAKE_VERSION VERSION_GREATER 3.0 AND SUPPORTED_CPU_FEATURES_ARCH) + set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE) set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "Build cpu_features with Position Independent Code (PIC)." FORCE 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 9001f224d..13e2cb30c 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 @@ -23,9 +23,6 @@ if(NOT CMAKE_BUILD_TYPE) FORCE) endif() -# BUILD_TESTING is a standard CMake variable, but we declare it here to make it -# prominent in the GUI. -option(BUILD_TESTING "Enable test (depends on googletest)." OFF) # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make # it prominent in the GUI. # cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field). @@ -61,7 +58,7 @@ set(PROCESSOR_IS_POWER FALSE) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") set(PROCESSOR_IS_MIPS TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") set(PROCESSOR_IS_AARCH64 TRUE) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") set(PROCESSOR_IS_ARM TRUE) @@ -74,22 +71,19 @@ endif() macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_macros.h) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpu_features_cache_info.h) + file(GLOB IMPL_SOURCES CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/src/impl_*.c") + list(APPEND ${SRCS_LIST_NAME} ${IMPL_SOURCES}) if(PROCESSOR_IS_MIPS) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_mips.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_mips.c) elseif(PROCESSOR_IS_ARM) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_arm.c) elseif(PROCESSOR_IS_AARCH64) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_aarch64.c) elseif(PROCESSOR_IS_X86) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_x86.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_x86.c) elseif(PROCESSOR_IS_POWER) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_ppc.h) - list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/src/cpuinfo_ppc.c) else() message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") endif() @@ -147,8 +141,10 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS}) target_include_directories(cpu_features PUBLIC $ ) -if(APPLE AND (PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64)) - target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) +if(PROCESSOR_IS_X86) + if(APPLE) + target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) + endif() endif() add_library(CpuFeature::cpu_features ALIAS cpu_features) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md index 51efb42b7..9a71c5841 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/README.md @@ -1,4 +1,4 @@ -# CMake build instructions +#CMake build instructions [comment]: # ( @@ -29,11 +29,11 @@ cpu_features directly and use the `cpu_features` target in your project. 3- Add the `cpu_features` target to the `target_link_libraries()` section of your executable or of your library. -## Enabling tests +## Disabling tests -CMake default options for cpu_features is Release built type with tests -disabled. To enable testing set cmake `BUILD_TESTING` variable to `ON`, -[.travis.yml](https://github.com/google/cpu_features/blob/master/.travis.yml) -and -[appveyor.yml](https://github.com/google/cpu_features/blob/master/appveyor.yml) -have up to date examples. +CMake default options for cpu_features is `Release` built type with tests +enabled. To disable testing set cmake `BUILD_TESTING` variable to `OFF`. e.g. + +```sh +cmake -S. -Bbuild -DBUILD_TESTING=OFF +``` diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in index 66b17383e..0a0a6d2ad 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/cmake/googletest.CMakeLists.txt.in @@ -8,7 +8,7 @@ project(googletest-download NONE) include(ExternalProject) ExternalProject_Add(googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG master + GIT_TAG main SOURCE_DIR "${CMAKE_BINARY_DIR}/googletest-src" BINARY_DIR "${CMAKE_BINARY_DIR}/googletest-build" CONFIGURE_COMMAND "" 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 78ecbdad1..97c37e658 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 @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ @@ -29,7 +28,7 @@ #define CPU_FEATURES_ARCH_ARM #endif -#if (defined(__aarch64__) || (defined(__APPLE__) && defined(__arm64__))) +#if defined(__aarch64__) #define CPU_FEATURES_ARCH_AARCH64 #endif @@ -57,24 +56,33 @@ // Os //////////////////////////////////////////////////////////////////////////////// -#if defined(__linux__) -#define CPU_FEATURES_OS_LINUX_OR_ANDROID +#if (defined(__freebsd__) || defined(__FreeBSD__)) +#define CPU_FEATURES_OS_FREEBSD #endif #if defined(__ANDROID__) #define CPU_FEATURES_OS_ANDROID #endif +#if defined(__linux__) && !defined(CPU_FEATURES_OS_FREEBSD) && \ + !defined(CPU_FEATURES_OS_ANDROID) +#define CPU_FEATURES_OS_LINUX +#endif + #if (defined(_WIN64) || defined(_WIN32)) #define CPU_FEATURES_OS_WINDOWS #endif #if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__)) -#define CPU_FEATURES_OS_DARWIN +// From https://stackoverflow.com/a/49560690 +#include "TargetConditionals.h" +#if defined(TARGET_OS_OSX) +#define CPU_FEATURES_OS_MACOS +#endif +#if defined(TARGET_OS_IPHONE) +// This is set for any non-Mac Apple products (IOS, TV, WATCH) +#define CPU_FEATURES_OS_IPHONE #endif - -#if (defined(__freebsd__) || defined(__FreeBSD__)) -#define CPU_FEATURES_OS_FREEBSD #endif //////////////////////////////////////////////////////////////////////////////// diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h index 34d258873..a18209f3a 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_aarch64.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h index 0571fe7ee..4b73c572e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_arm.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_ARM_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h index c935e5a91..61e0299de 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_mips.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h index f626eae53..455192aa8 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpuinfo_ppc.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_PPC_H_ @@ -62,7 +61,6 @@ typedef struct PPCFeatures features; } PPCInfo; -// This function is guaranteed to be malloc, memset and memcpy free. PPCInfo GetPPCInfo(void); typedef struct @@ -113,7 +111,7 @@ typedef enum PPC_ARCH_2_06, /* ISA 2.06 - POWER7 */ PPC_HAS_VSX, /* Vector-scalar extension */ PPC_PSERIES_PERFMON_COMPAT, /* Set of backwards compatibile performance - monitoring events */ + monitoring events */ PPC_TRUE_LE, PPC_PPC_LE, PPC_ARCH_2_07, /* ISA 2.07 - POWER8 */ 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 9abde468c..7f23efdb0 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 @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ #define CPU_FEATURES_INCLUDE_CPUINFO_X86_H_ @@ -98,18 +97,19 @@ typedef struct } X86Info; // Calls cpuid and returns an initialized X86info. -// This function is guaranteed to be malloc, memset and memcpy free. X86Info GetX86Info(void); // Returns cache hierarchy informations. // Can call cpuid multiple times. // Only works on Intel CPU at the moment. -// This function is guaranteed to be malloc, memset and memcpy free. CacheInfo GetX86CacheInfo(void); typedef enum { X86_UNKNOWN, + INTEL_80486, // 80486 + INTEL_P5, // P5 + INTEL_LAKEMONT, // LAKEMONT INTEL_CORE, // CORE INTEL_PNR, // PENRYN INTEL_NHM, // NEHALEM @@ -129,6 +129,13 @@ typedef enum 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 @@ -144,6 +151,7 @@ typedef enum AMD_ZEN_PLUS, // K17 ZEN+ AMD_ZEN2, // K17 ZEN 2 AMD_ZEN3, // K19 ZEN 3 + X86_MICROARCHITECTURE_LAST_, } X86Microarchitecture; // Returns the underlying microarchitecture by looking at X86Info's vendor, @@ -153,7 +161,6 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info); // Calls cpuid and fills the brand_string. // - brand_string *must* be of size 49 (beware of array decaying). // - brand_string will be zero terminated. -// - This function calls memcpy. void FillX86BrandString(char brand_string[49]); //////////////////////////////////////////////////////////////////////////////// @@ -237,4 +244,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_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h index 5957dd117..13f9334f5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/bit_utils.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_BIT_UTILS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h index c675a9468..4f743147c 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/cpuid_x86.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - #ifndef CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h index f8593fd66..fb3f9a506 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/filesystem.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // An interface for the filesystem that allows mocking the filesystem in // unittests. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_FILESYSTEM_H_ 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 8651b08a6..bb18a9a9e 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 @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // Interface to retrieve hardware capabilities. It relies on Linux's getauxval // or `/proc/self/auxval` under the hood. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h index d2099066e..6fb3016d5 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/stack_line_reader.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // Reads a file line by line and stores the data on the stack. This allows // parsing files in one go without allocating. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_STACK_LINE_READER_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h index b687da035..5100c789e 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/internal/string_view.h @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 - // A view over a piece of string. The view is not 0 terminated. #ifndef CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ #define CPU_FEATURES_INCLUDE_INTERNAL_STRING_VIEW_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh index 5ea6d9888..967b7d734 100755 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/run_integration.sh @@ -3,210 +3,365 @@ # SPDX-FileCopyrightText: 2017 Google LLC # SPDX-License-Identifier: Apache-2.0 -readonly SCRIPT_FOLDER=$(cd -P -- "$(dirname -- "$0")" && pwd -P) -readonly PROJECT_FOLDER="${SCRIPT_FOLDER}/.." -readonly ARCHIVE_FOLDER=~/cpu_features_archives -readonly QEMU_INSTALL=${ARCHIVE_FOLDER}/qemu -readonly DEFAULT_CMAKE_ARGS=" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON" +set -eo pipefail function extract() { + echo "Extracting ${1}..." case $1 in *.tar.bz2) tar xjf "$1" ;; *.tar.xz) tar xJf "$1" ;; *.tar.gz) tar xzf "$1" ;; *) - echo "don't know how to extract '$1'..." + >&2 echo "don't know how to extract '$1'..." exit 1 esac } -function unpackifnotexists() { - mkdir -p "${ARCHIVE_FOLDER}" - cd "${ARCHIVE_FOLDER}" || exit - local URL=$1 - local RELATIVE_FOLDER=$2 - local DESTINATION="${ARCHIVE_FOLDER}/${RELATIVE_FOLDER}" +function unpack() { + mkdir -p "${ARCHIVE_DIR}" + cd "${ARCHIVE_DIR}" || exit 2 + local -r URL=$1 + local -r RELATIVE_DIR=$2 + local -r DESTINATION="${ARCHIVE_DIR}/${RELATIVE_DIR}" if [[ ! -d "${DESTINATION}" ]] ; then - local ARCHIVE_NAME=$(echo ${URL} | sed 's/.*\///') - test -f "${ARCHIVE_NAME}" || wget -q "${URL}" + echo "Downloading ${URL}..." + local -r ARCHIVE_NAME=$(basename "${URL}") + test -f "${ARCHIVE_NAME}" || wget --no-verbose "${URL}" extract "${ARCHIVE_NAME}" rm -f "${ARCHIVE_NAME}" fi } -function installqemuifneeded() { - local VERSION=${QEMU_VERSION:=2.11.1} - local ARCHES=${QEMU_ARCHES:=arm aarch64 i386 x86_64 mips mipsel mips64 mips64el} - local TARGETS=${QEMU_TARGETS:=$(echo "$ARCHES" | sed 's#$# #;s#\([^ ]*\) #\1-linux-user #g')} +function install_qemu() { + if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then + >&2 echo 'QEMU is disabled !' + return 0 + fi + local -r QEMU_VERSION=${QEMU_VERSION:=5.2.0} + local -r QEMU_TARGET=${QEMU_ARCH}-linux-user - if echo "${VERSION} ${TARGETS}" | cmp --silent ${QEMU_INSTALL}/.build -; then - echo "qemu ${VERSION} up to date!" + if echo "${QEMU_VERSION} ${QEMU_TARGET}" | cmp --silent "${QEMU_INSTALL}/.build" -; then + echo "qemu ${QEMU_VERSION} up to date!" return 0 fi - echo "VERSION: ${VERSION}" - echo "TARGETS: ${TARGETS}" + echo "QEMU_VERSION: ${QEMU_VERSION}" + echo "QEMU_TARGET: ${QEMU_TARGET}" - rm -rf ${QEMU_INSTALL} + rm -rf "${QEMU_INSTALL}" # Checking for a tarball before downloading makes testing easier :-) - local QEMU_URL="http://wiki.qemu-project.org/download/qemu-${VERSION}.tar.xz" - local QEMU_FOLDER="qemu-${VERSION}" - unpackifnotexists ${QEMU_URL} ${QEMU_FOLDER} - cd ${QEMU_FOLDER} || exit + local -r QEMU_URL="http://wiki.qemu-project.org/download/qemu-${QEMU_VERSION}.tar.xz" + local -r QEMU_DIR="qemu-${QEMU_VERSION}" + unpack ${QEMU_URL} ${QEMU_DIR} + cd ${QEMU_DIR} || exit 2 + # Qemu (meson based build) depends on: pkgconf, libglib2.0, python3, ninja ./configure \ --prefix="${QEMU_INSTALL}" \ - --target-list="${TARGETS}" \ - --disable-docs \ - --disable-sdl \ - --disable-gtk \ - --disable-gnutls \ - --disable-gcrypt \ - --disable-nettle \ + --target-list="${QEMU_TARGET}" \ + --audio-drv-list= \ + --disable-brlapi \ + --disable-curl \ --disable-curses \ - --static + --disable-docs \ + --disable-gcrypt \ + --disable-gnutls \ + --disable-gtk \ + --disable-libnfs \ + --disable-libssh \ + --disable-nettle \ + --disable-opengl \ + --disable-sdl \ + --disable-virglrenderer \ + --disable-vte \ + --enable-modules - make -j4 + # --static Not supported on Archlinux + # so we use --enable-modules + + # wrapper on ninja + make -j8 make install - echo "$VERSION $TARGETS" > ${QEMU_INSTALL}/.build + echo "$QEMU_VERSION $QEMU_TARGET" > "${QEMU_INSTALL}/.build" } function assert_defined(){ - local VALUE=${1} - : "${VALUE?"${1} needs to be defined"}" + if [[ -z "${!1}" ]]; then + >&2 echo "Variable '${1}' must be defined" + exit 1 + fi } -function integrate() { - cd "${PROJECT_FOLDER}" - case "${OS}" in - "Windows_NT") CMAKE_BUILD_ARGS="--config Debug --target ALL_BUILD" - CMAKE_TEST_FILES="${BUILD_DIR}/test/Debug/*_test.exe" - DEMO=${BUILD_DIR}/Debug/list_cpu_features.exe - ;; - *) CMAKE_BUILD_ARGS="--target all" - CMAKE_TEST_FILES="${BUILD_DIR}/test/*_test" - DEMO=${BUILD_DIR}/list_cpu_features - ;; - esac - - # Generating CMake configuration - cmake -H. -B"${BUILD_DIR}" ${DEFAULT_CMAKE_ARGS} "${CMAKE_ADDITIONAL_ARGS[@]}" -G"${CMAKE_GENERATOR:-Unix Makefiles}" - - # Building - cmake --build "${BUILD_DIR}" ${CMAKE_BUILD_ARGS} - - # Running tests if needed - if [[ "${QEMU_ARCH}" == "DISABLED" ]]; then - return - fi - RUN_CMD="" - if [[ -n "${QEMU_ARCH}" ]]; then - installqemuifneeded - RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[@]}" - fi - for test_binary in ${CMAKE_TEST_FILES}; do - ${RUN_CMD} ${test_binary} - done - ${RUN_CMD} ${DEMO} +function clean_build() { + # Cleanup previous build + rm -rf "${BUILD_DIR}" + mkdir -p "${BUILD_DIR}" } function expand_linaro_config() { - assert_defined TARGET - local LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/7.2-2017.11 + #ref: https://releases.linaro.org/components/toolchain/binaries/ + local -r LINARO_VERSION=7.5-2019.12 + local -r LINARO_ROOT_URL=https://releases.linaro.org/components/toolchain/binaries/${LINARO_VERSION} - local GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}.tar.xz - local GCC_RELATIVE_FOLDER="gcc-linaro-7.2.1-2017.11-x86_64_${TARGET}" - unpackifnotexists "${GCC_URL}" "${GCC_RELATIVE_FOLDER}" + local -r GCC_VERSION=7.5.0-2019.12 + local -r GCC_URL=${LINARO_ROOT_URL}/${TARGET}/gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}.tar.xz + local -r GCC_RELATIVE_DIR="gcc-linaro-${GCC_VERSION}-x86_64_${TARGET}" + unpack "${GCC_URL}" "${GCC_RELATIVE_DIR}" - local SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-2.25-2017.11-${TARGET}.tar.xz - local SYSROOT_RELATIVE_FOLDER=sysroot-glibc-linaro-2.25-2017.11-${TARGET} - unpackifnotexists "${SYSROOT_URL}" "${SYSROOT_RELATIVE_FOLDER}" + local -r SYSROOT_VERSION=2.25-2019.12 + local -r SYSROOT_URL=${LINARO_ROOT_URL}/${TARGET}/sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET}.tar.xz + local -r SYSROOT_RELATIVE_DIR=sysroot-glibc-linaro-${SYSROOT_VERSION}-${TARGET} + unpack "${SYSROOT_URL}" "${SYSROOT_RELATIVE_DIR}" - local SYSROOT_FOLDER=${ARCHIVE_FOLDER}/${SYSROOT_RELATIVE_FOLDER} - local GCC_FOLDER=${ARCHIVE_FOLDER}/${GCC_RELATIVE_FOLDER} + local -r SYSROOT_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR} + local -r STAGING_DIR=${ARCHIVE_DIR}/${SYSROOT_RELATIVE_DIR}-stage + local -r GCC_DIR=${ARCHIVE_DIR}/${GCC_RELATIVE_DIR} - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) + # Write a Toolchain file + # note: This is manadatory to use a file in order to have the CMake variable + # 'CMAKE_CROSSCOMPILING' set to TRUE. + # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux + cat >"$TOOLCHAIN_FILE" <&2 echo 'unknown mips platform' + exit 1 ;; esac + local -r SYSROOT_DIR=${GCC_DIR}/sysroot + local -r STAGING_DIR=${SYSROOT_DIR}-stage - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_FIND_ROOT_PATH=${GCC_FOLDER}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_NAME=Linux) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_SYSTEM_PROCESSOR=${TARGET}) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER=mips-mti-linux-gnu-gcc) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER=mips-mti-linux-gnu-g++) - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_C_COMPILER_ARG1="${MIPS_FLAGS}") - CMAKE_ADDITIONAL_ARGS+=(-DCMAKE_CXX_COMPILER_ARG1="${MIPS_FLAGS}") + # Write a Toolchain file + # note: This is manadatory to use a file in order to have the CMake variable + # 'CMAKE_CROSSCOMPILING' set to TRUE. + # ref: https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html#cross-compiling-for-linux + cat >"${TOOLCHAIN_FILE}" <&2 echo "QEMU is disabled for ${TARGET}" + return + fi + install_qemu + RUN_CMD="${QEMU_INSTALL}/bin/qemu-${QEMU_ARCH} ${QEMU_ARGS[*]}" + + cd "${BUILD_DIR}" || exit 2 + set -x + for test_binary in "${BUILD_DIR}"/list_cpu_feature* ; do + ${RUN_CMD} "${test_binary}" + done + set +x +} + +function usage() { + local -r NAME=$(basename "$0") + echo -e "$NAME - Build using a cross toolchain. + +SYNOPSIS +\t$NAME [-h|--help] [toolchain|build|qemu|test|all] + +DESCRIPTION +\tCross compile using a cross toolchain. + +\tYou MUST define the following variables before running this script: +\t* TARGET: +\t\tx86_64 +\t\taarch64-linux-gnu aarch64_be-linux-gnu +\t\tarm-linux-gnueabihf armv8l-linux-gnueabihf arm-linux-gnueabi +\t\tarmeb-linux-gnueabihf armeb-linux-gnueabi +\t\tmips32 mips32el +\t\tmips64 mips64el + +OPTIONS +\t-h --help: show this help text +\ttoolchain: download, unpack toolchain and generate CMake toolchain file +\tbuild: toolchain + build the project using the toolchain file (note: remove previous build dir) +\tqemu: download, unpack and build qemu +\ttest: qemu + run all executable using qemu (note: don't build !) +\tall: build + test (default) + +EXAMPLES +* Using export: +export TARGET=aarch64-linux-gnu +$0 + +* One-liner: +TARGET=aarch64-linux-gnu $0" +} + +# Main +function main() { + case ${1} in + -h | --help) + usage; exit ;; + esac + assert_defined TARGET - BUILD_DIR="${PROJECT_FOLDER}/cmake_build/${TARGET}" - mkdir -p "${BUILD_DIR}" + declare -r PROJECT_DIR="$(cd -P -- "$(dirname -- "$0")/.." && pwd -P)" + declare -r ARCHIVE_DIR="${PROJECT_DIR}/build_cross/archives" + declare -r BUILD_DIR="${PROJECT_DIR}/build_cross/${TARGET}" + declare -r TOOLCHAIN_FILE=${ARCHIVE_DIR}/toolchain_${TARGET}.cmake - declare -a CONFIG_NAMES=() - declare -a QEMU_ARGS=() + echo "Target: '${TARGET}'" + + echo "Project dir: '${PROJECT_DIR}'" + echo "Archive dir: '${ARCHIVE_DIR}'" + echo "Build dir: '${BUILD_DIR}'" + echo "toolchain file: '${TOOLCHAIN_FILE}'" + + declare -a CMAKE_DEFAULT_ARGS=( -G ${CMAKE_GENERATOR:-"Ninja"} ) declare -a CMAKE_ADDITIONAL_ARGS=() - case ${TOOLCHAIN} in - LINARO) expand_linaro_config ;; - CODESCAPE) expand_codescape_config ;; - NATIVE) QEMU_ARCH="" ;; - *) echo "Unknown toolchain '${TOOLCHAIN}'..."; exit 1;; + declare -a QEMU_ARGS=() + case ${TARGET} in + x86_64) + declare -r QEMU_ARCH=x86_64 ;; + arm-linux-gnueabihf | armv8l-linux-gnueabihf | arm-linux-gnueabi) + expand_linaro_config + declare -r QEMU_ARCH=arm ;; + armeb-linux-gnueabihf | armeb-linux-gnueabi) + expand_linaro_config + declare -r QEMU_ARCH=DISABLED ;; + aarch64-linux-gnu) + expand_linaro_config + declare -r QEMU_ARCH=aarch64 ;; + aarch64_be-linux-gnu) + expand_linaro_config + declare -r QEMU_ARCH=DISABLED ;; + mips32) + expand_codescape_config + declare -r QEMU_ARCH=mips ;; + mips32el) + expand_codescape_config + declare -r QEMU_ARCH=mipsel ;; + mips64) + expand_codescape_config + declare -r QEMU_ARCH=mips64 ;; + mips64el) + expand_codescape_config + declare -r QEMU_ARCH=mips64el ;; + *) + >&2 echo "Unknown TARGET '${TARGET}'..." + exit 1 ;; + esac + declare -r QEMU_INSTALL=${ARCHIVE_DIR}/qemu-${QEMU_ARCH} + + case ${1} in + toolchain) + exit ;; + build) + build ;; + qemu) + install_qemu ;; + test) + run_test ;; + *) + build + run_test ;; esac - integrate } -if [ "${CONTINUOUS_INTEGRATION}" = "true" ]; then - QEMU_ARCHES=${QEMU_ARCH} - expand_environment_and_integrate -fi +main "${1:-all}" diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh index 2256de59e..b58537d00 100755 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/scripts/test_integration.sh @@ -3,85 +3,59 @@ # SPDX-FileCopyrightText: 2017 Google LLC # SPDX-License-Identifier: Apache-2.0 -source "$(dirname -- "$0")"/run_integration.sh - # Toolchains for little-endian, 64-bit ARMv8 for GNU/Linux systems function set_aarch64-linux-gnu() { - TOOLCHAIN=LINARO - TARGET=aarch64-linux-gnu - QEMU_ARCH=aarch64 + export TARGET=aarch64-linux-gnu } # Toolchains for little-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_arm-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabihf - QEMU_ARCH=arm + export TARGET=arm-linux-gnueabihf } # Toolchains for little-endian, 32-bit ARMv8 for GNU/Linux systems function set_armv8l-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=armv8l-linux-gnueabihf - QEMU_ARCH=arm + export TARGET=armv8l-linux-gnueabihf } # Toolchains for little-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_arm-linux-gnueabi() { - TOOLCHAIN=LINARO - TARGET=arm-linux-gnueabi - QEMU_ARCH=arm + export TARGET=arm-linux-gnueabi } # Toolchains for big-endian, 64-bit ARMv8 for GNU/Linux systems function set_aarch64_be-linux-gnu() { - TOOLCHAIN=LINARO - TARGET=aarch64_be-linux-gnu - QEMU_ARCH=DISABLED + export TARGET=aarch64_be-linux-gnu } # Toolchains for big-endian, hard-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_armeb-linux-gnueabihf() { - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabihf - QEMU_ARCH=DISABLED + export TARGET=armeb-linux-gnueabihf } # Toolchains for big-endian, soft-float, 32-bit ARMv7 (and earlier) for GNU/Linux systems function set_armeb-linux-gnueabi() { - TOOLCHAIN=LINARO - TARGET=armeb-linux-gnueabi - QEMU_ARCH=DISABLED + export TARGET=armeb-linux-gnueabi } function set_mips32() { - TOOLCHAIN=CODESCAPE - TARGET=mips32 - QEMU_ARCH=mips + export TARGET=mips32 } function set_mips32el() { - TOOLCHAIN=CODESCAPE - TARGET=mips32el - QEMU_ARCH=mipsel + export TARGET=mips32el } function set_mips64() { - TOOLCHAIN=CODESCAPE - TARGET=mips64 - QEMU_ARCH=mips64 + export TARGET=mips64 } function set_mips64el() { - TOOLCHAIN=CODESCAPE - TARGET=mips64el - QEMU_ARCH=mips64el + export TARGET=mips64el } -function set_native() { - TOOLCHAIN=NATIVE - TARGET=native - QEMU_ARCH="" +function set_x86_64() { + export TARGET=x86_64 } ENVIRONMENTS=" @@ -96,14 +70,13 @@ ENVIRONMENTS=" set_mips32el set_mips64 set_mips64el - set_native + set_x86_64 " set -e -CMAKE_GENERATOR="Ninja" - for SET_ENVIRONMENT in ${ENVIRONMENTS}; do + echo "testing ${SET_ENVIRONMENT}" ${SET_ENVIRONMENT} - expand_environment_and_integrate + ./"$(dirname -- "$0")"/run_integration.sh done diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl new file mode 100644 index 000000000..e657e8ac6 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/copy.inl @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: 2021 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include + +static void copy(char *__restrict dst, const char *src, size_t count) +{ + for (size_t i = 0; i < count; ++i) dst[i] = src[i]; +} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c deleted file mode 100644 index da7972763..000000000 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c +++ /dev/null @@ -1,210 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Google LLC -// SPDX-License-Identifier: Apache-2.0 - -#include "cpuinfo_aarch64.h" -#include "internal/filesystem.h" -#include "internal/hwcaps.h" -#include "internal/stack_line_reader.h" -#include "internal/string_view.h" -#include -#include - -#if defined(CPU_FEATURES_OS_DARWIN) -#if !defined(HAVE_SYSCTLBYNAME) -#error "Darwin needs support for sysctlbyname" -#endif -#include - -#if defined(CPU_FEATURES_MOCK_CPUID_ARM64) -extern bool GetDarwinSysCtlByName(const char*); -extern int GetDarwinSysCtlByNameValue(const char*); -#else // CPU_FEATURES_MOCK_CPUID_ARM64 -static bool GetDarwinSysCtlByName(const char* name) -{ - int enabled; - size_t enabled_len = sizeof(enabled); - const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); - return failure ? false : enabled; -} -static int GetDarwinSysCtlByNameValue(const char* name) -{ - int enabled; - size_t enabled_len = sizeof(enabled); - const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); - return failure ? 0 : enabled; -} -#endif -#endif // CPU_FEATURES_OS_DARWIN - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0) \ - FEATURE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0) \ - FEATURE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0) \ - FEATURE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0) \ - FEATURE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0) \ - FEATURE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0) \ - FEATURE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0) \ - FEATURE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0) \ - FEATURE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0) \ - FEATURE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0) \ - FEATURE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0) \ - FEATURE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0) \ - FEATURE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0) \ - FEATURE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0) \ - FEATURE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0) \ - FEATURE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0) \ - FEATURE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0) \ - FEATURE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0) \ - FEATURE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0) \ - FEATURE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0) \ - FEATURE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0) \ - FEATURE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0) \ - FEATURE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0) \ - FEATURE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0) \ - FEATURE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0) \ - FEATURE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0) \ - FEATURE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0) \ - FEATURE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0) \ - FEATURE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0) \ - FEATURE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0) \ - FEATURE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0) \ - FEATURE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0) \ - FEATURE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP) \ - FEATURE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2) \ - FEATURE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES) \ - FEATURE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \ - FEATURE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0, \ - AARCH64_HWCAP2_SVEBITPERM) \ - FEATURE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3) \ - FEATURE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4) \ - FEATURE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2) \ - FEATURE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT) \ - FEATURE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM) \ - FEATURE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \ - FEATURE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \ - FEATURE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16) \ - FEATURE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM) \ - FEATURE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16) \ - FEATURE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH) \ - FEATURE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG) \ - FEATURE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI) \ - FEATURE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE) -#define DEFINE_TABLE_FEATURE_TYPE Aarch64Features -#include "define_tables.h" - -#if !defined(CPU_FEATURES_OS_DARWIN) - -static bool HandleAarch64Line(const LineResult result, - Aarch64Info* const info) -{ - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) - { - if (CpuFeatures_StringView_IsEquals(key, str("Features"))) - { - for (size_t i = 0; i < AARCH64_LAST_; ++i) - { - kSetters[i](&info->features, CpuFeatures_StringView_HasWord( - value, kCpuInfoFlags[i], ' ')); - } - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) - { - info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) - { - info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) - { - info->part = CpuFeatures_StringView_ParsePositiveNumber(value); - } - else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) - { - info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(Aarch64Info* const info) -{ - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) - { - if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) - { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -#endif /* !CPU_FEATURES_OS_DARWIN */ - -static const Aarch64Info kEmptyAarch64Info; - -Aarch64Info GetAarch64Info(void) -{ - // capabilities are fetched from both getauxval and /proc/cpuinfo so we can - // have some information if the executable is sandboxed (aka no access to - // /proc/cpuinfo). - Aarch64Info info = kEmptyAarch64Info; - -#if defined(CPU_FEATURES_OS_DARWIN) - - // Handling Darwin platform through sysctlbyname - info.implementer = GetDarwinSysCtlByNameValue("hw.cputype"); - info.variant = GetDarwinSysCtlByNameValue("hw.cpusubtype"); - info.part = GetDarwinSysCtlByNameValue("hw.cpufamily"); - info.revision = GetDarwinSysCtlByNameValue("hw.cpusubfamily"); - - info.features.fp = GetDarwinSysCtlByName("hw.optional.floatingpoint"); - info.features.fphp = GetDarwinSysCtlByName("hw.optional.neon_hpfp"); - info.features.sha512 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha512"); - info.features.atomics = GetDarwinSysCtlByName("hw.optional.armv8_1_atomics"); - info.features.asimdfhm = GetDarwinSysCtlByName("hw.optional.armv8_2_fhm"); - info.features.sha3 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha3"); - info.features.crc32 = GetDarwinSysCtlByName("hw.optional.armv8_crc32"); - -#else - - FillProcCpuInfoData(&info); - const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); - for (size_t i = 0; i < AARCH64_LAST_; ++i) - { - if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) - { - kSetters[i](&info.features, true); - } - } - -#endif - - return info; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetAarch64FeaturesEnumValue(const Aarch64Features* features, - Aarch64FeaturesEnum value) -{ - if (value >= AARCH64_LAST_) return false; - return kGetters[value](features); -} - -const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum value) -{ - if (value >= AARCH64_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c deleted file mode 100644 index d2d68a437..000000000 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_ppc.c +++ /dev/null @@ -1,175 +0,0 @@ -// SPDX-FileCopyrightText: 2018 IBM. -// SPDX-License-Identifier: Apache-2.0 - -#include "cpuinfo_ppc.h" -#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 -#include -#include - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0) \ - FEATURE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0) \ - FEATURE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0) \ - FEATURE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0) \ - FEATURE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0) \ - FEATURE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0) \ - FEATURE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0) \ - FEATURE(PPC_UNIFIED_CACHE, unifiedcache, "ucache", \ - PPC_FEATURE_UNIFIED_CACHE, 0) \ - FEATURE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0) \ - FEATURE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle", \ - PPC_FEATURE_HAS_EFP_SINGLE, 0) \ - FEATURE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble", \ - PPC_FEATURE_HAS_EFP_DOUBLE, 0) \ - FEATURE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0) \ - FEATURE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0) \ - FEATURE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0) \ - FEATURE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0) \ - FEATURE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0) \ - FEATURE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0) \ - FEATURE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0) \ - FEATURE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, \ - 0) \ - FEATURE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0) \ - FEATURE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0) \ - FEATURE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0) \ - FEATURE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0) \ - FEATURE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0) \ - FEATURE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0) \ - FEATURE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu", \ - PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0) \ - FEATURE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0) \ - FEATURE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0) \ - FEATURE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07) \ - FEATURE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM) \ - FEATURE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR) \ - FEATURE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB) \ - FEATURE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL) \ - FEATURE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR) \ - FEATURE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO) \ - FEATURE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC) \ - FEATURE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00) \ - FEATURE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128) \ - FEATURE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN) \ - FEATURE(PPC_SCV, scv, "scv", 0, PPC_FEATURE2_SCV) \ - FEATURE(PPC_HTM_NO_SUSPEND, htm_no_suspend, "htm-no-suspend", 0, \ - PPC_FEATURE2_HTM_NO_SUSPEND) -#define DEFINE_TABLE_FEATURE_TYPE PPCFeatures -#include "define_tables.h" - -static bool HandlePPCLine(const LineResult result, - PPCPlatformStrings* const strings) -{ - StringView line = result.line; - StringView key, value; - if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) - { - if (CpuFeatures_StringView_HasWord(key, "platform", ' ')) - { - CpuFeatures_StringView_CopyString(value, strings->platform, - sizeof(strings->platform)); - } - else if (CpuFeatures_StringView_IsEquals(key, str("model"))) - { - CpuFeatures_StringView_CopyString(value, strings->model, - sizeof(strings->platform)); - } - else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) - { - CpuFeatures_StringView_CopyString(value, strings->machine, - sizeof(strings->platform)); - } - else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) - { - CpuFeatures_StringView_CopyString(value, strings->cpu, - sizeof(strings->platform)); - } - } - return !result.eof; -} - -static void FillProcCpuInfoData(PPCPlatformStrings* const strings) -{ - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (;;) - { - if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) - { - break; - } - } - CpuFeatures_CloseFile(fd); - } -} - -static const PPCInfo kEmptyPPCInfo; - -PPCInfo GetPPCInfo(void) -{ - /* - * On Power feature flags aren't currently in cpuinfo so we only look at - * the auxilary vector. - */ - PPCInfo info = kEmptyPPCInfo; - const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); - for (size_t i = 0; i < PPC_LAST_; ++i) - { - if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) - { - kSetters[i](&info.features, true); - } - } - return info; -} - -static const PPCPlatformStrings kEmptyPPCPlatformStrings; - -PPCPlatformStrings GetPPCPlatformStrings(void) -{ - PPCPlatformStrings strings = kEmptyPPCPlatformStrings; - const char* platform = CpuFeatures_GetPlatformPointer(); - const char* base_platform = CpuFeatures_GetBasePlatformPointer(); - - FillProcCpuInfoData(&strings); - - if (platform != NULL) - { - CpuFeatures_StringView_CopyString(str(platform), strings.type.platform, - sizeof(strings.type.platform)); - } - if (base_platform != NULL) - { - CpuFeatures_StringView_CopyString(str(base_platform), - strings.type.base_platform, - sizeof(strings.type.base_platform)); - } - - return strings; -} - -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetPPCFeaturesEnumValue(const PPCFeatures* features, - PPCFeaturesEnum value) -{ - if (value >= PPC_LAST_) return false; - return kGetters[value](features); -} - -const char* GetPPCFeaturesEnumName(PPCFeaturesEnum value) -{ - if (value >= PPC_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl new file mode 100644 index 000000000..62a7b096c --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection.inl @@ -0,0 +1,79 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#ifndef INTROSPECTION_PREFIX +#error "missing INTROSPECTION_PREFIX" +#endif +#ifndef INTROSPECTION_ENUM_PREFIX +#error "missing INTROSPECTION_ENUM_PREFIX" +#endif +#ifndef INTROSPECTION_TABLE +#error "missing INTROSPECTION_TABLE" +#endif + +#include + +#define STRINGIZE_(s) #s +#define STRINGIZE(s) STRINGIZE_(s) + +#define FEAT_TYPE_NAME__(X) X##Features +#define FEAT_TYPE_NAME_(X) FEAT_TYPE_NAME__(X) +#define FEAT_TYPE_NAME FEAT_TYPE_NAME_(INTROSPECTION_PREFIX) + +#define FEAT_ENUM_NAME__(X) X##FeaturesEnum +#define FEAT_ENUM_NAME_(X) FEAT_ENUM_NAME__(X) +#define FEAT_ENUM_NAME FEAT_ENUM_NAME_(INTROSPECTION_PREFIX) + +#define GET_FEAT_ENUM_VALUE__(X) Get##X##FeaturesEnumValue +#define GET_FEAT_ENUM_VALUE_(X) GET_FEAT_ENUM_VALUE__(X) +#define GET_FEAT_ENUM_VALUE GET_FEAT_ENUM_VALUE_(INTROSPECTION_PREFIX) + +#define GET_FEAT_ENUM_NAME__(X) Get##X##FeaturesEnumName +#define GET_FEAT_ENUM_NAME_(X) GET_FEAT_ENUM_NAME__(X) +#define GET_FEAT_ENUM_NAME GET_FEAT_ENUM_NAME_(INTROSPECTION_PREFIX) + +#define FEAT_ENUM_LAST__(X) X##_LAST_ +#define FEAT_ENUM_LAST_(X) FEAT_ENUM_LAST__(X) +#define FEAT_ENUM_LAST FEAT_ENUM_LAST_(INTROSPECTION_ENUM_PREFIX) + +// Generate individual getters and setters. +#define LINE(ENUM, NAME, A, B, C) \ + static void set_##ENUM(FEAT_TYPE_NAME* features, bool value) \ + { \ + features->NAME = value; \ + } \ + static int get_##ENUM(const FEAT_TYPE_NAME* features) \ + { \ + return features->NAME; \ + } +INTROSPECTION_TABLE +#undef LINE + +// Generate getters table +#define LINE(ENUM, NAME, A, B, C) [ENUM] = get_##ENUM, +static int (*const kGetters[])(const FEAT_TYPE_NAME*) = {INTROSPECTION_TABLE}; +#undef LINE + +// Generate setters table +#define LINE(ENUM, NAME, A, B, C) [ENUM] = set_##ENUM, +static void (*const kSetters[])(FEAT_TYPE_NAME*, bool) = {INTROSPECTION_TABLE}; +#undef LINE + +// Implements the `GetXXXFeaturesEnumValue` API. +int GET_FEAT_ENUM_VALUE(const FEAT_TYPE_NAME* features, FEAT_ENUM_NAME value) +{ + if (value >= FEAT_ENUM_LAST) return false; + return kGetters[value](features); +} + +// Generate feature name table. +#define LINE(ENUM, NAME, A, B, C) [ENUM] = STRINGIZE(NAME), +static const char* kFeatureNames[] = {INTROSPECTION_TABLE}; +#undef LINE + +// Implements the `GetXXXFeaturesEnumName` API. +const char* GET_FEAT_ENUM_NAME(FEAT_ENUM_NAME value) +{ + if (value >= FEAT_ENUM_LAST) return "unknown_feature"; + return kFeatureNames[value]; +} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl new file mode 100644 index 000000000..6a84c2bea --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_introspection_and_hwcaps.inl @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "internal/hwcaps.h" +#include "define_introspection.inl" + +#define LINE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \ + [ENUM] = (HardwareCapabilities){HWCAP, HWCAP2}, +static const HardwareCapabilities kHardwareCapabilities[] = { + INTROSPECTION_TABLE}; +#undef LINE + +#define LINE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = CPUINFO_FLAG, +static const char* kCpuInfoFlags[] = {INTROSPECTION_TABLE}; +#undef LINE diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h deleted file mode 100644 index b0a069d34..000000000 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/define_tables.h +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-FileCopyrightText: 2017 Google LLC -// SPDX-License-Identifier: Apache-2.0 - -// The following preprocessor constants must be defined before including this -// file: -// - DEFINE_TABLE_FEATURE_TYPE, the underlying type (e.g. X86Features) -// - DEFINE_TABLE_FEATURES, the list of FEATURE macros to be inserted. - -// This file is to be included once per `cpuinfo_XXX.c` in order to construct -// feature getters and setters functions as well as several enum indexed tables -// from the db file. -// - `kGetters` a table of getters function pointers from feature enum to -// retrieve a feature, -// - `kSetters` a table of setters function pointers from feature enum to set a -// feature, -// - `kCpuInfoFlags` a table of strings from feature enum to /proc/cpuinfo -// flags, -// - `kHardwareCapabilities` a table of HardwareCapabilities structs indexed by -// their feature enum. - -#ifndef SRC_DEFINE_TABLES_H_ -#define SRC_DEFINE_TABLES_H_ - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = CPUINFO_FLAG, -static const char* kCpuInfoFlags[] = {DEFINE_TABLE_FEATURES}; -#undef FEATURE - -#ifndef DEFINE_TABLE_DONT_GENERATE_HWCAPS -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \ - [ENUM] = (HardwareCapabilities){HWCAP, HWCAP2}, -static const HardwareCapabilities kHardwareCapabilities[] = { - DEFINE_TABLE_FEATURES}; -#undef FEATURE -#endif // DEFINE_TABLE_DONT_GENERATE_HWCAPS - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) \ - static void set_##ENUM(DEFINE_TABLE_FEATURE_TYPE* features, bool value) \ - { \ - features->NAME = value; \ - } \ - static int get_##ENUM(const DEFINE_TABLE_FEATURE_TYPE* features) \ - { \ - return features->NAME; \ - } -DEFINE_TABLE_FEATURES -#undef FEATURE - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = set_##ENUM, -static void (*const kSetters[])(DEFINE_TABLE_FEATURE_TYPE*, - bool) = {DEFINE_TABLE_FEATURES}; -#undef FEATURE - -#define FEATURE(ENUM, NAME, CPUINFO_FLAG, HWCAP, HWCAP2) [ENUM] = get_##ENUM, -static int (*const kGetters[])(const DEFINE_TABLE_FEATURE_TYPE*) = { - DEFINE_TABLE_FEATURES}; -#undef FEATURE - -#endif // SRC_DEFINE_TABLES_H_ diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl new file mode 100644 index 000000000..1936d7a71 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/equals.inl @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: 2021 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include +#include + +static bool equals(const char *lhs, const char *rhs, size_t count) +{ + for (size_t i = 0; i < count; ++i) + if (lhs[i] != rhs[i]) return false; + return true; +} diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c new file mode 100644 index 000000000..fec374025 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_aarch64_linux_or_android.c @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_AARCH64 +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + +#include "cpuinfo_aarch64.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0) \ + LINE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0) \ + LINE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0) \ + LINE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0) \ + LINE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0) \ + LINE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0) \ + LINE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0) \ + LINE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0) \ + LINE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0) \ + LINE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0) \ + LINE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0) \ + LINE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0) \ + LINE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0) \ + LINE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0) \ + LINE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0) \ + LINE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0) \ + LINE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0) \ + LINE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0) \ + LINE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0) \ + LINE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0) \ + LINE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0) \ + LINE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0) \ + LINE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0) \ + LINE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0) \ + LINE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0) \ + LINE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0) \ + LINE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0) \ + LINE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0) \ + LINE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0) \ + LINE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0) \ + LINE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0) \ + LINE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0) \ + LINE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP) \ + LINE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2) \ + LINE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES) \ + LINE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \ + LINE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0, \ + AARCH64_HWCAP2_SVEBITPERM) \ + LINE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3) \ + LINE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4) \ + LINE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2) \ + LINE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT) \ + LINE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM) \ + LINE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \ + LINE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \ + LINE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16) \ + LINE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM) \ + LINE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16) \ + LINE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH) \ + LINE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG) \ + LINE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI) \ + LINE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE) +#define INTROSPECTION_PREFIX Aarch64 +#define INTROSPECTION_ENUM_PREFIX AARCH64 +#include "define_introspection_and_hwcaps.inl" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation. +//////////////////////////////////////////////////////////////////////////////// + +#include "internal/bit_utils.h" +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +#include + +static bool HandleAarch64Line(const LineResult result, + Aarch64Info* const info) +{ + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) + { + if (CpuFeatures_StringView_IsEquals(key, str("Features"))) + { + for (size_t i = 0; i < AARCH64_LAST_; ++i) + { + kSetters[i](&info->features, CpuFeatures_StringView_HasWord( + value, kCpuInfoFlags[i], ' ')); + } + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU implementer"))) + { + info->implementer = CpuFeatures_StringView_ParsePositiveNumber(value); + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU variant"))) + { + info->variant = CpuFeatures_StringView_ParsePositiveNumber(value); + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU part"))) + { + info->part = CpuFeatures_StringView_ParsePositiveNumber(value); + } + else if (CpuFeatures_StringView_IsEquals(key, str("CPU revision"))) + { + info->revision = CpuFeatures_StringView_ParsePositiveNumber(value); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(Aarch64Info* const info) +{ + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) + { + if (!HandleAarch64Line(StackLineReader_NextLine(&reader), info)) + { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const Aarch64Info kEmptyAarch64Info; + +Aarch64Info GetAarch64Info(void) +{ + // capabilities are fetched from both getauxval and /proc/cpuinfo so we can + // have some information if the executable is sandboxed (aka no access to + // /proc/cpuinfo). + Aarch64Info info = kEmptyAarch64Info; + + FillProcCpuInfoData(&info); + const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); + for (size_t i = 0; i < AARCH64_LAST_; ++i) + { + if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) + { + kSetters[i](&info.features, true); + } + } + + return info; +} + +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_AARCH64 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_arm.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_arm_linux_or_android.c similarity index 72% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_arm.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_arm_linux_or_android.c index 69abe91f4..1a4d526ab 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_arm.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_arm_linux_or_android.c @@ -1,47 +1,58 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_ARM +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + #include "cpuinfo_arm.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(ARM_SWP, swp, "swp", ARM_HWCAP_SWP, 0) \ + LINE(ARM_HALF, half, "half", ARM_HWCAP_HALF, 0) \ + LINE(ARM_THUMB, thumb, "thumb", ARM_HWCAP_THUMB, 0) \ + LINE(ARM_26BIT, _26bit, "26bit", ARM_HWCAP_26BIT, 0) \ + LINE(ARM_FASTMULT, fastmult, "fastmult", ARM_HWCAP_FAST_MULT, 0) \ + LINE(ARM_FPA, fpa, "fpa", ARM_HWCAP_FPA, 0) \ + LINE(ARM_VFP, vfp, "vfp", ARM_HWCAP_VFP, 0) \ + LINE(ARM_EDSP, edsp, "edsp", ARM_HWCAP_EDSP, 0) \ + LINE(ARM_JAVA, java, "java", ARM_HWCAP_JAVA, 0) \ + LINE(ARM_IWMMXT, iwmmxt, "iwmmxt", ARM_HWCAP_IWMMXT, 0) \ + LINE(ARM_CRUNCH, crunch, "crunch", ARM_HWCAP_CRUNCH, 0) \ + LINE(ARM_THUMBEE, thumbee, "thumbee", ARM_HWCAP_THUMBEE, 0) \ + LINE(ARM_NEON, neon, "neon", ARM_HWCAP_NEON, 0) \ + LINE(ARM_VFPV3, vfpv3, "vfpv3", ARM_HWCAP_VFPV3, 0) \ + LINE(ARM_VFPV3D16, vfpv3d16, "vfpv3d16", ARM_HWCAP_VFPV3D16, 0) \ + LINE(ARM_TLS, tls, "tls", ARM_HWCAP_TLS, 0) \ + LINE(ARM_VFPV4, vfpv4, "vfpv4", ARM_HWCAP_VFPV4, 0) \ + LINE(ARM_IDIVA, idiva, "idiva", ARM_HWCAP_IDIVA, 0) \ + LINE(ARM_IDIVT, idivt, "idivt", ARM_HWCAP_IDIVT, 0) \ + LINE(ARM_VFPD32, vfpd32, "vfpd32", ARM_HWCAP_VFPD32, 0) \ + LINE(ARM_LPAE, lpae, "lpae", ARM_HWCAP_LPAE, 0) \ + LINE(ARM_EVTSTRM, evtstrm, "evtstrm", ARM_HWCAP_EVTSTRM, 0) \ + LINE(ARM_AES, aes, "aes", 0, ARM_HWCAP2_AES) \ + LINE(ARM_PMULL, pmull, "pmull", 0, ARM_HWCAP2_PMULL) \ + LINE(ARM_SHA1, sha1, "sha1", 0, ARM_HWCAP2_SHA1) \ + LINE(ARM_SHA2, sha2, "sha2", 0, ARM_HWCAP2_SHA2) \ + LINE(ARM_CRC32, crc32, "crc32", 0, ARM_HWCAP2_CRC32) +#define INTROSPECTION_PREFIX Arm +#define INTROSPECTION_ENUM_PREFIX ARM +#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 #include - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(ARM_SWP, swp, "swp", ARM_HWCAP_SWP, 0) \ - FEATURE(ARM_HALF, half, "half", ARM_HWCAP_HALF, 0) \ - FEATURE(ARM_THUMB, thumb, "thumb", ARM_HWCAP_THUMB, 0) \ - FEATURE(ARM_26BIT, _26bit, "26bit", ARM_HWCAP_26BIT, 0) \ - FEATURE(ARM_FASTMULT, fastmult, "fastmult", ARM_HWCAP_FAST_MULT, 0) \ - FEATURE(ARM_FPA, fpa, "fpa", ARM_HWCAP_FPA, 0) \ - FEATURE(ARM_VFP, vfp, "vfp", ARM_HWCAP_VFP, 0) \ - FEATURE(ARM_EDSP, edsp, "edsp", ARM_HWCAP_EDSP, 0) \ - FEATURE(ARM_JAVA, java, "java", ARM_HWCAP_JAVA, 0) \ - FEATURE(ARM_IWMMXT, iwmmxt, "iwmmxt", ARM_HWCAP_IWMMXT, 0) \ - FEATURE(ARM_CRUNCH, crunch, "crunch", ARM_HWCAP_CRUNCH, 0) \ - FEATURE(ARM_THUMBEE, thumbee, "thumbee", ARM_HWCAP_THUMBEE, 0) \ - FEATURE(ARM_NEON, neon, "neon", ARM_HWCAP_NEON, 0) \ - FEATURE(ARM_VFPV3, vfpv3, "vfpv3", ARM_HWCAP_VFPV3, 0) \ - FEATURE(ARM_VFPV3D16, vfpv3d16, "vfpv3d16", ARM_HWCAP_VFPV3D16, 0) \ - FEATURE(ARM_TLS, tls, "tls", ARM_HWCAP_TLS, 0) \ - FEATURE(ARM_VFPV4, vfpv4, "vfpv4", ARM_HWCAP_VFPV4, 0) \ - FEATURE(ARM_IDIVA, idiva, "idiva", ARM_HWCAP_IDIVA, 0) \ - FEATURE(ARM_IDIVT, idivt, "idivt", ARM_HWCAP_IDIVT, 0) \ - FEATURE(ARM_VFPD32, vfpd32, "vfpd32", ARM_HWCAP_VFPD32, 0) \ - FEATURE(ARM_LPAE, lpae, "lpae", ARM_HWCAP_LPAE, 0) \ - FEATURE(ARM_EVTSTRM, evtstrm, "evtstrm", ARM_HWCAP_EVTSTRM, 0) \ - FEATURE(ARM_AES, aes, "aes", 0, ARM_HWCAP2_AES) \ - FEATURE(ARM_PMULL, pmull, "pmull", 0, ARM_HWCAP2_PMULL) \ - FEATURE(ARM_SHA1, sha1, "sha1", 0, ARM_HWCAP2_SHA1) \ - FEATURE(ARM_SHA2, sha2, "sha2", 0, ARM_HWCAP2_SHA2) \ - FEATURE(ARM_CRC32, crc32, "crc32", 0, ARM_HWCAP2_CRC32) -#define DEFINE_TABLE_FEATURE_TYPE ArmFeatures -#include "define_tables.h" +#include typedef struct { @@ -217,18 +228,5 @@ ArmInfo GetArmInfo(void) return info; } -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetArmFeaturesEnumValue(const ArmFeatures* features, - ArmFeaturesEnum value) -{ - if (value >= ARM_LAST_) return false; - return kGetters[value](features); -} - -const char* GetArmFeaturesEnumName(ArmFeaturesEnum value) -{ - if (value >= ARM_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_ARM diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_mips.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_mips_linux_or_android.c similarity index 71% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_mips.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_mips_linux_or_android.c index 31794dc93..cb874ffc6 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_mips.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_mips_linux_or_android.c @@ -1,21 +1,32 @@ // SPDX-FileCopyrightText: 2017 Google LLC // SPDX-License-Identifier: Apache-2.0 +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_MIPS +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + #include "cpuinfo_mips.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \ + LINE(MIPS_EVA, eva, "eva", 0, 0) \ + LINE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0) +#define INTROSPECTION_PREFIX Mips +#define INTROSPECTION_ENUM_PREFIX MIPS +#include "define_introspection_and_hwcaps.inl" + +//////////////////////////////////////////////////////////////////////////////// +// Implementation. +//////////////////////////////////////////////////////////////////////////////// + #include "internal/filesystem.h" #include "internal/hwcaps.h" #include "internal/stack_line_reader.h" #include "internal/string_view.h" -#include - -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags and kHardwareCapabilities global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(MIPS_MSA, msa, "msa", MIPS_HWCAP_MSA, 0) \ - FEATURE(MIPS_EVA, eva, "eva", 0, 0) \ - FEATURE(MIPS_R6, r6, "r6", MIPS_HWCAP_R6, 0) -#define DEFINE_TABLE_FEATURE_TYPE MipsFeatures -#include "define_tables.h" static bool HandleMipsLine(const LineResult result, MipsFeatures* const features) @@ -75,18 +86,5 @@ MipsInfo GetMipsInfo(void) return info; } -//////////////////////////////////////////////////////////////////////////////// -// Introspection functions - -int GetMipsFeaturesEnumValue(const MipsFeatures* features, - MipsFeaturesEnum value) -{ - if (value >= MIPS_LAST_) return false; - return kGetters[value](features); -} - -const char* GetMipsFeaturesEnumName(MipsFeaturesEnum value) -{ - if (value >= MIPS_LAST_) return "unknown feature"; - return kCpuInfoFlags[value]; -} +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_MIPS 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 new file mode 100644 index 000000000..3303be405 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_ppc_linux.c @@ -0,0 +1,167 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_PPC +#ifdef CPU_FEATURES_OS_LINUX + +#include "cpuinfo_ppc.h" + +//////////////////////////////////////////////////////////////////////////////// +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(PPC_32, ppc32, "ppc32", PPC_FEATURE_32, 0) \ + LINE(PPC_64, ppc64, "ppc64", PPC_FEATURE_64, 0) \ + LINE(PPC_601_INSTR, ppc601, "ppc601", PPC_FEATURE_601_INSTR, 0) \ + LINE(PPC_HAS_ALTIVEC, altivec, "altivec", PPC_FEATURE_HAS_ALTIVEC, 0) \ + LINE(PPC_HAS_FPU, fpu, "fpu", PPC_FEATURE_HAS_FPU, 0) \ + LINE(PPC_HAS_MMU, mmu, "mmu", PPC_FEATURE_HAS_MMU, 0) \ + LINE(PPC_HAS_4xxMAC, mac_4xx, "4xxmac", PPC_FEATURE_HAS_4xxMAC, 0) \ + LINE(PPC_UNIFIED_CACHE, unifiedcache, "ucache", PPC_FEATURE_UNIFIED_CACHE, \ + 0) \ + LINE(PPC_HAS_SPE, spe, "spe", PPC_FEATURE_HAS_SPE, 0) \ + LINE(PPC_HAS_EFP_SINGLE, efpsingle, "efpsingle", PPC_FEATURE_HAS_EFP_SINGLE, \ + 0) \ + LINE(PPC_HAS_EFP_DOUBLE, efpdouble, "efpdouble", PPC_FEATURE_HAS_EFP_DOUBLE, \ + 0) \ + LINE(PPC_NO_TB, no_tb, "notb", PPC_FEATURE_NO_TB, 0) \ + LINE(PPC_POWER4, power4, "power4", PPC_FEATURE_POWER4, 0) \ + LINE(PPC_POWER5, power5, "power5", PPC_FEATURE_POWER5, 0) \ + LINE(PPC_POWER5_PLUS, power5plus, "power5+", PPC_FEATURE_POWER5_PLUS, 0) \ + LINE(PPC_CELL, cell, "cellbe", PPC_FEATURE_CELL, 0) \ + LINE(PPC_BOOKE, booke, "booke", PPC_FEATURE_BOOKE, 0) \ + LINE(PPC_SMT, smt, "smt", PPC_FEATURE_SMT, 0) \ + LINE(PPC_ICACHE_SNOOP, icachesnoop, "ic_snoop", PPC_FEATURE_ICACHE_SNOOP, 0) \ + LINE(PPC_ARCH_2_05, arch205, "arch_2_05", PPC_FEATURE_ARCH_2_05, 0) \ + LINE(PPC_PA6T, pa6t, "pa6t", PPC_FEATURE_PA6T, 0) \ + LINE(PPC_HAS_DFP, dfp, "dfp", PPC_FEATURE_HAS_DFP, 0) \ + LINE(PPC_POWER6_EXT, power6ext, "power6x", PPC_FEATURE_POWER6_EXT, 0) \ + LINE(PPC_ARCH_2_06, arch206, "arch_2_06", PPC_FEATURE_ARCH_2_06, 0) \ + LINE(PPC_HAS_VSX, vsx, "vsx", PPC_FEATURE_HAS_VSX, 0) \ + LINE(PPC_PSERIES_PERFMON_COMPAT, pseries_perfmon_compat, "archpmu", \ + PPC_FEATURE_PSERIES_PERFMON_COMPAT, 0) \ + LINE(PPC_TRUE_LE, truele, "true_le", PPC_FEATURE_TRUE_LE, 0) \ + LINE(PPC_PPC_LE, ppcle, "ppcle", PPC_FEATURE_PPC_LE, 0) \ + LINE(PPC_ARCH_2_07, arch207, "arch_2_07", 0, PPC_FEATURE2_ARCH_2_07) \ + LINE(PPC_HTM, htm, "htm", 0, PPC_FEATURE2_HTM) \ + LINE(PPC_DSCR, dscr, "dscr", 0, PPC_FEATURE2_DSCR) \ + LINE(PPC_EBB, ebb, "ebb", 0, PPC_FEATURE2_EBB) \ + LINE(PPC_ISEL, isel, "isel", 0, PPC_FEATURE2_ISEL) \ + LINE(PPC_TAR, tar, "tar", 0, PPC_FEATURE2_TAR) \ + LINE(PPC_VEC_CRYPTO, vcrypto, "vcrypto", 0, PPC_FEATURE2_VEC_CRYPTO) \ + LINE(PPC_HTM_NOSC, htm_nosc, "htm-nosc", 0, PPC_FEATURE2_HTM_NOSC) \ + LINE(PPC_ARCH_3_00, arch300, "arch_3_00", 0, PPC_FEATURE2_ARCH_3_00) \ + LINE(PPC_HAS_IEEE128, ieee128, "ieee128", 0, PPC_FEATURE2_HAS_IEEE128) \ + LINE(PPC_DARN, darn, "darn", 0, PPC_FEATURE2_DARN) \ + 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) +#define INTROSPECTION_PREFIX PPC +#define INTROSPECTION_ENUM_PREFIX PPC +#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 HandlePPCLine(const LineResult result, + PPCPlatformStrings* const strings) +{ + StringView line = result.line; + StringView key, value; + if (CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) + { + if (CpuFeatures_StringView_HasWord(key, "platform", ' ')) + { + CpuFeatures_StringView_CopyString(value, strings->platform, + sizeof(strings->platform)); + } + else if (CpuFeatures_StringView_IsEquals(key, str("model"))) + { + CpuFeatures_StringView_CopyString(value, strings->model, + sizeof(strings->platform)); + } + else if (CpuFeatures_StringView_IsEquals(key, str("machine"))) + { + CpuFeatures_StringView_CopyString(value, strings->machine, + sizeof(strings->platform)); + } + else if (CpuFeatures_StringView_IsEquals(key, str("cpu"))) + { + CpuFeatures_StringView_CopyString(value, strings->cpu, + sizeof(strings->platform)); + } + } + return !result.eof; +} + +static void FillProcCpuInfoData(PPCPlatformStrings* const strings) +{ + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (;;) + { + if (!HandlePPCLine(StackLineReader_NextLine(&reader), strings)) + { + break; + } + } + CpuFeatures_CloseFile(fd); + } +} + +static const PPCInfo kEmptyPPCInfo; + +PPCInfo GetPPCInfo(void) +{ + /* + * On Power feature flags aren't currently in cpuinfo so we only look at + * the auxilary vector. + */ + PPCInfo info = kEmptyPPCInfo; + const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); + for (size_t i = 0; i < PPC_LAST_; ++i) + { + if (CpuFeatures_IsHwCapsSet(kHardwareCapabilities[i], hwcaps)) + { + kSetters[i](&info.features, true); + } + } + return info; +} + +static const PPCPlatformStrings kEmptyPPCPlatformStrings; + +PPCPlatformStrings GetPPCPlatformStrings(void) +{ + PPCPlatformStrings strings = kEmptyPPCPlatformStrings; + const char* platform = CpuFeatures_GetPlatformPointer(); + const char* base_platform = CpuFeatures_GetBasePlatformPointer(); + + FillProcCpuInfoData(&strings); + + if (platform != NULL) + CpuFeatures_StringView_CopyString(str(platform), strings.type.platform, + sizeof(strings.type.platform)); + if (base_platform != NULL) + CpuFeatures_StringView_CopyString(str(base_platform), + strings.type.base_platform, + sizeof(strings.type.base_platform)); + + return strings; +} + +#endif // CPU_FEATURES_OS_LINUX +#endif // CPU_FEATURES_ARCH_PPC diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl similarity index 79% rename from src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c rename to src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl index f7b79f54c..430d55b77 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_x86.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86__base_implementation.inl @@ -1,9 +1,11 @@ -// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-FileCopyrightText: 2017 Google LLC, 2020 Intel Corporation // SPDX-License-Identifier: Apache-2.0 #include "cpuinfo_x86.h" #include "internal/bit_utils.h" #include "internal/cpuid_x86.h" +#include "copy.inl" +#include "equals.inl" #include #include @@ -11,94 +13,6 @@ #error "Cannot compile cpuinfo_x86 on a non x86 platform." #endif -// Generation of feature's getters/setters functions and kGetters, kSetters, -// kCpuInfoFlags global tables. -#define DEFINE_TABLE_FEATURES \ - FEATURE(X86_FPU, fpu, "fpu", 0, 0) \ - FEATURE(X86_TSC, tsc, "tsc", 0, 0) \ - FEATURE(X86_CX8, cx8, "cx8", 0, 0) \ - FEATURE(X86_CLFSH, clfsh, "clfsh", 0, 0) \ - FEATURE(X86_MMX, mmx, "mmx", 0, 0) \ - FEATURE(X86_AES, aes, "aes", 0, 0) \ - FEATURE(X86_ERMS, erms, "erms", 0, 0) \ - FEATURE(X86_F16C, f16c, "f16c", 0, 0) \ - FEATURE(X86_FMA4, fma4, "fma4", 0, 0) \ - FEATURE(X86_FMA3, fma3, "fma3", 0, 0) \ - FEATURE(X86_VAES, vaes, "vaes", 0, 0) \ - FEATURE(X86_VPCLMULQDQ, vpclmulqdq, "vpclmulqdq", 0, 0) \ - FEATURE(X86_BMI1, bmi1, "bmi1", 0, 0) \ - FEATURE(X86_HLE, hle, "hle", 0, 0) \ - FEATURE(X86_BMI2, bmi2, "bmi2", 0, 0) \ - FEATURE(X86_RTM, rtm, "rtm", 0, 0) \ - FEATURE(X86_RDSEED, rdseed, "rdseed", 0, 0) \ - FEATURE(X86_CLFLUSHOPT, clflushopt, "clflushopt", 0, 0) \ - FEATURE(X86_CLWB, clwb, "clwb", 0, 0) \ - FEATURE(X86_SSE, sse, "sse", 0, 0) \ - FEATURE(X86_SSE2, sse2, "sse2", 0, 0) \ - FEATURE(X86_SSE3, sse3, "sse3", 0, 0) \ - FEATURE(X86_SSSE3, ssse3, "ssse3", 0, 0) \ - FEATURE(X86_SSE4_1, sse4_1, "sse4_1", 0, 0) \ - FEATURE(X86_SSE4_2, sse4_2, "sse4_2", 0, 0) \ - FEATURE(X86_SSE4A, sse4a, "sse4a", 0, 0) \ - FEATURE(X86_AVX, avx, "avx", 0, 0) \ - FEATURE(X86_AVX2, avx2, "avx2", 0, 0) \ - FEATURE(X86_AVX512F, avx512f, "avx512f", 0, 0) \ - FEATURE(X86_AVX512CD, avx512cd, "avx512cd", 0, 0) \ - FEATURE(X86_AVX512ER, avx512er, "avx512er", 0, 0) \ - FEATURE(X86_AVX512PF, avx512pf, "avx512pf", 0, 0) \ - FEATURE(X86_AVX512BW, avx512bw, "avx512bw", 0, 0) \ - FEATURE(X86_AVX512DQ, avx512dq, "avx512dq", 0, 0) \ - FEATURE(X86_AVX512VL, avx512vl, "avx512vl", 0, 0) \ - FEATURE(X86_AVX512IFMA, avx512ifma, "avx512ifma", 0, 0) \ - FEATURE(X86_AVX512VBMI, avx512vbmi, "avx512vbmi", 0, 0) \ - FEATURE(X86_AVX512VBMI2, avx512vbmi2, "avx512vbmi2", 0, 0) \ - FEATURE(X86_AVX512VNNI, avx512vnni, "avx512vnni", 0, 0) \ - FEATURE(X86_AVX512BITALG, avx512bitalg, "avx512bitalg", 0, 0) \ - FEATURE(X86_AVX512VPOPCNTDQ, avx512vpopcntdq, "avx512vpopcntdq", 0, 0) \ - FEATURE(X86_AVX512_4VNNIW, avx512_4vnniw, "avx512_4vnniw", 0, 0) \ - FEATURE(X86_AVX512_4VBMI2, avx512_4vbmi2, "avx512_4vbmi2", 0, 0) \ - FEATURE(X86_AVX512_SECOND_FMA, avx512_second_fma, "avx512_second_fma", 0, 0) \ - FEATURE(X86_AVX512_4FMAPS, avx512_4fmaps, "avx512_4fmaps", 0, 0) \ - FEATURE(X86_AVX512_BF16, avx512_bf16, "avx512_bf16", 0, 0) \ - FEATURE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, "avx512_vp2intersect", \ - 0, 0) \ - FEATURE(X86_AMX_BF16, amx_bf16, "amx_bf16", 0, 0) \ - FEATURE(X86_AMX_TILE, amx_tile, "amx_tile", 0, 0) \ - FEATURE(X86_AMX_INT8, amx_int8, "amx_int8", 0, 0) \ - FEATURE(X86_PCLMULQDQ, pclmulqdq, "pclmulqdq", 0, 0) \ - FEATURE(X86_SMX, smx, "smx", 0, 0) \ - FEATURE(X86_SGX, sgx, "sgx", 0, 0) \ - FEATURE(X86_CX16, cx16, "cx16", 0, 0) \ - FEATURE(X86_SHA, sha, "sha", 0, 0) \ - FEATURE(X86_POPCNT, popcnt, "popcnt", 0, 0) \ - FEATURE(X86_MOVBE, movbe, "movbe", 0, 0) \ - FEATURE(X86_RDRND, rdrnd, "rdrnd", 0, 0) \ - FEATURE(X86_DCA, dca, "dca", 0, 0) \ - FEATURE(X86_SS, ss, "ss", 0, 0) \ - FEATURE(X86_ADX, adx, "adx", 0, 0) -#define DEFINE_TABLE_FEATURE_TYPE X86Features -#define DEFINE_TABLE_DONT_GENERATE_HWCAPS -#include "define_tables.h" - -// The following includes are necessary to provide SSE detections on pre-AVX -// microarchitectures. -#if defined(CPU_FEATURES_OS_WINDOWS) -#include // IsProcessorFeaturePresent -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) || \ - defined(CPU_FEATURES_OS_FREEBSD) -#include "internal/filesystem.h" // Needed to parse /proc/cpuinfo -#include "internal/stack_line_reader.h" // Needed to parse /proc/cpuinfo -#elif defined(CPU_FEATURES_OS_DARWIN) -#if !defined(HAVE_SYSCTLBYNAME) -#error "Darwin needs support for sysctlbyname" -#endif -#include -#else -#error "Unsupported OS" -#endif // CPU_FEATURES_OS - -#include "internal/string_view.h" - //////////////////////////////////////////////////////////////////////////////// // Definitions for CpuId and GetXCR0Eax. //////////////////////////////////////////////////////////////////////////////// @@ -120,8 +34,8 @@ uint32_t GetXCR0Eax(void) { uint32_t eax, edx; /* named form of xgetbv not supported on OSX, so must use byte form, see: - https://github.com/asmjit/asmjit/issues/78 - */ + https://github.com/asmjit/asmjit/issues/78 + */ __asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0)); @@ -175,6 +89,11 @@ static Leaf SafeCpuId(uint32_t max_cpuid_leaf, uint32_t leaf_id) return SafeCpuIdEx(max_cpuid_leaf, leaf_id, 0); } +//////////////////////////////////////////////////////////////////////////////// +// OS support +// TODO: Add documentation +//////////////////////////////////////////////////////////////////////////////// + #define MASK_XMM 0x2 #define MASK_YMM 0x4 #define MASK_MASKREG 0x20 @@ -202,7 +121,6 @@ static bool HasYmmOsXSave(uint32_t xcr0_eax) return HasMask(xcr0_eax, MASK_XMM | MASK_YMM); } -#if !defined(CPU_FEATURES_OS_DARWIN) // Checks that operating system saves and restores zmm registers during context // switches. static bool HasZmmOsXSave(uint32_t xcr0_eax) @@ -210,7 +128,6 @@ static bool HasZmmOsXSave(uint32_t xcr0_eax) return HasMask(xcr0_eax, MASK_XMM | MASK_YMM | MASK_MASKREG | MASK_ZMM0_15 | MASK_ZMM16_31); } -#endif // Checks that operating system saves and restores AMX/TMUL state during context // switches. @@ -220,6 +137,51 @@ static bool HasTmmOsXSave(uint32_t xcr0_eax) MASK_ZMM16_31 | MASK_XTILECFG | MASK_XTILEDATA); } +//////////////////////////////////////////////////////////////////////////////// +// Vendor +//////////////////////////////////////////////////////////////////////////////// + +static void SetVendor(const Leaf leaf, char* const vendor) +{ + *(uint32_t*)(vendor) = leaf.ebx; + *(uint32_t*)(vendor + 4) = leaf.edx; + *(uint32_t*)(vendor + 8) = leaf.ecx; + vendor[12] = '\0'; +} + +static int IsVendor(const Leaf leaf, const char* const name) +{ + const uint32_t ebx = *(const uint32_t*)(name); + const uint32_t edx = *(const uint32_t*)(name + 4); + const uint32_t ecx = *(const uint32_t*)(name + 8); + return leaf.ebx == ebx && leaf.ecx == ecx && leaf.edx == edx; +} + +static int IsVendorByX86Info(const X86Info* info, const char* const name) +{ + return equals(info->vendor, name, sizeof(info->vendor)); +} + +void FillX86BrandString(char brand_string[49]) +{ + const Leaf leaf_ext_0 = CpuId(0x80000000); + const uint32_t max_cpuid_leaf_ext = leaf_ext_0.eax; + const Leaf leaves[3] = { + SafeCpuId(max_cpuid_leaf_ext, 0x80000002), + SafeCpuId(max_cpuid_leaf_ext, 0x80000003), + SafeCpuId(max_cpuid_leaf_ext, 0x80000004), + }; +#if __STDC_VERSION__ >= 201112L + _Static_assert(sizeof(leaves) == 48, "Leaves must be packed"); +#endif + copy(brand_string, (const char*)(leaves), 48); + brand_string[48] = '\0'; +} + +//////////////////////////////////////////////////////////////////////////////// +// CpuId +//////////////////////////////////////////////////////////////////////////////// + static bool HasSecondFMA(uint32_t model) { // Skylake server @@ -252,27 +214,480 @@ static bool HasSecondFMA(uint32_t model) return true; } -static void SetVendor(const Leaf leaf, char* const vendor) +// Internal structure to hold the OS support for vector operations. +// Avoid to recompute them since each call to cpuid is ~100 cycles. +typedef struct { - *(uint32_t*)(vendor) = leaf.ebx; - *(uint32_t*)(vendor + 4) = leaf.edx; - *(uint32_t*)(vendor + 8) = leaf.ecx; - vendor[12] = '\0'; + bool sse_registers; + bool avx_registers; + bool avx512_registers; + bool amx_registers; +} OsPreserves; + +// These two functions have to be implemented by the OS, that is the file +// including this file. +static void OverrideOsPreserves(OsPreserves* os_preserves); +static void DetectFeaturesFromOs(X86Features* features); + +// Reference https://en.wikipedia.org/wiki/CPUID. +static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, + OsPreserves* os_preserves) +{ + const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1); + const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7); + const Leaf leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 7, 1); + + const bool have_xsave = IsBitSet(leaf_1.ecx, 26); + const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); + const bool have_xcr0 = have_xsave && have_osxsave; + + const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); + const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); + const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4); + const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16); + + X86Features* const features = &info->features; + + info->family = extended_family + family; + info->model = (extended_model << 4) + model; + info->stepping = ExtractBitRange(leaf_1.eax, 3, 0); + + features->fpu = IsBitSet(leaf_1.edx, 0); + features->tsc = IsBitSet(leaf_1.edx, 4); + features->cx8 = IsBitSet(leaf_1.edx, 8); + features->clfsh = IsBitSet(leaf_1.edx, 19); + features->mmx = IsBitSet(leaf_1.edx, 23); + features->ss = IsBitSet(leaf_1.edx, 27); + features->pclmulqdq = IsBitSet(leaf_1.ecx, 1); + features->smx = IsBitSet(leaf_1.ecx, 6); + features->cx16 = IsBitSet(leaf_1.ecx, 13); + features->dca = IsBitSet(leaf_1.ecx, 18); + features->movbe = IsBitSet(leaf_1.ecx, 22); + features->popcnt = IsBitSet(leaf_1.ecx, 23); + features->aes = IsBitSet(leaf_1.ecx, 25); + features->f16c = IsBitSet(leaf_1.ecx, 29); + features->rdrnd = IsBitSet(leaf_1.ecx, 30); + features->sgx = IsBitSet(leaf_7.ebx, 2); + features->bmi1 = IsBitSet(leaf_7.ebx, 3); + features->hle = IsBitSet(leaf_7.ebx, 4); + features->bmi2 = IsBitSet(leaf_7.ebx, 8); + features->erms = IsBitSet(leaf_7.ebx, 9); + features->rtm = IsBitSet(leaf_7.ebx, 11); + features->rdseed = IsBitSet(leaf_7.ebx, 18); + features->clflushopt = IsBitSet(leaf_7.ebx, 23); + features->clwb = IsBitSet(leaf_7.ebx, 24); + features->sha = IsBitSet(leaf_7.ebx, 29); + features->vaes = IsBitSet(leaf_7.ecx, 9); + features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); + features->adx = IsBitSet(leaf_7.ebx, 19); + + ///////////////////////////////////////////////////////////////////////////// + // The following section is devoted to Vector Extensions. + ///////////////////////////////////////////////////////////////////////////// + + // CPU with AVX expose XCR0 which enables checking vector extensions OS + // support through cpuid. + if (have_xcr0) + { + // Here we rely exclusively on cpuid for both CPU and OS support of vector + // extensions. + const uint32_t xcr0_eax = GetXCR0Eax(); + os_preserves->sse_registers = HasXmmOsXSave(xcr0_eax); + os_preserves->avx_registers = HasYmmOsXSave(xcr0_eax); + os_preserves->avx512_registers = HasZmmOsXSave(xcr0_eax); + os_preserves->amx_registers = HasTmmOsXSave(xcr0_eax); + OverrideOsPreserves(os_preserves); + + if (os_preserves->sse_registers) + { + features->sse = IsBitSet(leaf_1.edx, 25); + features->sse2 = IsBitSet(leaf_1.edx, 26); + features->sse3 = IsBitSet(leaf_1.ecx, 0); + features->ssse3 = IsBitSet(leaf_1.ecx, 9); + features->sse4_1 = IsBitSet(leaf_1.ecx, 19); + features->sse4_2 = IsBitSet(leaf_1.ecx, 20); + } + if (os_preserves->avx_registers) + { + features->fma3 = IsBitSet(leaf_1.ecx, 12); + features->avx = IsBitSet(leaf_1.ecx, 28); + features->avx2 = IsBitSet(leaf_7.ebx, 5); + } + if (os_preserves->avx512_registers) + { + features->avx512f = IsBitSet(leaf_7.ebx, 16); + features->avx512cd = IsBitSet(leaf_7.ebx, 28); + features->avx512er = IsBitSet(leaf_7.ebx, 27); + features->avx512pf = IsBitSet(leaf_7.ebx, 26); + features->avx512bw = IsBitSet(leaf_7.ebx, 30); + features->avx512dq = IsBitSet(leaf_7.ebx, 17); + features->avx512vl = IsBitSet(leaf_7.ebx, 31); + features->avx512ifma = IsBitSet(leaf_7.ebx, 21); + features->avx512vbmi = IsBitSet(leaf_7.ecx, 1); + features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6); + features->avx512vnni = IsBitSet(leaf_7.ecx, 11); + features->avx512bitalg = IsBitSet(leaf_7.ecx, 12); + features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14); + features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2); + features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3); + features->avx512_second_fma = HasSecondFMA(info->model); + 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); + } + if (os_preserves->amx_registers) + { + features->amx_bf16 = IsBitSet(leaf_7.edx, 22); + features->amx_tile = IsBitSet(leaf_7.edx, 24); + features->amx_int8 = IsBitSet(leaf_7.edx, 25); + } + } + else + { + // When XCR0 is not available (Atom based or older cpus) we need to defer to + // the OS via custom code. + DetectFeaturesFromOs(features); + // Now that we have queried the OS for SSE support, we report this back to + // os_preserves. This is needed in case of AMD CPU's to enable testing of + // sse4a (See ParseExtraAMDCpuId below). + if (features->sse) os_preserves->sse_registers = true; + } } -static int IsVendor(const Leaf leaf, const char* const name) +// Reference +// https://en.wikipedia.org/wiki/CPUID#EAX=80000000h:_Get_Highest_Extended_Function_Implemented. +static Leaf GetLeafByIdAMD(uint32_t leaf_id) { - const uint32_t ebx = *(const uint32_t*)(name); - const uint32_t edx = *(const uint32_t*)(name + 4); - const uint32_t ecx = *(const uint32_t*)(name + 8); - return leaf.ebx == ebx && leaf.ecx == ecx && leaf.edx == edx; + uint32_t max_extended = CpuId(0x80000000).eax; + return SafeCpuId(max_extended, leaf_id); } -static int IsVendorByX86Info(const X86Info* info, const char* const name) +static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves) { - return memcmp(info->vendor, name, sizeof(info->vendor)) == 0; + const Leaf leaf_80000001 = GetLeafByIdAMD(0x80000001); + + X86Features* const features = &info->features; + + if (os_preserves.sse_registers) + { + features->sse4a = IsBitSet(leaf_80000001.ecx, 6); + } + + if (os_preserves.avx_registers) + { + features->fma4 = IsBitSet(leaf_80000001.ecx, 16); + } } +static const X86Info kEmptyX86Info; +static const OsPreserves kEmptyOsPreserves; + +X86Info GetX86Info(void) +{ + X86Info info = kEmptyX86Info; + const Leaf leaf_0 = CpuId(0); + const bool is_intel = IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL); + const bool is_amd = IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); + const bool is_hygon = IsVendor(leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE); + SetVendor(leaf_0, info.vendor); + if (is_intel || is_amd || is_hygon) + { + OsPreserves os_preserves = kEmptyOsPreserves; + const uint32_t max_cpuid_leaf = leaf_0.eax; + ParseCpuId(max_cpuid_leaf, &info, &os_preserves); + if (is_amd || is_hygon) + { + ParseExtraAMDCpuId(&info, os_preserves); + } + } + return info; +} + +//////////////////////////////////////////////////////////////////////////////// +// Microarchitecture +//////////////////////////////////////////////////////////////////////////////// + +#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) + +X86Microarchitecture GetX86Microarchitecture(const X86Info* info) +{ + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_GENUINE_INTEL)) + { + switch (CPUID(info->family, info->model)) + { + case CPUID(0x04, 0x01): + case CPUID(0x04, 0x02): + case CPUID(0x04, 0x03): + case CPUID(0x04, 0x04): + case CPUID(0x04, 0x05): + case CPUID(0x04, 0x07): + case CPUID(0x04, 0x08): + case CPUID(0x04, 0x09): + // https://en.wikichip.org/wiki/intel/microarchitectures/80486 + return INTEL_80486; + case CPUID(0x05, 0x01): + case CPUID(0x05, 0x02): + case CPUID(0x05, 0x04): + case CPUID(0x05, 0x07): + case CPUID(0x05, 0x08): + // https://en.wikichip.org/wiki/intel/microarchitectures/p5 + return INTEL_P5; + case CPUID(0x05, 0x09): + case CPUID(0x05, 0x0A): + // https://en.wikichip.org/wiki/intel/quark + return INTEL_LAKEMONT; + case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz + case CPUID(0x06, 0x35): + case CPUID(0x06, 0x36): + case CPUID(0x06, 0x70): // https://en.wikichip.org/wiki/intel/atom/230 + // https://en.wikipedia.org/wiki/Bonnell_(microarchitecture) + return INTEL_ATOM_BNL; + case CPUID(0x06, 0x37): + case CPUID(0x06, 0x4C): + // https://en.wikipedia.org/wiki/Silvermont + return INTEL_ATOM_SMT; + case CPUID(0x06, 0x5C): + // https://en.wikipedia.org/wiki/Goldmont + return INTEL_ATOM_GMT; + case CPUID(0x06, 0x0F): + case CPUID(0x06, 0x16): + // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) + return INTEL_CORE; + case CPUID(0x06, 0x17): + case CPUID(0x06, 0x1D): + // https://en.wikipedia.org/wiki/Penryn_(microarchitecture) + return INTEL_PNR; + case CPUID(0x06, 0x1A): + case CPUID(0x06, 0x1E): + case CPUID(0x06, 0x1F): + case CPUID(0x06, 0x2E): + // https://en.wikipedia.org/wiki/Nehalem_(microarchitecture) + return INTEL_NHM; + case CPUID(0x06, 0x25): + case CPUID(0x06, 0x2C): + case CPUID(0x06, 0x2F): + // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) + return INTEL_WSM; + case CPUID(0x06, 0x2A): + case CPUID(0x06, 0x2D): + // https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings + return INTEL_SNB; + case CPUID(0x06, 0x3A): + case CPUID(0x06, 0x3E): + // https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings + return INTEL_IVB; + case CPUID(0x06, 0x3C): + case CPUID(0x06, 0x3F): + case CPUID(0x06, 0x45): + case CPUID(0x06, 0x46): + // https://en.wikipedia.org/wiki/Haswell_(microarchitecture) + return INTEL_HSW; + case CPUID(0x06, 0x3D): + case CPUID(0x06, 0x47): + case CPUID(0x06, 0x4F): + case CPUID(0x06, 0x56): + // 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, 0x66): + // https://en.wikipedia.org/wiki/Cannon_Lake_(microarchitecture) + return INTEL_CNL; + case CPUID(0x06, 0x7D): // client + case CPUID(0x06, 0x7E): // client + case CPUID(0x06, 0x9D): // NNP-I + case CPUID(0x06, 0x6A): // server + case CPUID(0x06, 0x6C): // server + // https://en.wikipedia.org/wiki/Ice_Lake_(microprocessor) + return INTEL_ICL; + case CPUID(0x06, 0x8C): + case CPUID(0x06, 0x8D): + // https://en.wikipedia.org/wiki/Tiger_Lake_(microarchitecture) + return INTEL_TGL; + case CPUID(0x06, 0x8F): + // https://en.wikipedia.org/wiki/Sapphire_Rapids + return INTEL_SPR; + case CPUID(0x06, 0x8E): + switch (info->stepping) + { + case 9: + return INTEL_KBL; // https://en.wikipedia.org/wiki/Kaby_Lake + case 10: + return INTEL_CFL; // https://en.wikipedia.org/wiki/Coffee_Lake + case 11: + return INTEL_WHL; // https://en.wikipedia.org/wiki/Whiskey_Lake_(microarchitecture) + default: + return X86_UNKNOWN; + } + case CPUID(0x06, 0x9E): + if (info->stepping > 9) + { + // https://en.wikipedia.org/wiki/Coffee_Lake + return INTEL_CFL; + } + else + { + // https://en.wikipedia.org/wiki/Kaby_Lake + return INTEL_KBL; + } + case CPUID(0x06, 0x97): + case CPUID(0x06, 0x9A): + // https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake + return INTEL_ADL; + case CPUID(0x06, 0xA7): + // https://en.wikichip.org/wiki/intel/microarchitectures/rocket_lake + return INTEL_RCL; + case CPUID(0x06, 0x85): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_mill + return INTEL_KNIGHTS_M; + case CPUID(0x06, 0x57): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_landing + return INTEL_KNIGHTS_L; + case CPUID(0x0B, 0x00): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_ferry + return INTEL_KNIGHTS_F; + case CPUID(0x0B, 0x01): + // https://en.wikichip.org/wiki/intel/microarchitectures/knights_corner + return INTEL_KNIGHTS_C; + case CPUID(0x0F, 0x01): + case CPUID(0x0F, 0x02): + case CPUID(0x0F, 0x03): + case CPUID(0x0F, 0x04): + case CPUID(0x0F, 0x06): + // https://en.wikichip.org/wiki/intel/microarchitectures/netburst + return INTEL_NETBURST; + default: + return X86_UNKNOWN; + } + } + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD)) + { + switch (CPUID(info->family, info->model)) + { + // https://en.wikichip.org/wiki/amd/cpuid + case CPUID(0xF, 0x04): + case CPUID(0xF, 0x05): + case CPUID(0xF, 0x07): + case CPUID(0xF, 0x08): + case CPUID(0xF, 0x0C): + case CPUID(0xF, 0x0E): + case CPUID(0xF, 0x0F): + case CPUID(0xF, 0x14): + case CPUID(0xF, 0x15): + case CPUID(0xF, 0x17): + case CPUID(0xF, 0x18): + case CPUID(0xF, 0x1B): + case CPUID(0xF, 0x1C): + case CPUID(0xF, 0x1F): + case CPUID(0xF, 0x21): + case CPUID(0xF, 0x23): + case CPUID(0xF, 0x24): + case CPUID(0xF, 0x25): + case CPUID(0xF, 0x27): + case CPUID(0xF, 0x2B): + case CPUID(0xF, 0x2C): + case CPUID(0xF, 0x2F): + case CPUID(0xF, 0x41): + case CPUID(0xF, 0x43): + case CPUID(0xF, 0x48): + case CPUID(0xF, 0x4B): + case CPUID(0xF, 0x4C): + case CPUID(0xF, 0x4F): + case CPUID(0xF, 0x5D): + case CPUID(0xF, 0x5F): + case CPUID(0xF, 0x68): + case CPUID(0xF, 0x6B): + case CPUID(0xF, 0x6F): + case CPUID(0xF, 0x7F): + case CPUID(0xF, 0xC1): + return AMD_HAMMER; + case CPUID(0x10, 0x02): + case CPUID(0x10, 0x04): + case CPUID(0x10, 0x05): + case CPUID(0x10, 0x06): + case CPUID(0x10, 0x08): + case CPUID(0x10, 0x09): + case CPUID(0x10, 0x0A): + return AMD_K10; + case CPUID(0x11, 0x03): + // http://developer.amd.com/wordpress/media/2012/10/41788.pdf + return AMD_K11; + case CPUID(0x12, 0x01): + // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf + return AMD_K12; + case CPUID(0x14, 0x00): + case CPUID(0x14, 0x01): + case CPUID(0x14, 0x02): + // https://www.amd.com/system/files/TechDocs/47534_14h_Mod_00h-0Fh_Rev_Guide.pdf + return AMD_BOBCAT; + case CPUID(0x15, 0x01): + // https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer + return AMD_BULLDOZER; + case CPUID(0x15, 0x02): + case CPUID(0x15, 0x11): + case CPUID(0x15, 0x13): + // https://en.wikichip.org/wiki/amd/microarchitectures/piledriver + return AMD_PILEDRIVER; + case CPUID(0x15, 0x30): + case CPUID(0x15, 0x38): + // https://en.wikichip.org/wiki/amd/microarchitectures/steamroller + return AMD_STREAMROLLER; + case CPUID(0x15, 0x60): + case CPUID(0x15, 0x65): + case CPUID(0x15, 0x70): + // https://en.wikichip.org/wiki/amd/microarchitectures/excavator + return AMD_EXCAVATOR; + case CPUID(0x16, 0x00): + return AMD_JAGUAR; + case CPUID(0x16, 0x30): + return AMD_PUMA; + case CPUID(0x17, 0x01): + case CPUID(0x17, 0x11): + case CPUID(0x17, 0x18): + case CPUID(0x17, 0x20): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen + return AMD_ZEN; + case CPUID(0x17, 0x08): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen%2B + return AMD_ZEN_PLUS; + case CPUID(0x17, 0x31): + case CPUID(0x17, 0x47): + case CPUID(0x17, 0x60): + case CPUID(0x17, 0x68): + case CPUID(0x17, 0x71): + case CPUID(0x17, 0x90): + case CPUID(0x17, 0x98): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen_2 + return AMD_ZEN2; + case CPUID(0x19, 0x01): + case CPUID(0x19, 0x21): + case CPUID(0x19, 0x30): + case CPUID(0x19, 0x40): + case CPUID(0x19, 0x50): + // https://en.wikichip.org/wiki/amd/microarchitectures/zen_3 + return AMD_ZEN3; + default: + return X86_UNKNOWN; + } + } + if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_HYGON_GENUINE)) + { + switch (CPUID(info->family, info->model)) + { + case CPUID(0x18, 0x00): + return AMD_ZEN; + } + } + return X86_UNKNOWN; +} + +//////////////////////////////////////////////////////////////////////////////// +// CacheInfo +//////////////////////////////////////////////////////////////////////////////// + static const CacheLevelInfo kEmptyCacheLevelInfo; static CacheLevelInfo GetCacheLevelInfo(const uint32_t reg) @@ -1154,7 +1569,7 @@ static void ParseLeaf2(const int max_cpuid_leaf, CacheInfo* info) #if __STDC_VERSION__ >= 201112L _Static_assert(sizeof(Leaf) == sizeof(data), "Leaf must be 16 bytes"); #endif - memcpy(&data, &leaf, sizeof(data)); + copy((char*)(data), (const char*)(&leaf), sizeof(data)); for (size_t i = 0; i < sizeof(data); ++i) { const uint8_t descriptor = data[i]; @@ -1208,304 +1623,6 @@ static void ParseCacheInfo(const int max_cpuid_leaf, uint32_t leaf_id, if (info.size > 0) *old_info = info; } -#if defined(CPU_FEATURES_OS_DARWIN) -#if defined(CPU_FEATURES_MOCK_CPUID_X86) -extern bool GetDarwinSysCtlByName(const char*); -#else // CPU_FEATURES_MOCK_CPUID_X86 -static bool GetDarwinSysCtlByName(const char* name) -{ - int enabled; - size_t enabled_len = sizeof(enabled); - const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); - return failure ? false : enabled; -} -#endif -#endif // CPU_FEATURES_OS_DARWIN - -// Internal structure to hold the OS support for vector operations. -// Avoid to recompute them since each call to cpuid is ~100 cycles. -typedef struct -{ - bool sse_registers; - bool avx_registers; - bool avx512_registers; - bool amx_registers; -} OsPreserves; - -#if defined(CPU_FEATURES_OS_WINDOWS) -#if defined(CPU_FEATURES_MOCK_CPUID_X86) -extern bool GetWindowsIsProcessorFeaturePresent(DWORD); -#else // CPU_FEATURES_MOCK_CPUID_X86 -static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) -{ - return IsProcessorFeaturePresent(ProcessorFeature); -} -#endif -#endif // CPU_FEATURES_OS_WINDOWS - -// Reference https://en.wikipedia.org/wiki/CPUID. -static void ParseCpuId(const uint32_t max_cpuid_leaf, X86Info* info, - OsPreserves* os_preserves) -{ - const Leaf leaf_1 = SafeCpuId(max_cpuid_leaf, 1); - const Leaf leaf_7 = SafeCpuId(max_cpuid_leaf, 7); - const Leaf leaf_7_1 = SafeCpuIdEx(max_cpuid_leaf, 7, 1); - - const bool have_xsave = IsBitSet(leaf_1.ecx, 26); - const bool have_osxsave = IsBitSet(leaf_1.ecx, 27); - const bool have_xcr0 = have_xsave && have_osxsave; - - const uint32_t family = ExtractBitRange(leaf_1.eax, 11, 8); - const uint32_t extended_family = ExtractBitRange(leaf_1.eax, 27, 20); - const uint32_t model = ExtractBitRange(leaf_1.eax, 7, 4); - const uint32_t extended_model = ExtractBitRange(leaf_1.eax, 19, 16); - - X86Features* const features = &info->features; - - info->family = extended_family + family; - info->model = (extended_model << 4) + model; - info->stepping = ExtractBitRange(leaf_1.eax, 3, 0); - - features->fpu = IsBitSet(leaf_1.edx, 0); - features->tsc = IsBitSet(leaf_1.edx, 4); - features->cx8 = IsBitSet(leaf_1.edx, 8); - features->clfsh = IsBitSet(leaf_1.edx, 19); - features->mmx = IsBitSet(leaf_1.edx, 23); - features->ss = IsBitSet(leaf_1.edx, 27); - features->pclmulqdq = IsBitSet(leaf_1.ecx, 1); - features->smx = IsBitSet(leaf_1.ecx, 6); - features->cx16 = IsBitSet(leaf_1.ecx, 13); - features->dca = IsBitSet(leaf_1.ecx, 18); - features->movbe = IsBitSet(leaf_1.ecx, 22); - features->popcnt = IsBitSet(leaf_1.ecx, 23); - features->aes = IsBitSet(leaf_1.ecx, 25); - features->f16c = IsBitSet(leaf_1.ecx, 29); - features->rdrnd = IsBitSet(leaf_1.ecx, 30); - features->sgx = IsBitSet(leaf_7.ebx, 2); - features->bmi1 = IsBitSet(leaf_7.ebx, 3); - features->hle = IsBitSet(leaf_7.ebx, 4); - features->bmi2 = IsBitSet(leaf_7.ebx, 8); - features->erms = IsBitSet(leaf_7.ebx, 9); - features->rtm = IsBitSet(leaf_7.ebx, 11); - features->rdseed = IsBitSet(leaf_7.ebx, 18); - features->clflushopt = IsBitSet(leaf_7.ebx, 23); - features->clwb = IsBitSet(leaf_7.ebx, 24); - features->sha = IsBitSet(leaf_7.ebx, 29); - features->vaes = IsBitSet(leaf_7.ecx, 9); - features->vpclmulqdq = IsBitSet(leaf_7.ecx, 10); - features->adx = IsBitSet(leaf_7.ebx, 19); - - ///////////////////////////////////////////////////////////////////////////// - // The following section is devoted to Vector Extensions. - ///////////////////////////////////////////////////////////////////////////// - - // CPU with AVX expose XCR0 which enables checking vector extensions OS - // support through cpuid. - if (have_xcr0) - { - // Here we rely exclusively on cpuid for both CPU and OS support of vector - // extensions. - const uint32_t xcr0_eax = GetXCR0Eax(); - os_preserves->sse_registers = HasXmmOsXSave(xcr0_eax); - os_preserves->avx_registers = HasYmmOsXSave(xcr0_eax); -#if defined(CPU_FEATURES_OS_DARWIN) - // On Darwin AVX512 support is On-demand. - // We have to query the OS instead of querying the Zmm save/restore state. - // https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/i386/fpu.c#L173-L199 - os_preserves->avx512_registers = - GetDarwinSysCtlByName("hw.optional.avx512f"); -#else - os_preserves->avx512_registers = HasZmmOsXSave(xcr0_eax); -#endif // CPU_FEATURES_OS_DARWIN - os_preserves->amx_registers = HasTmmOsXSave(xcr0_eax); - - if (os_preserves->sse_registers) - { - features->sse = IsBitSet(leaf_1.edx, 25); - features->sse2 = IsBitSet(leaf_1.edx, 26); - features->sse3 = IsBitSet(leaf_1.ecx, 0); - features->ssse3 = IsBitSet(leaf_1.ecx, 9); - features->sse4_1 = IsBitSet(leaf_1.ecx, 19); - features->sse4_2 = IsBitSet(leaf_1.ecx, 20); - } - if (os_preserves->avx_registers) - { - features->fma3 = IsBitSet(leaf_1.ecx, 12); - features->avx = IsBitSet(leaf_1.ecx, 28); - features->avx2 = IsBitSet(leaf_7.ebx, 5); - } - if (os_preserves->avx512_registers) - { - features->avx512f = IsBitSet(leaf_7.ebx, 16); - features->avx512cd = IsBitSet(leaf_7.ebx, 28); - features->avx512er = IsBitSet(leaf_7.ebx, 27); - features->avx512pf = IsBitSet(leaf_7.ebx, 26); - features->avx512bw = IsBitSet(leaf_7.ebx, 30); - features->avx512dq = IsBitSet(leaf_7.ebx, 17); - features->avx512vl = IsBitSet(leaf_7.ebx, 31); - features->avx512ifma = IsBitSet(leaf_7.ebx, 21); - features->avx512vbmi = IsBitSet(leaf_7.ecx, 1); - features->avx512vbmi2 = IsBitSet(leaf_7.ecx, 6); - features->avx512vnni = IsBitSet(leaf_7.ecx, 11); - features->avx512bitalg = IsBitSet(leaf_7.ecx, 12); - features->avx512vpopcntdq = IsBitSet(leaf_7.ecx, 14); - features->avx512_4vnniw = IsBitSet(leaf_7.edx, 2); - features->avx512_4vbmi2 = IsBitSet(leaf_7.edx, 3); - features->avx512_second_fma = HasSecondFMA(info->model); - 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); - } - if (os_preserves->amx_registers) - { - features->amx_bf16 = IsBitSet(leaf_7.edx, 22); - features->amx_tile = IsBitSet(leaf_7.edx, 24); - features->amx_int8 = IsBitSet(leaf_7.edx, 25); - } - } - else - { - // When XCR0 is not available (Atom based or older cpus) we need to defer to - // the OS via custom code. -#if defined(CPU_FEATURES_OS_WINDOWS) - // Handling Windows platform through IsProcessorFeaturePresent. - // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent - features->sse = - GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); - features->sse2 = - GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); - features->sse3 = - GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) - // Handling Darwin platform through sysctlbyname. - features->sse = GetDarwinSysCtlByName("hw.optional.sse"); - features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2"); - features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3"); - features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3"); - features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1"); - features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2"); -#elif defined(CPU_FEATURES_OS_FREEBSD) - // Handling FreeBSD platform through parsing /var/run/dmesg.boot. - const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (bool stop = false; !stop;) - { - const LineResult result = StackLineReader_NextLine(&reader); - if (result.eof) stop = true; - const StringView line = result.line; - if (!CpuFeatures_StringView_StartsWith(line, str(" Features"))) - continue; - // Lines of interests are of the following form: - // " Features=0x1783fbff" - // We first extract the comma separated values between angle brackets. - StringView csv = result.line; - int index = CpuFeatures_StringView_IndexOfChar(csv, '<'); - if (index >= 0) csv = CpuFeatures_StringView_PopFront(csv, index + 1); - if (csv.size > 0 && CpuFeatures_StringView_Back(csv) == '>') - csv = CpuFeatures_StringView_PopBack(csv, 1); - if (CpuFeatures_StringView_HasWord(csv, "SSE", ',')) - features->sse = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE2", ',')) - features->sse2 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE3", ',')) - features->sse3 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSSE3", ',')) - features->ssse3 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE4.1", ',')) - features->sse4_1 = true; - if (CpuFeatures_StringView_HasWord(csv, "SSE4.2", ',')) - features->sse4_2 = true; - } - CpuFeatures_CloseFile(fd); - } -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) - // Handling Linux platform through /proc/cpuinfo. - const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); - if (fd >= 0) - { - StackLineReader reader; - StackLineReader_Initialize(&reader, fd); - for (bool stop = false; !stop;) - { - const LineResult result = StackLineReader_NextLine(&reader); - if (result.eof) stop = true; - const StringView line = result.line; - StringView key, value; - if (!CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) - continue; - if (!CpuFeatures_StringView_IsEquals(key, str("flags"))) continue; - features->sse = CpuFeatures_StringView_HasWord(value, "sse", ' '); - features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2", ' '); - features->sse3 = CpuFeatures_StringView_HasWord(value, "sse3", ' '); - features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3", ' '); - features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1", ' '); - features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2", ' '); - break; - } - CpuFeatures_CloseFile(fd); - } -#else -#error "Unsupported fallback detection of SSE OS support." -#endif - // Now that we have queried the OS for SSE support, we report this back to - // os_preserves. This is needed in case of AMD CPU's to enable testing of - // sse4a (See ParseExtraAMDCpuId below). - if (features->sse) os_preserves->sse_registers = true; - } -} - -// Reference -// https://en.wikipedia.org/wiki/CPUID#EAX=80000000h:_Get_Highest_Extended_Function_Implemented. -static Leaf GetLeafByIdAMD(uint32_t leaf_id) -{ - uint32_t max_extended = CpuId(0x80000000).eax; - return SafeCpuId(max_extended, leaf_id); -} - -static void ParseExtraAMDCpuId(X86Info* info, OsPreserves os_preserves) -{ - const Leaf leaf_80000001 = GetLeafByIdAMD(0x80000001); - - X86Features* const features = &info->features; - - if (os_preserves.sse_registers) - { - features->sse4a = IsBitSet(leaf_80000001.ecx, 6); - } - - if (os_preserves.avx_registers) - { - features->fma4 = IsBitSet(leaf_80000001.ecx, 16); - } -} - -static const X86Info kEmptyX86Info; -static const OsPreserves kEmptyOsPreserves; - -X86Info GetX86Info(void) -{ - X86Info info = kEmptyX86Info; - const Leaf leaf_0 = CpuId(0); - const bool is_intel = IsVendor(leaf_0, CPU_FEATURES_VENDOR_GENUINE_INTEL); - const bool is_amd = IsVendor(leaf_0, CPU_FEATURES_VENDOR_AUTHENTIC_AMD); - const bool is_hygon = IsVendor(leaf_0, CPU_FEATURES_VENDOR_HYGON_GENUINE); - SetVendor(leaf_0, info.vendor); - if (is_intel || is_amd || is_hygon) - { - OsPreserves os_preserves = kEmptyOsPreserves; - const uint32_t max_cpuid_leaf = leaf_0.eax; - ParseCpuId(max_cpuid_leaf, &info, &os_preserves); - if (is_amd || is_hygon) - { - ParseExtraAMDCpuId(&info, os_preserves); - } - } - return info; -} - CacheInfo GetX86CacheInfo(void) { CacheInfo info = kEmptyCacheInfo; @@ -1532,342 +1649,127 @@ CacheInfo GetX86CacheInfo(void) return info; } -#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) - -X86Microarchitecture GetX86Microarchitecture(const X86Info* info) -{ - if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_GENUINE_INTEL)) - { - switch (CPUID(info->family, info->model)) - { - case CPUID(0x06, 0x1C): // Intel(R) Atom(TM) CPU 230 @ 1.60GHz - case CPUID(0x06, 0x35): - case CPUID(0x06, 0x36): - case CPUID(0x06, 0x70): // https://en.wikichip.org/wiki/intel/atom/230 - // https://en.wikipedia.org/wiki/Bonnell_(microarchitecture) - return INTEL_ATOM_BNL; - case CPUID(0x06, 0x37): - case CPUID(0x06, 0x4C): - // https://en.wikipedia.org/wiki/Silvermont - return INTEL_ATOM_SMT; - case CPUID(0x06, 0x5C): - // https://en.wikipedia.org/wiki/Goldmont - return INTEL_ATOM_GMT; - case CPUID(0x06, 0x0F): - case CPUID(0x06, 0x16): - // https://en.wikipedia.org/wiki/Intel_Core_(microarchitecture) - return INTEL_CORE; - case CPUID(0x06, 0x17): - case CPUID(0x06, 0x1D): - // https://en.wikipedia.org/wiki/Penryn_(microarchitecture) - return INTEL_PNR; - case CPUID(0x06, 0x1A): - case CPUID(0x06, 0x1E): - case CPUID(0x06, 0x1F): - case CPUID(0x06, 0x2E): - // https://en.wikipedia.org/wiki/Nehalem_(microarchitecture) - return INTEL_NHM; - case CPUID(0x06, 0x25): - case CPUID(0x06, 0x2C): - case CPUID(0x06, 0x2F): - // https://en.wikipedia.org/wiki/Westmere_(microarchitecture) - return INTEL_WSM; - case CPUID(0x06, 0x2A): - case CPUID(0x06, 0x2D): - // https://en.wikipedia.org/wiki/Sandy_Bridge#Models_and_steppings - return INTEL_SNB; - case CPUID(0x06, 0x3A): - case CPUID(0x06, 0x3E): - // https://en.wikipedia.org/wiki/Ivy_Bridge_(microarchitecture)#Models_and_steppings - return INTEL_IVB; - case CPUID(0x06, 0x3C): - case CPUID(0x06, 0x3F): - case CPUID(0x06, 0x45): - case CPUID(0x06, 0x46): - // https://en.wikipedia.org/wiki/Haswell_(microarchitecture) - return INTEL_HSW; - case CPUID(0x06, 0x3D): - case CPUID(0x06, 0x47): - case CPUID(0x06, 0x4F): - case CPUID(0x06, 0x56): - // 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, 0x66): - // https://en.wikipedia.org/wiki/Cannon_Lake_(microarchitecture) - return INTEL_CNL; - case CPUID(0x06, 0x7D): // client - case CPUID(0x06, 0x7E): // client - case CPUID(0x06, 0x9D): // NNP-I - case CPUID(0x06, 0x6A): // server - case CPUID(0x06, 0x6C): // server - // https://en.wikipedia.org/wiki/Ice_Lake_(microprocessor) - return INTEL_ICL; - case CPUID(0x06, 0x8C): - case CPUID(0x06, 0x8D): - // https://en.wikipedia.org/wiki/Tiger_Lake_(microarchitecture) - return INTEL_TGL; - case CPUID(0x06, 0x8F): - // https://en.wikipedia.org/wiki/Sapphire_Rapids - return INTEL_SPR; - case CPUID(0x06, 0x8E): - switch (info->stepping) - { - case 9: - return INTEL_KBL; // https://en.wikipedia.org/wiki/Kaby_Lake - case 10: - return INTEL_CFL; // https://en.wikipedia.org/wiki/Coffee_Lake - case 11: - return INTEL_WHL; // https://en.wikipedia.org/wiki/Whiskey_Lake_(microarchitecture) - default: - return X86_UNKNOWN; - } - case CPUID(0x06, 0x9E): - if (info->stepping > 9) - { - // https://en.wikipedia.org/wiki/Coffee_Lake - return INTEL_CFL; - } - else - { - // https://en.wikipedia.org/wiki/Kaby_Lake - return INTEL_KBL; - } - default: - return X86_UNKNOWN; - } - } - if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_AUTHENTIC_AMD)) - { - switch (CPUID(info->family, info->model)) - { - // https://en.wikichip.org/wiki/amd/cpuid - case CPUID(0xF, 0x04): - case CPUID(0xF, 0x05): - case CPUID(0xF, 0x07): - case CPUID(0xF, 0x08): - case CPUID(0xF, 0x0C): - case CPUID(0xF, 0x0E): - case CPUID(0xF, 0x0F): - case CPUID(0xF, 0x14): - case CPUID(0xF, 0x15): - case CPUID(0xF, 0x17): - case CPUID(0xF, 0x18): - case CPUID(0xF, 0x1B): - case CPUID(0xF, 0x1C): - case CPUID(0xF, 0x1F): - case CPUID(0xF, 0x21): - case CPUID(0xF, 0x23): - case CPUID(0xF, 0x24): - case CPUID(0xF, 0x25): - case CPUID(0xF, 0x27): - case CPUID(0xF, 0x2B): - case CPUID(0xF, 0x2C): - case CPUID(0xF, 0x2F): - case CPUID(0xF, 0x41): - case CPUID(0xF, 0x43): - case CPUID(0xF, 0x48): - case CPUID(0xF, 0x4B): - case CPUID(0xF, 0x4C): - case CPUID(0xF, 0x4F): - case CPUID(0xF, 0x5D): - case CPUID(0xF, 0x5F): - case CPUID(0xF, 0x68): - case CPUID(0xF, 0x6B): - case CPUID(0xF, 0x6F): - case CPUID(0xF, 0x7F): - case CPUID(0xF, 0xC1): - return AMD_HAMMER; - case CPUID(0x10, 0x02): - case CPUID(0x10, 0x04): - case CPUID(0x10, 0x05): - case CPUID(0x10, 0x06): - case CPUID(0x10, 0x08): - case CPUID(0x10, 0x09): - case CPUID(0x10, 0x0A): - return AMD_K10; - case CPUID(0x11, 0x03): - // http://developer.amd.com/wordpress/media/2012/10/41788.pdf - return AMD_K11; - case CPUID(0x12, 0x01): - // https://www.amd.com/system/files/TechDocs/44739_12h_Rev_Gd.pdf - return AMD_K12; - case CPUID(0x14, 0x00): - case CPUID(0x14, 0x01): - case CPUID(0x14, 0x02): - // https://www.amd.com/system/files/TechDocs/47534_14h_Mod_00h-0Fh_Rev_Guide.pdf - return AMD_BOBCAT; - case CPUID(0x15, 0x01): - // https://en.wikichip.org/wiki/amd/microarchitectures/bulldozer - return AMD_BULLDOZER; - case CPUID(0x15, 0x02): - case CPUID(0x15, 0x11): - case CPUID(0x15, 0x13): - // https://en.wikichip.org/wiki/amd/microarchitectures/piledriver - return AMD_PILEDRIVER; - case CPUID(0x15, 0x30): - case CPUID(0x15, 0x38): - // https://en.wikichip.org/wiki/amd/microarchitectures/steamroller - return AMD_STREAMROLLER; - case CPUID(0x15, 0x60): - case CPUID(0x15, 0x65): - case CPUID(0x15, 0x70): - // https://en.wikichip.org/wiki/amd/microarchitectures/excavator - return AMD_EXCAVATOR; - case CPUID(0x16, 0x00): - return AMD_JAGUAR; - case CPUID(0x16, 0x30): - return AMD_PUMA; - case CPUID(0x17, 0x01): - case CPUID(0x17, 0x11): - case CPUID(0x17, 0x18): - case CPUID(0x17, 0x20): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen - return AMD_ZEN; - case CPUID(0x17, 0x08): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen%2B - return AMD_ZEN_PLUS; - case CPUID(0x17, 0x31): - case CPUID(0x17, 0x47): - case CPUID(0x17, 0x60): - case CPUID(0x17, 0x68): - case CPUID(0x17, 0x71): - case CPUID(0x17, 0x90): - case CPUID(0x17, 0x98): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen_2 - return AMD_ZEN2; - case CPUID(0x19, 0x01): - case CPUID(0x19, 0x21): - case CPUID(0x19, 0x30): - case CPUID(0x19, 0x40): - case CPUID(0x19, 0x50): - // https://en.wikichip.org/wiki/amd/microarchitectures/zen_3 - return AMD_ZEN3; - default: - return X86_UNKNOWN; - } - } - if (IsVendorByX86Info(info, CPU_FEATURES_VENDOR_HYGON_GENUINE)) - { - switch (CPUID(info->family, info->model)) - { - case CPUID(0x18, 0x00): - return AMD_ZEN; - } - } - return X86_UNKNOWN; -} - -void FillX86BrandString(char brand_string[49]) -{ - const Leaf leaf_ext_0 = CpuId(0x80000000); - const uint32_t max_cpuid_leaf_ext = leaf_ext_0.eax; - const Leaf leaves[3] = { - SafeCpuId(max_cpuid_leaf_ext, 0x80000002), - SafeCpuId(max_cpuid_leaf_ext, 0x80000003), - SafeCpuId(max_cpuid_leaf_ext, 0x80000004), - }; -#if __STDC_VERSION__ >= 201112L - _Static_assert(sizeof(leaves) == 48, "Leaves must be packed"); -#endif - CpuFeatures_StringView_CopyString(view((const char*)leaves, sizeof(leaves)), - brand_string, 49); -} - //////////////////////////////////////////////////////////////////////////////// -// Introspection functions +// Definitions for introspection. +//////////////////////////////////////////////////////////////////////////////// +#define INTROSPECTION_TABLE \ + LINE(X86_FPU, fpu, , , ) \ + LINE(X86_TSC, tsc, , , ) \ + LINE(X86_CX8, cx8, , , ) \ + LINE(X86_CLFSH, clfsh, , , ) \ + LINE(X86_MMX, mmx, , , ) \ + LINE(X86_AES, aes, , , ) \ + LINE(X86_ERMS, erms, , , ) \ + LINE(X86_F16C, f16c, , , ) \ + LINE(X86_FMA4, fma4, , , ) \ + LINE(X86_FMA3, fma3, , , ) \ + LINE(X86_VAES, vaes, , , ) \ + LINE(X86_VPCLMULQDQ, vpclmulqdq, , , ) \ + LINE(X86_BMI1, bmi1, , , ) \ + LINE(X86_HLE, hle, , , ) \ + LINE(X86_BMI2, bmi2, , , ) \ + LINE(X86_RTM, rtm, , , ) \ + LINE(X86_RDSEED, rdseed, , , ) \ + LINE(X86_CLFLUSHOPT, clflushopt, , , ) \ + LINE(X86_CLWB, clwb, , , ) \ + LINE(X86_SSE, sse, , , ) \ + LINE(X86_SSE2, sse2, , , ) \ + LINE(X86_SSE3, sse3, , , ) \ + LINE(X86_SSSE3, ssse3, , , ) \ + LINE(X86_SSE4_1, sse4_1, , , ) \ + LINE(X86_SSE4_2, sse4_2, , , ) \ + LINE(X86_SSE4A, sse4a, , , ) \ + LINE(X86_AVX, avx, , , ) \ + LINE(X86_AVX2, avx2, , , ) \ + LINE(X86_AVX512F, avx512f, , , ) \ + LINE(X86_AVX512CD, avx512cd, , , ) \ + LINE(X86_AVX512ER, avx512er, , , ) \ + LINE(X86_AVX512PF, avx512pf, , , ) \ + LINE(X86_AVX512BW, avx512bw, , , ) \ + LINE(X86_AVX512DQ, avx512dq, , , ) \ + LINE(X86_AVX512VL, avx512vl, , , ) \ + LINE(X86_AVX512IFMA, avx512ifma, , , ) \ + LINE(X86_AVX512VBMI, avx512vbmi, , , ) \ + LINE(X86_AVX512VBMI2, avx512vbmi2, , , ) \ + LINE(X86_AVX512VNNI, avx512vnni, , , ) \ + LINE(X86_AVX512BITALG, avx512bitalg, , , ) \ + LINE(X86_AVX512VPOPCNTDQ, avx512vpopcntdq, , , ) \ + LINE(X86_AVX512_4VNNIW, avx512_4vnniw, , , ) \ + LINE(X86_AVX512_4VBMI2, avx512_4vbmi2, , , ) \ + LINE(X86_AVX512_SECOND_FMA, avx512_second_fma, , , ) \ + LINE(X86_AVX512_4FMAPS, avx512_4fmaps, , , ) \ + LINE(X86_AVX512_BF16, avx512_bf16, , , ) \ + LINE(X86_AVX512_VP2INTERSECT, avx512_vp2intersect, , , ) \ + LINE(X86_AMX_BF16, amx_bf16, , , ) \ + LINE(X86_AMX_TILE, amx_tile, , , ) \ + LINE(X86_AMX_INT8, amx_int8, , , ) \ + LINE(X86_PCLMULQDQ, pclmulqdq, , , ) \ + LINE(X86_SMX, smx, , , ) \ + LINE(X86_SGX, sgx, , , ) \ + LINE(X86_CX16, cx16, , , ) \ + LINE(X86_SHA, sha, , , ) \ + LINE(X86_POPCNT, popcnt, , , ) \ + LINE(X86_MOVBE, movbe, , , ) \ + LINE(X86_RDRND, rdrnd, , , ) \ + LINE(X86_DCA, dca, , , ) \ + LINE(X86_SS, ss, , , ) \ + LINE(X86_ADX, adx, , , ) +#define INTROSPECTION_PREFIX X86 +#define INTROSPECTION_ENUM_PREFIX X86 +#include "define_introspection.inl" -int GetX86FeaturesEnumValue(const X86Features* features, - X86FeaturesEnum value) -{ - if (value >= X86_LAST_) return false; - return kGetters[value](features); -} +#define X86_MICROARCHITECTURE_NAMES \ + LINE(X86_UNKNOWN) \ + LINE(INTEL_80486) \ + LINE(INTEL_P5) \ + LINE(INTEL_LAKEMONT) \ + LINE(INTEL_CORE) \ + LINE(INTEL_PNR) \ + LINE(INTEL_NHM) \ + LINE(INTEL_ATOM_BNL) \ + LINE(INTEL_WSM) \ + LINE(INTEL_SNB) \ + LINE(INTEL_IVB) \ + LINE(INTEL_ATOM_SMT) \ + LINE(INTEL_HSW) \ + LINE(INTEL_BDW) \ + LINE(INTEL_SKL) \ + LINE(INTEL_ATOM_GMT) \ + LINE(INTEL_KBL) \ + LINE(INTEL_CFL) \ + LINE(INTEL_WHL) \ + LINE(INTEL_CNL) \ + LINE(INTEL_ICL) \ + LINE(INTEL_TGL) \ + LINE(INTEL_SPR) \ + LINE(INTEL_ADL) \ + LINE(INTEL_RCL) \ + LINE(INTEL_KNIGHTS_M) \ + LINE(INTEL_KNIGHTS_L) \ + LINE(INTEL_KNIGHTS_F) \ + LINE(INTEL_KNIGHTS_C) \ + LINE(INTEL_NETBURST) \ + LINE(AMD_HAMMER) \ + LINE(AMD_K10) \ + LINE(AMD_K11) \ + LINE(AMD_K12) \ + LINE(AMD_BOBCAT) \ + LINE(AMD_PILEDRIVER) \ + LINE(AMD_STREAMROLLER) \ + LINE(AMD_EXCAVATOR) \ + LINE(AMD_BULLDOZER) \ + LINE(AMD_JAGUAR) \ + LINE(AMD_PUMA) \ + LINE(AMD_ZEN) \ + LINE(AMD_ZEN_PLUS) \ + LINE(AMD_ZEN2) \ + LINE(AMD_ZEN3) -const char* GetX86FeaturesEnumName(X86FeaturesEnum value) +const char* GetX86MicroarchitectureName(X86Microarchitecture value) { - if (value >= X86_LAST_) return "unknown_feature"; - return kCpuInfoFlags[value]; -} - -const char* GetX86MicroarchitectureName(X86Microarchitecture uarch) -{ - switch (uarch) - { - case X86_UNKNOWN: - return "X86_UNKNOWN"; - case INTEL_CORE: - return "INTEL_CORE"; - case INTEL_PNR: - return "INTEL_PNR"; - case INTEL_NHM: - return "INTEL_NHM"; - case INTEL_ATOM_BNL: - return "INTEL_ATOM_BNL"; - case INTEL_WSM: - return "INTEL_WSM"; - case INTEL_SNB: - return "INTEL_SNB"; - case INTEL_IVB: - return "INTEL_IVB"; - case INTEL_ATOM_SMT: - return "INTEL_ATOM_SMT"; - case INTEL_HSW: - return "INTEL_HSW"; - case INTEL_BDW: - return "INTEL_BDW"; - case INTEL_SKL: - return "INTEL_SKL"; - case INTEL_ATOM_GMT: - return "INTEL_ATOM_GMT"; - case INTEL_KBL: - return "INTEL_KBL"; - case INTEL_CFL: - return "INTEL_CFL"; - case INTEL_WHL: - return "INTEL_WHL"; - case INTEL_CNL: - return "INTEL_CNL"; - case INTEL_ICL: - return "INTEL_ICL"; - case INTEL_TGL: - return "INTEL_TGL"; - case INTEL_SPR: - return "INTEL_SPR"; - case AMD_HAMMER: - return "AMD_HAMMER"; - case AMD_K10: - return "AMD_K10"; - case AMD_K11: - return "AMD_K11"; - case AMD_K12: - return "AMD_K12"; - case AMD_BOBCAT: - return "AMD_BOBCAT"; - case AMD_PILEDRIVER: - return "AMD_PILEDRIVER"; - case AMD_STREAMROLLER: - return "AMD_STREAMROLLER"; - case AMD_EXCAVATOR: - return "AMD_EXCAVATOR"; - case AMD_BULLDOZER: - return "AMD_BULLDOZER"; - case AMD_PUMA: - return "AMD_PUMA"; - case AMD_JAGUAR: - return "AMD_JAGUAR"; - case AMD_ZEN: - return "AMD_ZEN"; - case AMD_ZEN_PLUS: - return "AMD_ZEN_PLUS"; - case AMD_ZEN2: - return "AMD_ZEN2"; - case AMD_ZEN3: - return "AMD_ZEN3"; - } - return "unknown microarchitecture"; +#define LINE(ENUM) [ENUM] = STRINGIZE(ENUM), + static const char* kMicroarchitectureNames[] = {X86_MICROARCHITECTURE_NAMES}; +#undef LINE + if (value >= X86_MICROARCHITECTURE_LAST_) return "unknown microarchitecture"; + return kMicroarchitectureNames[value]; } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c new file mode 100644 index 000000000..14ab23dfc --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_freebsd.c @@ -0,0 +1,60 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#ifdef CPU_FEATURES_OS_FREEBSD + +#include "impl_x86__base_implementation.inl" + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + (void)os_preserves; + // No override +} + +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" + +static void DetectFeaturesFromOs(X86Features* features) +{ + // Handling FreeBSD platform through parsing /var/run/dmesg.boot. + const int fd = CpuFeatures_OpenFile("/var/run/dmesg.boot"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (bool stop = false; !stop;) + { + const LineResult result = StackLineReader_NextLine(&reader); + if (result.eof) stop = true; + const StringView line = result.line; + if (!CpuFeatures_StringView_StartsWith(line, str(" Features"))) continue; + // Lines of interests are of the following form: + // " Features=0x1783fbff" + // We first extract the comma separated values between angle brackets. + StringView csv = result.line; + int index = CpuFeatures_StringView_IndexOfChar(csv, '<'); + if (index >= 0) csv = CpuFeatures_StringView_PopFront(csv, index + 1); + if (csv.size > 0 && CpuFeatures_StringView_Back(csv) == '>') + csv = CpuFeatures_StringView_PopBack(csv, 1); + if (CpuFeatures_StringView_HasWord(csv, "SSE", ',')) features->sse = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE2", ',')) + features->sse2 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE3", ',')) + features->sse3 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSSE3", ',')) + features->ssse3 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE4.1", ',')) + features->sse4_1 = true; + if (CpuFeatures_StringView_HasWord(csv, "SSE4.2", ',')) + features->sse4_2 = true; + } + CpuFeatures_CloseFile(fd); + } +} + +#endif // CPU_FEATURES_OS_FREEBSD +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c new file mode 100644 index 000000000..4eb8b378e --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_linux_or_android.c @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) + +#include "impl_x86__base_implementation.inl" + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + (void)os_preserves; + // No override +} + +#include "internal/filesystem.h" +#include "internal/stack_line_reader.h" +#include "internal/string_view.h" +static void DetectFeaturesFromOs(X86Features* features) +{ + // Handling Linux platform through /proc/cpuinfo. + const int fd = CpuFeatures_OpenFile("/proc/cpuinfo"); + if (fd >= 0) + { + StackLineReader reader; + StackLineReader_Initialize(&reader, fd); + for (bool stop = false; !stop;) + { + const LineResult result = StackLineReader_NextLine(&reader); + if (result.eof) stop = true; + const StringView line = result.line; + StringView key, value; + if (!CpuFeatures_StringView_GetAttributeKeyValue(line, &key, &value)) + continue; + if (!CpuFeatures_StringView_IsEquals(key, str("flags"))) continue; + features->sse = CpuFeatures_StringView_HasWord(value, "sse", ' '); + features->sse2 = CpuFeatures_StringView_HasWord(value, "sse2", ' '); + features->sse3 = CpuFeatures_StringView_HasWord(value, "sse3", ' '); + features->ssse3 = CpuFeatures_StringView_HasWord(value, "ssse3", ' '); + features->sse4_1 = CpuFeatures_StringView_HasWord(value, "sse4_1", ' '); + features->sse4_2 = CpuFeatures_StringView_HasWord(value, "sse4_2", ' '); + break; + } + CpuFeatures_CloseFile(fd); + } +} + +#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c new file mode 100644 index 000000000..01f7b7c52 --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_macos.c @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#ifdef CPU_FEATURES_OS_MACOS + +#include "impl_x86__base_implementation.inl" + +#if !defined(HAVE_SYSCTLBYNAME) +#error "Darwin needs support for sysctlbyname" +#endif +#include + +#if defined(CPU_FEATURES_MOCK_CPUID_X86) +extern bool GetDarwinSysCtlByName(const char*); +#else // CPU_FEATURES_MOCK_CPUID_X86 +static bool GetDarwinSysCtlByName(const char* name) +{ + int enabled; + size_t enabled_len = sizeof(enabled); + const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); + return failure ? false : enabled; +} +#endif + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + // On Darwin AVX512 support is On-demand. + // We have to query the OS instead of querying the Zmm save/restore state. + // https://github.com/apple/darwin-xnu/blob/8f02f2a044b9bb1ad951987ef5bab20ec9486310/osfmk/i386/fpu.c#L173-L199 + os_preserves->avx512_registers = GetDarwinSysCtlByName("hw.optional.avx512f"); +} + +static void DetectFeaturesFromOs(X86Features* features) +{ + // Handling Darwin platform through sysctlbyname. + features->sse = GetDarwinSysCtlByName("hw.optional.sse"); + features->sse2 = GetDarwinSysCtlByName("hw.optional.sse2"); + features->sse3 = GetDarwinSysCtlByName("hw.optional.sse3"); + features->ssse3 = GetDarwinSysCtlByName("hw.optional.supplementalsse3"); + features->sse4_1 = GetDarwinSysCtlByName("hw.optional.sse4_1"); + features->sse4_2 = GetDarwinSysCtlByName("hw.optional.sse4_2"); +} + +#endif // CPU_FEATURES_OS_MACOS +#endif // CPU_FEATURES_ARCH_X86 diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c new file mode 100644 index 000000000..c450e6ece --- /dev/null +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/impl_x86_windows.c @@ -0,0 +1,41 @@ +// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-License-Identifier: Apache-2.0 + +#include "cpu_features_macros.h" + +#ifdef CPU_FEATURES_ARCH_X86 +#ifdef CPU_FEATURES_OS_WINDOWS + +#include "impl_x86__base_implementation.inl" + +static void OverrideOsPreserves(OsPreserves* os_preserves) +{ + (void)os_preserves; + // No override +} + +#include // IsProcessorFeaturePresent + +#if defined(CPU_FEATURES_MOCK_CPUID_X86) +extern bool GetWindowsIsProcessorFeaturePresent(DWORD); +#else // CPU_FEATURES_MOCK_CPUID_X86 +static bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) +{ + return IsProcessorFeaturePresent(ProcessorFeature); +} +#endif + +static void DetectFeaturesFromOs(X86Features* features) +{ + // Handling Windows platform through IsProcessorFeaturePresent. + // https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent + features->sse = + GetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); + features->sse2 = + GetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); + features->sse3 = + GetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); +} + +#endif // CPU_FEATURES_OS_WINDOWS +#endif // CPU_FEATURES_ARCH_X86 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 db72230c7..778c80505 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 @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2017 Google LLC +// SPDX-FileCopyrightText: 2021 Google LLC // SPDX-License-Identifier: Apache-2.0 // This program dumps current host data to the standard output. 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 6f8f2f397..f5330653c 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 @@ -50,7 +50,13 @@ add_test(NAME stack_line_reader_test COMMAND stack_line_reader_test) ##------------------------------------------------------------------------------ ## cpuinfo_x86_test if(PROCESSOR_IS_X86) - add_executable(cpuinfo_x86_test cpuinfo_x86_test.cc ../src/cpuinfo_x86.c) + add_executable(cpuinfo_x86_test + cpuinfo_x86_test.cc + ../src/impl_x86_freebsd.c + ../src/impl_x86_linux_or_android.c + ../src/impl_x86_macos.c + ../src/impl_x86_windows.c + ) target_compile_definitions(cpuinfo_x86_test PUBLIC CPU_FEATURES_MOCK_CPUID_X86) if(APPLE) target_compile_definitions(cpuinfo_x86_test PRIVATE HAVE_SYSCTLBYNAME) @@ -61,32 +67,28 @@ endif() ##------------------------------------------------------------------------------ ## cpuinfo_arm_test if(PROCESSOR_IS_ARM) - add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/cpuinfo_arm.c) + add_executable(cpuinfo_arm_test cpuinfo_arm_test.cc ../src/impl_arm_linux_or_android.c) target_link_libraries(cpuinfo_arm_test all_libraries) add_test(NAME cpuinfo_arm_test COMMAND cpuinfo_arm_test) endif() ##------------------------------------------------------------------------------ ## cpuinfo_aarch64_test if(PROCESSOR_IS_AARCH64) - add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c) - if(APPLE) - target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_ARM64) - target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME) - endif() + add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/impl_aarch64_linux_or_android.c) target_link_libraries(cpuinfo_aarch64_test all_libraries) add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) endif() ##------------------------------------------------------------------------------ ## cpuinfo_mips_test if(PROCESSOR_IS_MIPS) - add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/cpuinfo_mips.c) + add_executable(cpuinfo_mips_test cpuinfo_mips_test.cc ../src/impl_mips_linux_or_android.c) target_link_libraries(cpuinfo_mips_test all_libraries) add_test(NAME cpuinfo_mips_test COMMAND cpuinfo_mips_test) endif() ##------------------------------------------------------------------------------ ## cpuinfo_ppc_test if(PROCESSOR_IS_POWER) - add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/cpuinfo_ppc.c) + add_executable(cpuinfo_ppc_test cpuinfo_ppc_test.cc ../src/impl_ppc_linux.c) target_link_libraries(cpuinfo_ppc_test all_libraries) add_test(NAME cpuinfo_ppc_test COMMAND cpuinfo_ppc_test) endif() 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 4c242cf8b..5ccd73306 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 @@ -16,6 +16,7 @@ namespace cpu_features { + class FakeCpu { public: @@ -41,7 +42,7 @@ public: xcr0_eax_ = os_backups_extended_registers ? -1 : 0; } -#if defined(CPU_FEATURES_OS_DARWIN) +#if defined(CPU_FEATURES_OS_MACOS) bool GetDarwinSysCtlByName(std::string name) const { return darwin_sysctlbyname_.count(name); @@ -51,7 +52,7 @@ public: { darwin_sysctlbyname_.insert(name); } -#endif // CPU_FEATURES_OS_DARWIN +#endif // CPU_FEATURES_OS_MACOS #if defined(CPU_FEATURES_OS_WINDOWS) bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) @@ -67,9 +68,9 @@ public: private: std::map, Leaf> cpuid_leaves_; -#if defined(CPU_FEATURES_OS_DARWIN) +#if defined(CPU_FEATURES_OS_MACOS) std::set darwin_sysctlbyname_; -#endif // CPU_FEATURES_OS_DARWIN +#endif // CPU_FEATURES_OS_MACOS #if defined(CPU_FEATURES_OS_WINDOWS) std::set windows_isprocessorfeaturepresent_; #endif // CPU_FEATURES_OS_WINDOWS @@ -91,12 +92,12 @@ extern "C" Leaf GetCpuidLeaf(uint32_t leaf_id, int ecx) extern "C" uint32_t GetXCR0Eax(void) { return cpu().GetXCR0Eax(); } -#if defined(CPU_FEATURES_OS_DARWIN) +#if defined(CPU_FEATURES_OS_MACOS) extern "C" bool GetDarwinSysCtlByName(const char* name) { return cpu().GetDarwinSysCtlByName(name); } -#endif // CPU_FEATURES_OS_DARWIN +#endif // CPU_FEATURES_OS_MACOS #if defined(CPU_FEATURES_OS_WINDOWS) extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) @@ -107,6 +108,7 @@ extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD ProcessorFeature) namespace { + class CpuidX86Test : public ::testing::Test { protected: @@ -800,7 +802,7 @@ TEST_F(CpuidX86Test, Nehalem) cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) +#elif defined(CPU_FEATURES_OS_MACOS) cpu().SetDarwinSysCtlByName("hw.optional.sse"); cpu().SetDarwinSysCtlByName("hw.optional.sse2"); cpu().SetDarwinSysCtlByName("hw.optional.sse3"); @@ -817,7 +819,7 @@ FreeBSD is a registered trademark of The FreeBSD Foundation. Features2=0x5eda2203 real memory = 2147418112 (2047 MB) )"); -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) +#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"(processor : flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 @@ -883,7 +885,7 @@ TEST_F(CpuidX86Test, Atom) cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) +#elif defined(CPU_FEATURES_OS_MACOS) cpu().SetDarwinSysCtlByName("hw.optional.sse"); cpu().SetDarwinSysCtlByName("hw.optional.sse2"); cpu().SetDarwinSysCtlByName("hw.optional.sse3"); @@ -900,7 +902,7 @@ FreeBSD is a registered trademark of The FreeBSD Foundation. Features2=0x5eda2203 real memory = 2147418112 (2047 MB) )"); -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) +#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"( flags : fpu mmx sse sse2 sse3 ssse3 sse4_1 sse4_2 @@ -1017,7 +1019,7 @@ TEST_F(CpuidX86Test, P3) cpu().SetOsBackupsExtendedRegisters(false); #if defined(CPU_FEATURES_OS_WINDOWS) cpu().SetWindowsIsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE); -#elif defined(CPU_FEATURES_OS_DARWIN) +#elif defined(CPU_FEATURES_OS_MACOS) cpu().SetDarwinSysCtlByName("hw.optional.sse"); #elif defined(CPU_FEATURES_OS_FREEBSD) auto& fs = GetEmptyFilesystem(); @@ -1028,7 +1030,7 @@ FreeBSD is a registered trademark of The FreeBSD Foundation. Features=0x1783fbff real memory = 2147418112 (2047 MB) )"); -#elif defined(CPU_FEATURES_OS_LINUX_OR_ANDROID) +#elif defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) auto& fs = GetEmptyFilesystem(); fs.CreateFile("/proc/cpuinfo", R"( flags : fpu mmx sse @@ -1065,6 +1067,68 @@ flags : fpu mmx sse #endif // !defined(CPU_FEATURES_OS_WINDOWS) } +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000480_486_CPUID.txt +TEST_F(CpuidX86Test, INTEL_80486) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000480, 0x00000000, 0x00000000, 0x00000003}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x04); + EXPECT_EQ(info.model, 0x08); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_80486); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000526_P54C_CPUID.txt +TEST_F(CpuidX86Test, INTEL_P54C) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000001, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000525, 0x00000000, 0x00000000, 0x000001BF}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x05); + EXPECT_EQ(info.model, 0x02); + EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_P5); +} + +// https://github.com/InstLatx64/InstLatx64/blob/master/GenuineIntel/GenuineIntel0000590_Lakemont_CPUID2.txt +TEST_F(CpuidX86Test, INTEL_LAKEMONT) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x00000002, 0x756E6547, 0x6c65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00000590, 0x00000000, 0x00010200, 0x8000237B}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + 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/GenuineIntel0050670_KnightsLanding_CPUID.txt +TEST_F(CpuidX86Test, INTEL_KNIGHTS_LANDING) +{ + cpu().SetLeaves({ + {{0x00000000, 0}, Leaf{0x0000000D, 0x756E6547, 0x6C65746E, 0x49656E69}}, + {{0x00000001, 0}, Leaf{0x00050670, 0x02FF0800, 0x7FF8F3BF, 0xBFEBFBFF}}, + }); + const auto info = GetX86Info(); + + EXPECT_STREQ(info.vendor, "GenuineIntel"); + EXPECT_EQ(info.family, 0x06); + EXPECT_EQ(info.model, 0x57); + EXPECT_EQ(GetX86Microarchitecture(&info), + X86Microarchitecture::INTEL_KNIGHTS_L); +} + // TODO(user): test what happens when xsave/osxsave are not present. // TODO(user): test what happens when xmm/ymm/zmm os support are not // present.