mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2024-10-30 22:56:22 +00:00
Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into osnma
This commit is contained in:
commit
1d295e0d51
1
.github/workflows/volk_gnsssdr_archs.yml
vendored
1
.github/workflows/volk_gnsssdr_archs.yml
vendored
@ -71,7 +71,6 @@ jobs:
|
||||
cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/
|
||||
echo "Build with $(nproc) thread(s)"
|
||||
make -j$(nproc)
|
||||
./cpu_features/list_cpu_features
|
||||
./apps/volk_gnsssdr-config-info --alignment
|
||||
./apps/volk_gnsssdr-config-info --avail-machines
|
||||
./apps/volk_gnsssdr-config-info --all-machines
|
||||
|
@ -1208,8 +1208,14 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
endif()
|
||||
include(GNUInstallDirs)
|
||||
set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES
|
||||
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv")
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)|(^ARM64)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
|
||||
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
|
||||
endif()
|
||||
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
|
||||
@ -1248,14 +1254,14 @@ if(NOT VOLKGNSSSDR_FOUND)
|
||||
set_package_properties(CPUFEATURES PROPERTIES
|
||||
DESCRIPTION "A cross platform C99 library to get CPU features at runtime (version: ${CPUFEATURES_VERSION})"
|
||||
)
|
||||
if((CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0")) # detect cpu_features without s390x / riscv support
|
||||
if((CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|(^riscv)|(^loongarch)") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0")) # detect cpu_features without s390x / riscv support
|
||||
set(ENABLE_CPUFEATURES OFF)
|
||||
endif()
|
||||
else()
|
||||
set_package_properties(CPUFEATURES PROPERTIES
|
||||
DESCRIPTION "A cross platform C99 library to get CPU features at runtime"
|
||||
)
|
||||
if(DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3") # avoid clash with volk's cpufeatures.
|
||||
if((DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3") OR (CMAKE_VERSION VERSION_LESS "3.13")) # avoid clash with volk's cpufeatures.
|
||||
set(ENABLE_CPUFEATURES OFF)
|
||||
else()
|
||||
set_package_properties(CPUFEATURES PROPERTIES
|
||||
|
@ -31,6 +31,10 @@ All notable changes to GNSS-SDR will be documented in this file.
|
||||
- `geohash`, an
|
||||
[encoded geographic location](https://en.wikipedia.org/wiki/Geohash).
|
||||
|
||||
### Improvements in Portability:
|
||||
|
||||
- Updated local `cpu_features` library to v0.9.0.
|
||||
|
||||
### Improvements in Repeatability:
|
||||
|
||||
- A Kalman filter is now available in the PVT block, smoothing the outputs of a
|
||||
|
@ -257,8 +257,14 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortex")
|
||||
endif()
|
||||
|
||||
# cpu_features - sensible defaults, user settable option
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES
|
||||
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv")
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)|(^ARM64)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv" OR
|
||||
CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
|
||||
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON)
|
||||
else()
|
||||
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF)
|
||||
@ -266,7 +272,7 @@ endif()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
|
||||
find_package(CPUFEATURES)
|
||||
if(CPUFEATURES_FOUND AND (CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0"))
|
||||
if(CPUFEATURES_FOUND AND (CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv|^loongarch") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0"))
|
||||
set(USE_CPU_FEATURES OFF)
|
||||
unset(CPUFEATURES_FOUND CACHE)
|
||||
message(STATUS "Building volk-gnsssdr without cpu_features, installed version v${CPUFEATURES_VERSION} does not support the ${CMAKE_SYSTEM_PROCESSOR} architecture")
|
||||
@ -274,6 +280,9 @@ if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
|
||||
set(USE_CPU_FEATURES ON)
|
||||
endif()
|
||||
if(NOT CPUFEATURES_FOUND)
|
||||
if(CMAKE_VERSION VERSION_LESS 3.13)
|
||||
message(STATUS "Building volk-gnsssdr without cpu_features")
|
||||
else()
|
||||
message(STATUS "Building volk-gnsssdr with cpu_features")
|
||||
set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE)
|
||||
set(BUILD_PIC ON CACHE BOOL
|
||||
@ -286,9 +295,19 @@ if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
|
||||
)
|
||||
set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
|
||||
set(BUILD_SHARED_LIBS OFF)
|
||||
if(ENABLE_INSTALL)
|
||||
set(ENABLE_INSTALL_AUX ${ENABLE_INSTALL})
|
||||
endif()
|
||||
set(ENABLE_INSTALL ON)
|
||||
add_subdirectory(cpu_features)
|
||||
unset(ENABLE_INSTALL)
|
||||
if(ENABLE_INSTALL_AUX)
|
||||
set(ENABLE_INSTALL ${ENABLE_INSTALL_AUX})
|
||||
unset(ENABLE_INSTALL_AUX)
|
||||
endif()
|
||||
set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
message(STATUS "Building volk-gnsssdr without cpu_features")
|
||||
endif()
|
||||
@ -307,7 +326,7 @@ if(NOT MAKO_FOUND)
|
||||
endif()
|
||||
|
||||
# Six
|
||||
if(Python2_VERSION OR (PYTHON_VERSION_STRING VERSION_LESS "3.0"))
|
||||
if(PYTHON_VERSION_STRING VERSION_LESS "3.0")
|
||||
if(NOT SIX_FOUND)
|
||||
message(FATAL_ERROR "six - python 2 and 3 compatibility library required to build VOLK_GNSSSDR")
|
||||
endif()
|
||||
|
@ -232,7 +232,7 @@ void read_results(std::vector<volk_gnsssdr_test_results_t> *results, std::string
|
||||
|
||||
if (single_kernel_result.size() == 3)
|
||||
{
|
||||
volk_gnsssdr_test_results_t kernel_result{};
|
||||
volk_gnsssdr_test_results_t kernel_result;
|
||||
kernel_result.name = std::string(single_kernel_result[0]);
|
||||
kernel_result.config_name = std::string(single_kernel_result[0]);
|
||||
kernel_result.best_arch_u = std::string(single_kernel_result[1]);
|
||||
|
@ -87,10 +87,10 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING)
|
||||
set(PYTHON_VERSION_MAJOR "${Python2_VERSION_MAJOR}")
|
||||
set(PYTHON_EXECUTABLE "${Python2_EXECUTABLE}")
|
||||
set(PYTHON_VERSION_STRING "${Python2_VERSION_MAJOR}.${Python2_VERSION_MINOR}")
|
||||
endif()
|
||||
volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND)
|
||||
else()
|
||||
if(PYTHON_EXECUTABLE)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# SPDX-FileCopyrightText: 2017 Google LLC
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
# option() honors normal variables.
|
||||
# see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html
|
||||
@ -9,11 +9,16 @@ if(POLICY CMP0077)
|
||||
cmake_policy(SET CMP0077 NEW)
|
||||
endif()
|
||||
|
||||
project(CpuFeatures VERSION 0.7.0 LANGUAGES C)
|
||||
project(CpuFeatures VERSION 0.9.0 LANGUAGES C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
if(CMAKE_VERSION LESS "3.1")
|
||||
add_compile_options("$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:-std=gnu99>")
|
||||
|
||||
# when cpu_features is included as subproject (i.e. using add_subdirectory(cpu_features))
|
||||
# in the source tree of a project that uses it, test rules are disabled.
|
||||
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
option(BUILD_TESTING "Enable test rule" OFF)
|
||||
else()
|
||||
option(BUILD_TESTING "Enable test rule" ON)
|
||||
endif()
|
||||
|
||||
# Default Build Type to be Release
|
||||
@ -23,6 +28,22 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
FORCE)
|
||||
endif()
|
||||
|
||||
# An option to enable/disable the executable target list_cpu_features.
|
||||
# Disable it by default if the project is included as a subproject.
|
||||
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
option(BUILD_EXECUTABLE "Build list_cpu_features executable." OFF)
|
||||
else()
|
||||
option(BUILD_EXECUTABLE "Build list_cpu_features executable." ON)
|
||||
endif()
|
||||
|
||||
# An option which allows to switch off install steps. Useful for embedding.
|
||||
# Disable it by default if the project is included as a subproject.
|
||||
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
option(ENABLE_INSTALL "Enable install targets" OFF)
|
||||
else()
|
||||
option(ENABLE_INSTALL "Enable install targets" ON)
|
||||
endif()
|
||||
|
||||
# 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).
|
||||
@ -57,14 +78,15 @@ set(PROCESSOR_IS_X86 FALSE)
|
||||
set(PROCESSOR_IS_POWER FALSE)
|
||||
set(PROCESSOR_IS_S390X FALSE)
|
||||
set(PROCESSOR_IS_RISCV FALSE)
|
||||
set(PROCESSOR_IS_LOONGARCH 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)|(^ARM64)")
|
||||
set(PROCESSOR_IS_AARCH64 TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
|
||||
set(PROCESSOR_IS_ARM TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)")
|
||||
set(PROCESSOR_IS_X86 TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
|
||||
set(PROCESSOR_IS_POWER TRUE)
|
||||
@ -72,6 +94,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
|
||||
set(PROCESSOR_IS_S390X TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv")
|
||||
set(PROCESSOR_IS_RISCV TRUE)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
|
||||
set(PROCESSOR_IS_LOONGARCH TRUE)
|
||||
endif()
|
||||
|
||||
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
||||
@ -85,6 +109,7 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h)
|
||||
elseif(PROCESSOR_IS_AARCH64)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h)
|
||||
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_aarch64.h)
|
||||
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/windows_utils.h)
|
||||
elseif(PROCESSOR_IS_X86)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h)
|
||||
@ -96,6 +121,8 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
|
||||
elseif(PROCESSOR_IS_RISCV)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h)
|
||||
elseif(PROCESSOR_IS_LOONGARCH)
|
||||
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_loongarch.h)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
@ -123,6 +150,8 @@ setup_include_and_definitions(utils)
|
||||
if(UNIX)
|
||||
add_library(unix_based_hardware_detection OBJECT
|
||||
${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h
|
||||
${PROJECT_SOURCE_DIR}/src/hwcaps_linux_or_android.c
|
||||
${PROJECT_SOURCE_DIR}/src/hwcaps_freebsd.c
|
||||
${PROJECT_SOURCE_DIR}/src/hwcaps.c
|
||||
)
|
||||
setup_include_and_definitions(unix_based_hardware_detection)
|
||||
@ -131,9 +160,13 @@ if(UNIX)
|
||||
target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H)
|
||||
endif()
|
||||
check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL)
|
||||
check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_STRONG_ELF_AUX_INFO)
|
||||
if(HAVE_STRONG_GETAUXVAL)
|
||||
target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL)
|
||||
endif()
|
||||
if(HAVE_STRONG_ELF_AUX_INFO)
|
||||
target_compile_definitions(unix_based_hardware_detection PUBLIC HAVE_STRONG_ELF_AUX_INFO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
@ -153,20 +186,21 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
|
||||
target_include_directories(cpu_features
|
||||
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
|
||||
)
|
||||
if(PROCESSOR_IS_X86)
|
||||
if(APPLE)
|
||||
|
||||
if(APPLE)
|
||||
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
|
||||
endif()
|
||||
endif()
|
||||
add_library(CpuFeature::cpu_features ALIAS cpu_features)
|
||||
add_library(CpuFeatures::cpu_features ALIAS cpu_features)
|
||||
|
||||
#
|
||||
# program : list_cpu_features
|
||||
#
|
||||
|
||||
add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c)
|
||||
target_link_libraries(list_cpu_features PRIVATE cpu_features)
|
||||
add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features)
|
||||
if(BUILD_EXECUTABLE)
|
||||
add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c)
|
||||
target_link_libraries(list_cpu_features PRIVATE cpu_features)
|
||||
add_executable(CpuFeatures::list_cpu_features ALIAS list_cpu_features)
|
||||
endif()
|
||||
|
||||
#
|
||||
# ndk_compat
|
||||
@ -232,36 +266,47 @@ endif()
|
||||
#
|
||||
# Install cpu_features and list_cpu_features
|
||||
#
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS cpu_features list_cpu_features
|
||||
if(ENABLE_INSTALL)
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS cpu_features
|
||||
EXPORT CpuFeaturesTargets
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
install(EXPORT CpuFeaturesTargets
|
||||
)
|
||||
if(BUILD_EXECUTABLE)
|
||||
install(TARGETS list_cpu_features
|
||||
EXPORT CpuFeaturesTargets
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
install(EXPORT CpuFeaturesTargets
|
||||
NAMESPACE CpuFeatures::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures
|
||||
COMPONENT Devel
|
||||
)
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in
|
||||
)
|
||||
include(CMakePackageConfigHelpers)
|
||||
configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in
|
||||
"${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake"
|
||||
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures"
|
||||
NO_SET_AND_CHECK_MACRO
|
||||
NO_CHECK_REQUIRED_COMPONENTS_MACRO
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
)
|
||||
write_basic_package_version_file(
|
||||
"${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake"
|
||||
COMPATIBILITY SameMajorVersion
|
||||
)
|
||||
install(
|
||||
)
|
||||
install(
|
||||
FILES
|
||||
"${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake"
|
||||
"${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures"
|
||||
COMPONENT Devel
|
||||
)
|
||||
)
|
||||
endif()
|
@ -158,14 +158,14 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
|
||||
|
||||
## What's supported
|
||||
|
||||
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | s390x |
|
||||
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-----: |
|
||||
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
|
||||
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet |
|
||||
| MacOs | yes² | not yet | N/A | N/A | no | N/A | no |
|
||||
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A |
|
||||
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A |
|
||||
| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A |
|
||||
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | Loongarch | s390x |
|
||||
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-------: | :-----: |
|
||||
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
|
||||
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | not yet |
|
||||
| MacOs | yes² | yes⁵ | N/A | N/A | N/A | N/A | N/A | N/A |
|
||||
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A | N/A |
|
||||
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A | N/A |
|
||||
| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A | N/A |
|
||||
|
||||
1. **Features revealed from Linux.** We gather data from several sources
|
||||
depending on availability:
|
||||
@ -180,6 +180,8 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
|
||||
microarchitecture allows the client to reject particular microarchitectures.
|
||||
4. All flavors of Mips are supported, little and big endian as well as 32/64
|
||||
bits.
|
||||
5. **Features revealed from sysctl.** features are retrieved by the `sysctl`
|
||||
instruction.
|
||||
|
||||
<a name="ndk"></a>
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
|
||||
#define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Architectures
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -52,14 +53,14 @@
|
||||
#define CPU_FEATURES_ARCH_PPC
|
||||
#endif
|
||||
|
||||
#if defined(__riscv)
|
||||
#define CPU_FEATURES_ARCH_RISCV
|
||||
#endif
|
||||
|
||||
#if defined(__s390x__)
|
||||
#define CPU_FEATURES_ARCH_S390X
|
||||
#endif
|
||||
|
||||
#if defined(__riscv)
|
||||
#define CPU_FEATURES_ARCH_RISCV
|
||||
#endif
|
||||
|
||||
#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32
|
||||
#define CPU_FEATURES_ARCH_RISCV32
|
||||
#endif
|
||||
@ -72,6 +73,10 @@
|
||||
#define CPU_FEATURES_ARCH_RISCV128
|
||||
#endif
|
||||
|
||||
#if defined(__loongarch64)
|
||||
#define CPU_FEATURES_ARCH_LOONGARCH
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Os
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -159,6 +159,27 @@ typedef struct
|
||||
int ecv : 1; // Enhanced counter virtualization.
|
||||
int afp : 1; // Alternate floating-point behaviour.
|
||||
int rpres : 1; // 12-bit reciprocal (square root) estimate precision.
|
||||
int mte3 : 1; // MTE asymmetric fault handling.
|
||||
int sme : 1; // Scalable Matrix Extension.
|
||||
int smei16i64 : 1; // 16-bit to 64-bit integer widening outer product.
|
||||
int smef64f64 : 1; // FP64 to FP64 outer product.
|
||||
int smei8i32 : 1; // 8-bit to 32-bit integer widening outer product.
|
||||
int smef16f32 : 1; // FP16 to FP32 outer product.
|
||||
int smeb16f32 : 1; // BFloat16 to FP32 outper product.
|
||||
int smef32f32 : 1; // FP32 to FP32 outer product.
|
||||
int smefa64 : 1; // Full A64 support for SME in streaming mode.
|
||||
int wfxt : 1; // WFE and WFI with timeout.
|
||||
int ebf16 : 1; // Extended BFloat16 instructions.
|
||||
int sveebf16 : 1; // SVE BFloat16 instructions.
|
||||
int cssc : 1; // Common short sequence compression instructions.
|
||||
int rprfm : 1; // Range Prefetch Memory hint instruction.
|
||||
int sve2p1 : 1; // Scalable Vector Extension (version 2.1).
|
||||
int sme2 : 1; // Scalable Matrix Extension (version 2).
|
||||
int sme2p1 : 1; // Scalable Matrix Extension (version 2.1).
|
||||
int smei16i32 : 1; // 16-bit to 64-bit integer widening outer product.
|
||||
int smebi32i32 : 1; // 1-bit binary to 32-bit integer outer product.
|
||||
int smeb16b16 : 1; // SME2.1 BFloat16 instructions.
|
||||
int smef16f16 : 1; // FP16 to FP16 outer product.
|
||||
|
||||
// Make sure to update Aarch64FeaturesEnum below if you add a field here.
|
||||
} Aarch64Features;
|
||||
@ -234,6 +255,27 @@ typedef enum
|
||||
AARCH64_ECV,
|
||||
AARCH64_AFP,
|
||||
AARCH64_RPRES,
|
||||
AARCH64_MTE3,
|
||||
AARCH64_SME,
|
||||
AARCH64_SME_I16I64,
|
||||
AARCH64_SME_F64F64,
|
||||
AARCH64_SME_I8I32,
|
||||
AARCH64_SME_F16F32,
|
||||
AARCH64_SME_B16F32,
|
||||
AARCH64_SME_F32F32,
|
||||
AARCH64_SME_FA64,
|
||||
AARCH64_WFXT,
|
||||
AARCH64_EBF16,
|
||||
AARCH64_SVE_EBF16,
|
||||
AARCH64_CSSC,
|
||||
AARCH64_RPRFM,
|
||||
AARCH64_SVE2P1,
|
||||
AARCH64_SME2,
|
||||
AARCH64_SME2P1,
|
||||
AARCH64_SME_I16I32,
|
||||
AARCH64_SME_BI32I32,
|
||||
AARCH64_SME_B16B16,
|
||||
AARCH64_SME_F16F16,
|
||||
AARCH64_LAST_,
|
||||
} Aarch64FeaturesEnum;
|
||||
|
||||
|
@ -0,0 +1,70 @@
|
||||
// SPDX-FileCopyrightText: 2013 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
|
||||
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_LOONGARCH_H_
|
||||
#define CPU_FEATURES_INCLUDE_CPUINFO_LOONGARCH_H_
|
||||
|
||||
#include "cpu_features_cache_info.h"
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#if !defined(CPU_FEATURES_ARCH_LOONGARCH)
|
||||
#error "Including cpuinfo_loongarch.h from a non-loongarch target."
|
||||
#endif
|
||||
|
||||
CPU_FEATURES_START_CPP_NAMESPACE
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Base
|
||||
int CPUCFG : 1; // Instruction for Identify CPU Features
|
||||
|
||||
// Extension
|
||||
int LAM : 1; // Extension for Atomic Memory Access Instructions
|
||||
int UAL : 1; // Extension for Non-Aligned Memory Access
|
||||
int FPU : 1; // Extension for Basic Floating-Point Instructions
|
||||
int LSX : 1; // Extension for Loongson SIMD eXtension
|
||||
int LASX : 1; // Extension for Loongson Advanced SIMD eXtension
|
||||
int CRC32 : 1; // Extension for Cyclic Redundancy Check Instructions
|
||||
int COMPLEX : 1; // Extension for Complex Vector Operation Instructions
|
||||
int CRYPTO : 1; // Extension for Encryption And Decryption Vector
|
||||
// Instructions
|
||||
int LVZ : 1; // Extension for Virtualization
|
||||
int LBT_X86 : 1; // Extension for X86 Binary Translation Extension
|
||||
int LBT_ARM : 1; // Extension for ARM Binary Translation Extension
|
||||
int LBT_MIPS : 1; // Extension for MIPS Binary Translation Extension
|
||||
int PTW : 1; // Extension for Page Table Walker
|
||||
} LoongArchFeatures;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LoongArchFeatures features;
|
||||
} LoongArchInfo;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LOONGARCH_CPUCFG,
|
||||
LOONGARCH_LAM,
|
||||
LOONGARCH_UAL,
|
||||
LOONGARCH_FPU,
|
||||
LOONGARCH_LSX,
|
||||
LOONGARCH_LASX,
|
||||
LOONGARCH_CRC32,
|
||||
LOONGARCH_COMPLEX,
|
||||
LOONGARCH_CRYPTO,
|
||||
LOONGARCH_LVZ,
|
||||
LOONGARCH_LBT_X86,
|
||||
LOONGARCH_LBT_ARM,
|
||||
LOONGARCH_LBT_MIPS,
|
||||
LOONGARCH_PTW,
|
||||
LOONGARCH_LAST_,
|
||||
} LoongArchFeaturesEnum;
|
||||
|
||||
LoongArchInfo GetLoongArchInfo(void);
|
||||
int GetLoongArchFeaturesEnumValue(const LoongArchFeatures* features,
|
||||
LoongArchFeaturesEnum value);
|
||||
const char* GetLoongArchFeaturesEnumName(LoongArchFeaturesEnum);
|
||||
|
||||
CPU_FEATURES_END_CPP_NAMESPACE
|
||||
|
||||
#endif // CPU_FEATURES_INCLUDE_CPUINFO_LOONGARCH_H_
|
@ -26,6 +26,7 @@ typedef struct
|
||||
int D : 1; // Standard Extension for Double-Precision Floating-Point
|
||||
int Q : 1; // Standard Extension for Quad-Precision Floating-Point
|
||||
int C : 1; // Standard Extension for Compressed Instructions
|
||||
int V : 1; // Standard Extension for Vector Instructions
|
||||
int Zicsr : 1; // Control and Status Register (CSR)
|
||||
int Zifencei : 1; // Instruction-Fetch Fence
|
||||
} RiscvFeatures;
|
||||
@ -47,6 +48,7 @@ typedef enum
|
||||
RISCV_D,
|
||||
RISCV_Q,
|
||||
RISCV_C,
|
||||
RISCV_V,
|
||||
RISCV_Zicsr,
|
||||
RISCV_Zifencei,
|
||||
RISCV_LAST_,
|
||||
|
@ -89,7 +89,8 @@ typedef enum
|
||||
S390X_LAST_,
|
||||
} S390XFeaturesEnum;
|
||||
|
||||
int GetS390XFeaturesEnumValue(const S390XFeatures* features, S390XFeaturesEnum value);
|
||||
int GetS390XFeaturesEnumValue(const S390XFeatures* features,
|
||||
S390XFeaturesEnum value);
|
||||
|
||||
const char* GetS390XFeaturesEnumName(S390XFeaturesEnum);
|
||||
|
||||
|
@ -75,6 +75,7 @@ typedef struct
|
||||
int amx_bf16 : 1;
|
||||
int amx_tile : 1;
|
||||
int amx_int8 : 1;
|
||||
int amx_fp16 : 1;
|
||||
|
||||
int pclmulqdq : 1;
|
||||
int smx : 1;
|
||||
@ -96,6 +97,9 @@ typedef struct
|
||||
int fz_rep_movsb : 1; // Fast zero-length REP MOVSB
|
||||
int fs_rep_stosb : 1; // Fast short REP STOSB
|
||||
int fs_rep_cmpsb_scasb : 1; // Fast short REP CMPSB/SCASB
|
||||
|
||||
int lam : 1; // Intel Linear Address Mask
|
||||
int uai : 1; // AMD Upper Address Ignore
|
||||
// Make sure to update X86FeaturesEnum below if you add a field here.
|
||||
} X86Features;
|
||||
|
||||
@ -114,7 +118,6 @@ X86Info GetX86Info(void);
|
||||
|
||||
// Returns cache hierarchy informations.
|
||||
// Can call cpuid multiple times.
|
||||
// Only works on Intel CPU at the moment.
|
||||
CacheInfo GetX86CacheInfo(void);
|
||||
|
||||
typedef enum
|
||||
@ -244,6 +247,7 @@ typedef enum
|
||||
X86_AMX_BF16,
|
||||
X86_AMX_TILE,
|
||||
X86_AMX_INT8,
|
||||
X86_AMX_FP16,
|
||||
X86_PCLMULQDQ,
|
||||
X86_SMX,
|
||||
X86_SGX,
|
||||
@ -263,6 +267,8 @@ typedef enum
|
||||
X86_FZ_REP_MOVSB,
|
||||
X86_FS_REP_STOSB,
|
||||
X86_FS_REP_CMPSB_SCASB,
|
||||
X86_LAM,
|
||||
X86_UAI,
|
||||
X86_LAST_,
|
||||
} X86FeaturesEnum;
|
||||
|
||||
|
@ -0,0 +1,293 @@
|
||||
// SPDX-FileCopyrightText: 2017 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// A note on Windows AArch64 implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Getting cpu info via EL1 system registers is not possible, so we delegate it
|
||||
// to the Windows API (i.e., IsProcessorFeaturePresent and GetNativeSystemInfo).
|
||||
// The `implementer`, `variant` and `part` fields of the `Aarch64Info` struct
|
||||
// are not used, so they are set to 0. To get `revision` we use
|
||||
// `wProcessorRevision` from `SYSTEM_INFO`.
|
||||
//
|
||||
// Cryptographic Extension:
|
||||
// -----------------------------------------------------------------------------
|
||||
// According to documentation Arm Architecture Reference Manual for
|
||||
// A-profile architecture. A2.3 The Armv8 Cryptographic Extension. The Armv8.0
|
||||
// Cryptographic Extension provides instructions for the acceleration of
|
||||
// encryption and decryption, and includes the following features: FEAT_AES,
|
||||
// FEAT_PMULL, FEAT_SHA1, FEAT_SHA256.
|
||||
// see: https://developer.arm.com/documentation/ddi0487/latest
|
||||
//
|
||||
// We use `PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE` to detect all Armv8.0 crypto
|
||||
// features. This value reports all features or nothing, so even if you only
|
||||
// have support FEAT_AES and FEAT_PMULL, it will still return false.
|
||||
//
|
||||
// From Armv8.2, an implementation of the Armv8.0 Cryptographic Extension can
|
||||
// include either or both of:
|
||||
//
|
||||
// • The AES functionality, including support for multiplication of 64-bit
|
||||
// polynomials. The ID_AA64ISAR0_EL1.AES field indicates whether this
|
||||
// functionality is supported.
|
||||
// • The SHA1 and SHA2-256 functionality. The ID_AA64ISAR0_EL1.{SHA2, SHA1}
|
||||
// fields indicate whether this functionality is supported.
|
||||
//
|
||||
// ID_AA64ISAR0_EL1.AES, bits [7:4]:
|
||||
// Indicates support for AES instructions in AArch64 state. Defined values are:
|
||||
// - 0b0000 No AES instructions implemented.
|
||||
// - 0b0001 AESE, AESD, AESMC, and AESIMC instructions implemented.
|
||||
// - 0b0010 As for 0b0001, plus PMULL/PMULL2 instructions operating on 64-bit
|
||||
// data quantities.
|
||||
//
|
||||
// FEAT_AES implements the functionality identified by the value 0b0001.
|
||||
// FEAT_PMULL implements the functionality identified by the value 0b0010.
|
||||
// From Armv8, the permitted values are 0b0000 and 0b0010.
|
||||
//
|
||||
// ID_AA64ISAR0_EL1.SHA1, bits [11:8]:
|
||||
// Indicates support for SHA1 instructions in AArch64 state. Defined values are:
|
||||
// - 0b0000 No SHA1 instructions implemented.
|
||||
// - 0b0001 SHA1C, SHA1P, SHA1M, SHA1H, SHA1SU0, and SHA1SU1 instructions
|
||||
// implemented.
|
||||
//
|
||||
// FEAT_SHA1 implements the functionality identified by the value 0b0001.
|
||||
// From Armv8, the permitted values are 0b0000 and 0b0001.
|
||||
// If the value of ID_AA64ISAR0_EL1.SHA2 is 0b0000, this field must have the
|
||||
// value 0b0000.
|
||||
//
|
||||
// ID_AA64ISAR0_EL1.SHA2, bits [15:12]:
|
||||
// Indicates support for SHA2 instructions in AArch64 state. Defined values are:
|
||||
// - 0b0000 No SHA2 instructions implemented.
|
||||
// - 0b0001 Implements instructions: SHA256H, SHA256H2, SHA256SU0, and
|
||||
// SHA256SU1.
|
||||
// - 0b0010 Implements instructions:
|
||||
// • SHA256H, SHA256H2, SHA256SU0, and SHA256SU1.
|
||||
// • SHA512H, SHA512H2, SHA512SU0, and SHA512SU1.
|
||||
//
|
||||
// FEAT_SHA256 implements the functionality identified by the value 0b0001.
|
||||
// FEAT_SHA512 implements the functionality identified by the value 0b0010.
|
||||
//
|
||||
// In Armv8, the permitted values are 0b0000 and 0b0001.
|
||||
// From Armv8.2, the permitted values are 0b0000, 0b0001, and 0b0010.
|
||||
//
|
||||
// If the value of ID_AA64ISAR0_EL1.SHA1 is 0b0000, this field must have the
|
||||
// value 0b0000.
|
||||
//
|
||||
// If the value of this field is 0b0010, ID_AA64ISAR0_EL1.SHA3
|
||||
// must have the value 0b0001.
|
||||
//
|
||||
// Other cryptographic features that we cannot detect such as sha512, sha3, sm3,
|
||||
// sm4, sveaes, svepmull, svesha3, svesm4 we set to 0.
|
||||
//
|
||||
// FP/SIMD:
|
||||
// -----------------------------------------------------------------------------
|
||||
// FP/SIMD must be implemented on all Armv8.0 implementations, but
|
||||
// implementations targeting specialized markets may support the following
|
||||
// combinations:
|
||||
//
|
||||
// • No NEON or floating-point.
|
||||
// • Full floating-point and SIMD support with exception trapping.
|
||||
// • Full floating-point and SIMD support without exception trapping.
|
||||
//
|
||||
// ref:
|
||||
// https://developer.arm.com/documentation/den0024/a/AArch64-Floating-point-and-NEON
|
||||
//
|
||||
// So, we use `PF_ARM_VFP_32_REGISTERS_AVAILABLE`,
|
||||
// `PF_ARM_NEON_INSTRUCTIONS_AVAILABLE` to detect `asimd` and `fp`
|
||||
|
||||
#ifndef CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
|
||||
#define CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
|
||||
|
||||
#include "cpu_features_cache_info.h"
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
CPU_FEATURES_START_CPP_NAMESPACE
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fp : 1; // Floating-point.
|
||||
int asimd : 1; // Advanced SIMD.
|
||||
int evtstrm : 1; // Generic timer generated events.
|
||||
int aes : 1; // Hardware-accelerated Advanced Encryption Standard.
|
||||
int pmull : 1; // Polynomial multiply long.
|
||||
int sha1 : 1; // Hardware-accelerated SHA1.
|
||||
int sha2 : 1; // Hardware-accelerated SHA2-256.
|
||||
int crc32 : 1; // Hardware-accelerated CRC-32.
|
||||
int atomics : 1; // Armv8.1 atomic instructions.
|
||||
int fphp : 1; // Half-precision floating point support.
|
||||
int asimdhp : 1; // Advanced SIMD half-precision support.
|
||||
int cpuid : 1; // Access to certain ID registers.
|
||||
int asimdrdm : 1; // Rounding Double Multiply Accumulate/Subtract.
|
||||
int jscvt : 1; // Support for JavaScript conversion.
|
||||
int fcma : 1; // Floating point complex numbers.
|
||||
int lrcpc : 1; // Support for weaker release consistency.
|
||||
int dcpop : 1; // Data persistence writeback.
|
||||
int sha3 : 1; // Hardware-accelerated SHA3.
|
||||
int sm3 : 1; // Hardware-accelerated SM3.
|
||||
int sm4 : 1; // Hardware-accelerated SM4.
|
||||
int asimddp : 1; // Dot product instruction.
|
||||
int sha512 : 1; // Hardware-accelerated SHA512.
|
||||
int sve : 1; // Scalable Vector Extension.
|
||||
int asimdfhm : 1; // Additional half-precision instructions.
|
||||
int dit : 1; // Data independent timing.
|
||||
int uscat : 1; // Unaligned atomics support.
|
||||
int ilrcpc : 1; // Additional support for weaker release consistency.
|
||||
int flagm : 1; // Flag manipulation instructions.
|
||||
int ssbs : 1; // Speculative Store Bypass Safe PSTATE bit.
|
||||
int sb : 1; // Speculation barrier.
|
||||
int paca : 1; // Address authentication.
|
||||
int pacg : 1; // Generic authentication.
|
||||
int dcpodp : 1; // Data cache clean to point of persistence.
|
||||
int sve2 : 1; // Scalable Vector Extension (version 2).
|
||||
int sveaes : 1; // SVE AES instructions.
|
||||
int svepmull : 1; // SVE polynomial multiply long instructions.
|
||||
int svebitperm : 1; // SVE bit permute instructions.
|
||||
int svesha3 : 1; // SVE SHA3 instructions.
|
||||
int svesm4 : 1; // SVE SM4 instructions.
|
||||
int flagm2 : 1; // Additional flag manipulation instructions.
|
||||
int frint : 1; // Floating point to integer rounding.
|
||||
int svei8mm : 1; // SVE Int8 matrix multiplication instructions.
|
||||
int svef32mm : 1; // SVE FP32 matrix multiplication instruction.
|
||||
int svef64mm : 1; // SVE FP64 matrix multiplication instructions.
|
||||
int svebf16 : 1; // SVE BFloat16 instructions.
|
||||
int i8mm : 1; // Int8 matrix multiplication instructions.
|
||||
int bf16 : 1; // BFloat16 instructions.
|
||||
int dgh : 1; // Data Gathering Hint instruction.
|
||||
int rng : 1; // True random number generator support.
|
||||
int bti : 1; // Branch target identification.
|
||||
int mte : 1; // Memory tagging extension.
|
||||
int ecv : 1; // Enhanced counter virtualization.
|
||||
int afp : 1; // Alternate floating-point behaviour.
|
||||
int rpres : 1; // 12-bit reciprocal (square root) estimate precision.
|
||||
int mte3 : 1; // MTE asymmetric fault handling.
|
||||
int sme : 1; // Scalable Matrix Extension.
|
||||
int smei16i64 : 1; // 16-bit to 64-bit integer widening outer product.
|
||||
int smef64f64 : 1; // FP64 to FP64 outer product.
|
||||
int smei8i32 : 1; // 8-bit to 32-bit integer widening outer product.
|
||||
int smef16f32 : 1; // FP16 to FP32 outer product.
|
||||
int smeb16f32 : 1; // BFloat16 to FP32 outper product.
|
||||
int smef32f32 : 1; // FP32 to FP32 outer product.
|
||||
int smefa64 : 1; // Full A64 support for SME in streaming mode.
|
||||
int wfxt : 1; // WFE and WFI with timeout.
|
||||
int ebf16 : 1; // Extended BFloat16 instructions.
|
||||
int sveebf16 : 1; // SVE BFloat16 instructions.
|
||||
int cssc : 1; // Common short sequence compression instructions.
|
||||
int rprfm : 1; // Range Prefetch Memory hint instruction.
|
||||
int sve2p1 : 1; // Scalable Vector Extension (version 2.1).
|
||||
int sme2 : 1; // Scalable Matrix Extension (version 2).
|
||||
int sme2p1 : 1; // Scalable Matrix Extension (version 2.1).
|
||||
int smei16i32 : 1; // 16-bit to 64-bit integer widening outer product.
|
||||
int smebi32i32 : 1; // 1-bit binary to 32-bit integer outer product.
|
||||
int smeb16b16 : 1; // SME2.1 BFloat16 instructions.
|
||||
int smef16f16 : 1; // FP16 to FP16 outer product.
|
||||
|
||||
// Make sure to update Aarch64FeaturesEnum below if you add a field here.
|
||||
} Aarch64Features;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Aarch64Features features;
|
||||
int implementer; // We set 0 for Windows.
|
||||
int variant; // We set 0 for Windows.
|
||||
int part; // We set 0 for Windows.
|
||||
int revision; // We use GetNativeSystemInfo to get processor revision for
|
||||
// Windows.
|
||||
} Aarch64Info;
|
||||
|
||||
Aarch64Info GetAarch64Info(void);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Introspection functions
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AARCH64_FP,
|
||||
AARCH64_ASIMD,
|
||||
AARCH64_EVTSTRM,
|
||||
AARCH64_AES,
|
||||
AARCH64_PMULL,
|
||||
AARCH64_SHA1,
|
||||
AARCH64_SHA2,
|
||||
AARCH64_CRC32,
|
||||
AARCH64_ATOMICS,
|
||||
AARCH64_FPHP,
|
||||
AARCH64_ASIMDHP,
|
||||
AARCH64_CPUID,
|
||||
AARCH64_ASIMDRDM,
|
||||
AARCH64_JSCVT,
|
||||
AARCH64_FCMA,
|
||||
AARCH64_LRCPC,
|
||||
AARCH64_DCPOP,
|
||||
AARCH64_SHA3,
|
||||
AARCH64_SM3,
|
||||
AARCH64_SM4,
|
||||
AARCH64_ASIMDDP,
|
||||
AARCH64_SHA512,
|
||||
AARCH64_SVE,
|
||||
AARCH64_ASIMDFHM,
|
||||
AARCH64_DIT,
|
||||
AARCH64_USCAT,
|
||||
AARCH64_ILRCPC,
|
||||
AARCH64_FLAGM,
|
||||
AARCH64_SSBS,
|
||||
AARCH64_SB,
|
||||
AARCH64_PACA,
|
||||
AARCH64_PACG,
|
||||
AARCH64_DCPODP,
|
||||
AARCH64_SVE2,
|
||||
AARCH64_SVEAES,
|
||||
AARCH64_SVEPMULL,
|
||||
AARCH64_SVEBITPERM,
|
||||
AARCH64_SVESHA3,
|
||||
AARCH64_SVESM4,
|
||||
AARCH64_FLAGM2,
|
||||
AARCH64_FRINT,
|
||||
AARCH64_SVEI8MM,
|
||||
AARCH64_SVEF32MM,
|
||||
AARCH64_SVEF64MM,
|
||||
AARCH64_SVEBF16,
|
||||
AARCH64_I8MM,
|
||||
AARCH64_BF16,
|
||||
AARCH64_DGH,
|
||||
AARCH64_RNG,
|
||||
AARCH64_BTI,
|
||||
AARCH64_MTE,
|
||||
AARCH64_ECV,
|
||||
AARCH64_AFP,
|
||||
AARCH64_RPRES,
|
||||
AARCH64_MTE3,
|
||||
AARCH64_SME,
|
||||
AARCH64_SME_I16I64,
|
||||
AARCH64_SME_F64F64,
|
||||
AARCH64_SME_I8I32,
|
||||
AARCH64_SME_F16F32,
|
||||
AARCH64_SME_B16F32,
|
||||
AARCH64_SME_F32F32,
|
||||
AARCH64_SME_FA64,
|
||||
AARCH64_WFXT,
|
||||
AARCH64_EBF16,
|
||||
AARCH64_SVE_EBF16,
|
||||
AARCH64_CSSC,
|
||||
AARCH64_RPRFM,
|
||||
AARCH64_SVE2P1,
|
||||
AARCH64_SME2,
|
||||
AARCH64_SME2P1,
|
||||
AARCH64_SME_I16I32,
|
||||
AARCH64_SME_BI32I32,
|
||||
AARCH64_SME_B16B16,
|
||||
AARCH64_SME_F16F16,
|
||||
AARCH64_LAST_,
|
||||
} Aarch64FeaturesEnum;
|
||||
|
||||
int GetAarch64FeaturesEnumValue(const Aarch64Features* features,
|
||||
Aarch64FeaturesEnum value);
|
||||
|
||||
const char* GetAarch64FeaturesEnumName(Aarch64FeaturesEnum);
|
||||
|
||||
CPU_FEATURES_END_CPP_NAMESPACE
|
||||
|
||||
#if !defined(CPU_FEATURES_ARCH_AARCH64)
|
||||
#error "Including cpuinfo_aarch64.h from a non-aarch64 target."
|
||||
#endif
|
||||
|
||||
#endif // CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_
|
@ -71,6 +71,27 @@ CPU_FEATURES_START_CPP_NAMESPACE
|
||||
#define AARCH64_HWCAP2_ECV (1UL << 19)
|
||||
#define AARCH64_HWCAP2_AFP (1UL << 20)
|
||||
#define AARCH64_HWCAP2_RPRES (1UL << 21)
|
||||
#define AARCH64_HWCAP2_MTE3 (1UL << 22)
|
||||
#define AARCH64_HWCAP2_SME (1UL << 23)
|
||||
#define AARCH64_HWCAP2_SME_I16I64 (1UL << 24)
|
||||
#define AARCH64_HWCAP2_SME_F64F64 (1UL << 25)
|
||||
#define AARCH64_HWCAP2_SME_I8I32 (1UL << 26)
|
||||
#define AARCH64_HWCAP2_SME_F16F32 (1UL << 27)
|
||||
#define AARCH64_HWCAP2_SME_B16F32 (1UL << 28)
|
||||
#define AARCH64_HWCAP2_SME_F32F32 (1UL << 29)
|
||||
#define AARCH64_HWCAP2_SME_FA64 (1UL << 30)
|
||||
#define AARCH64_HWCAP2_WFXT (1UL << 31)
|
||||
#define AARCH64_HWCAP2_EBF16 (1UL << 32)
|
||||
#define AARCH64_HWCAP2_SVE_EBF16 (1UL << 33)
|
||||
#define AARCH64_HWCAP2_CSSC (1UL << 34)
|
||||
#define AARCH64_HWCAP2_RPRFM (1UL << 35)
|
||||
#define AARCH64_HWCAP2_SVE2P1 (1UL << 36)
|
||||
#define AARCH64_HWCAP2_SME2 (1UL << 37)
|
||||
#define AARCH64_HWCAP2_SME2P1 (1UL << 38)
|
||||
#define AARCH64_HWCAP2_SME_I16I32 (1UL << 39)
|
||||
#define AARCH64_HWCAP2_SME_BI32I32 (1UL << 40)
|
||||
#define AARCH64_HWCAP2_SME_B16B16 (1UL << 41)
|
||||
#define AARCH64_HWCAP2_SME_F16F16 (1UL << 42)
|
||||
|
||||
// http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
|
||||
#define ARM_HWCAP_SWP (1UL << 0)
|
||||
@ -202,6 +223,23 @@ CPU_FEATURES_START_CPP_NAMESPACE
|
||||
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
|
||||
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
|
||||
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
|
||||
#define RISCV_HWCAP_V (1UL << ('V' - 'A'))
|
||||
|
||||
// https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h
|
||||
#define HWCAP_LOONGARCH_CPUCFG (1 << 0)
|
||||
#define HWCAP_LOONGARCH_LAM (1 << 1)
|
||||
#define HWCAP_LOONGARCH_UAL (1 << 2)
|
||||
#define HWCAP_LOONGARCH_FPU (1 << 3)
|
||||
#define HWCAP_LOONGARCH_LSX (1 << 4)
|
||||
#define HWCAP_LOONGARCH_LASX (1 << 5)
|
||||
#define HWCAP_LOONGARCH_CRC32 (1 << 6)
|
||||
#define HWCAP_LOONGARCH_COMPLEX (1 << 7)
|
||||
#define HWCAP_LOONGARCH_CRYPTO (1 << 8)
|
||||
#define HWCAP_LOONGARCH_LVZ (1 << 9)
|
||||
#define HWCAP_LOONGARCH_LBT_X86 (1 << 10)
|
||||
#define HWCAP_LOONGARCH_LBT_ARM (1 << 11)
|
||||
#define HWCAP_LOONGARCH_LBT_MIPS (1 << 12)
|
||||
#define HWCAP_LOONGARCH_PTW (1 << 13)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -2,11 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "internal/hwcaps.h"
|
||||
#include "cpu_features_macros.h"
|
||||
#include "internal/filesystem.h"
|
||||
#include "internal/string_view.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
static bool IsSet(const uint32_t mask, const uint32_t value)
|
||||
{
|
||||
@ -20,159 +16,3 @@ bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
|
||||
return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) ||
|
||||
IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2);
|
||||
}
|
||||
|
||||
#ifdef CPU_FEATURES_TEST
|
||||
// In test mode, hwcaps_for_testing will define the following functions.
|
||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
|
||||
const char* CpuFeatures_GetPlatformPointer(void);
|
||||
const char* CpuFeatures_GetBasePlatformPointer(void);
|
||||
#else
|
||||
|
||||
// Debug facilities
|
||||
#if defined(NDEBUG)
|
||||
#define D(...)
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define D(...) \
|
||||
do \
|
||||
{ \
|
||||
printf(__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of GetElfHwcapFromGetauxval
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define AT_HWCAP 16
|
||||
#define AT_HWCAP2 26
|
||||
#define AT_PLATFORM 15
|
||||
#define AT_BASE_PLATFORM 24
|
||||
|
||||
#if defined(HAVE_STRONG_GETAUXVAL)
|
||||
#include <sys/auxv.h>
|
||||
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type)
|
||||
{
|
||||
return getauxval(hwcap_type);
|
||||
}
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
// On Android we probe the system's C library for a 'getauxval' function and
|
||||
// call it if it exits, or return 0 for failure. This function is available
|
||||
// since API level 18.
|
||||
//
|
||||
// Note that getauxval() can't really be re-implemented here, because its
|
||||
// implementation does not parse /proc/self/auxv. Instead it depends on values
|
||||
// that are passed by the kernel at process-init time to the C runtime
|
||||
// initialization layer.
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef unsigned long getauxval_func_t(unsigned long);
|
||||
|
||||
static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
void *libc_handle = NULL;
|
||||
getauxval_func_t *func = NULL;
|
||||
|
||||
dlerror(); // Cleaning error state before calling dlopen.
|
||||
libc_handle = dlopen("libc.so", RTLD_NOW);
|
||||
if (!libc_handle)
|
||||
{
|
||||
D("Could not dlopen() C library: %s\n", dlerror());
|
||||
return 0;
|
||||
}
|
||||
func = (getauxval_func_t *)dlsym(libc_handle, "getauxval");
|
||||
if (!func)
|
||||
{
|
||||
D("Could not find getauxval() in C library\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: getauxval() returns 0 on failure. Doesn't touch errno.
|
||||
ret = (uint32_t)(*func)(hwcap_type);
|
||||
}
|
||||
dlclose(libc_handle);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#error "This platform does not provide hardware capabilities."
|
||||
#endif
|
||||
|
||||
// Implementation of GetHardwareCapabilities for OS that provide
|
||||
// GetElfHwcapFromGetauxval().
|
||||
|
||||
// Fallback when getauxval is not available, retrieves hwcaps from
|
||||
// "/proc/self/auxv".
|
||||
static uint32_t GetElfHwcapFromProcSelfAuxv(uint32_t hwcap_type)
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t tag;
|
||||
uint32_t value;
|
||||
} entry;
|
||||
uint32_t result = 0;
|
||||
const char filepath[] = "/proc/self/auxv";
|
||||
const int fd = CpuFeatures_OpenFile(filepath);
|
||||
if (fd < 0)
|
||||
{
|
||||
D("Could not open %s\n", filepath);
|
||||
return 0;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
const int ret = CpuFeatures_ReadFile(fd, (char *)&entry, sizeof entry);
|
||||
if (ret < 0)
|
||||
{
|
||||
D("Error while reading %s\n", filepath);
|
||||
break;
|
||||
}
|
||||
// Detect end of list.
|
||||
if (ret == 0 || (entry.tag == 0 && entry.value == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (entry.tag == hwcap_type)
|
||||
{
|
||||
result = entry.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CpuFeatures_CloseFile(fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Retrieves hardware capabilities by first trying to call getauxval, if not
|
||||
// available falls back to reading "/proc/self/auxv".
|
||||
static unsigned long GetHardwareCapabilitiesFor(uint32_t type)
|
||||
{
|
||||
unsigned long hwcaps = GetElfHwcapFromGetauxval(type);
|
||||
if (!hwcaps)
|
||||
{
|
||||
D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
|
||||
hwcaps = GetElfHwcapFromProcSelfAuxv(type);
|
||||
}
|
||||
return hwcaps;
|
||||
}
|
||||
|
||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void)
|
||||
{
|
||||
HardwareCapabilities capabilities;
|
||||
capabilities.hwcaps = GetHardwareCapabilitiesFor(AT_HWCAP);
|
||||
capabilities.hwcaps2 = GetHardwareCapabilitiesFor(AT_HWCAP2);
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
const char *CpuFeatures_GetPlatformPointer(void)
|
||||
{
|
||||
return (const char *)GetHardwareCapabilitiesFor(AT_PLATFORM);
|
||||
}
|
||||
|
||||
const char *CpuFeatures_GetBasePlatformPointer(void)
|
||||
{
|
||||
return (const char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM);
|
||||
}
|
||||
|
||||
#endif // CPU_FEATURES_TEST
|
||||
|
@ -0,0 +1,45 @@
|
||||
// SPDX-FileCopyrightText: 2023 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_OS_FREEBSD
|
||||
|
||||
#include "internal/hwcaps.h"
|
||||
|
||||
#ifdef CPU_FEATURES_TEST
|
||||
// In test mode, hwcaps_for_testing will define the following functions.
|
||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
|
||||
const char* CpuFeatures_GetPlatformPointer(void);
|
||||
const char* CpuFeatures_GetBasePlatformPointer(void);
|
||||
#else
|
||||
|
||||
#ifdef HAVE_STRONG_ELF_AUX_INFO
|
||||
#include <stddef.h>
|
||||
#include <sys/auxv.h>
|
||||
|
||||
static unsigned long GetElfHwcapFromElfAuxInfo(int hwcap_type)
|
||||
{
|
||||
unsigned long hwcap;
|
||||
elf_aux_info(hwcap_type, &hwcap, sizeof(hwcap));
|
||||
return hwcap;
|
||||
}
|
||||
|
||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void)
|
||||
{
|
||||
HardwareCapabilities capabilities;
|
||||
capabilities.hwcaps = GetElfHwcapFromElfAuxInfo(AT_HWCAP);
|
||||
capabilities.hwcaps2 = GetElfHwcapFromElfAuxInfo(AT_HWCAP2);
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
const char *CpuFeatures_GetPlatformPointer(void) { return NULL; }
|
||||
|
||||
const char *CpuFeatures_GetBasePlatformPointer(void) { return NULL; }
|
||||
|
||||
#else
|
||||
#error "FreeBSD needs support for elf_aux_info"
|
||||
#endif // HAVE_STRONG_ELF_AUX_INFO
|
||||
|
||||
#endif // CPU_FEATURES_TEST
|
||||
#endif // CPU_FEATURES_OS_FREEBSD
|
@ -0,0 +1,166 @@
|
||||
// SPDX-FileCopyrightText: 2023 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
#include "internal/filesystem.h"
|
||||
#include "internal/hwcaps.h"
|
||||
#include "internal/string_view.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef CPU_FEATURES_TEST
|
||||
// In test mode, hwcaps_for_testing will define the following functions.
|
||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
|
||||
const char* CpuFeatures_GetPlatformPointer(void);
|
||||
const char* CpuFeatures_GetBasePlatformPointer(void);
|
||||
#else
|
||||
|
||||
// Debug facilities
|
||||
#if defined(NDEBUG)
|
||||
#define D(...)
|
||||
#else
|
||||
#include <stdio.h>
|
||||
// clang-format off
|
||||
#define D(...) \
|
||||
do { \
|
||||
printf(__VA_ARGS__); \
|
||||
fflush(stdout); \
|
||||
} \
|
||||
while (0)
|
||||
// clang-format on
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of GetElfHwcapFromGetauxval
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(HAVE_STRONG_GETAUXVAL)
|
||||
#include <sys/auxv.h>
|
||||
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type)
|
||||
{
|
||||
return getauxval(hwcap_type);
|
||||
}
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
// On Android we probe the system's C library for a 'getauxval' function and
|
||||
// call it if it exits, or return 0 for failure. This function is available
|
||||
// since API level 18.
|
||||
//
|
||||
// Note that getauxval() can't really be re-implemented here, because its
|
||||
// implementation does not parse /proc/self/auxv. Instead it depends on values
|
||||
// that are passed by the kernel at process-init time to the C runtime
|
||||
// initialization layer.
|
||||
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef unsigned long getauxval_func_t(unsigned long);
|
||||
|
||||
static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
void *libc_handle = NULL;
|
||||
getauxval_func_t *func = NULL;
|
||||
|
||||
dlerror(); // Cleaning error state before calling dlopen.
|
||||
libc_handle = dlopen("libc.so", RTLD_NOW);
|
||||
if (!libc_handle)
|
||||
{
|
||||
D("Could not dlopen() C library: %s\n", dlerror());
|
||||
return 0;
|
||||
}
|
||||
func = (getauxval_func_t *)dlsym(libc_handle, "getauxval");
|
||||
if (!func)
|
||||
{
|
||||
D("Could not find getauxval() in C library\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Note: getauxval() returns 0 on failure. Doesn't touch errno.
|
||||
ret = (uint32_t)(*func)(hwcap_type);
|
||||
}
|
||||
dlclose(libc_handle);
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#error "This platform does not provide hardware capabilities."
|
||||
#endif
|
||||
|
||||
// Implementation of GetHardwareCapabilities for OS that provide
|
||||
// GetElfHwcapFromGetauxval().
|
||||
|
||||
// Fallback when getauxval is not available, retrieves hwcaps from
|
||||
// "/proc/self/auxv".
|
||||
static uint32_t GetElfHwcapFromProcSelfAuxv(uint32_t hwcap_type)
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t tag;
|
||||
uint32_t value;
|
||||
} entry;
|
||||
uint32_t result = 0;
|
||||
const char filepath[] = "/proc/self/auxv";
|
||||
const int fd = CpuFeatures_OpenFile(filepath);
|
||||
if (fd < 0)
|
||||
{
|
||||
D("Could not open %s\n", filepath);
|
||||
return 0;
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
const int ret = CpuFeatures_ReadFile(fd, (char *)&entry, sizeof entry);
|
||||
if (ret < 0)
|
||||
{
|
||||
D("Error while reading %s\n", filepath);
|
||||
break;
|
||||
}
|
||||
// Detect end of list.
|
||||
if (ret == 0 || (entry.tag == 0 && entry.value == 0))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (entry.tag == hwcap_type)
|
||||
{
|
||||
result = entry.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CpuFeatures_CloseFile(fd);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Retrieves hardware capabilities by first trying to call getauxval, if not
|
||||
// available falls back to reading "/proc/self/auxv".
|
||||
static unsigned long GetHardwareCapabilitiesFor(uint32_t type)
|
||||
{
|
||||
unsigned long hwcaps = GetElfHwcapFromGetauxval(type);
|
||||
if (!hwcaps)
|
||||
{
|
||||
D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
|
||||
hwcaps = GetElfHwcapFromProcSelfAuxv(type);
|
||||
}
|
||||
return hwcaps;
|
||||
}
|
||||
|
||||
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void)
|
||||
{
|
||||
HardwareCapabilities capabilities;
|
||||
capabilities.hwcaps = GetHardwareCapabilitiesFor(AT_HWCAP);
|
||||
capabilities.hwcaps2 = GetHardwareCapabilitiesFor(AT_HWCAP2);
|
||||
return capabilities;
|
||||
}
|
||||
|
||||
const char *CpuFeatures_GetPlatformPointer(void)
|
||||
{
|
||||
return (const char *)GetHardwareCapabilitiesFor(AT_PLATFORM);
|
||||
}
|
||||
|
||||
const char *CpuFeatures_GetBasePlatformPointer(void)
|
||||
{
|
||||
return (const char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM);
|
||||
}
|
||||
|
||||
#endif // CPU_FEATURES_TEST
|
||||
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
|
@ -0,0 +1,106 @@
|
||||
// SPDX-FileCopyrightText: 2021 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
#include "cpuinfo_aarch64.h"
|
||||
#include "internal/bit_utils.h"
|
||||
#include "internal/filesystem.h"
|
||||
#include "internal/stack_line_reader.h"
|
||||
#include "internal/string_view.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !defined(CPU_FEATURES_ARCH_AARCH64)
|
||||
#error "Cannot compile aarch64_base on a non aarch64 platform."
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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) \
|
||||
LINE(AARCH64_ECV, ecv, "ecv", 0, AARCH64_HWCAP2_ECV) \
|
||||
LINE(AARCH64_AFP, afp, "afp", 0, AARCH64_HWCAP2_AFP) \
|
||||
LINE(AARCH64_RPRES, rpres, "rpres", 0, AARCH64_HWCAP2_RPRES) \
|
||||
LINE(AARCH64_MTE3, mte3, "mte3", 0, AARCH64_HWCAP2_MTE3) \
|
||||
LINE(AARCH64_SME, sme, "sme", 0, AARCH64_HWCAP2_SME) \
|
||||
LINE(AARCH64_SME_I16I64, smei16i64, "smei16i64", 0, \
|
||||
AARCH64_HWCAP2_SME_I16I64) \
|
||||
LINE(AARCH64_SME_F64F64, smef64f64, "smef64f64", 0, \
|
||||
AARCH64_HWCAP2_SME_F64F64) \
|
||||
LINE(AARCH64_SME_I8I32, smei8i32, "smei8i32", 0, AARCH64_HWCAP2_SME_I8I32) \
|
||||
LINE(AARCH64_SME_F16F32, smef16f32, "smef16f32", 0, \
|
||||
AARCH64_HWCAP2_SME_F16F32) \
|
||||
LINE(AARCH64_SME_B16F32, smeb16f32, "smeb16f32", 0, \
|
||||
AARCH64_HWCAP2_SME_B16F32) \
|
||||
LINE(AARCH64_SME_F32F32, smef32f32, "smef32f32", 0, \
|
||||
AARCH64_HWCAP2_SME_F32F32) \
|
||||
LINE(AARCH64_SME_FA64, smefa64, "smefa64", 0, AARCH64_HWCAP2_SME_FA64) \
|
||||
LINE(AARCH64_WFXT, wfxt, "wfxt", 0, AARCH64_HWCAP2_WFXT) \
|
||||
LINE(AARCH64_EBF16, ebf16, "ebf16", 0, AARCH64_HWCAP2_EBF16) \
|
||||
LINE(AARCH64_SVE_EBF16, sveebf16, "sveebf16", 0, AARCH64_HWCAP2_SVE_EBF16) \
|
||||
LINE(AARCH64_CSSC, cssc, "cssc", 0, AARCH64_HWCAP2_CSSC) \
|
||||
LINE(AARCH64_RPRFM, rprfm, "rprfm", 0, AARCH64_HWCAP2_RPRFM) \
|
||||
LINE(AARCH64_SVE2P1, sve2p1, "sve2p1", 0, AARCH64_HWCAP2_SVE2P1) \
|
||||
LINE(AARCH64_SME2, sme2, "sme2", 0, AARCH64_HWCAP2_SME2) \
|
||||
LINE(AARCH64_SME2P1, sme2p1, "sme2p1", 0, AARCH64_HWCAP2_SME2P1) \
|
||||
LINE(AARCH64_SME_I16I32, smei16i32, "smei16i32", 0, \
|
||||
AARCH64_HWCAP2_SME_I16I32) \
|
||||
LINE(AARCH64_SME_BI32I32, smebi32i32, "smebi32i32", 0, \
|
||||
AARCH64_HWCAP2_SME_BI32I32) \
|
||||
LINE(AARCH64_SME_B16B16, smeb16b16, "smeb16b16", 0, \
|
||||
AARCH64_HWCAP2_SME_B16B16) \
|
||||
LINE(AARCH64_SME_F16F16, smef16f16, "smef16f16", 0, AARCH64_HWCAP2_SME_F16F16)
|
||||
#define INTROSPECTION_PREFIX Aarch64
|
||||
#define INTROSPECTION_ENUM_PREFIX AARCH64
|
||||
#include "define_introspection_and_hwcaps.inl"
|
@ -0,0 +1,32 @@
|
||||
// SPDX-FileCopyrightText: 2023 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_ARCH_AARCH64
|
||||
#if (defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX) || \
|
||||
defined(CPU_FEATURES_OS_ANDROID))
|
||||
#if (defined(CPU_FEATURES_COMPILER_GCC) || defined(CPU_FEATURES_COMPILER_CLANG))
|
||||
|
||||
#include "internal/cpuid_aarch64.h"
|
||||
|
||||
#ifdef CPU_FEATURES_MOCK_CPUID_AARCH64
|
||||
// Implementation will be provided by test/cpuinfo_aarch64_test.cc.
|
||||
#else
|
||||
uint64_t GetMidrEl1(void)
|
||||
{
|
||||
uint64_t midr_el1;
|
||||
// clang-format off
|
||||
__asm("mrs %0, MIDR_EL1" : "=r"(midr_el1));
|
||||
// clang-format on
|
||||
return midr_el1;
|
||||
}
|
||||
#endif // CPU_FEATURES_MOCK_CPUID_AARCH64
|
||||
|
||||
#else
|
||||
#error "Unsupported compiler, aarch64 cpuid requires either GCC or Clang."
|
||||
#endif // (defined(CPU_FEATURES_COMPILER_GCC) ||
|
||||
// defined(CPU_FEATURES_COMPILER_CLANG))
|
||||
#endif // (defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
|
||||
// || defined(CPU_FEATURES_OS_ANDROID))
|
||||
#endif // CPU_FEATURES_ARCH_AARCH64
|
@ -0,0 +1,39 @@
|
||||
// SPDX-FileCopyrightText: 2023 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_ARCH_AARCH64
|
||||
#ifdef CPU_FEATURES_OS_FREEBSD
|
||||
|
||||
#include "cpuinfo_aarch64.h"
|
||||
#include "internal/cpuid_aarch64.h"
|
||||
#include "internal/hwcaps.h"
|
||||
#include "impl_aarch64__base_implementation.inl"
|
||||
|
||||
static const Aarch64Info kEmptyAarch64Info;
|
||||
|
||||
Aarch64Info GetAarch64Info(void)
|
||||
{
|
||||
Aarch64Info info = kEmptyAarch64Info;
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (info.features.cpuid)
|
||||
{
|
||||
const uint64_t midr_el1 = GetMidrEl1();
|
||||
info.implementer = (int)ExtractBitRange(midr_el1, 31, 24);
|
||||
info.variant = (int)ExtractBitRange(midr_el1, 23, 20);
|
||||
info.part = (int)ExtractBitRange(midr_el1, 15, 4);
|
||||
info.revision = (int)ExtractBitRange(midr_el1, 3, 0);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
#endif // CPU_FEATURES_OS_FREEBSD
|
||||
#endif // CPU_FEATURES_ARCH_AARCH64
|
@ -6,80 +6,7 @@
|
||||
#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) \
|
||||
LINE(AARCH64_ECV, ecv, "ecv", 0, AARCH64_HWCAP2_ECV) \
|
||||
LINE(AARCH64_AFP, afp, "afp", 0, AARCH64_HWCAP2_AFP) \
|
||||
LINE(AARCH64_RPRES, rpres, "rpres", 0, AARCH64_HWCAP2_RPRES)
|
||||
#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 <stdbool.h>
|
||||
#include "impl_aarch64__base_implementation.inl"
|
||||
|
||||
static bool HandleAarch64Line(const LineResult result,
|
||||
Aarch64Info* const info)
|
||||
|
@ -0,0 +1,81 @@
|
||||
// SPDX-FileCopyrightText: 2021 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_ARCH_AARCH64
|
||||
#if defined(CPU_FEATURES_OS_MACOS) || defined(CPU_FEATURES_OS_IPHONE)
|
||||
|
||||
#include "impl_aarch64__base_implementation.inl"
|
||||
|
||||
#if !defined(HAVE_SYSCTLBYNAME)
|
||||
#error "Darwin needs support for sysctlbyname"
|
||||
#endif
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#if defined(CPU_FEATURES_MOCK_SYSCTL_AARCH64)
|
||||
extern bool GetDarwinSysCtlByName(const char*);
|
||||
extern int GetDarwinSysCtlByNameValue(const char* name);
|
||||
#else
|
||||
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;
|
||||
}
|
||||
|
||||
static bool GetDarwinSysCtlByName(const char* name)
|
||||
{
|
||||
return GetDarwinSysCtlByNameValue(name) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const Aarch64Info kEmptyAarch64Info;
|
||||
|
||||
Aarch64Info GetAarch64Info(void)
|
||||
{
|
||||
Aarch64Info info = kEmptyAarch64Info;
|
||||
|
||||
// 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.asimd = GetDarwinSysCtlByName("hw.optional.AdvSIMD");
|
||||
info.features.aes = GetDarwinSysCtlByName("hw.optional.arm.FEAT_AES");
|
||||
info.features.pmull = GetDarwinSysCtlByName("hw.optional.arm.FEAT_PMULL");
|
||||
info.features.sha1 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA1");
|
||||
info.features.sha2 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA256");
|
||||
info.features.crc32 = GetDarwinSysCtlByName("hw.optional.armv8_crc32");
|
||||
info.features.atomics = GetDarwinSysCtlByName("hw.optional.arm.FEAT_LSE");
|
||||
info.features.fphp = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FP16");
|
||||
info.features.asimdhp =
|
||||
GetDarwinSysCtlByName("hw.optional.arm.AdvSIMD_HPFPCvt");
|
||||
info.features.asimdrdm = GetDarwinSysCtlByName("hw.optional.arm.FEAT_RDM");
|
||||
info.features.jscvt = GetDarwinSysCtlByName("hw.optional.arm.FEAT_JSCVT");
|
||||
info.features.fcma = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FCMA");
|
||||
info.features.lrcpc = GetDarwinSysCtlByName("hw.optional.arm.FEAT_LRCPC");
|
||||
info.features.dcpop = GetDarwinSysCtlByName("hw.optional.arm.FEAT_DPB");
|
||||
info.features.sha3 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA3");
|
||||
info.features.asimddp = GetDarwinSysCtlByName("hw.optional.arm.FEAT_DotProd");
|
||||
info.features.sha512 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA512");
|
||||
info.features.asimdfhm = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FHM");
|
||||
info.features.dit = GetDarwinSysCtlByName("hw.optional.arm.FEAT_DIT");
|
||||
info.features.uscat = GetDarwinSysCtlByName("hw.optional.arm.FEAT_LSE2");
|
||||
info.features.flagm = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FlagM");
|
||||
info.features.ssbs = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SSBS");
|
||||
info.features.sb = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SB");
|
||||
info.features.flagm2 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FlagM2");
|
||||
info.features.frint = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FRINTTS");
|
||||
info.features.i8mm = GetDarwinSysCtlByName("hw.optional.arm.FEAT_I8MM");
|
||||
info.features.bf16 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_BF16");
|
||||
info.features.bti = GetDarwinSysCtlByName("hw.optional.arm.FEAT_BTI");
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
#endif // defined(CPU_FEATURES_OS_MACOS) || defined(CPU_FEATURES_OS_IPHONE)
|
||||
#endif // CPU_FEATURES_ARCH_AARCH64
|
@ -81,8 +81,7 @@
|
||||
extern bool GetWindowsIsProcessorFeaturePresent(DWORD);
|
||||
extern WORD GetWindowsNativeSystemInfoProcessorRevision();
|
||||
#else // CPU_FEATURES_MOCK_CPUID_AARCH64
|
||||
static bool
|
||||
GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
|
||||
static bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
|
||||
{
|
||||
return IsProcessorFeaturePresent(dwProcessorFeature);
|
||||
}
|
||||
@ -116,7 +115,6 @@ Aarch64Info GetAarch64Info(void)
|
||||
info.features.atomics = GetWindowsIsProcessorFeaturePresent(
|
||||
PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE);
|
||||
|
||||
|
||||
bool is_crypto_available = GetWindowsIsProcessorFeaturePresent(
|
||||
PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
|
||||
info.features.aes = is_crypto_available;
|
||||
|
@ -0,0 +1,86 @@
|
||||
// SPDX-FileCopyrightText: 2023 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
||||
#ifdef CPU_FEATURES_ARCH_LOONGARCH
|
||||
#if defined(CPU_FEATURES_OS_LINUX)
|
||||
|
||||
#include "cpuinfo_loongarch.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions for introspection.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#define INTROSPECTION_TABLE \
|
||||
LINE(LOONGARCH_CPUCFG, CPUCFG, "cfg", HWCAP_LOONGARCH_CPUCFG, 0) \
|
||||
LINE(LOONGARCH_LAM, LAM, "lam", HWCAP_LOONGARCH_LAM, 0) \
|
||||
LINE(LOONGARCH_UAL, UAL, "ual", HWCAP_LOONGARCH_UAL, 0) \
|
||||
LINE(LOONGARCH_FPU, FPU, "fpu", HWCAP_LOONGARCH_FPU, 0) \
|
||||
LINE(LOONGARCH_LSX, LSX, "lsx", HWCAP_LOONGARCH_LSX, 0) \
|
||||
LINE(LOONGARCH_LASX, LASX, "lasx", HWCAP_LOONGARCH_LASX, 0) \
|
||||
LINE(LOONGARCH_CRC32, CRC32, "crc32", HWCAP_LOONGARCH_CRC32, 0) \
|
||||
LINE(LOONGARCH_COMPLEX, COMPLEX, "complex", HWCAP_LOONGARCH_COMPLEX, 0) \
|
||||
LINE(LOONGARCH_CRYPTO, CRYPTO, "crypto", HWCAP_LOONGARCH_CRYPTO, 0) \
|
||||
LINE(LOONGARCH_LVZ, LVZ, "lvz", HWCAP_LOONGARCH_LVZ, 0) \
|
||||
LINE(LOONGARCH_LBT_X86, LBT_X86, "lbt_x86", HWCAP_LOONGARCH_LBT_X86, 0) \
|
||||
LINE(LOONGARCH_LBT_ARM, LBT_ARM, "lbt_arm", HWCAP_LOONGARCH_LBT_ARM, 0) \
|
||||
LINE(LOONGARCH_LBT_MIPS, LBT_MIPS, "lbt_mips", HWCAP_LOONGARCH_LBT_MIPS, 0) \
|
||||
LINE(LOONGARCH_PTW, PTW, "ptw", HWCAP_LOONGARCH_PTW, 0)
|
||||
#define INTROSPECTION_PREFIX LoongArch
|
||||
#define INTROSPECTION_ENUM_PREFIX LOONGARCH
|
||||
#include "define_introspection_and_hwcaps.inl"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "internal/filesystem.h"
|
||||
#include "internal/stack_line_reader.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const LoongArchInfo kEmptyLoongArchInfo;
|
||||
|
||||
static bool HandleLoongArchLine(const LineResult result,
|
||||
LoongArchInfo* 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 < LOONGARCH_LAST_; ++i)
|
||||
{
|
||||
kSetters[i](&info->features, CpuFeatures_StringView_HasWord(
|
||||
value, kCpuInfoFlags[i], ' '));
|
||||
}
|
||||
}
|
||||
}
|
||||
return !result.eof;
|
||||
}
|
||||
|
||||
static void FillProcCpuInfoData(LoongArchInfo* const info)
|
||||
{
|
||||
const int fd = CpuFeatures_OpenFile("/proc/cpuinfo");
|
||||
if (fd >= 0)
|
||||
{
|
||||
StackLineReader reader;
|
||||
StackLineReader_Initialize(&reader, fd);
|
||||
for (;;)
|
||||
{
|
||||
if (!HandleLoongArchLine(StackLineReader_NextLine(&reader), info)) break;
|
||||
}
|
||||
CpuFeatures_CloseFile(fd);
|
||||
}
|
||||
}
|
||||
|
||||
LoongArchInfo GetLoongArchInfo(void)
|
||||
{
|
||||
LoongArchInfo info = kEmptyLoongArchInfo;
|
||||
FillProcCpuInfoData(&info);
|
||||
return info;
|
||||
}
|
||||
|
||||
#endif // defined(CPU_FEATURES_OS_LINUX)
|
||||
#endif // CPU_FEATURES_ARCH_LOONGARCH
|
@ -1,4 +1,4 @@
|
||||
// SPDX-FileCopyrightText: 2017 Google LLC
|
||||
// SPDX-FileCopyrightText: 2018 IBM
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpu_features_macros.h"
|
||||
|
@ -28,6 +28,7 @@
|
||||
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
|
||||
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
|
||||
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 0) \
|
||||
LINE(RISCV_V, V, "v", RISCV_HWCAP_V, 0) \
|
||||
LINE(RISCV_Zicsr, Zicsr, "_zicsr", 0, 0) \
|
||||
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
|
||||
#define INTROSPECTION_PREFIX Riscv
|
||||
|
@ -59,7 +59,8 @@ static bool HandleS390XLine(const LineResult result,
|
||||
{
|
||||
if (CpuFeatures_StringView_IsEquals(key, str("# processors")))
|
||||
{
|
||||
strings->num_processors = CpuFeatures_StringView_ParsePositiveNumber(value);
|
||||
strings->num_processors =
|
||||
CpuFeatures_StringView_ParsePositiveNumber(value);
|
||||
}
|
||||
}
|
||||
return !result.eof;
|
||||
|
@ -36,9 +36,7 @@ uint32_t GetXCR0Eax(void)
|
||||
/* named form of xgetbv not supported on OSX, so must use byte form, see:
|
||||
https://github.com/asmjit/asmjit/issues/78
|
||||
*/
|
||||
__asm(".byte 0x0F, 0x01, 0xd0"
|
||||
: "=a"(eax), "=d"(edx)
|
||||
: "c"(0));
|
||||
__asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
|
||||
return eax;
|
||||
}
|
||||
|
||||
@ -93,6 +91,7 @@ typedef struct
|
||||
Leaf leaf_80000002; // brand string
|
||||
Leaf leaf_80000003; // brand string
|
||||
Leaf leaf_80000004; // brand string
|
||||
Leaf leaf_80000021; // AMD Extended Feature Identification 2
|
||||
} Leaves;
|
||||
|
||||
static Leaves ReadLeaves(void)
|
||||
@ -114,12 +113,12 @@ static Leaves ReadLeaves(void)
|
||||
.leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0),
|
||||
.leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0),
|
||||
.leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0),
|
||||
.leaf_80000021 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000021, 0),
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// OS support
|
||||
// TODO: Add documentation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MASK_XMM 0x2
|
||||
@ -333,6 +332,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info,
|
||||
features->fs_rep_cmpsb_scasb = IsBitSet(leaf_7_1.eax, 12);
|
||||
features->adx = IsBitSet(leaf_7.ebx, 19);
|
||||
features->lzcnt = IsBitSet(leaf_80000001.ecx, 5);
|
||||
features->lam = IsBitSet(leaf_7_1.eax, 26);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// The following section is devoted to Vector Extensions.
|
||||
@ -395,6 +395,7 @@ static void ParseCpuId(const Leaves* leaves, X86Info* info,
|
||||
features->amx_bf16 = IsBitSet(leaf_7.edx, 22);
|
||||
features->amx_tile = IsBitSet(leaf_7.edx, 24);
|
||||
features->amx_int8 = IsBitSet(leaf_7.edx, 25);
|
||||
features->amx_fp16 = IsBitSet(leaf_7_1.eax, 21);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -413,6 +414,7 @@ static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
|
||||
OsPreserves os_preserves)
|
||||
{
|
||||
const Leaf leaf_80000001 = leaves->leaf_80000001;
|
||||
const Leaf leaf_80000021 = leaves->leaf_80000021;
|
||||
|
||||
X86Features* const features = &info->features;
|
||||
|
||||
@ -425,6 +427,8 @@ static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
|
||||
{
|
||||
features->fma4 = IsBitSet(leaf_80000001.ecx, 16);
|
||||
}
|
||||
|
||||
features->uai = IsBitSet(leaf_80000021.eax, 7);
|
||||
}
|
||||
|
||||
static const X86Info kEmptyX86Info;
|
||||
@ -460,7 +464,7 @@ X86Info GetX86Info(void)
|
||||
// Microarchitecture
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF))
|
||||
#define CPUID(FAMILY, MODEL) ((((FAMILY) & 0xFF) << 8) | ((MODEL) & 0xFF))
|
||||
|
||||
X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
|
||||
{
|
||||
@ -605,6 +609,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
|
||||
}
|
||||
case CPUID(0x06, 0x97):
|
||||
case CPUID(0x06, 0x9A):
|
||||
case CPUID(0x06, 0xBE):
|
||||
// https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake
|
||||
return INTEL_ADL;
|
||||
case CPUID(0x06, 0xA5):
|
||||
@ -781,8 +786,10 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
|
||||
case CPUID(0x17, 0x60):
|
||||
case CPUID(0x17, 0x68):
|
||||
case CPUID(0x17, 0x71):
|
||||
case CPUID(0x17, 0x84):
|
||||
case CPUID(0x17, 0x90):
|
||||
case CPUID(0x17, 0x98):
|
||||
case CPUID(0x17, 0xA0):
|
||||
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_2
|
||||
return AMD_ZEN2;
|
||||
case CPUID(0x19, 0x00):
|
||||
@ -796,7 +803,9 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
|
||||
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_3
|
||||
return AMD_ZEN3;
|
||||
case CPUID(0x19, 0x10):
|
||||
case CPUID(0x19, 0x11):
|
||||
case CPUID(0x19, 0x61):
|
||||
case CPUID(0x19, 0x74):
|
||||
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_4
|
||||
return AMD_ZEN4;
|
||||
default:
|
||||
@ -1958,6 +1967,7 @@ CacheInfo GetX86CacheInfo(void)
|
||||
LINE(X86_AMX_BF16, amx_bf16, , , ) \
|
||||
LINE(X86_AMX_TILE, amx_tile, , , ) \
|
||||
LINE(X86_AMX_INT8, amx_int8, , , ) \
|
||||
LINE(X86_AMX_FP16, amx_fp16, , , ) \
|
||||
LINE(X86_PCLMULQDQ, pclmulqdq, , , ) \
|
||||
LINE(X86_SMX, smx, , , ) \
|
||||
LINE(X86_SGX, sgx, , , ) \
|
||||
@ -1976,7 +1986,9 @@ CacheInfo GetX86CacheInfo(void)
|
||||
LINE(X86_FS_REP_MOV, fs_rep_mov, , , ) \
|
||||
LINE(X86_FZ_REP_MOVSB, fz_rep_movsb, , , ) \
|
||||
LINE(X86_FS_REP_STOSB, fs_rep_stosb, , , ) \
|
||||
LINE(X86_FS_REP_CMPSB_SCASB, fs_rep_cmpsb_scasb, , , )
|
||||
LINE(X86_FS_REP_CMPSB_SCASB, fs_rep_cmpsb_scasb, , , ) \
|
||||
LINE(X86_LAM, lam, , , ) \
|
||||
LINE(X86_UAI, uai, , , )
|
||||
#define INTROSPECTION_PREFIX X86
|
||||
#define INTROSPECTION_ENUM_PREFIX X86
|
||||
#include "define_introspection.inl"
|
||||
|
@ -42,8 +42,8 @@ static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
|
||||
features->sse4_2 =
|
||||
GetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
|
||||
|
||||
// do not bother checking PF_AVX*
|
||||
// cause AVX enabled processor will have XCR0 be exposed and this function will be skipped at all
|
||||
// Do not bother checking PF_AVX* : AVX enabled processor will have their XCR0
|
||||
// register exposed and this function will be skipped altogether.
|
||||
}
|
||||
|
||||
#endif // CPU_FEATURES_OS_WINDOWS
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "cpuinfo_s390x.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
#include "cpuinfo_riscv.h"
|
||||
#elif defined(CPU_FEATURES_ARCH_LOONGARCH)
|
||||
#include "cpuinfo_loongarch.h"
|
||||
#endif
|
||||
|
||||
// Design principles
|
||||
@ -217,11 +219,14 @@ DEFINE_ADD_FLAGS(GetMipsFeaturesEnumValue, GetMipsFeaturesEnumName,
|
||||
DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures,
|
||||
PPC_LAST_)
|
||||
#elif defined(CPU_FEATURES_ARCH_S390X)
|
||||
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures,
|
||||
S390X_LAST_)
|
||||
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName,
|
||||
S390XFeatures, S390X_LAST_)
|
||||
#elif defined(CPU_FEATURES_ARCH_RISCV)
|
||||
DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName, RiscvFeatures,
|
||||
RISCV_LAST_)
|
||||
DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName,
|
||||
RiscvFeatures, RISCV_LAST_)
|
||||
#elif defined(CPU_FEATURES_ARCH_LOONGARCH)
|
||||
DEFINE_ADD_FLAGS(GetLoongArchFeaturesEnumValue, GetLoongArchFeaturesEnumName,
|
||||
LoongArchFeatures, LOONGARCH_LAST_)
|
||||
#endif
|
||||
|
||||
// Prints a json string with characters escaping.
|
||||
@ -458,6 +463,10 @@ static Node* CreateTree(void)
|
||||
AddMapEntry(root, "vendor", CreateString(info.vendor));
|
||||
AddMapEntry(root, "microarchitecture", CreateString(info.uarch));
|
||||
AddFlags(root, &info.features);
|
||||
#elif defined(CPU_FEATURES_ARCH_LOONGARCH)
|
||||
const LoongArchInfo info = GetLoongArchInfo();
|
||||
AddMapEntry(root, "arch", CreateString("loongarch"));
|
||||
AddFlags(root, &info.features);
|
||||
#endif
|
||||
return root;
|
||||
}
|
||||
|
@ -25,7 +25,11 @@ add_library(stack_line_reader_for_test ../src/stack_line_reader.c)
|
||||
target_compile_definitions(stack_line_reader_for_test PUBLIC STACK_LINE_READER_BUFFER_SIZE=16)
|
||||
target_link_libraries(stack_line_reader_for_test string_view filesystem_for_testing)
|
||||
##------------------------------------------------------------------------------
|
||||
add_library(all_libraries ../src/hwcaps.c ../src/stack_line_reader.c)
|
||||
add_library(all_libraries
|
||||
../src/hwcaps.c
|
||||
../src/hwcaps_linux_or_android.c
|
||||
../src/hwcaps_freebsd.c
|
||||
../src/stack_line_reader.c)
|
||||
target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view)
|
||||
|
||||
#
|
||||
@ -76,9 +80,18 @@ endif()
|
||||
if(PROCESSOR_IS_AARCH64)
|
||||
add_executable(cpuinfo_aarch64_test
|
||||
cpuinfo_aarch64_test.cc
|
||||
../src/impl_aarch64_cpuid.c
|
||||
../src/impl_aarch64_linux_or_android.c
|
||||
../src/impl_aarch64_windows.c)
|
||||
../src/impl_aarch64_windows.c
|
||||
../src/impl_aarch64_macos_or_iphone.c
|
||||
../src/impl_aarch64_freebsd.c
|
||||
)
|
||||
if(APPLE)
|
||||
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_SYSCTL_AARCH64)
|
||||
target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME)
|
||||
else()
|
||||
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_AARCH64)
|
||||
endif()
|
||||
target_link_libraries(cpuinfo_aarch64_test all_libraries)
|
||||
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
|
||||
endif()
|
||||
@ -110,3 +123,10 @@ if(PROCESSOR_IS_RISCV)
|
||||
target_link_libraries(cpuinfo_riscv_test all_libraries)
|
||||
add_test(NAME cpuinfo_riscv_test COMMAND cpuinfo_riscv_test)
|
||||
endif()
|
||||
##------------------------------------------------------------------------------
|
||||
## cpuinfo_loongarch_test
|
||||
if(PROCESSOR_IS_LOONGARCH)
|
||||
add_executable(cpuinfo_loongarch_test cpuinfo_loongarch_test.cc ../src/impl_loongarch_linux.c)
|
||||
target_link_libraries(cpuinfo_loongarch_test all_libraries)
|
||||
add_test(NAME cpuinfo_loongarch_test COMMAND cpuinfo_loongarch_test)
|
||||
endif()
|
@ -6,17 +6,56 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "hwcaps_for_testing.h"
|
||||
#include <set>
|
||||
|
||||
#if defined(CPU_FEATURES_OS_WINDOWS)
|
||||
#include "internal/windows_utils.h"
|
||||
#endif // CPU_FEATURES_OS_WINDOWS
|
||||
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
|
||||
#include "internal/cpuid_aarch64.h"
|
||||
#endif // defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
|
||||
|
||||
namespace cpu_features
|
||||
{
|
||||
class FakeCpuAarch64
|
||||
{
|
||||
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
|
||||
public:
|
||||
uint64_t GetMidrEl1() const { return _midr_el1; }
|
||||
|
||||
void SetMidrEl1(uint64_t midr_el1) { _midr_el1 = midr_el1; }
|
||||
|
||||
private:
|
||||
uint64_t _midr_el1;
|
||||
#elif defined(CPU_FEATURES_OS_MACOS)
|
||||
std::set<std::string> darwin_sysctlbyname_;
|
||||
std::map<std::string, int> darwin_sysctlbynamevalue_;
|
||||
|
||||
public:
|
||||
bool GetDarwinSysCtlByName(std::string name) const
|
||||
{
|
||||
return darwin_sysctlbyname_.count(name);
|
||||
}
|
||||
|
||||
int GetDarwinSysCtlByNameValue(std::string name) const
|
||||
{
|
||||
const auto iter = darwin_sysctlbynamevalue_.find(name);
|
||||
if (iter != darwin_sysctlbynamevalue_.end()) return iter->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetDarwinSysCtlByName(std::string name)
|
||||
{
|
||||
darwin_sysctlbyname_.insert(name);
|
||||
}
|
||||
|
||||
void SetDarwinSysCtlByNameValue(std::string name, int value)
|
||||
{
|
||||
darwin_sysctlbynamevalue_[name] = value;
|
||||
}
|
||||
#elif defined(CPU_FEATURES_OS_WINDOWS)
|
||||
std::set<DWORD> windows_isprocessorfeaturepresent_;
|
||||
WORD processor_revision_{};
|
||||
|
||||
public:
|
||||
#if defined(CPU_FEATURES_OS_WINDOWS)
|
||||
bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
|
||||
{
|
||||
return windows_isprocessorfeaturepresent_.count(dwProcessorFeature);
|
||||
@ -36,11 +75,7 @@ public:
|
||||
{
|
||||
processor_revision_ = wProcessorRevision;
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<DWORD> windows_isprocessorfeaturepresent_;
|
||||
WORD processor_revision_{};
|
||||
#endif // CPU_FEATURES_OS_WINDOWS
|
||||
#endif
|
||||
};
|
||||
|
||||
static FakeCpuAarch64* g_fake_cpu_instance = nullptr;
|
||||
@ -51,7 +86,23 @@ static FakeCpuAarch64& cpu()
|
||||
return *g_fake_cpu_instance;
|
||||
}
|
||||
|
||||
#if defined(CPU_FEATURES_OS_WINDOWS)
|
||||
// Define OS dependent mock functions
|
||||
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
|
||||
extern "C" uint64_t GetMidrEl1(void)
|
||||
{
|
||||
return cpu().GetMidrEl1();
|
||||
}
|
||||
#elif defined(CPU_FEATURES_OS_MACOS)
|
||||
extern "C" bool GetDarwinSysCtlByName(const char* name)
|
||||
{
|
||||
return cpu().GetDarwinSysCtlByName(name);
|
||||
}
|
||||
|
||||
extern "C" int GetDarwinSysCtlByNameValue(const char* name)
|
||||
{
|
||||
return cpu().GetDarwinSysCtlByNameValue(name);
|
||||
}
|
||||
#elif defined(CPU_FEATURES_OS_WINDOWS)
|
||||
extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
|
||||
{
|
||||
return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature);
|
||||
@ -61,7 +112,7 @@ extern "C" WORD GetWindowsNativeSystemInfoProcessorRevision()
|
||||
{
|
||||
return cpu().GetWindowsNativeSystemInfoProcessorRevision();
|
||||
}
|
||||
#endif // CPU_FEATURES_OS_WINDOWS
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -81,7 +132,7 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum)
|
||||
TEST_F(CpuidAarch64Test, Aarch64FeaturesEnum)
|
||||
{
|
||||
const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_);
|
||||
EXPECT_STREQ(last_name, "unknown_feature");
|
||||
@ -96,13 +147,9 @@ TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CPU_FEATURES_OS_LINUX)
|
||||
void DisableHardwareCapabilities()
|
||||
{
|
||||
SetHardwareCapabilities(0, 0);
|
||||
}
|
||||
|
||||
TEST(CpuinfoAarch64Test, FromHardwareCap)
|
||||
// AT_HWCAP tests
|
||||
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD)
|
||||
TEST_F(CpuidAarch64Test, FromHardwareCap)
|
||||
{
|
||||
ResetHwcaps();
|
||||
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
|
||||
@ -142,7 +189,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap)
|
||||
EXPECT_FALSE(info.features.pacg);
|
||||
}
|
||||
|
||||
TEST(CpuinfoAarch64Test, FromHardwareCap2)
|
||||
TEST_F(CpuidAarch64Test, FromHardwareCap2)
|
||||
{
|
||||
ResetHwcaps();
|
||||
SetHardwareCapabilities(AARCH64_HWCAP_FP,
|
||||
@ -171,8 +218,11 @@ TEST(CpuinfoAarch64Test, FromHardwareCap2)
|
||||
EXPECT_FALSE(info.features.dgh);
|
||||
EXPECT_FALSE(info.features.rng);
|
||||
}
|
||||
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD)
|
||||
|
||||
TEST(CpuinfoAarch64Test, ARMCortexA53)
|
||||
// OS dependent tests
|
||||
#if defined(CPU_FEATURES_OS_LINUX)
|
||||
TEST_F(CpuidAarch64Test, ARMCortexA53)
|
||||
{
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
@ -253,10 +303,91 @@ CPU revision : 3)");
|
||||
EXPECT_FALSE(info.features.ecv);
|
||||
EXPECT_FALSE(info.features.afp);
|
||||
EXPECT_FALSE(info.features.rpres);
|
||||
EXPECT_FALSE(info.features.mte3);
|
||||
EXPECT_FALSE(info.features.sme);
|
||||
EXPECT_FALSE(info.features.smei16i64);
|
||||
EXPECT_FALSE(info.features.smef64f64);
|
||||
EXPECT_FALSE(info.features.smei8i32);
|
||||
EXPECT_FALSE(info.features.smef16f32);
|
||||
EXPECT_FALSE(info.features.smeb16f32);
|
||||
EXPECT_FALSE(info.features.smef32f32);
|
||||
EXPECT_FALSE(info.features.smefa64);
|
||||
EXPECT_FALSE(info.features.wfxt);
|
||||
EXPECT_FALSE(info.features.ebf16);
|
||||
EXPECT_FALSE(info.features.sveebf16);
|
||||
EXPECT_FALSE(info.features.cssc);
|
||||
EXPECT_FALSE(info.features.rprfm);
|
||||
EXPECT_FALSE(info.features.sve2p1);
|
||||
EXPECT_FALSE(info.features.sme2);
|
||||
EXPECT_FALSE(info.features.sme2p1);
|
||||
EXPECT_FALSE(info.features.smei16i32);
|
||||
EXPECT_FALSE(info.features.smebi32i32);
|
||||
EXPECT_FALSE(info.features.smeb16b16);
|
||||
EXPECT_FALSE(info.features.smef16f16);
|
||||
}
|
||||
#endif // CPU_FEATURES_OS_LINUX
|
||||
#elif defined(CPU_FEATURES_OS_MACOS)
|
||||
TEST_F(CpuidAarch64Test, FromDarwinSysctlFromName)
|
||||
{
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.floatingpoint");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.neon");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.AdvSIMD_HPFPCvt");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_FP16");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_LSE");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.armv8_crc32");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_FHM");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA512");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA3");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.amx_version");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.ucnormal_mem");
|
||||
cpu().SetDarwinSysCtlByName("hw.optional.arm64");
|
||||
|
||||
#if defined(CPU_FEATURES_OS_WINDOWS)
|
||||
cpu().SetDarwinSysCtlByNameValue("hw.cputype", 16777228);
|
||||
cpu().SetDarwinSysCtlByNameValue("hw.cpusubtype", 2);
|
||||
cpu().SetDarwinSysCtlByNameValue("hw.cpu64bit", 1);
|
||||
cpu().SetDarwinSysCtlByNameValue("hw.cpufamily", 458787763);
|
||||
cpu().SetDarwinSysCtlByNameValue("hw.cpusubfamily", 2);
|
||||
|
||||
const auto info = GetAarch64Info();
|
||||
|
||||
EXPECT_EQ(info.implementer, 0x100000C);
|
||||
EXPECT_EQ(info.variant, 2);
|
||||
EXPECT_EQ(info.part, 0x1B588BB3);
|
||||
EXPECT_EQ(info.revision, 2);
|
||||
|
||||
EXPECT_TRUE(info.features.fp);
|
||||
EXPECT_FALSE(info.features.asimd);
|
||||
EXPECT_FALSE(info.features.evtstrm);
|
||||
EXPECT_FALSE(info.features.aes);
|
||||
EXPECT_FALSE(info.features.pmull);
|
||||
EXPECT_FALSE(info.features.sha1);
|
||||
EXPECT_FALSE(info.features.sha2);
|
||||
EXPECT_TRUE(info.features.crc32);
|
||||
EXPECT_TRUE(info.features.atomics);
|
||||
EXPECT_TRUE(info.features.fphp);
|
||||
EXPECT_FALSE(info.features.asimdhp);
|
||||
EXPECT_FALSE(info.features.cpuid);
|
||||
EXPECT_FALSE(info.features.asimdrdm);
|
||||
EXPECT_FALSE(info.features.jscvt);
|
||||
EXPECT_FALSE(info.features.fcma);
|
||||
EXPECT_FALSE(info.features.lrcpc);
|
||||
EXPECT_FALSE(info.features.dcpop);
|
||||
EXPECT_TRUE(info.features.sha3);
|
||||
EXPECT_FALSE(info.features.sm3);
|
||||
EXPECT_FALSE(info.features.sm4);
|
||||
EXPECT_FALSE(info.features.asimddp);
|
||||
EXPECT_TRUE(info.features.sha512);
|
||||
EXPECT_FALSE(info.features.sve);
|
||||
EXPECT_TRUE(info.features.asimdfhm);
|
||||
EXPECT_FALSE(info.features.dit);
|
||||
EXPECT_FALSE(info.features.uscat);
|
||||
EXPECT_FALSE(info.features.ilrcpc);
|
||||
EXPECT_FALSE(info.features.flagm);
|
||||
EXPECT_FALSE(info.features.ssbs);
|
||||
EXPECT_FALSE(info.features.sb);
|
||||
EXPECT_FALSE(info.features.paca);
|
||||
EXPECT_FALSE(info.features.pacg);
|
||||
}
|
||||
#elif defined(CPU_FEATURES_OS_WINDOWS)
|
||||
TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4)
|
||||
{
|
||||
cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03);
|
||||
@ -280,7 +411,38 @@ TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4)
|
||||
EXPECT_FALSE(info.features.jscvt);
|
||||
EXPECT_FALSE(info.features.lrcpc);
|
||||
}
|
||||
#endif // CPU_FEATURES_OS_WINDOWS
|
||||
#elif defined(CPU_FEATURES_OS_FREEBSD)
|
||||
TEST_F(CpuidAarch64Test, MrsMidrEl1_RPI4)
|
||||
{
|
||||
ResetHwcaps();
|
||||
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_CPUID, 0);
|
||||
cpu().SetMidrEl1(0x410FD083);
|
||||
const auto info = GetAarch64Info();
|
||||
|
||||
EXPECT_EQ(info.implementer, 0x41);
|
||||
EXPECT_EQ(info.variant, 0);
|
||||
EXPECT_EQ(info.part, 0xD08);
|
||||
EXPECT_EQ(info.revision, 0x3);
|
||||
|
||||
EXPECT_TRUE(info.features.fp);
|
||||
|
||||
EXPECT_FALSE(info.features.dcpodp);
|
||||
EXPECT_FALSE(info.features.sveaes);
|
||||
EXPECT_FALSE(info.features.svepmull);
|
||||
EXPECT_FALSE(info.features.svebitperm);
|
||||
EXPECT_FALSE(info.features.svesha3);
|
||||
EXPECT_FALSE(info.features.svesm4);
|
||||
EXPECT_FALSE(info.features.flagm2);
|
||||
EXPECT_FALSE(info.features.frint);
|
||||
EXPECT_FALSE(info.features.svei8mm);
|
||||
EXPECT_FALSE(info.features.svef32mm);
|
||||
EXPECT_FALSE(info.features.svef64mm);
|
||||
EXPECT_FALSE(info.features.svebf16);
|
||||
EXPECT_FALSE(info.features.i8mm);
|
||||
EXPECT_FALSE(info.features.bf16);
|
||||
EXPECT_FALSE(info.features.dgh);
|
||||
EXPECT_FALSE(info.features.rng);
|
||||
}
|
||||
#endif // CPU_FEATURES_OS_FREEBSD
|
||||
} // namespace
|
||||
} // namespace cpu_features
|
@ -0,0 +1,171 @@
|
||||
// SPDX-FileCopyrightText: 2022 Google LLC
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "cpuinfo_loongarch.h"
|
||||
#include "filesystem_for_testing.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "hwcaps_for_testing.h"
|
||||
|
||||
namespace cpu_features
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
TEST(CpuinfoLoongArchvTest, UnknownFromCpuInfo)
|
||||
{
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(
|
||||
system type : generic-loongson-machine
|
||||
|
||||
processor : 0
|
||||
package : 0
|
||||
core : 0
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000-HV
|
||||
CPU Revision : 0x11
|
||||
FPU Revision : 0x00
|
||||
CPU MHz : 2500.00
|
||||
BogoMIPS : 5000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu lsx lasx crc32 complex crypto lvz lbt_x86 lbt_arm lbt_mips
|
||||
Hardware Watchpoint : yes, iwatch count: 8, dwatch count: 8
|
||||
|
||||
processor : 1
|
||||
package : 0
|
||||
core : 1
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000-HV
|
||||
CPU Revision : 0x11
|
||||
FPU Revision : 0x00
|
||||
CPU MHz : 2500.00
|
||||
BogoMIPS : 5000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu lsx lasx crc32 complex crypto lvz lbt_x86 lbt_arm lbt_mips
|
||||
Hardware Watchpoint : yes, iwatch count: 8, dwatch count: 8
|
||||
|
||||
processor : 2
|
||||
package : 0
|
||||
core : 2
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000-HV
|
||||
CPU Revision : 0x11
|
||||
FPU Revision : 0x00
|
||||
CPU MHz : 2500.00
|
||||
BogoMIPS : 5000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu lsx lasx crc32 complex crypto lvz lbt_x86 lbt_arm lbt_mips
|
||||
Hardware Watchpoint : yes, iwatch count: 8, dwatch count: 8
|
||||
|
||||
processor : 3
|
||||
package : 0
|
||||
core : 3
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000-HV
|
||||
CPU Revision : 0x11
|
||||
FPU Revision : 0x00
|
||||
CPU MHz : 2500.00
|
||||
BogoMIPS : 5000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu lsx lasx crc32 complex crypto lvz lbt_x86 lbt_arm lbt_mips
|
||||
Hardware Watchpoint : yes, iwatch count: 8, dwatch count: 8)");
|
||||
const auto info = GetLoongArchInfo();
|
||||
EXPECT_FALSE(info.features.CPUCFG);
|
||||
EXPECT_TRUE(info.features.LAM);
|
||||
EXPECT_TRUE(info.features.UAL);
|
||||
EXPECT_TRUE(info.features.FPU);
|
||||
EXPECT_TRUE(info.features.LSX);
|
||||
EXPECT_TRUE(info.features.LASX);
|
||||
EXPECT_TRUE(info.features.CRC32);
|
||||
EXPECT_TRUE(info.features.COMPLEX);
|
||||
EXPECT_TRUE(info.features.CRYPTO);
|
||||
EXPECT_TRUE(info.features.LVZ);
|
||||
EXPECT_TRUE(info.features.LBT_X86);
|
||||
EXPECT_TRUE(info.features.LBT_ARM);
|
||||
EXPECT_TRUE(info.features.LBT_MIPS);
|
||||
}
|
||||
|
||||
TEST(CpuinfoLoongArchvTest, QemuCpuInfo)
|
||||
{
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(
|
||||
system type : generic-loongson-machine
|
||||
|
||||
processor : 0
|
||||
package : 0
|
||||
core : 0
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000
|
||||
CPU Revision : 0x10
|
||||
FPU Revision : 0x01
|
||||
CPU MHz : 2000.00
|
||||
BogoMIPS : 4000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu crc32
|
||||
Hardware Watchpoint : yes, iwatch count: 0, dwatch count: 0
|
||||
|
||||
processor : 1
|
||||
package : 0
|
||||
core : 1
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000
|
||||
CPU Revision : 0x10
|
||||
FPU Revision : 0x01
|
||||
CPU MHz : 2000.00
|
||||
BogoMIPS : 4000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu crc32
|
||||
Hardware Watchpoint : yes, iwatch count: 0, dwatch count: 0
|
||||
|
||||
processor : 2
|
||||
package : 0
|
||||
core : 2
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000
|
||||
CPU Revision : 0x10
|
||||
FPU Revision : 0x01
|
||||
CPU MHz : 2000.00
|
||||
BogoMIPS : 4000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu crc32
|
||||
Hardware Watchpoint : yes, iwatch count: 0, dwatch count: 0
|
||||
|
||||
processor : 3
|
||||
package : 0
|
||||
core : 3
|
||||
CPU Family : Loongson-64bit
|
||||
Model Name : Loongson-3A5000
|
||||
CPU Revision : 0x10
|
||||
FPU Revision : 0x01
|
||||
CPU MHz : 2000.00
|
||||
BogoMIPS : 4000.00
|
||||
TLB Entries : 2112
|
||||
Address Sizes : 48 bits physical, 48 bits virtual
|
||||
ISA : loongarch32 loongarch64
|
||||
Features : cpucfg lam ual fpu crc32
|
||||
Hardware Watchpoint : yes, iwatch count: 0, dwatch count: 0)");
|
||||
const auto info = GetLoongArchInfo();
|
||||
EXPECT_FALSE(info.features.CPUCFG);
|
||||
EXPECT_TRUE(info.features.LAM);
|
||||
EXPECT_TRUE(info.features.UAL);
|
||||
EXPECT_TRUE(info.features.FPU);
|
||||
EXPECT_TRUE(info.features.CRC32);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace cpu_features
|
@ -32,6 +32,7 @@ uarch : thead,c906)");
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
EXPECT_FALSE(info.features.V);
|
||||
}
|
||||
|
||||
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/Kendryte-K510-4.17.0.cpuinfo
|
||||
@ -50,6 +51,7 @@ mmu : sv39");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_STREQ(info.uarch, "");
|
||||
EXPECT_STREQ(info.vendor, "");
|
||||
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
@ -58,6 +60,7 @@ mmu : sv39");
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
EXPECT_FALSE(info.features.V);
|
||||
}
|
||||
|
||||
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/T-Head-C910-5.10.4.cpuinfo
|
||||
@ -76,6 +79,7 @@ cpu-l2cache : 2MB
|
||||
cpu-tlb : 1024 4-ways
|
||||
cpu-cacheline : 64Bytes
|
||||
cpu-vector : 0.7.1
|
||||
|
||||
processor : 1
|
||||
hart : 1
|
||||
isa : rv64imafdcsu
|
||||
@ -90,6 +94,7 @@ cpu-vector : 0.7.1");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_STREQ(info.uarch, "");
|
||||
EXPECT_STREQ(info.vendor, "");
|
||||
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
@ -98,7 +103,9 @@ cpu-vector : 0.7.1");
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
EXPECT_FALSE(info.features.V);
|
||||
}
|
||||
|
||||
TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) {
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
@ -108,16 +115,19 @@ hart : 2
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0
|
||||
|
||||
processor : 1
|
||||
hart : 1
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0
|
||||
|
||||
processor : 2
|
||||
hart : 3
|
||||
isa : rv64imafdc
|
||||
mmu : sv39
|
||||
uarch : sifive,bullet0
|
||||
|
||||
processor : 3
|
||||
hart : 4
|
||||
isa : rv64imafdc
|
||||
@ -135,6 +145,28 @@ uarch : sifive,bullet0)");
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
EXPECT_FALSE(info.features.V);
|
||||
}
|
||||
|
||||
TEST(CpuinfoRiscvTest, QemuCpuInfo)
|
||||
{
|
||||
ResetHwcaps();
|
||||
auto& fs = GetEmptyFilesystem();
|
||||
fs.CreateFile("/proc/cpuinfo", R"(
|
||||
processor : 0
|
||||
hart : 0
|
||||
isa : rv64imafdcvh_zba_zbb_zbc_zbs
|
||||
mmu : sv48)");
|
||||
const auto info = GetRiscvInfo();
|
||||
EXPECT_FALSE(info.features.RV32I);
|
||||
EXPECT_TRUE(info.features.RV64I);
|
||||
EXPECT_TRUE(info.features.M);
|
||||
EXPECT_TRUE(info.features.A);
|
||||
EXPECT_TRUE(info.features.F);
|
||||
EXPECT_TRUE(info.features.D);
|
||||
EXPECT_FALSE(info.features.Q);
|
||||
EXPECT_TRUE(info.features.C);
|
||||
EXPECT_TRUE(info.features.V);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -195,6 +195,8 @@ TEST_F(CpuidX86Test, SandyBridge)
|
||||
EXPECT_FALSE(features.movbe);
|
||||
EXPECT_FALSE(features.rdrnd);
|
||||
EXPECT_FALSE(features.adx);
|
||||
EXPECT_FALSE(features.lam);
|
||||
EXPECT_FALSE(features.uai);
|
||||
}
|
||||
|
||||
const int UNDEF = -1;
|
||||
@ -802,6 +804,21 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0880F40_K17_CPUID.txt
|
||||
TEST_F(CpuidX86Test, AMD_K17_ZEN2_4800S)
|
||||
{
|
||||
cpu().SetLeaves({
|
||||
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
|
||||
{{0x00000001, 0}, Leaf{0x00880F40, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
|
||||
});
|
||||
const auto info = GetX86Info();
|
||||
|
||||
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
|
||||
EXPECT_EQ(info.family, 0x17);
|
||||
EXPECT_EQ(info.model, 0x84);
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID3.txt
|
||||
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
|
||||
{
|
||||
@ -931,6 +948,7 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL)
|
||||
{{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2035206E, 0x30303637}},
|
||||
{{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}},
|
||||
{{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}},
|
||||
{{0x80000021, 0}, Leaf{0x00062FCF, 0x0000015C, 0x00000000, 0x00000000}},
|
||||
});
|
||||
const auto info = GetX86Info();
|
||||
|
||||
@ -939,9 +957,26 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL)
|
||||
EXPECT_EQ(info.model, 0x61);
|
||||
EXPECT_STREQ(info.brand_string,
|
||||
"AMD Ryzen 5 7600X 6-Core Processor ");
|
||||
EXPECT_TRUE(info.features.uai);
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A70F41_K19_Phoenix_03_CPUID.txt
|
||||
TEST_F(CpuidX86Test, AMD_K19_ZEN4_PHOENIX)
|
||||
{
|
||||
cpu().SetLeaves({
|
||||
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
|
||||
{{0x00000001, 0}, Leaf{0x00A70F41, 0x00100800, 0x7EF8320B, 0x178BFBFF}},
|
||||
{{0x80000000, 0}, Leaf{0x80000028, 0x68747541, 0x444D4163, 0x69746E65}},
|
||||
{{0x80000001, 0}, Leaf{0x00A70F41, 0x50000000, 0x75C237FF, 0x2FD3FBFF}},
|
||||
});
|
||||
const auto info = GetX86Info();
|
||||
|
||||
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
|
||||
EXPECT_EQ(info.family, 0x19);
|
||||
EXPECT_EQ(info.model, 0x74);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F11_Hygon_01_CPUID.txt
|
||||
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250)
|
||||
{
|
||||
@ -964,6 +999,36 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250)
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD08A0F00_K17_Mendocino_01_CPUID.txt
|
||||
TEST_F(CpuidX86Test, AMD_ZEN2_MENDOCINO)
|
||||
{
|
||||
cpu().SetLeaves({
|
||||
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
|
||||
{{0x00000001, 0}, Leaf{0x008A0F00, 0x00080800, 0x7EF8320B, 0x178BFBFF}},
|
||||
});
|
||||
const auto info = GetX86Info();
|
||||
|
||||
EXPECT_EQ(info.model, 0xA0);
|
||||
EXPECT_EQ(info.family, 0x17);
|
||||
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A10F11_K19_Genoa_02_CPUID.txt
|
||||
TEST_F(CpuidX86Test, AMD_K19_ZEN4_GENOA)
|
||||
{
|
||||
cpu().SetLeaves({
|
||||
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
|
||||
{{0x00000001, 0}, Leaf{0x00A10F11, 0x00200800, 0x7EFA320B, 0x178BFBFF}},
|
||||
});
|
||||
const auto info = GetX86Info();
|
||||
|
||||
EXPECT_EQ(info.model, 0x11);
|
||||
EXPECT_EQ(info.family, 0x19);
|
||||
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906A4_AlderLakeP_00_CPUID.txt
|
||||
TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX_VNNI)
|
||||
{
|
||||
@ -1742,6 +1807,20 @@ TEST_F(CpuidX86Test, INTEL_RAPTOR_LAKE_S)
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_RPL);
|
||||
}
|
||||
|
||||
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B06E0_AlderLakeN_03_CPUID.txt
|
||||
TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_N)
|
||||
{
|
||||
cpu().SetLeaves({
|
||||
{{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
|
||||
{{0x00000001, 0}, Leaf{0x000B06E0, 0x00800800, 0x7FFAFBBF, 0xBFEBFBFF}},
|
||||
});
|
||||
const auto info = GetX86Info();
|
||||
|
||||
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
|
||||
EXPECT_EQ(info.family, 0x06);
|
||||
EXPECT_EQ(info.model, 0xBE);
|
||||
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL);
|
||||
}
|
||||
|
||||
// https://github.com/google/cpu_features/issues/200
|
||||
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt
|
||||
|
@ -544,7 +544,6 @@ if(NOT (CMAKE_GENERATOR STREQUAL Xcode))
|
||||
PRIVATE
|
||||
$<TARGET_PROPERTY:cpu_features,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
)
|
||||
add_dependencies(volk_gnsssdr_obj list_cpu_features)
|
||||
endif()
|
||||
endif()
|
||||
# Configure object target properties
|
||||
|
@ -298,11 +298,14 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
const std::shared_ptr<Beidou_Dnav_Ephemeris> tmp_obj = std::make_shared<Beidou_Dnav_Ephemeris>(d_nav.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New BEIDOU B1I DNAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << " dB-Hz" << std::endl;
|
||||
std::cout << std::setprecision(default_precision); // restore defaults
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl;
|
||||
}
|
||||
if (d_nav.have_new_utc_model() == true)
|
||||
{
|
||||
@ -310,7 +313,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
const std::shared_ptr<Beidou_Dnav_Utc_Model> tmp_obj = std::make_shared<Beidou_Dnav_Utc_Model>(d_nav.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV UTC Model data have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New BEIDOU B1I DNAV utc model message received in channel "
|
||||
<< d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
@ -323,7 +330,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
const std::shared_ptr<Beidou_Dnav_Iono> tmp_obj = std::make_shared<Beidou_Dnav_Iono>(d_nav.get_iono());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Iono data have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel
|
||||
<< ": Iono model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << cn0 << std::setprecision(default_precision)
|
||||
@ -335,7 +346,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
// std::shared_ptr<Beidou_Dnav_Almanac> tmp_obj = std::make_shared<Beidou_Dnav_Almanac>(d_nav.get_almanac(slot_nbr));
|
||||
// this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Almanac data have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New BEIDOU B1I DNAV almanac received in channel " << d_channel
|
||||
<< " from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
|
@ -300,7 +300,11 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel"
|
||||
<< d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -314,7 +318,11 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV UTC Model data have been received in channel"
|
||||
<< d_channel << " from satellite " << d_satellite;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV utc model message received in channel "
|
||||
<< d_channel << ": UTC model parameters from satellite "
|
||||
<< d_satellite
|
||||
@ -329,7 +337,11 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Iono data have been received in channel" << d_channel
|
||||
<< " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV Iono message received in channel "
|
||||
<< d_channel << ": Iono model parameters from satellite "
|
||||
<< d_satellite << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -344,7 +356,11 @@ void beidou_b3i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
|
||||
// pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "BEIDOU DNAV Almanac data have been received in channel"
|
||||
<< d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV almanac received in channel " << d_channel
|
||||
<< " from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
|
@ -440,7 +440,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_inav_nav.get_ephemeris());
|
||||
if (d_band == '1')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite << " with CN0="
|
||||
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -448,7 +452,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
}
|
||||
else if (d_band == '7')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE
|
||||
<< "New Galileo E5b I/NAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite << " with CN0="
|
||||
@ -465,7 +473,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
{
|
||||
const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_inav_nav.get_reduced_ced());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New Galileo E1 I/NAV reduced CED message received in channel "
|
||||
<< d_channel << " from satellite " << d_satellite << " with CN0="
|
||||
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -480,7 +492,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
if (d_band == '1')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
|
||||
<< ": iono/GST model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -488,7 +504,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
}
|
||||
else if (d_band == '7')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel "
|
||||
<< d_channel << ": iono/GST model parameters from satellite "
|
||||
<< d_satellite << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -503,7 +523,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
if (d_band == '1')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -511,7 +535,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
}
|
||||
else if (d_band == '7')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel "
|
||||
<< d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
@ -530,14 +558,22 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
|
||||
// debug
|
||||
if (d_band == '1')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel
|
||||
<< " from satellite " << d_satellite << " with CN0="
|
||||
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl;
|
||||
}
|
||||
else if (d_band == '7')
|
||||
{
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE << "Galileo E5b I/NAV almanac received in channel "
|
||||
<< d_channel << " from satellite " << d_satellite << " with CN0="
|
||||
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -612,7 +648,11 @@ void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t
|
||||
{
|
||||
const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_fnav_nav.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
|
||||
<< d_channel << ": ephemeris from satellite " << d_satellite << " with CN0="
|
||||
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -623,7 +663,11 @@ void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t
|
||||
{
|
||||
const std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(d_fnav_nav.get_iono());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
|
||||
<< d_channel << ": iono/GST model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -634,7 +678,11 @@ void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t
|
||||
{
|
||||
const std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(d_fnav_nav.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
|
||||
<< d_channel << ": UTC model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -695,8 +743,13 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float *
|
||||
if (is_page_dummy != d_cnav_dummy_page)
|
||||
{
|
||||
d_cnav_dummy_page = is_page_dummy;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel " << d_channel << " from satellite "
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel "
|
||||
<< d_channel << " from satellite "
|
||||
<< d_satellite << " with CN0="
|
||||
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz"
|
||||
<< TEXT_RESET << std::endl;
|
||||
@ -713,7 +766,11 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float *
|
||||
if (d_print_cnav_page == true)
|
||||
{
|
||||
d_print_cnav_page = false; // only print the first page
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 HAS pages"
|
||||
<< (d_cnav_nav.is_HAS_in_test_mode() == true ? " (test mode) " : " ")
|
||||
<< "in channel " << d_channel << " from satellite " << d_satellite
|
||||
|
@ -239,7 +239,11 @@ void glonass_l1_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
|
||||
const std::shared_ptr<Glonass_Gnav_Ephemeris> tmp_obj = std::make_shared<Glonass_Gnav_Ephemeris>(d_nav.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "GLONASS GNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -251,7 +255,11 @@ void glonass_l1_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
|
||||
const std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "GLONASS GNAV UTC Model data have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -264,7 +272,11 @@ void glonass_l1_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
|
||||
tmp_obj = std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac(slot_nbr));
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "GLONASS GNAV Almanac data have been received in channel" << d_channel << " in slot number " << slot_nbr;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New GLONASS L1 GNAV almanac received in channel " << d_channel << " from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
<< " dB-Hz" << std::endl;
|
||||
|
@ -239,7 +239,11 @@ void glonass_l2_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
|
||||
const std::shared_ptr<Glonass_Gnav_Ephemeris> tmp_obj = std::make_shared<Glonass_Gnav_Ephemeris>(d_nav.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "GLONASS GNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -251,7 +255,11 @@ void glonass_l2_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
|
||||
const std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "GLONASS GNAV UTC Model data have been received in channel" << d_channel << " from satellite " << d_satellite;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
@ -263,7 +271,11 @@ void glonass_l2_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
|
||||
const std::shared_ptr<Glonass_Gnav_Almanac> tmp_obj = std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac(slot_nbr));
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
LOG(INFO) << "GLONASS GNAV Almanac data have been received in channel" << d_channel << " in slot number " << slot_nbr;
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV almanac received in channel " << d_channel
|
||||
<< " from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
|
||||
|
@ -397,7 +397,11 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe(double cn0, bool flag_inver
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << "New GPS NAV message received in channel " << this->d_channel << ": "
|
||||
<< "subframe "
|
||||
<< subframe_ID << " from satellite "
|
||||
|
@ -259,7 +259,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
|
||||
// get ephemeris object for this SV
|
||||
const std::shared_ptr<Gps_CNAV_Ephemeris> tmp_obj = std::make_shared<Gps_CNAV_Ephemeris>(d_CNAV_Message.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
|
||||
@ -269,7 +273,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
|
||||
{
|
||||
const std::shared_ptr<Gps_CNAV_Iono> tmp_obj = std::make_shared<Gps_CNAV_Iono>(d_CNAV_Message.get_iono());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
|
||||
<< ": iono model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
|
||||
@ -280,7 +288,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
|
||||
{
|
||||
const std::shared_ptr<Gps_CNAV_Utc_Model> tmp_obj = std::make_shared<Gps_CNAV_Utc_Model>(d_CNAV_Message.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
|
||||
|
@ -256,7 +256,11 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
|
||||
// get ephemeris object for this SV
|
||||
const std::shared_ptr<Gps_CNAV_Ephemeris> tmp_obj = std::make_shared<Gps_CNAV_Ephemeris>(d_CNAV_Message.get_ephemeris());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
|
||||
<< ": ephemeris from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz
|
||||
@ -266,7 +270,11 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
|
||||
{
|
||||
const std::shared_ptr<Gps_CNAV_Iono> tmp_obj = std::make_shared<Gps_CNAV_Iono>(d_CNAV_Message.get_iono());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
|
||||
<< ": iono model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
|
||||
@ -277,7 +285,11 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
|
||||
{
|
||||
const std::shared_ptr<Gps_CNAV_Utc_Model> tmp_obj = std::make_shared<Gps_CNAV_Utc_Model>(d_CNAV_Message.get_utc_model());
|
||||
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
|
||||
#if __cplusplus == 201103L
|
||||
const int default_precision = std::cout.precision();
|
||||
#else
|
||||
const auto default_precision{std::cout.precision()};
|
||||
#endif
|
||||
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
|
||||
<< ": UTC model parameters from satellite " << d_satellite
|
||||
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz
|
||||
|
Loading…
Reference in New Issue
Block a user