Update local version of cpu_features to 0.9.0

This commit is contained in:
Carles Fernandez 2023-11-04 11:54:16 +01:00
parent c004232518
commit 710f85dc03
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
48 changed files with 1862 additions and 385 deletions

View File

@ -71,7 +71,6 @@ jobs:
cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/ cmake ../src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/
echo "Build with $(nproc) thread(s)" echo "Build with $(nproc) thread(s)"
make -j$(nproc) make -j$(nproc)
./cpu_features/list_cpu_features
./apps/volk_gnsssdr-config-info --alignment ./apps/volk_gnsssdr-config-info --alignment
./apps/volk_gnsssdr-config-info --avail-machines ./apps/volk_gnsssdr-config-info --avail-machines
./apps/volk_gnsssdr-config-info --all-machines ./apps/volk_gnsssdr-config-info --all-machines

View File

@ -1208,8 +1208,14 @@ if(NOT VOLKGNSSSDR_FOUND)
endif() endif()
include(GNUInstallDirs) include(GNUInstallDirs)
set(SUPPORTED_CPU_FEATURES_ARCH FALSE) set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips" OR
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv") 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) set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
endif() endif()
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64) if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
@ -1248,14 +1254,14 @@ if(NOT VOLKGNSSSDR_FOUND)
set_package_properties(CPUFEATURES PROPERTIES set_package_properties(CPUFEATURES PROPERTIES
DESCRIPTION "A cross platform C99 library to get CPU features at runtime (version: ${CPUFEATURES_VERSION})" 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) set(ENABLE_CPUFEATURES OFF)
endif() endif()
else() else()
set_package_properties(CPUFEATURES PROPERTIES set_package_properties(CPUFEATURES PROPERTIES
DESCRIPTION "A cross platform C99 library to get CPU features at runtime" 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) set(ENABLE_CPUFEATURES OFF)
else() else()
set_package_properties(CPUFEATURES PROPERTIES set_package_properties(CPUFEATURES PROPERTIES

View File

@ -31,6 +31,10 @@ All notable changes to GNSS-SDR will be documented in this file.
- `geohash`, an - `geohash`, an
[encoded geographic location](https://en.wikipedia.org/wiki/Geohash). [encoded geographic location](https://en.wikipedia.org/wiki/Geohash).
### Improvements in Portability:
- Updated local `cpu_features` library to v0.9.0.
### Improvements in Repeatability: ### Improvements in Repeatability:
- A Kalman filter is now available in the PVT block, smoothing the outputs of a - A Kalman filter is now available in the PVT block, smoothing the outputs of a

View File

@ -257,8 +257,14 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortex")
endif() endif()
# cpu_features - sensible defaults, user settable option # cpu_features - sensible defaults, user settable option
if(CMAKE_SYSTEM_PROCESSOR MATCHES if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips" OR
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv") 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) option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON)
else() else()
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF) 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) if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
find_package(CPUFEATURES) 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) set(USE_CPU_FEATURES OFF)
unset(CPUFEATURES_FOUND CACHE) 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") message(STATUS "Building volk-gnsssdr without cpu_features, installed version v${CPUFEATURES_VERSION} does not support the ${CMAKE_SYSTEM_PROCESSOR} architecture")
@ -274,20 +280,33 @@ if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
set(USE_CPU_FEATURES ON) set(USE_CPU_FEATURES ON)
endif() endif()
if(NOT CPUFEATURES_FOUND) if(NOT CPUFEATURES_FOUND)
message(STATUS "Building volk-gnsssdr with cpu_features") if(CMAKE_VERSION VERSION_LESS 3.13)
set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE) message(STATUS "Building volk-gnsssdr without cpu_features")
set(BUILD_PIC ON CACHE BOOL else()
"Build cpu_features with Position Independent Code (PIC)." message(STATUS "Building volk-gnsssdr with cpu_features")
FORCE set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE)
) set(BUILD_PIC ON CACHE BOOL
set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "Build cpu_features with Position Independent Code (PIC)."
"Build cpu_features with Position Independent Code (PIC)." FORCE
FORCE )
) set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL
set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}") "Build cpu_features with Position Independent Code (PIC)."
set(BUILD_SHARED_LIBS OFF) FORCE
add_subdirectory(cpu_features) )
set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}") 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() endif()
else() else()
message(STATUS "Building volk-gnsssdr without cpu_features") message(STATUS "Building volk-gnsssdr without cpu_features")

View File

@ -232,7 +232,7 @@ void read_results(std::vector<volk_gnsssdr_test_results_t> *results, std::string
if (single_kernel_result.size() == 3) 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.name = std::string(single_kernel_result[0]);
kernel_result.config_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]); kernel_result.best_arch_u = std::string(single_kernel_result[1]);

View File

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2017 Google LLC # SPDX-FileCopyrightText: 2017 Google LLC
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.13)
# option() honors normal variables. # option() honors normal variables.
# see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html # see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html
@ -9,11 +9,16 @@ if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW) cmake_policy(SET CMP0077 NEW)
endif() endif()
project(CpuFeatures VERSION 0.7.0 LANGUAGES C) project(CpuFeatures VERSION 0.9.0 LANGUAGES C)
set(CMAKE_C_STANDARD 99) 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() endif()
# Default Build Type to be Release # Default Build Type to be Release
@ -23,6 +28,22 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE) FORCE)
endif() 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 # BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
# it prominent in the GUI. # 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). # 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_POWER FALSE)
set(PROCESSOR_IS_S390X FALSE) set(PROCESSOR_IS_S390X FALSE)
set(PROCESSOR_IS_RISCV FALSE) set(PROCESSOR_IS_RISCV FALSE)
set(PROCESSOR_IS_LOONGARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(PROCESSOR_IS_MIPS TRUE) 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) set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(PROCESSOR_IS_ARM TRUE) 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) set(PROCESSOR_IS_X86 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
set(PROCESSOR_IS_POWER TRUE) set(PROCESSOR_IS_POWER TRUE)
@ -72,6 +94,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
set(PROCESSOR_IS_S390X TRUE) set(PROCESSOR_IS_S390X TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv")
set(PROCESSOR_IS_RISCV TRUE) set(PROCESSOR_IS_RISCV TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
set(PROCESSOR_IS_LOONGARCH TRUE)
endif() endif()
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME) 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) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h)
elseif(PROCESSOR_IS_AARCH64) elseif(PROCESSOR_IS_AARCH64)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h) 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) list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/windows_utils.h)
elseif(PROCESSOR_IS_X86) elseif(PROCESSOR_IS_X86)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h) 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) list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
elseif(PROCESSOR_IS_RISCV) elseif(PROCESSOR_IS_RISCV)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h) 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() else()
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}") message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
endif() endif()
@ -123,6 +150,8 @@ setup_include_and_definitions(utils)
if(UNIX) if(UNIX)
add_library(unix_based_hardware_detection OBJECT add_library(unix_based_hardware_detection OBJECT
${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h ${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 ${PROJECT_SOURCE_DIR}/src/hwcaps.c
) )
setup_include_and_definitions(unix_based_hardware_detection) 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) target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H)
endif() endif()
check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL) 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) if(HAVE_STRONG_GETAUXVAL)
target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL) target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL)
endif() endif()
if(HAVE_STRONG_ELF_AUX_INFO)
target_compile_definitions(unix_based_hardware_detection PUBLIC HAVE_STRONG_ELF_AUX_INFO)
endif()
endif() endif()
# #
@ -153,20 +186,21 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
target_include_directories(cpu_features target_include_directories(cpu_features
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/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) target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
endif() endif()
add_library(CpuFeature::cpu_features ALIAS cpu_features) add_library(CpuFeatures::cpu_features ALIAS cpu_features)
# #
# program : list_cpu_features # program : list_cpu_features
# #
add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c) if(BUILD_EXECUTABLE)
target_link_libraries(list_cpu_features PRIVATE cpu_features) add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c)
add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features) target_link_libraries(list_cpu_features PRIVATE cpu_features)
add_executable(CpuFeatures::list_cpu_features ALIAS list_cpu_features)
endif()
# #
# ndk_compat # ndk_compat
@ -232,36 +266,47 @@ endif()
# #
# Install cpu_features and list_cpu_features # Install cpu_features and list_cpu_features
# #
if(ENABLE_INSTALL)
include(GNUInstallDirs) include(GNUInstallDirs)
install(TARGETS cpu_features list_cpu_features install(TARGETS cpu_features
EXPORT CpuFeaturesTargets EXPORT CpuFeaturesTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR} BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
) )
install(EXPORT CpuFeaturesTargets if(BUILD_EXECUTABLE)
NAMESPACE CpuFeatures:: install(TARGETS list_cpu_features
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures EXPORT CpuFeaturesTargets
COMPONENT Devel PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
) ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
include(CMakePackageConfigHelpers) LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
"${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" )
NO_SET_AND_CHECK_MACRO endif()
NO_CHECK_REQUIRED_COMPONENTS_MACRO install(EXPORT CpuFeaturesTargets
) NAMESPACE CpuFeatures::
write_basic_package_version_file( DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures
"${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" COMPONENT Devel
COMPATIBILITY SameMajorVersion )
) include(CMakePackageConfigHelpers)
install( configure_package_config_file(cmake/CpuFeaturesConfig.cmake.in
FILES
"${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake" "${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(
"${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake" "${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures" COMPATIBILITY SameMajorVersion
COMPONENT Devel )
) install(
FILES
"${PROJECT_BINARY_DIR}/CpuFeaturesConfig.cmake"
"${PROJECT_BINARY_DIR}/CpuFeaturesConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures"
COMPONENT Devel
)
endif()

View File

@ -158,14 +158,14 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
## What's supported ## What's supported
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | s390x | | | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | Loongarch | s390x |
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-----: | | ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-------: | :-----: |
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | | Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | | FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | not yet |
| MacOs | yes² | not yet | N/A | N/A | no | N/A | no | | 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 | | 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 | | 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 | | 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 1. **Features revealed from Linux.** We gather data from several sources
depending on availability: 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. microarchitecture allows the client to reject particular microarchitectures.
4. All flavors of Mips are supported, little and big endian as well as 32/64 4. All flavors of Mips are supported, little and big endian as well as 32/64
bits. bits.
5. **Features revealed from sysctl.** features are retrieved by the `sysctl`
instruction.
<a name="ndk"></a> <a name="ndk"></a>

View File

@ -4,6 +4,7 @@
#ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #ifndef CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
#define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #define CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_
#include <stdint.h>
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Architectures // Architectures
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -52,14 +53,14 @@
#define CPU_FEATURES_ARCH_PPC #define CPU_FEATURES_ARCH_PPC
#endif #endif
#if defined(__riscv)
#define CPU_FEATURES_ARCH_RISCV
#endif
#if defined(__s390x__) #if defined(__s390x__)
#define CPU_FEATURES_ARCH_S390X #define CPU_FEATURES_ARCH_S390X
#endif #endif
#if defined(__riscv)
#define CPU_FEATURES_ARCH_RISCV
#endif
#if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32 #if defined(__riscv) && defined(__riscv_xlen) && __riscv_xlen == 32
#define CPU_FEATURES_ARCH_RISCV32 #define CPU_FEATURES_ARCH_RISCV32
#endif #endif
@ -72,6 +73,10 @@
#define CPU_FEATURES_ARCH_RISCV128 #define CPU_FEATURES_ARCH_RISCV128
#endif #endif
#if defined(__loongarch64)
#define CPU_FEATURES_ARCH_LOONGARCH
#endif
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Os // Os
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -372,4 +377,4 @@
#define CPU_FEATURES_DEPRECATED(message) #define CPU_FEATURES_DEPRECATED(message)
#endif #endif
#endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_ #endif // CPU_FEATURES_INCLUDE_CPU_FEATURES_MACROS_H_

View File

@ -159,6 +159,27 @@ typedef struct
int ecv : 1; // Enhanced counter virtualization. int ecv : 1; // Enhanced counter virtualization.
int afp : 1; // Alternate floating-point behaviour. int afp : 1; // Alternate floating-point behaviour.
int rpres : 1; // 12-bit reciprocal (square root) estimate precision. 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. // Make sure to update Aarch64FeaturesEnum below if you add a field here.
} Aarch64Features; } Aarch64Features;
@ -234,6 +255,27 @@ typedef enum
AARCH64_ECV, AARCH64_ECV,
AARCH64_AFP, AARCH64_AFP,
AARCH64_RPRES, 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_, AARCH64_LAST_,
} Aarch64FeaturesEnum; } Aarch64FeaturesEnum;
@ -248,4 +290,4 @@ CPU_FEATURES_END_CPP_NAMESPACE
#error "Including cpuinfo_aarch64.h from a non-aarch64 target." #error "Including cpuinfo_aarch64.h from a non-aarch64 target."
#endif #endif
#endif // CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_ #endif // CPU_FEATURES_INCLUDE_CPUINFO_AARCH64_H_

View File

@ -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_

View File

@ -63,4 +63,4 @@ CPU_FEATURES_END_CPP_NAMESPACE
#error "Including cpuinfo_mips.h from a non-mips target." #error "Including cpuinfo_mips.h from a non-mips target."
#endif #endif
#endif // CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_ #endif // CPU_FEATURES_INCLUDE_CPUINFO_MIPS_H_

View File

@ -26,6 +26,7 @@ typedef struct
int D : 1; // Standard Extension for Double-Precision Floating-Point int D : 1; // Standard Extension for Double-Precision Floating-Point
int Q : 1; // Standard Extension for Quad-Precision Floating-Point int Q : 1; // Standard Extension for Quad-Precision Floating-Point
int C : 1; // Standard Extension for Compressed Instructions 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 Zicsr : 1; // Control and Status Register (CSR)
int Zifencei : 1; // Instruction-Fetch Fence int Zifencei : 1; // Instruction-Fetch Fence
} RiscvFeatures; } RiscvFeatures;
@ -47,6 +48,7 @@ typedef enum
RISCV_D, RISCV_D,
RISCV_Q, RISCV_Q,
RISCV_C, RISCV_C,
RISCV_V,
RISCV_Zicsr, RISCV_Zicsr,
RISCV_Zifencei, RISCV_Zifencei,
RISCV_LAST_, RISCV_LAST_,

View File

@ -89,7 +89,8 @@ typedef enum
S390X_LAST_, S390X_LAST_,
} S390XFeaturesEnum; } S390XFeaturesEnum;
int GetS390XFeaturesEnumValue(const S390XFeatures* features, S390XFeaturesEnum value); int GetS390XFeaturesEnumValue(const S390XFeatures* features,
S390XFeaturesEnum value);
const char* GetS390XFeaturesEnumName(S390XFeaturesEnum); const char* GetS390XFeaturesEnumName(S390XFeaturesEnum);

View File

@ -75,6 +75,7 @@ typedef struct
int amx_bf16 : 1; int amx_bf16 : 1;
int amx_tile : 1; int amx_tile : 1;
int amx_int8 : 1; int amx_int8 : 1;
int amx_fp16 : 1;
int pclmulqdq : 1; int pclmulqdq : 1;
int smx : 1; int smx : 1;
@ -96,7 +97,10 @@ typedef struct
int fz_rep_movsb : 1; // Fast zero-length REP MOVSB int fz_rep_movsb : 1; // Fast zero-length REP MOVSB
int fs_rep_stosb : 1; // Fast short REP STOSB int fs_rep_stosb : 1; // Fast short REP STOSB
int fs_rep_cmpsb_scasb : 1; // Fast short REP CMPSB/SCASB int fs_rep_cmpsb_scasb : 1; // Fast short REP CMPSB/SCASB
// Make sure to update X86FeaturesEnum below if you add a field here.
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; } X86Features;
typedef struct typedef struct
@ -114,7 +118,6 @@ X86Info GetX86Info(void);
// Returns cache hierarchy informations. // Returns cache hierarchy informations.
// Can call cpuid multiple times. // Can call cpuid multiple times.
// Only works on Intel CPU at the moment.
CacheInfo GetX86CacheInfo(void); CacheInfo GetX86CacheInfo(void);
typedef enum typedef enum
@ -244,6 +247,7 @@ typedef enum
X86_AMX_BF16, X86_AMX_BF16,
X86_AMX_TILE, X86_AMX_TILE,
X86_AMX_INT8, X86_AMX_INT8,
X86_AMX_FP16,
X86_PCLMULQDQ, X86_PCLMULQDQ,
X86_SMX, X86_SMX,
X86_SGX, X86_SGX,
@ -263,6 +267,8 @@ typedef enum
X86_FZ_REP_MOVSB, X86_FZ_REP_MOVSB,
X86_FS_REP_STOSB, X86_FS_REP_STOSB,
X86_FS_REP_CMPSB_SCASB, X86_FS_REP_CMPSB_SCASB,
X86_LAM,
X86_UAI,
X86_LAST_, X86_LAST_,
} X86FeaturesEnum; } X86FeaturesEnum;

View File

@ -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_

View File

@ -23,4 +23,4 @@ uint32_t GetXCR0Eax(void);
CPU_FEATURES_END_CPP_NAMESPACE CPU_FEATURES_END_CPP_NAMESPACE
#endif // CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_ #endif // CPU_FEATURES_INCLUDE_INTERNAL_CPUID_X86_H_

View File

@ -71,6 +71,27 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define AARCH64_HWCAP2_ECV (1UL << 19) #define AARCH64_HWCAP2_ECV (1UL << 19)
#define AARCH64_HWCAP2_AFP (1UL << 20) #define AARCH64_HWCAP2_AFP (1UL << 20)
#define AARCH64_HWCAP2_RPRES (1UL << 21) #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 // http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
#define ARM_HWCAP_SWP (1UL << 0) #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_D (1UL << ('D' - 'A'))
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A')) #define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
#define RISCV_HWCAP_C (1UL << ('C' - '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 typedef struct
{ {
@ -225,4 +263,4 @@ const char* CpuFeatures_GetBasePlatformPointer(void);
CPU_FEATURES_END_CPP_NAMESPACE CPU_FEATURES_END_CPP_NAMESPACE
#endif // CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_ #endif // CPU_FEATURES_INCLUDE_INTERNAL_HWCAPS_H_

View File

@ -55,4 +55,4 @@
#endif #endif
#endif // CPU_FEATURES_OS_WINDOWS #endif // CPU_FEATURES_OS_WINDOWS
#endif // CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_ #endif // CPU_FEATURES_INCLUDE_INTERNAL_WINDOWS_UTILS_H_

View File

@ -2,11 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#include "internal/hwcaps.h" #include "internal/hwcaps.h"
#include "cpu_features_macros.h" #include <stdbool.h>
#include "internal/filesystem.h"
#include "internal/string_view.h"
#include <stdlib.h>
#include <string.h>
static bool IsSet(const uint32_t mask, const uint32_t value) 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) || return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) ||
IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2); 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

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -6,80 +6,7 @@
#ifdef CPU_FEATURES_ARCH_AARCH64 #ifdef CPU_FEATURES_ARCH_AARCH64
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) #if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#include "cpuinfo_aarch64.h" #include "impl_aarch64__base_implementation.inl"
////////////////////////////////////////////////////////////////////////////////
// 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>
static bool HandleAarch64Line(const LineResult result, static bool HandleAarch64Line(const LineResult result,
Aarch64Info* const info) Aarch64Info* const info)
@ -157,4 +84,4 @@ Aarch64Info GetAarch64Info(void)
} }
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) #endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#endif // CPU_FEATURES_ARCH_AARCH64 #endif // CPU_FEATURES_ARCH_AARCH64

View File

@ -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

View File

@ -81,8 +81,7 @@
extern bool GetWindowsIsProcessorFeaturePresent(DWORD); extern bool GetWindowsIsProcessorFeaturePresent(DWORD);
extern WORD GetWindowsNativeSystemInfoProcessorRevision(); extern WORD GetWindowsNativeSystemInfoProcessorRevision();
#else // CPU_FEATURES_MOCK_CPUID_AARCH64 #else // CPU_FEATURES_MOCK_CPUID_AARCH64
static bool static bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
{ {
return IsProcessorFeaturePresent(dwProcessorFeature); return IsProcessorFeaturePresent(dwProcessorFeature);
} }
@ -116,7 +115,6 @@ Aarch64Info GetAarch64Info(void)
info.features.atomics = GetWindowsIsProcessorFeaturePresent( info.features.atomics = GetWindowsIsProcessorFeaturePresent(
PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE); PF_ARM_V81_ATOMIC_INSTRUCTIONS_AVAILABLE);
bool is_crypto_available = GetWindowsIsProcessorFeaturePresent( bool is_crypto_available = GetWindowsIsProcessorFeaturePresent(
PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE);
info.features.aes = is_crypto_available; info.features.aes = is_crypto_available;

View File

@ -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

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2017 Google LLC // SPDX-FileCopyrightText: 2018 IBM
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
#include "cpu_features_macros.h" #include "cpu_features_macros.h"
@ -165,4 +165,4 @@ PPCPlatformStrings GetPPCPlatformStrings(void)
} }
#endif // CPU_FEATURES_OS_LINUX #endif // CPU_FEATURES_OS_LINUX
#endif // CPU_FEATURES_ARCH_PPC #endif // CPU_FEATURES_ARCH_PPC

View File

@ -28,6 +28,7 @@
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \ LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \ LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 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_Zicsr, Zicsr, "_zicsr", 0, 0) \
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0) LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
#define INTROSPECTION_PREFIX Riscv #define INTROSPECTION_PREFIX Riscv
@ -106,4 +107,4 @@ RiscvInfo GetRiscvInfo(void)
} }
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID) #endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#endif // CPU_FEATURES_ARCH_RISCV #endif // CPU_FEATURES_ARCH_RISCV

View File

@ -59,7 +59,8 @@ static bool HandleS390XLine(const LineResult result,
{ {
if (CpuFeatures_StringView_IsEquals(key, str("# processors"))) if (CpuFeatures_StringView_IsEquals(key, str("# processors")))
{ {
strings->num_processors = CpuFeatures_StringView_ParsePositiveNumber(value); strings->num_processors =
CpuFeatures_StringView_ParsePositiveNumber(value);
} }
} }
return !result.eof; return !result.eof;

View File

@ -36,9 +36,7 @@ uint32_t GetXCR0Eax(void)
/* named form of xgetbv not supported on OSX, so must use byte form, see: /* named form of xgetbv not supported on OSX, so must use byte form, see:
https://github.com/asmjit/asmjit/issues/78 https://github.com/asmjit/asmjit/issues/78
*/ */
__asm(".byte 0x0F, 0x01, 0xd0" __asm(".byte 0x0F, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
: "=a"(eax), "=d"(edx)
: "c"(0));
return eax; return eax;
} }
@ -93,6 +91,7 @@ typedef struct
Leaf leaf_80000002; // brand string Leaf leaf_80000002; // brand string
Leaf leaf_80000003; // brand string Leaf leaf_80000003; // brand string
Leaf leaf_80000004; // brand string Leaf leaf_80000004; // brand string
Leaf leaf_80000021; // AMD Extended Feature Identification 2
} Leaves; } Leaves;
static Leaves ReadLeaves(void) static Leaves ReadLeaves(void)
@ -114,12 +113,12 @@ static Leaves ReadLeaves(void)
.leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0), .leaf_80000002 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000002, 0),
.leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0), .leaf_80000003 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000003, 0),
.leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0), .leaf_80000004 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000004, 0),
.leaf_80000021 = SafeCpuIdEx(max_cpuid_leaf_ext, 0x80000021, 0),
}; };
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// OS support // OS support
// TODO: Add documentation
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define MASK_XMM 0x2 #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->fs_rep_cmpsb_scasb = IsBitSet(leaf_7_1.eax, 12);
features->adx = IsBitSet(leaf_7.ebx, 19); features->adx = IsBitSet(leaf_7.ebx, 19);
features->lzcnt = IsBitSet(leaf_80000001.ecx, 5); features->lzcnt = IsBitSet(leaf_80000001.ecx, 5);
features->lam = IsBitSet(leaf_7_1.eax, 26);
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// The following section is devoted to Vector Extensions. // 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_bf16 = IsBitSet(leaf_7.edx, 22);
features->amx_tile = IsBitSet(leaf_7.edx, 24); features->amx_tile = IsBitSet(leaf_7.edx, 24);
features->amx_int8 = IsBitSet(leaf_7.edx, 25); features->amx_int8 = IsBitSet(leaf_7.edx, 25);
features->amx_fp16 = IsBitSet(leaf_7_1.eax, 21);
} }
} }
else else
@ -413,6 +414,7 @@ static void ParseExtraAMDCpuId(const Leaves* leaves, X86Info* info,
OsPreserves os_preserves) OsPreserves os_preserves)
{ {
const Leaf leaf_80000001 = leaves->leaf_80000001; const Leaf leaf_80000001 = leaves->leaf_80000001;
const Leaf leaf_80000021 = leaves->leaf_80000021;
X86Features* const features = &info->features; 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->fma4 = IsBitSet(leaf_80000001.ecx, 16);
} }
features->uai = IsBitSet(leaf_80000021.eax, 7);
} }
static const X86Info kEmptyX86Info; static const X86Info kEmptyX86Info;
@ -460,7 +464,7 @@ X86Info GetX86Info(void)
// Microarchitecture // Microarchitecture
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#define CPUID(FAMILY, MODEL) ((((FAMILY)&0xFF) << 8) | ((MODEL)&0xFF)) #define CPUID(FAMILY, MODEL) ((((FAMILY) & 0xFF) << 8) | ((MODEL) & 0xFF))
X86Microarchitecture GetX86Microarchitecture(const X86Info* info) X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
{ {
@ -605,6 +609,7 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
} }
case CPUID(0x06, 0x97): case CPUID(0x06, 0x97):
case CPUID(0x06, 0x9A): case CPUID(0x06, 0x9A):
case CPUID(0x06, 0xBE):
// https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake // https://en.wikichip.org/wiki/intel/microarchitectures/alder_lake
return INTEL_ADL; return INTEL_ADL;
case CPUID(0x06, 0xA5): case CPUID(0x06, 0xA5):
@ -781,8 +786,10 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
case CPUID(0x17, 0x60): case CPUID(0x17, 0x60):
case CPUID(0x17, 0x68): case CPUID(0x17, 0x68):
case CPUID(0x17, 0x71): case CPUID(0x17, 0x71):
case CPUID(0x17, 0x84):
case CPUID(0x17, 0x90): case CPUID(0x17, 0x90):
case CPUID(0x17, 0x98): case CPUID(0x17, 0x98):
case CPUID(0x17, 0xA0):
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_2 // https://en.wikichip.org/wiki/amd/microarchitectures/zen_2
return AMD_ZEN2; return AMD_ZEN2;
case CPUID(0x19, 0x00): case CPUID(0x19, 0x00):
@ -796,7 +803,9 @@ X86Microarchitecture GetX86Microarchitecture(const X86Info* info)
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_3 // https://en.wikichip.org/wiki/amd/microarchitectures/zen_3
return AMD_ZEN3; return AMD_ZEN3;
case CPUID(0x19, 0x10): case CPUID(0x19, 0x10):
case CPUID(0x19, 0x11):
case CPUID(0x19, 0x61): case CPUID(0x19, 0x61):
case CPUID(0x19, 0x74):
// https://en.wikichip.org/wiki/amd/microarchitectures/zen_4 // https://en.wikichip.org/wiki/amd/microarchitectures/zen_4
return AMD_ZEN4; return AMD_ZEN4;
default: default:
@ -1958,6 +1967,7 @@ CacheInfo GetX86CacheInfo(void)
LINE(X86_AMX_BF16, amx_bf16, , , ) \ LINE(X86_AMX_BF16, amx_bf16, , , ) \
LINE(X86_AMX_TILE, amx_tile, , , ) \ LINE(X86_AMX_TILE, amx_tile, , , ) \
LINE(X86_AMX_INT8, amx_int8, , , ) \ LINE(X86_AMX_INT8, amx_int8, , , ) \
LINE(X86_AMX_FP16, amx_fp16, , , ) \
LINE(X86_PCLMULQDQ, pclmulqdq, , , ) \ LINE(X86_PCLMULQDQ, pclmulqdq, , , ) \
LINE(X86_SMX, smx, , , ) \ LINE(X86_SMX, smx, , , ) \
LINE(X86_SGX, sgx, , , ) \ LINE(X86_SGX, sgx, , , ) \
@ -1976,7 +1986,9 @@ CacheInfo GetX86CacheInfo(void)
LINE(X86_FS_REP_MOV, fs_rep_mov, , , ) \ LINE(X86_FS_REP_MOV, fs_rep_mov, , , ) \
LINE(X86_FZ_REP_MOVSB, fz_rep_movsb, , , ) \ LINE(X86_FZ_REP_MOVSB, fz_rep_movsb, , , ) \
LINE(X86_FS_REP_STOSB, fs_rep_stosb, , , ) \ 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_PREFIX X86
#define INTROSPECTION_ENUM_PREFIX X86 #define INTROSPECTION_ENUM_PREFIX X86
#include "define_introspection.inl" #include "define_introspection.inl"
@ -2045,4 +2057,4 @@ const char* GetX86MicroarchitectureName(X86Microarchitecture value)
#undef LINE #undef LINE
if (value >= X86_MICROARCHITECTURE_LAST_) return "unknown microarchitecture"; if (value >= X86_MICROARCHITECTURE_LAST_) return "unknown microarchitecture";
return kMicroarchitectureNames[value]; return kMicroarchitectureNames[value];
} }

View File

@ -42,9 +42,9 @@ static void DetectFeaturesFromOs(X86Info* info, X86Features* features)
features->sse4_2 = features->sse4_2 =
GetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE); GetWindowsIsProcessorFeaturePresent(PF_SSE4_2_INSTRUCTIONS_AVAILABLE);
// do not bother checking PF_AVX* // Do not bother checking PF_AVX* : AVX enabled processor will have their XCR0
// cause AVX enabled processor will have XCR0 be exposed and this function will be skipped at all // register exposed and this function will be skipped altogether.
} }
#endif // CPU_FEATURES_OS_WINDOWS #endif // CPU_FEATURES_OS_WINDOWS
#endif // CPU_FEATURES_ARCH_X86 #endif // CPU_FEATURES_ARCH_X86

View File

@ -27,6 +27,8 @@
#include "cpuinfo_s390x.h" #include "cpuinfo_s390x.h"
#elif defined(CPU_FEATURES_ARCH_RISCV) #elif defined(CPU_FEATURES_ARCH_RISCV)
#include "cpuinfo_riscv.h" #include "cpuinfo_riscv.h"
#elif defined(CPU_FEATURES_ARCH_LOONGARCH)
#include "cpuinfo_loongarch.h"
#endif #endif
// Design principles // Design principles
@ -217,11 +219,14 @@ DEFINE_ADD_FLAGS(GetMipsFeaturesEnumValue, GetMipsFeaturesEnumName,
DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures, DEFINE_ADD_FLAGS(GetPPCFeaturesEnumValue, GetPPCFeaturesEnumName, PPCFeatures,
PPC_LAST_) PPC_LAST_)
#elif defined(CPU_FEATURES_ARCH_S390X) #elif defined(CPU_FEATURES_ARCH_S390X)
DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName, S390XFeatures, DEFINE_ADD_FLAGS(GetS390XFeaturesEnumValue, GetS390XFeaturesEnumName,
S390X_LAST_) S390XFeatures, S390X_LAST_)
#elif defined(CPU_FEATURES_ARCH_RISCV) #elif defined(CPU_FEATURES_ARCH_RISCV)
DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName, RiscvFeatures, DEFINE_ADD_FLAGS(GetRiscvFeaturesEnumValue, GetRiscvFeaturesEnumName,
RISCV_LAST_) RiscvFeatures, RISCV_LAST_)
#elif defined(CPU_FEATURES_ARCH_LOONGARCH)
DEFINE_ADD_FLAGS(GetLoongArchFeaturesEnumValue, GetLoongArchFeaturesEnumName,
LoongArchFeatures, LOONGARCH_LAST_)
#endif #endif
// Prints a json string with characters escaping. // Prints a json string with characters escaping.
@ -458,6 +463,10 @@ static Node* CreateTree(void)
AddMapEntry(root, "vendor", CreateString(info.vendor)); AddMapEntry(root, "vendor", CreateString(info.vendor));
AddMapEntry(root, "microarchitecture", CreateString(info.uarch)); AddMapEntry(root, "microarchitecture", CreateString(info.uarch));
AddFlags(root, &info.features); AddFlags(root, &info.features);
#elif defined(CPU_FEATURES_ARCH_LOONGARCH)
const LoongArchInfo info = GetLoongArchInfo();
AddMapEntry(root, "arch", CreateString("loongarch"));
AddFlags(root, &info.features);
#endif #endif
return root; return root;
} }
@ -489,4 +498,4 @@ int main(int argc, char** argv)
printTextRoot(root); printTextRoot(root);
putchar('\n'); putchar('\n');
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -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_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) 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) target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view)
# #
@ -76,9 +80,18 @@ endif()
if(PROCESSOR_IS_AARCH64) if(PROCESSOR_IS_AARCH64)
add_executable(cpuinfo_aarch64_test add_executable(cpuinfo_aarch64_test
cpuinfo_aarch64_test.cc cpuinfo_aarch64_test.cc
../src/impl_aarch64_cpuid.c
../src/impl_aarch64_linux_or_android.c ../src/impl_aarch64_linux_or_android.c
../src/impl_aarch64_windows.c) ../src/impl_aarch64_windows.c
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_AARCH64) ../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) target_link_libraries(cpuinfo_aarch64_test all_libraries)
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
endif() endif()
@ -109,4 +122,11 @@ if(PROCESSOR_IS_RISCV)
add_executable(cpuinfo_riscv_test cpuinfo_riscv_test.cc ../src/impl_riscv_linux.c) add_executable(cpuinfo_riscv_test cpuinfo_riscv_test.cc ../src/impl_riscv_linux.c)
target_link_libraries(cpuinfo_riscv_test all_libraries) target_link_libraries(cpuinfo_riscv_test all_libraries)
add_test(NAME cpuinfo_riscv_test COMMAND cpuinfo_riscv_test) 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() endif()

View File

@ -6,17 +6,56 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "hwcaps_for_testing.h" #include "hwcaps_for_testing.h"
#include <set> #include <set>
#if defined(CPU_FEATURES_OS_WINDOWS) #if defined(CPU_FEATURES_OS_WINDOWS)
#include "internal/windows_utils.h" #include "internal/windows_utils.h"
#endif // CPU_FEATURES_OS_WINDOWS #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 namespace cpu_features
{ {
class FakeCpuAarch64 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: public:
#if defined(CPU_FEATURES_OS_WINDOWS)
bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
{ {
return windows_isprocessorfeaturepresent_.count(dwProcessorFeature); return windows_isprocessorfeaturepresent_.count(dwProcessorFeature);
@ -36,11 +75,7 @@ public:
{ {
processor_revision_ = wProcessorRevision; processor_revision_ = wProcessorRevision;
} }
#endif
private:
std::set<DWORD> windows_isprocessorfeaturepresent_;
WORD processor_revision_{};
#endif // CPU_FEATURES_OS_WINDOWS
}; };
static FakeCpuAarch64* g_fake_cpu_instance = nullptr; static FakeCpuAarch64* g_fake_cpu_instance = nullptr;
@ -51,7 +86,23 @@ static FakeCpuAarch64& cpu()
return *g_fake_cpu_instance; 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) extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
{ {
return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature); return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature);
@ -61,7 +112,7 @@ extern "C" WORD GetWindowsNativeSystemInfoProcessorRevision()
{ {
return cpu().GetWindowsNativeSystemInfoProcessorRevision(); return cpu().GetWindowsNativeSystemInfoProcessorRevision();
} }
#endif // CPU_FEATURES_OS_WINDOWS #endif
namespace namespace
{ {
@ -81,7 +132,7 @@ protected:
} }
}; };
TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum) TEST_F(CpuidAarch64Test, Aarch64FeaturesEnum)
{ {
const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_); const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_);
EXPECT_STREQ(last_name, "unknown_feature"); EXPECT_STREQ(last_name, "unknown_feature");
@ -96,13 +147,9 @@ TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum)
} }
} }
#if defined(CPU_FEATURES_OS_LINUX) // AT_HWCAP tests
void DisableHardwareCapabilities() #if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD)
{ TEST_F(CpuidAarch64Test, FromHardwareCap)
SetHardwareCapabilities(0, 0);
}
TEST(CpuinfoAarch64Test, FromHardwareCap)
{ {
ResetHwcaps(); ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0); SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
@ -142,7 +189,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap)
EXPECT_FALSE(info.features.pacg); EXPECT_FALSE(info.features.pacg);
} }
TEST(CpuinfoAarch64Test, FromHardwareCap2) TEST_F(CpuidAarch64Test, FromHardwareCap2)
{ {
ResetHwcaps(); ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP, SetHardwareCapabilities(AARCH64_HWCAP_FP,
@ -171,8 +218,11 @@ TEST(CpuinfoAarch64Test, FromHardwareCap2)
EXPECT_FALSE(info.features.dgh); EXPECT_FALSE(info.features.dgh);
EXPECT_FALSE(info.features.rng); 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(); ResetHwcaps();
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
@ -253,10 +303,91 @@ CPU revision : 3)");
EXPECT_FALSE(info.features.ecv); EXPECT_FALSE(info.features.ecv);
EXPECT_FALSE(info.features.afp); EXPECT_FALSE(info.features.afp);
EXPECT_FALSE(info.features.rpres); 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) TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4)
{ {
cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03); cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03);
@ -280,7 +411,38 @@ TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4)
EXPECT_FALSE(info.features.jscvt); EXPECT_FALSE(info.features.jscvt);
EXPECT_FALSE(info.features.lrcpc); 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
} // namespace cpu_features } // namespace cpu_features

View File

@ -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

View File

@ -32,6 +32,7 @@ uarch : thead,c906)");
EXPECT_TRUE(info.features.D); EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q); EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C); 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 // https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/Kendryte-K510-4.17.0.cpuinfo
@ -41,15 +42,16 @@ TEST(CpuinfoRiscvTest, Kendryte_K510_FromCpuInfo)
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"( fs.CreateFile("/proc/cpuinfo", R"(
hart : 0 hart : 0
isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0 isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0
mmu : sv39 mmu : sv39
hart : 1 hart : 1
isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0 isa : rv64i2p0m2p0a2p0f2p0d2p0c2p0xv5-0p0
mmu : sv39"); mmu : sv39");
const auto info = GetRiscvInfo(); const auto info = GetRiscvInfo();
EXPECT_STREQ(info.uarch, ""); EXPECT_STREQ(info.uarch, "");
EXPECT_STREQ(info.vendor, ""); EXPECT_STREQ(info.vendor, "");
EXPECT_FALSE(info.features.RV32I); EXPECT_FALSE(info.features.RV32I);
EXPECT_TRUE(info.features.RV64I); EXPECT_TRUE(info.features.RV64I);
EXPECT_TRUE(info.features.M); EXPECT_TRUE(info.features.M);
@ -58,6 +60,7 @@ mmu : sv39");
EXPECT_TRUE(info.features.D); EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q); EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C); 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 // https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/T-Head-C910-5.10.4.cpuinfo
@ -67,8 +70,8 @@ TEST(CpuinfoRiscvTest, T_Head_C910_FromCpuInfo) {
fs.CreateFile("/proc/cpuinfo", R"( fs.CreateFile("/proc/cpuinfo", R"(
processor : 0 processor : 0
hart : 0 hart : 0
isa : rv64imafdcsu isa : rv64imafdcsu
mmu : sv39 mmu : sv39
cpu-freq : 1.2Ghz cpu-freq : 1.2Ghz
cpu-icache : 64KB cpu-icache : 64KB
cpu-dcache : 64KB cpu-dcache : 64KB
@ -76,10 +79,11 @@ cpu-l2cache : 2MB
cpu-tlb : 1024 4-ways cpu-tlb : 1024 4-ways
cpu-cacheline : 64Bytes cpu-cacheline : 64Bytes
cpu-vector : 0.7.1 cpu-vector : 0.7.1
processor : 1 processor : 1
hart : 1 hart : 1
isa : rv64imafdcsu isa : rv64imafdcsu
mmu : sv39 mmu : sv39
cpu-freq : 1.2Ghz cpu-freq : 1.2Ghz
cpu-icache : 64KB cpu-icache : 64KB
cpu-dcache : 64KB cpu-dcache : 64KB
@ -90,6 +94,7 @@ cpu-vector : 0.7.1");
const auto info = GetRiscvInfo(); const auto info = GetRiscvInfo();
EXPECT_STREQ(info.uarch, ""); EXPECT_STREQ(info.uarch, "");
EXPECT_STREQ(info.vendor, ""); EXPECT_STREQ(info.vendor, "");
EXPECT_FALSE(info.features.RV32I); EXPECT_FALSE(info.features.RV32I);
EXPECT_TRUE(info.features.RV64I); EXPECT_TRUE(info.features.RV64I);
EXPECT_TRUE(info.features.M); EXPECT_TRUE(info.features.M);
@ -98,7 +103,9 @@ cpu-vector : 0.7.1");
EXPECT_TRUE(info.features.D); EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q); EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C); EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.V);
} }
TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) { TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) {
ResetHwcaps(); ResetHwcaps();
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
@ -108,16 +115,19 @@ hart : 2
isa : rv64imafdc isa : rv64imafdc
mmu : sv39 mmu : sv39
uarch : sifive,bullet0 uarch : sifive,bullet0
processor : 1 processor : 1
hart : 1 hart : 1
isa : rv64imafdc isa : rv64imafdc
mmu : sv39 mmu : sv39
uarch : sifive,bullet0 uarch : sifive,bullet0
processor : 2 processor : 2
hart : 3 hart : 3
isa : rv64imafdc isa : rv64imafdc
mmu : sv39 mmu : sv39
uarch : sifive,bullet0 uarch : sifive,bullet0
processor : 3 processor : 3
hart : 4 hart : 4
isa : rv64imafdc isa : rv64imafdc
@ -135,7 +145,29 @@ uarch : sifive,bullet0)");
EXPECT_TRUE(info.features.D); EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q); EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C); 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 } // namespace
} // namespace cpu_features } // namespace cpu_features

View File

@ -195,6 +195,8 @@ TEST_F(CpuidX86Test, SandyBridge)
EXPECT_FALSE(features.movbe); EXPECT_FALSE(features.movbe);
EXPECT_FALSE(features.rdrnd); EXPECT_FALSE(features.rdrnd);
EXPECT_FALSE(features.adx); EXPECT_FALSE(features.adx);
EXPECT_FALSE(features.lam);
EXPECT_FALSE(features.uai);
} }
const int UNDEF = -1; const int UNDEF = -1;
@ -802,6 +804,21 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2); 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 // http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID3.txt
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA) 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}}, {{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2035206E, 0x30303637}},
{{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}}, {{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}},
{{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}}, {{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}},
{{0x80000021, 0}, Leaf{0x00062FCF, 0x0000015C, 0x00000000, 0x00000000}},
}); });
const auto info = GetX86Info(); const auto info = GetX86Info();
@ -939,9 +957,26 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL)
EXPECT_EQ(info.model, 0x61); EXPECT_EQ(info.model, 0x61);
EXPECT_STREQ(info.brand_string, EXPECT_STREQ(info.brand_string,
"AMD Ryzen 5 7600X 6-Core Processor "); "AMD Ryzen 5 7600X 6-Core Processor ");
EXPECT_TRUE(info.features.uai);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4); 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 // http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F11_Hygon_01_CPUID.txt
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250) 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); 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 // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906A4_AlderLakeP_00_CPUID.txt
TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX_VNNI) 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); 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 // https://github.com/google/cpu_features/issues/200
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt // http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt

View File

@ -544,7 +544,6 @@ if(NOT (CMAKE_GENERATOR STREQUAL Xcode))
PRIVATE PRIVATE
$<TARGET_PROPERTY:cpu_features,INTERFACE_INCLUDE_DIRECTORIES> $<TARGET_PROPERTY:cpu_features,INTERFACE_INCLUDE_DIRECTORIES>
) )
add_dependencies(volk_gnsssdr_obj list_cpu_features)
endif() endif()
endif() endif()
# Configure object target properties # Configure object target properties

View File

@ -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()); 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)); 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"; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV message received in channel " << d_channel std::cout << "New BEIDOU B1I DNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << " dB-Hz" << std::endl; << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl;
std::cout << std::setprecision(default_precision); // restore defaults
} }
if (d_nav.have_new_utc_model() == true) 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()); 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)); 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"; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV utc model message received in channel " std::cout << "New BEIDOU B1I DNAV utc model message received in channel "
<< d_channel << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": 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()); 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)); 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"; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel
<< ": Iono model parameters from satellite " << d_satellite << ": Iono model parameters from satellite " << d_satellite
<< " with CN0=" << cn0 << std::setprecision(default_precision) << " 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)); // 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)); // 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"; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV almanac received in channel " << d_channel std::cout << "New BEIDOU B1I DNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << " from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)

View File

@ -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)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel"
<< d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz"; << 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV message received in channel " << d_channel std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " 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)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV UTC Model data have been received in channel" LOG(INFO) << "BEIDOU DNAV UTC Model data have been received in channel"
<< d_channel << " from satellite " << d_satellite; << d_channel << " from satellite " << d_satellite;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV utc model message received in channel " std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV utc model message received in channel "
<< d_channel << ": UTC model parameters from satellite " << d_channel << ": UTC model parameters from satellite "
<< d_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)); 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 LOG(INFO) << "BEIDOU DNAV Iono data have been received in channel" << d_channel
<< " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz"; << " 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV Iono message received in channel " std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV Iono message received in channel "
<< d_channel << ": Iono model parameters from satellite " << d_channel << ": Iono model parameters from satellite "
<< d_satellite << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << 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)); // pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Almanac data have been received in channel" LOG(INFO) << "BEIDOU DNAV Almanac data have been received in channel"
<< d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz"; << 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV almanac received in channel " << d_channel std::cout << TEXT_YELLOW << "New BEIDOU B3I DNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << " from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)

View File

@ -432,7 +432,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()); const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_inav_nav.get_ephemeris());
if (d_band == '1') if (d_band == '1')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << " with CN0=" << ": ephemeris from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -440,7 +444,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
} }
else if (d_band == '7') else if (d_band == '7')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE std::cout << TEXT_BLUE
<< "New Galileo E5b I/NAV message received in channel " << d_channel << "New Galileo E5b I/NAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << " with CN0=" << ": ephemeris from satellite " << d_satellite << " with CN0="
@ -457,7 +465,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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV reduced CED message received in channel " std::cout << "New Galileo E1 I/NAV reduced CED message received in channel "
<< d_channel << " from satellite " << d_satellite << " with CN0=" << d_channel << " from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -472,7 +484,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)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
if (d_band == '1') if (d_band == '1')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
<< ": iono/GST model parameters from satellite " << d_satellite << ": iono/GST model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -480,7 +496,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
} }
else if (d_band == '7') else if (d_band == '7')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel " std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel "
<< d_channel << ": iono/GST model parameters from satellite " << d_channel << ": iono/GST model parameters from satellite "
<< d_satellite << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << d_satellite << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -495,7 +515,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)); this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
if (d_band == '1') if (d_band == '1')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -503,7 +527,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
} }
else if (d_band == '7') else if (d_band == '7')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel " std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel "
<< d_channel << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": UTC model parameters from satellite " << d_satellite
@ -522,14 +550,22 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
// debug // debug
if (d_band == '1') if (d_band == '1')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << " with CN0=" << " from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl; << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl;
} }
else if (d_band == '7') else if (d_band == '7')
{ {
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "Galileo E5b I/NAV almanac received in channel " std::cout << TEXT_BLUE << "Galileo E5b I/NAV almanac received in channel "
<< d_channel << " from satellite " << d_satellite << " with CN0=" << d_channel << " from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -598,7 +634,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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
<< d_channel << ": ephemeris from satellite " << d_satellite << " with CN0=" << d_channel << ": ephemeris from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -609,7 +649,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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
<< d_channel << ": iono/GST model parameters from satellite " << d_satellite << d_channel << ": iono/GST model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -620,7 +664,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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel " std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
<< d_channel << ": UTC model parameters from satellite " << d_satellite << d_channel << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -681,7 +729,11 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float *
if (is_page_dummy != d_cnav_dummy_page) if (is_page_dummy != d_cnav_dummy_page)
{ {
d_cnav_dummy_page = is_page_dummy; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel " std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel "
<< d_channel << " from satellite " << d_channel << " from satellite "
<< d_satellite << " with CN0=" << d_satellite << " with CN0="
@ -700,7 +752,11 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float *
if (d_print_cnav_page == true) if (d_print_cnav_page == true)
{ {
d_print_cnav_page = false; // only print the first page 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 HAS pages" std::cout << TEXT_MAGENTA << "Receiving Galileo E6 HAS pages"
<< (d_cnav_nav.is_HAS_in_test_mode() == true ? " (test mode) " : " ") << (d_cnav_nav.is_HAS_in_test_mode() == true ? " (test mode) " : " ")
<< "in channel " << d_channel << " from satellite " << d_satellite << "in channel " << d_channel << " from satellite " << d_satellite

View File

@ -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()); 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)); 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; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " 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()); 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)); 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; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " 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)); 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)); 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; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GLONASS L1 GNAV almanac received in channel " << d_channel << " from satellite " << d_satellite 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) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
<< " dB-Hz" << std::endl; << " dB-Hz" << std::endl;

View File

@ -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()); 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)); 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; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " 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()); 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)); 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; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " 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)); 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)); 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; 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV almanac received in channel " << d_channel std::cout << TEXT_CYAN << "New GLONASS L2 GNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << " from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)

View File

@ -397,7 +397,11 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe(double cn0, bool flag_inver
default: default:
break; break;
} }
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GPS NAV message received in channel " << this->d_channel << ": " std::cout << "New GPS NAV message received in channel " << this->d_channel << ": "
<< "subframe " << "subframe "
<< subframe_ID << " from satellite " << subframe_ID << " from satellite "

View File

@ -259,7 +259,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
// get ephemeris object for this SV // 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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision) << " 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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
<< ": iono model parameters from satellite " << d_satellite << ": iono model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision) << " 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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision) << " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)

View File

@ -256,7 +256,11 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
// get ephemeris object for this SV // 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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << " 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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
<< ": iono model parameters from satellite " << d_satellite << ": iono model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision) << " 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()); 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)); 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()}; const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz