1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-10-30 22:56:22 +00:00

Merge branch 'next' of https://github.com/gnss-sdr/gnss-sdr into osnma

This commit is contained in:
Carles Fernandez 2023-11-04 15:21:29 +01:00
commit 1d295e0d51
No known key found for this signature in database
GPG Key ID: 4C583C52B0C3877D
49 changed files with 1867 additions and 389 deletions

View File

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

View File

@ -1208,8 +1208,14 @@ if(NOT VOLKGNSSSDR_FOUND)
endif()
include(GNUInstallDirs)
set(SUPPORTED_CPU_FEATURES_ARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)|(^ARM64)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
set(SUPPORTED_CPU_FEATURES_ARCH TRUE)
endif()
if(${CMAKE_INSTALL_LIBDIR} MATCHES lib64)
@ -1248,14 +1254,14 @@ if(NOT VOLKGNSSSDR_FOUND)
set_package_properties(CPUFEATURES PROPERTIES
DESCRIPTION "A cross platform C99 library to get CPU features at runtime (version: ${CPUFEATURES_VERSION})"
)
if((CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0")) # detect cpu_features without s390x / riscv support
if((CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|(^riscv)|(^loongarch)") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0")) # detect cpu_features without s390x / riscv support
set(ENABLE_CPUFEATURES OFF)
endif()
else()
set_package_properties(CPUFEATURES PROPERTIES
DESCRIPTION "A cross platform C99 library to get CPU features at runtime"
)
if(DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3") # avoid clash with volk's cpufeatures.
if((DEFINED VOLK_VERSION AND VOLK_VERSION VERSION_GREATER "2.3") OR (CMAKE_VERSION VERSION_LESS "3.13")) # avoid clash with volk's cpufeatures.
set(ENABLE_CPUFEATURES OFF)
else()
set_package_properties(CPUFEATURES PROPERTIES

View File

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

View File

@ -257,8 +257,14 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "^cortex")
endif()
# cpu_features - sensible defaults, user settable option
if(CMAKE_SYSTEM_PROCESSOR MATCHES
"(^mips)|(^arm)|(^aarch64)|(x86_64)|(AMD64|amd64)|(^i.86$)|(^powerpc)|(^ppc)|(^s390x)|^riscv")
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)|(^ARM64)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv" OR
CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" ON)
else()
option(VOLK_CPU_FEATURES "volk-gnsssdr uses cpu_features" OFF)
@ -266,7 +272,7 @@ endif()
if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
find_package(CPUFEATURES)
if(CPUFEATURES_FOUND AND (CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0"))
if(CPUFEATURES_FOUND AND (CMAKE_SYSTEM_PROCESSOR MATCHES "(^s390x)|^riscv|^loongarch") AND (CPUFEATURES_VERSION VERSION_LESS "0.8.0"))
set(USE_CPU_FEATURES OFF)
unset(CPUFEATURES_FOUND CACHE)
message(STATUS "Building volk-gnsssdr without cpu_features, installed version v${CPUFEATURES_VERSION} does not support the ${CMAKE_SYSTEM_PROCESSOR} architecture")
@ -274,6 +280,9 @@ if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
set(USE_CPU_FEATURES ON)
endif()
if(NOT CPUFEATURES_FOUND)
if(CMAKE_VERSION VERSION_LESS 3.13)
message(STATUS "Building volk-gnsssdr without cpu_features")
else()
message(STATUS "Building volk-gnsssdr with cpu_features")
set(BUILD_TESTING OFF CACHE BOOL "Build cpu_features without tests." FORCE)
set(BUILD_PIC ON CACHE BOOL
@ -286,9 +295,19 @@ if(CMAKE_VERSION VERSION_GREATER 3.0 AND VOLK_CPU_FEATURES)
)
set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
set(BUILD_SHARED_LIBS OFF)
if(ENABLE_INSTALL)
set(ENABLE_INSTALL_AUX ${ENABLE_INSTALL})
endif()
set(ENABLE_INSTALL ON)
add_subdirectory(cpu_features)
unset(ENABLE_INSTALL)
if(ENABLE_INSTALL_AUX)
set(ENABLE_INSTALL ${ENABLE_INSTALL_AUX})
unset(ENABLE_INSTALL_AUX)
endif()
set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
endif()
endif()
else()
message(STATUS "Building volk-gnsssdr without cpu_features")
endif()
@ -307,7 +326,7 @@ if(NOT MAKO_FOUND)
endif()
# Six
if(Python2_VERSION OR (PYTHON_VERSION_STRING VERSION_LESS "3.0"))
if(PYTHON_VERSION_STRING VERSION_LESS "3.0")
if(NOT SIX_FOUND)
message(FATAL_ERROR "six - python 2 and 3 compatibility library required to build VOLK_GNSSSDR")
endif()

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)
{
volk_gnsssdr_test_results_t kernel_result{};
volk_gnsssdr_test_results_t kernel_result;
kernel_result.name = std::string(single_kernel_result[0]);
kernel_result.config_name = std::string(single_kernel_result[0]);
kernel_result.best_arch_u = std::string(single_kernel_result[1]);

View File

@ -87,10 +87,10 @@ if(CMAKE_VERSION VERSION_LESS 3.12 OR CMAKE_CROSSCOMPILING)
set(PYTHON_VERSION_MAJOR "${Python2_VERSION_MAJOR}")
set(PYTHON_EXECUTABLE "${Python2_EXECUTABLE}")
set(PYTHON_VERSION_STRING "${Python2_VERSION_MAJOR}.${Python2_VERSION_MINOR}")
endif()
volk_python_check_module("six - python 2 and 3 compatibility library" six "True" SIX_FOUND)
endif()
endif()
endif()
volk_python_check_module("mako >= 0.4.2" mako "mako.__version__ >= '0.4.2'" MAKO_FOUND)
else()
if(PYTHON_EXECUTABLE)

View File

@ -1,7 +1,7 @@
# SPDX-FileCopyrightText: 2017 Google LLC
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.13)
# option() honors normal variables.
# see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html
@ -9,11 +9,16 @@ if(POLICY CMP0077)
cmake_policy(SET CMP0077 NEW)
endif()
project(CpuFeatures VERSION 0.7.0 LANGUAGES C)
project(CpuFeatures VERSION 0.9.0 LANGUAGES C)
set(CMAKE_C_STANDARD 99)
if(CMAKE_VERSION LESS "3.1")
add_compile_options("$<$<STREQUAL:$<TARGET_PROPERTY:LINKER_LANGUAGE>,C>:-std=gnu99>")
# when cpu_features is included as subproject (i.e. using add_subdirectory(cpu_features))
# in the source tree of a project that uses it, test rules are disabled.
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
option(BUILD_TESTING "Enable test rule" OFF)
else()
option(BUILD_TESTING "Enable test rule" ON)
endif()
# Default Build Type to be Release
@ -23,6 +28,22 @@ if(NOT CMAKE_BUILD_TYPE)
FORCE)
endif()
# An option to enable/disable the executable target list_cpu_features.
# Disable it by default if the project is included as a subproject.
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
option(BUILD_EXECUTABLE "Build list_cpu_features executable." OFF)
else()
option(BUILD_EXECUTABLE "Build list_cpu_features executable." ON)
endif()
# An option which allows to switch off install steps. Useful for embedding.
# Disable it by default if the project is included as a subproject.
if(NOT CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
option(ENABLE_INSTALL "Enable install targets" OFF)
else()
option(ENABLE_INSTALL "Enable install targets" ON)
endif()
# BUILD_SHARED_LIBS is a standard CMake variable, but we declare it here to make
# it prominent in the GUI.
# cpu_features uses bit-fields which are - to some extends - implementation-defined (see https://en.cppreference.com/w/c/language/bit_field).
@ -57,14 +78,15 @@ set(PROCESSOR_IS_X86 FALSE)
set(PROCESSOR_IS_POWER FALSE)
set(PROCESSOR_IS_S390X FALSE)
set(PROCESSOR_IS_RISCV FALSE)
set(PROCESSOR_IS_LOONGARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(PROCESSOR_IS_MIPS TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)|(^ARM64)")
set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(PROCESSOR_IS_ARM TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)")
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(x86_64)|(AMD64|amd64)|(^i.86$)")
set(PROCESSOR_IS_X86 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)")
set(PROCESSOR_IS_POWER TRUE)
@ -72,6 +94,8 @@ elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(s390x)")
set(PROCESSOR_IS_S390X TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^riscv")
set(PROCESSOR_IS_RISCV TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^loongarch")
set(PROCESSOR_IS_LOONGARCH TRUE)
endif()
macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
@ -85,6 +109,7 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_arm.h)
elseif(PROCESSOR_IS_AARCH64)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_aarch64.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/cpuid_aarch64.h)
list(APPEND ${SRCS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/internal/windows_utils.h)
elseif(PROCESSOR_IS_X86)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_x86.h)
@ -96,6 +121,8 @@ macro(add_cpu_features_headers_and_sources HDRS_LIST_NAME SRCS_LIST_NAME)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_s390x.h)
elseif(PROCESSOR_IS_RISCV)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_riscv.h)
elseif(PROCESSOR_IS_LOONGARCH)
list(APPEND ${HDRS_LIST_NAME} ${PROJECT_SOURCE_DIR}/include/cpuinfo_loongarch.h)
else()
message(FATAL_ERROR "Unsupported architectures ${CMAKE_SYSTEM_PROCESSOR}")
endif()
@ -123,6 +150,8 @@ setup_include_and_definitions(utils)
if(UNIX)
add_library(unix_based_hardware_detection OBJECT
${PROJECT_SOURCE_DIR}/include/internal/hwcaps.h
${PROJECT_SOURCE_DIR}/src/hwcaps_linux_or_android.c
${PROJECT_SOURCE_DIR}/src/hwcaps_freebsd.c
${PROJECT_SOURCE_DIR}/src/hwcaps.c
)
setup_include_and_definitions(unix_based_hardware_detection)
@ -131,9 +160,13 @@ if(UNIX)
target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_DLFCN_H)
endif()
check_symbol_exists(getauxval "sys/auxv.h" HAVE_STRONG_GETAUXVAL)
check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_STRONG_ELF_AUX_INFO)
if(HAVE_STRONG_GETAUXVAL)
target_compile_definitions(unix_based_hardware_detection PRIVATE HAVE_STRONG_GETAUXVAL)
endif()
if(HAVE_STRONG_ELF_AUX_INFO)
target_compile_definitions(unix_based_hardware_detection PUBLIC HAVE_STRONG_ELF_AUX_INFO)
endif()
endif()
#
@ -153,20 +186,21 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
target_include_directories(cpu_features
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
)
if(PROCESSOR_IS_X86)
if(APPLE)
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
endif()
add_library(CpuFeature::cpu_features ALIAS cpu_features)
add_library(CpuFeatures::cpu_features ALIAS cpu_features)
#
# program : list_cpu_features
#
if(BUILD_EXECUTABLE)
add_executable(list_cpu_features ${PROJECT_SOURCE_DIR}/src/utils/list_cpu_features.c)
target_link_libraries(list_cpu_features PRIVATE cpu_features)
add_executable(CpuFeature::list_cpu_features ALIAS list_cpu_features)
add_executable(CpuFeatures::list_cpu_features ALIAS list_cpu_features)
endif()
#
# ndk_compat
@ -232,9 +266,9 @@ endif()
#
# Install cpu_features and list_cpu_features
#
if(ENABLE_INSTALL)
include(GNUInstallDirs)
install(TARGETS cpu_features list_cpu_features
install(TARGETS cpu_features
EXPORT CpuFeaturesTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
@ -242,6 +276,16 @@ install(TARGETS cpu_features list_cpu_features
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
)
if(BUILD_EXECUTABLE)
install(TARGETS list_cpu_features
EXPORT CpuFeaturesTargets
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/cpu_features
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif()
install(EXPORT CpuFeaturesTargets
NAMESPACE CpuFeatures::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/CpuFeatures
@ -265,3 +309,4 @@ install(
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
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | s390x |
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-----: |
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet |
| MacOs | yes² | not yet | N/A | N/A | no | N/A | no |
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A |
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A |
| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A |
| | x86³ | AArch64 | ARM | MIPS⁴ | POWER | RISCV | Loongarch | s390x |
| ------- | :--: | :-----: | :-----: | :-----: | :-----: | :---: | :-------: | :-----: |
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | not yet |
| MacOs | yes² | yes⁵ | N/A | N/A | N/A | N/A | N/A | N/A |
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A | N/A |
| Android | yes² | yes¹ | yes¹ | yes¹ | N/A | N/A | N/A | N/A |
| iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A | N/A |
1. **Features revealed from Linux.** We gather data from several sources
depending on availability:
@ -180,6 +180,8 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
microarchitecture allows the client to reject particular microarchitectures.
4. All flavors of Mips are supported, little and big endian as well as 32/64
bits.
5. **Features revealed from sysctl.** features are retrieved by the `sysctl`
instruction.
<a name="ndk"></a>

View File

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

View File

@ -159,6 +159,27 @@ typedef struct
int ecv : 1; // Enhanced counter virtualization.
int afp : 1; // Alternate floating-point behaviour.
int rpres : 1; // 12-bit reciprocal (square root) estimate precision.
int mte3 : 1; // MTE asymmetric fault handling.
int sme : 1; // Scalable Matrix Extension.
int smei16i64 : 1; // 16-bit to 64-bit integer widening outer product.
int smef64f64 : 1; // FP64 to FP64 outer product.
int smei8i32 : 1; // 8-bit to 32-bit integer widening outer product.
int smef16f32 : 1; // FP16 to FP32 outer product.
int smeb16f32 : 1; // BFloat16 to FP32 outper product.
int smef32f32 : 1; // FP32 to FP32 outer product.
int smefa64 : 1; // Full A64 support for SME in streaming mode.
int wfxt : 1; // WFE and WFI with timeout.
int ebf16 : 1; // Extended BFloat16 instructions.
int sveebf16 : 1; // SVE BFloat16 instructions.
int cssc : 1; // Common short sequence compression instructions.
int rprfm : 1; // Range Prefetch Memory hint instruction.
int sve2p1 : 1; // Scalable Vector Extension (version 2.1).
int sme2 : 1; // Scalable Matrix Extension (version 2).
int sme2p1 : 1; // Scalable Matrix Extension (version 2.1).
int smei16i32 : 1; // 16-bit to 64-bit integer widening outer product.
int smebi32i32 : 1; // 1-bit binary to 32-bit integer outer product.
int smeb16b16 : 1; // SME2.1 BFloat16 instructions.
int smef16f16 : 1; // FP16 to FP16 outer product.
// Make sure to update Aarch64FeaturesEnum below if you add a field here.
} Aarch64Features;
@ -234,6 +255,27 @@ typedef enum
AARCH64_ECV,
AARCH64_AFP,
AARCH64_RPRES,
AARCH64_MTE3,
AARCH64_SME,
AARCH64_SME_I16I64,
AARCH64_SME_F64F64,
AARCH64_SME_I8I32,
AARCH64_SME_F16F32,
AARCH64_SME_B16F32,
AARCH64_SME_F32F32,
AARCH64_SME_FA64,
AARCH64_WFXT,
AARCH64_EBF16,
AARCH64_SVE_EBF16,
AARCH64_CSSC,
AARCH64_RPRFM,
AARCH64_SVE2P1,
AARCH64_SME2,
AARCH64_SME2P1,
AARCH64_SME_I16I32,
AARCH64_SME_BI32I32,
AARCH64_SME_B16B16,
AARCH64_SME_F16F16,
AARCH64_LAST_,
} Aarch64FeaturesEnum;

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

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

View File

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

View File

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

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

@ -71,6 +71,27 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define AARCH64_HWCAP2_ECV (1UL << 19)
#define AARCH64_HWCAP2_AFP (1UL << 20)
#define AARCH64_HWCAP2_RPRES (1UL << 21)
#define AARCH64_HWCAP2_MTE3 (1UL << 22)
#define AARCH64_HWCAP2_SME (1UL << 23)
#define AARCH64_HWCAP2_SME_I16I64 (1UL << 24)
#define AARCH64_HWCAP2_SME_F64F64 (1UL << 25)
#define AARCH64_HWCAP2_SME_I8I32 (1UL << 26)
#define AARCH64_HWCAP2_SME_F16F32 (1UL << 27)
#define AARCH64_HWCAP2_SME_B16F32 (1UL << 28)
#define AARCH64_HWCAP2_SME_F32F32 (1UL << 29)
#define AARCH64_HWCAP2_SME_FA64 (1UL << 30)
#define AARCH64_HWCAP2_WFXT (1UL << 31)
#define AARCH64_HWCAP2_EBF16 (1UL << 32)
#define AARCH64_HWCAP2_SVE_EBF16 (1UL << 33)
#define AARCH64_HWCAP2_CSSC (1UL << 34)
#define AARCH64_HWCAP2_RPRFM (1UL << 35)
#define AARCH64_HWCAP2_SVE2P1 (1UL << 36)
#define AARCH64_HWCAP2_SME2 (1UL << 37)
#define AARCH64_HWCAP2_SME2P1 (1UL << 38)
#define AARCH64_HWCAP2_SME_I16I32 (1UL << 39)
#define AARCH64_HWCAP2_SME_BI32I32 (1UL << 40)
#define AARCH64_HWCAP2_SME_B16B16 (1UL << 41)
#define AARCH64_HWCAP2_SME_F16F16 (1UL << 42)
// http://elixir.free-electrons.com/linux/latest/source/arch/arm/include/uapi/asm/hwcap.h
#define ARM_HWCAP_SWP (1UL << 0)
@ -202,6 +223,23 @@ CPU_FEATURES_START_CPP_NAMESPACE
#define RISCV_HWCAP_D (1UL << ('D' - 'A'))
#define RISCV_HWCAP_Q (1UL << ('Q' - 'A'))
#define RISCV_HWCAP_C (1UL << ('C' - 'A'))
#define RISCV_HWCAP_V (1UL << ('V' - 'A'))
// https://github.com/torvalds/linux/blob/master/arch/loongarch/include/uapi/asm/hwcap.h
#define HWCAP_LOONGARCH_CPUCFG (1 << 0)
#define HWCAP_LOONGARCH_LAM (1 << 1)
#define HWCAP_LOONGARCH_UAL (1 << 2)
#define HWCAP_LOONGARCH_FPU (1 << 3)
#define HWCAP_LOONGARCH_LSX (1 << 4)
#define HWCAP_LOONGARCH_LASX (1 << 5)
#define HWCAP_LOONGARCH_CRC32 (1 << 6)
#define HWCAP_LOONGARCH_COMPLEX (1 << 7)
#define HWCAP_LOONGARCH_CRYPTO (1 << 8)
#define HWCAP_LOONGARCH_LVZ (1 << 9)
#define HWCAP_LOONGARCH_LBT_X86 (1 << 10)
#define HWCAP_LOONGARCH_LBT_ARM (1 << 11)
#define HWCAP_LOONGARCH_LBT_MIPS (1 << 12)
#define HWCAP_LOONGARCH_PTW (1 << 13)
typedef struct
{

View File

@ -2,11 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
#include "internal/hwcaps.h"
#include "cpu_features_macros.h"
#include "internal/filesystem.h"
#include "internal/string_view.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
static bool IsSet(const uint32_t mask, const uint32_t value)
{
@ -20,159 +16,3 @@ bool CpuFeatures_IsHwCapsSet(const HardwareCapabilities hwcaps_mask,
return IsSet(hwcaps_mask.hwcaps, hwcaps.hwcaps) ||
IsSet(hwcaps_mask.hwcaps2, hwcaps.hwcaps2);
}
#ifdef CPU_FEATURES_TEST
// In test mode, hwcaps_for_testing will define the following functions.
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void);
const char* CpuFeatures_GetPlatformPointer(void);
const char* CpuFeatures_GetBasePlatformPointer(void);
#else
// Debug facilities
#if defined(NDEBUG)
#define D(...)
#else
#include <stdio.h>
#define D(...) \
do \
{ \
printf(__VA_ARGS__); \
fflush(stdout); \
} \
while (0)
#endif
////////////////////////////////////////////////////////////////////////////////
// Implementation of GetElfHwcapFromGetauxval
////////////////////////////////////////////////////////////////////////////////
#define AT_HWCAP 16
#define AT_HWCAP2 26
#define AT_PLATFORM 15
#define AT_BASE_PLATFORM 24
#if defined(HAVE_STRONG_GETAUXVAL)
#include <sys/auxv.h>
static unsigned long GetElfHwcapFromGetauxval(uint32_t hwcap_type)
{
return getauxval(hwcap_type);
}
#elif defined(HAVE_DLFCN_H)
// On Android we probe the system's C library for a 'getauxval' function and
// call it if it exits, or return 0 for failure. This function is available
// since API level 18.
//
// Note that getauxval() can't really be re-implemented here, because its
// implementation does not parse /proc/self/auxv. Instead it depends on values
// that are passed by the kernel at process-init time to the C runtime
// initialization layer.
#include <dlfcn.h>
typedef unsigned long getauxval_func_t(unsigned long);
static uint32_t GetElfHwcapFromGetauxval(uint32_t hwcap_type)
{
uint32_t ret = 0;
void *libc_handle = NULL;
getauxval_func_t *func = NULL;
dlerror(); // Cleaning error state before calling dlopen.
libc_handle = dlopen("libc.so", RTLD_NOW);
if (!libc_handle)
{
D("Could not dlopen() C library: %s\n", dlerror());
return 0;
}
func = (getauxval_func_t *)dlsym(libc_handle, "getauxval");
if (!func)
{
D("Could not find getauxval() in C library\n");
}
else
{
// Note: getauxval() returns 0 on failure. Doesn't touch errno.
ret = (uint32_t)(*func)(hwcap_type);
}
dlclose(libc_handle);
return ret;
}
#else
#error "This platform does not provide hardware capabilities."
#endif
// Implementation of GetHardwareCapabilities for OS that provide
// GetElfHwcapFromGetauxval().
// Fallback when getauxval is not available, retrieves hwcaps from
// "/proc/self/auxv".
static uint32_t GetElfHwcapFromProcSelfAuxv(uint32_t hwcap_type)
{
struct
{
uint32_t tag;
uint32_t value;
} entry;
uint32_t result = 0;
const char filepath[] = "/proc/self/auxv";
const int fd = CpuFeatures_OpenFile(filepath);
if (fd < 0)
{
D("Could not open %s\n", filepath);
return 0;
}
for (;;)
{
const int ret = CpuFeatures_ReadFile(fd, (char *)&entry, sizeof entry);
if (ret < 0)
{
D("Error while reading %s\n", filepath);
break;
}
// Detect end of list.
if (ret == 0 || (entry.tag == 0 && entry.value == 0))
{
break;
}
if (entry.tag == hwcap_type)
{
result = entry.value;
break;
}
}
CpuFeatures_CloseFile(fd);
return result;
}
// Retrieves hardware capabilities by first trying to call getauxval, if not
// available falls back to reading "/proc/self/auxv".
static unsigned long GetHardwareCapabilitiesFor(uint32_t type)
{
unsigned long hwcaps = GetElfHwcapFromGetauxval(type);
if (!hwcaps)
{
D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
hwcaps = GetElfHwcapFromProcSelfAuxv(type);
}
return hwcaps;
}
HardwareCapabilities CpuFeatures_GetHardwareCapabilities(void)
{
HardwareCapabilities capabilities;
capabilities.hwcaps = GetHardwareCapabilitiesFor(AT_HWCAP);
capabilities.hwcaps2 = GetHardwareCapabilitiesFor(AT_HWCAP2);
return capabilities;
}
const char *CpuFeatures_GetPlatformPointer(void)
{
return (const char *)GetHardwareCapabilitiesFor(AT_PLATFORM);
}
const char *CpuFeatures_GetBasePlatformPointer(void)
{
return (const char *)GetHardwareCapabilitiesFor(AT_BASE_PLATFORM);
}
#endif // CPU_FEATURES_TEST

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
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
#include "cpuinfo_aarch64.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions for introspection.
////////////////////////////////////////////////////////////////////////////////
#define INTROSPECTION_TABLE \
LINE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0) \
LINE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0) \
LINE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0) \
LINE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0) \
LINE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0) \
LINE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0) \
LINE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0) \
LINE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0) \
LINE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0) \
LINE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0) \
LINE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0) \
LINE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0) \
LINE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0) \
LINE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0) \
LINE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0) \
LINE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0) \
LINE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0) \
LINE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0) \
LINE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0) \
LINE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0) \
LINE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0) \
LINE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0) \
LINE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0) \
LINE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0) \
LINE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0) \
LINE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0) \
LINE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0) \
LINE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0) \
LINE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0) \
LINE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0) \
LINE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0) \
LINE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0) \
LINE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP) \
LINE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2) \
LINE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES) \
LINE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \
LINE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0, \
AARCH64_HWCAP2_SVEBITPERM) \
LINE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3) \
LINE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4) \
LINE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2) \
LINE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT) \
LINE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM) \
LINE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \
LINE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \
LINE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16) \
LINE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM) \
LINE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16) \
LINE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH) \
LINE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG) \
LINE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI) \
LINE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE) \
LINE(AARCH64_ECV, ecv, "ecv", 0, AARCH64_HWCAP2_ECV) \
LINE(AARCH64_AFP, afp, "afp", 0, AARCH64_HWCAP2_AFP) \
LINE(AARCH64_RPRES, rpres, "rpres", 0, AARCH64_HWCAP2_RPRES)
#define INTROSPECTION_PREFIX Aarch64
#define INTROSPECTION_ENUM_PREFIX AARCH64
#include "define_introspection_and_hwcaps.inl"
////////////////////////////////////////////////////////////////////////////////
// Implementation.
////////////////////////////////////////////////////////////////////////////////
#include "internal/bit_utils.h"
#include "internal/filesystem.h"
#include "internal/stack_line_reader.h"
#include "internal/string_view.h"
#include <stdbool.h>
#include "impl_aarch64__base_implementation.inl"
static bool HandleAarch64Line(const LineResult result,
Aarch64Info* const info)

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

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
#include "cpu_features_macros.h"

View File

@ -28,6 +28,7 @@
LINE(RISCV_D, D, "d", RISCV_HWCAP_D, 0) \
LINE(RISCV_Q, Q, "q", RISCV_HWCAP_Q, 0) \
LINE(RISCV_C, C, "c", RISCV_HWCAP_C, 0) \
LINE(RISCV_V, V, "v", RISCV_HWCAP_V, 0) \
LINE(RISCV_Zicsr, Zicsr, "_zicsr", 0, 0) \
LINE(RISCV_Zifencei, Zifencei, "_zifencei", 0, 0)
#define INTROSPECTION_PREFIX Riscv

View File

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

View File

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

View File

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

View File

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

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_link_libraries(stack_line_reader_for_test string_view filesystem_for_testing)
##------------------------------------------------------------------------------
add_library(all_libraries ../src/hwcaps.c ../src/stack_line_reader.c)
add_library(all_libraries
../src/hwcaps.c
../src/hwcaps_linux_or_android.c
../src/hwcaps_freebsd.c
../src/stack_line_reader.c)
target_link_libraries(all_libraries hwcaps_for_testing stack_line_reader string_view)
#
@ -76,9 +80,18 @@ endif()
if(PROCESSOR_IS_AARCH64)
add_executable(cpuinfo_aarch64_test
cpuinfo_aarch64_test.cc
../src/impl_aarch64_cpuid.c
../src/impl_aarch64_linux_or_android.c
../src/impl_aarch64_windows.c)
../src/impl_aarch64_windows.c
../src/impl_aarch64_macos_or_iphone.c
../src/impl_aarch64_freebsd.c
)
if(APPLE)
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_SYSCTL_AARCH64)
target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME)
else()
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_AARCH64)
endif()
target_link_libraries(cpuinfo_aarch64_test all_libraries)
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
endif()
@ -110,3 +123,10 @@ if(PROCESSOR_IS_RISCV)
target_link_libraries(cpuinfo_riscv_test all_libraries)
add_test(NAME cpuinfo_riscv_test COMMAND cpuinfo_riscv_test)
endif()
##------------------------------------------------------------------------------
## cpuinfo_loongarch_test
if(PROCESSOR_IS_LOONGARCH)
add_executable(cpuinfo_loongarch_test cpuinfo_loongarch_test.cc ../src/impl_loongarch_linux.c)
target_link_libraries(cpuinfo_loongarch_test all_libraries)
add_test(NAME cpuinfo_loongarch_test COMMAND cpuinfo_loongarch_test)
endif()

View File

@ -6,17 +6,56 @@
#include "gtest/gtest.h"
#include "hwcaps_for_testing.h"
#include <set>
#if defined(CPU_FEATURES_OS_WINDOWS)
#include "internal/windows_utils.h"
#endif // CPU_FEATURES_OS_WINDOWS
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
#include "internal/cpuid_aarch64.h"
#endif // defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
namespace cpu_features
{
class FakeCpuAarch64
{
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
public:
uint64_t GetMidrEl1() const { return _midr_el1; }
void SetMidrEl1(uint64_t midr_el1) { _midr_el1 = midr_el1; }
private:
uint64_t _midr_el1;
#elif defined(CPU_FEATURES_OS_MACOS)
std::set<std::string> darwin_sysctlbyname_;
std::map<std::string, int> darwin_sysctlbynamevalue_;
public:
bool GetDarwinSysCtlByName(std::string name) const
{
return darwin_sysctlbyname_.count(name);
}
int GetDarwinSysCtlByNameValue(std::string name) const
{
const auto iter = darwin_sysctlbynamevalue_.find(name);
if (iter != darwin_sysctlbynamevalue_.end()) return iter->second;
return 0;
}
void SetDarwinSysCtlByName(std::string name)
{
darwin_sysctlbyname_.insert(name);
}
void SetDarwinSysCtlByNameValue(std::string name, int value)
{
darwin_sysctlbynamevalue_[name] = value;
}
#elif defined(CPU_FEATURES_OS_WINDOWS)
std::set<DWORD> windows_isprocessorfeaturepresent_;
WORD processor_revision_{};
public:
#if defined(CPU_FEATURES_OS_WINDOWS)
bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
{
return windows_isprocessorfeaturepresent_.count(dwProcessorFeature);
@ -36,11 +75,7 @@ public:
{
processor_revision_ = wProcessorRevision;
}
private:
std::set<DWORD> windows_isprocessorfeaturepresent_;
WORD processor_revision_{};
#endif // CPU_FEATURES_OS_WINDOWS
#endif
};
static FakeCpuAarch64* g_fake_cpu_instance = nullptr;
@ -51,7 +86,23 @@ static FakeCpuAarch64& cpu()
return *g_fake_cpu_instance;
}
#if defined(CPU_FEATURES_OS_WINDOWS)
// Define OS dependent mock functions
#if defined(CPU_FEATURES_OS_FREEBSD) || defined(CPU_FEATURES_OS_LINUX)
extern "C" uint64_t GetMidrEl1(void)
{
return cpu().GetMidrEl1();
}
#elif defined(CPU_FEATURES_OS_MACOS)
extern "C" bool GetDarwinSysCtlByName(const char* name)
{
return cpu().GetDarwinSysCtlByName(name);
}
extern "C" int GetDarwinSysCtlByNameValue(const char* name)
{
return cpu().GetDarwinSysCtlByNameValue(name);
}
#elif defined(CPU_FEATURES_OS_WINDOWS)
extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature)
{
return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature);
@ -61,7 +112,7 @@ extern "C" WORD GetWindowsNativeSystemInfoProcessorRevision()
{
return cpu().GetWindowsNativeSystemInfoProcessorRevision();
}
#endif // CPU_FEATURES_OS_WINDOWS
#endif
namespace
{
@ -81,7 +132,7 @@ protected:
}
};
TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum)
TEST_F(CpuidAarch64Test, Aarch64FeaturesEnum)
{
const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_);
EXPECT_STREQ(last_name, "unknown_feature");
@ -96,13 +147,9 @@ TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum)
}
}
#if defined(CPU_FEATURES_OS_LINUX)
void DisableHardwareCapabilities()
{
SetHardwareCapabilities(0, 0);
}
TEST(CpuinfoAarch64Test, FromHardwareCap)
// AT_HWCAP tests
#if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD)
TEST_F(CpuidAarch64Test, FromHardwareCap)
{
ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
@ -142,7 +189,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap)
EXPECT_FALSE(info.features.pacg);
}
TEST(CpuinfoAarch64Test, FromHardwareCap2)
TEST_F(CpuidAarch64Test, FromHardwareCap2)
{
ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP,
@ -171,8 +218,11 @@ TEST(CpuinfoAarch64Test, FromHardwareCap2)
EXPECT_FALSE(info.features.dgh);
EXPECT_FALSE(info.features.rng);
}
#endif // defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_FREEBSD)
TEST(CpuinfoAarch64Test, ARMCortexA53)
// OS dependent tests
#if defined(CPU_FEATURES_OS_LINUX)
TEST_F(CpuidAarch64Test, ARMCortexA53)
{
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
@ -253,10 +303,91 @@ CPU revision : 3)");
EXPECT_FALSE(info.features.ecv);
EXPECT_FALSE(info.features.afp);
EXPECT_FALSE(info.features.rpres);
EXPECT_FALSE(info.features.mte3);
EXPECT_FALSE(info.features.sme);
EXPECT_FALSE(info.features.smei16i64);
EXPECT_FALSE(info.features.smef64f64);
EXPECT_FALSE(info.features.smei8i32);
EXPECT_FALSE(info.features.smef16f32);
EXPECT_FALSE(info.features.smeb16f32);
EXPECT_FALSE(info.features.smef32f32);
EXPECT_FALSE(info.features.smefa64);
EXPECT_FALSE(info.features.wfxt);
EXPECT_FALSE(info.features.ebf16);
EXPECT_FALSE(info.features.sveebf16);
EXPECT_FALSE(info.features.cssc);
EXPECT_FALSE(info.features.rprfm);
EXPECT_FALSE(info.features.sve2p1);
EXPECT_FALSE(info.features.sme2);
EXPECT_FALSE(info.features.sme2p1);
EXPECT_FALSE(info.features.smei16i32);
EXPECT_FALSE(info.features.smebi32i32);
EXPECT_FALSE(info.features.smeb16b16);
EXPECT_FALSE(info.features.smef16f16);
}
#endif // CPU_FEATURES_OS_LINUX
#elif defined(CPU_FEATURES_OS_MACOS)
TEST_F(CpuidAarch64Test, FromDarwinSysctlFromName)
{
cpu().SetDarwinSysCtlByName("hw.optional.floatingpoint");
cpu().SetDarwinSysCtlByName("hw.optional.neon");
cpu().SetDarwinSysCtlByName("hw.optional.AdvSIMD_HPFPCvt");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_FP16");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_LSE");
cpu().SetDarwinSysCtlByName("hw.optional.armv8_crc32");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_FHM");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA512");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA3");
cpu().SetDarwinSysCtlByName("hw.optional.amx_version");
cpu().SetDarwinSysCtlByName("hw.optional.ucnormal_mem");
cpu().SetDarwinSysCtlByName("hw.optional.arm64");
#if defined(CPU_FEATURES_OS_WINDOWS)
cpu().SetDarwinSysCtlByNameValue("hw.cputype", 16777228);
cpu().SetDarwinSysCtlByNameValue("hw.cpusubtype", 2);
cpu().SetDarwinSysCtlByNameValue("hw.cpu64bit", 1);
cpu().SetDarwinSysCtlByNameValue("hw.cpufamily", 458787763);
cpu().SetDarwinSysCtlByNameValue("hw.cpusubfamily", 2);
const auto info = GetAarch64Info();
EXPECT_EQ(info.implementer, 0x100000C);
EXPECT_EQ(info.variant, 2);
EXPECT_EQ(info.part, 0x1B588BB3);
EXPECT_EQ(info.revision, 2);
EXPECT_TRUE(info.features.fp);
EXPECT_FALSE(info.features.asimd);
EXPECT_FALSE(info.features.evtstrm);
EXPECT_FALSE(info.features.aes);
EXPECT_FALSE(info.features.pmull);
EXPECT_FALSE(info.features.sha1);
EXPECT_FALSE(info.features.sha2);
EXPECT_TRUE(info.features.crc32);
EXPECT_TRUE(info.features.atomics);
EXPECT_TRUE(info.features.fphp);
EXPECT_FALSE(info.features.asimdhp);
EXPECT_FALSE(info.features.cpuid);
EXPECT_FALSE(info.features.asimdrdm);
EXPECT_FALSE(info.features.jscvt);
EXPECT_FALSE(info.features.fcma);
EXPECT_FALSE(info.features.lrcpc);
EXPECT_FALSE(info.features.dcpop);
EXPECT_TRUE(info.features.sha3);
EXPECT_FALSE(info.features.sm3);
EXPECT_FALSE(info.features.sm4);
EXPECT_FALSE(info.features.asimddp);
EXPECT_TRUE(info.features.sha512);
EXPECT_FALSE(info.features.sve);
EXPECT_TRUE(info.features.asimdfhm);
EXPECT_FALSE(info.features.dit);
EXPECT_FALSE(info.features.uscat);
EXPECT_FALSE(info.features.ilrcpc);
EXPECT_FALSE(info.features.flagm);
EXPECT_FALSE(info.features.ssbs);
EXPECT_FALSE(info.features.sb);
EXPECT_FALSE(info.features.paca);
EXPECT_FALSE(info.features.pacg);
}
#elif defined(CPU_FEATURES_OS_WINDOWS)
TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4)
{
cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03);
@ -280,7 +411,38 @@ TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4)
EXPECT_FALSE(info.features.jscvt);
EXPECT_FALSE(info.features.lrcpc);
}
#endif // CPU_FEATURES_OS_WINDOWS
#elif defined(CPU_FEATURES_OS_FREEBSD)
TEST_F(CpuidAarch64Test, MrsMidrEl1_RPI4)
{
ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_CPUID, 0);
cpu().SetMidrEl1(0x410FD083);
const auto info = GetAarch64Info();
EXPECT_EQ(info.implementer, 0x41);
EXPECT_EQ(info.variant, 0);
EXPECT_EQ(info.part, 0xD08);
EXPECT_EQ(info.revision, 0x3);
EXPECT_TRUE(info.features.fp);
EXPECT_FALSE(info.features.dcpodp);
EXPECT_FALSE(info.features.sveaes);
EXPECT_FALSE(info.features.svepmull);
EXPECT_FALSE(info.features.svebitperm);
EXPECT_FALSE(info.features.svesha3);
EXPECT_FALSE(info.features.svesm4);
EXPECT_FALSE(info.features.flagm2);
EXPECT_FALSE(info.features.frint);
EXPECT_FALSE(info.features.svei8mm);
EXPECT_FALSE(info.features.svef32mm);
EXPECT_FALSE(info.features.svef64mm);
EXPECT_FALSE(info.features.svebf16);
EXPECT_FALSE(info.features.i8mm);
EXPECT_FALSE(info.features.bf16);
EXPECT_FALSE(info.features.dgh);
EXPECT_FALSE(info.features.rng);
}
#endif // CPU_FEATURES_OS_FREEBSD
} // namespace
} // namespace cpu_features

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_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.V);
}
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/Kendryte-K510-4.17.0.cpuinfo
@ -50,6 +51,7 @@ mmu : sv39");
const auto info = GetRiscvInfo();
EXPECT_STREQ(info.uarch, "");
EXPECT_STREQ(info.vendor, "");
EXPECT_FALSE(info.features.RV32I);
EXPECT_TRUE(info.features.RV64I);
EXPECT_TRUE(info.features.M);
@ -58,6 +60,7 @@ mmu : sv39");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.V);
}
// https://github.com/ThomasKaiser/sbc-bench/blob/284e82b016ec1beeac42a5fcbe556b670f68441a/results/T-Head-C910-5.10.4.cpuinfo
@ -76,6 +79,7 @@ cpu-l2cache : 2MB
cpu-tlb : 1024 4-ways
cpu-cacheline : 64Bytes
cpu-vector : 0.7.1
processor : 1
hart : 1
isa : rv64imafdcsu
@ -90,6 +94,7 @@ cpu-vector : 0.7.1");
const auto info = GetRiscvInfo();
EXPECT_STREQ(info.uarch, "");
EXPECT_STREQ(info.vendor, "");
EXPECT_FALSE(info.features.RV32I);
EXPECT_TRUE(info.features.RV64I);
EXPECT_TRUE(info.features.M);
@ -98,7 +103,9 @@ cpu-vector : 0.7.1");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.V);
}
TEST(CpuinfoRiscvTest, UnknownFromCpuInfo) {
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
@ -108,16 +115,19 @@ hart : 2
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
processor : 1
hart : 1
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
processor : 2
hart : 3
isa : rv64imafdc
mmu : sv39
uarch : sifive,bullet0
processor : 3
hart : 4
isa : rv64imafdc
@ -135,6 +145,28 @@ uarch : sifive,bullet0)");
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_FALSE(info.features.V);
}
TEST(CpuinfoRiscvTest, QemuCpuInfo)
{
ResetHwcaps();
auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", R"(
processor : 0
hart : 0
isa : rv64imafdcvh_zba_zbb_zbc_zbs
mmu : sv48)");
const auto info = GetRiscvInfo();
EXPECT_FALSE(info.features.RV32I);
EXPECT_TRUE(info.features.RV64I);
EXPECT_TRUE(info.features.M);
EXPECT_TRUE(info.features.A);
EXPECT_TRUE(info.features.F);
EXPECT_TRUE(info.features.D);
EXPECT_FALSE(info.features.Q);
EXPECT_TRUE(info.features.C);
EXPECT_TRUE(info.features.V);
}
} // namespace

View File

@ -195,6 +195,8 @@ TEST_F(CpuidX86Test, SandyBridge)
EXPECT_FALSE(features.movbe);
EXPECT_FALSE(features.rdrnd);
EXPECT_FALSE(features.adx);
EXPECT_FALSE(features.lam);
EXPECT_FALSE(features.uai);
}
const int UNDEF = -1;
@ -802,6 +804,21 @@ TEST_F(CpuidX86Test, AMD_K17_ZEN2_XBOX_SERIES_X)
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0880F40_K17_CPUID.txt
TEST_F(CpuidX86Test, AMD_K17_ZEN2_4800S)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00880F40, 0x00100800, 0x7ED8320B, 0x178BFBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
EXPECT_EQ(info.family, 0x17);
EXPECT_EQ(info.model, 0x84);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
}
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F02_Hygon_CPUID3.txt
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA)
{
@ -931,6 +948,7 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL)
{{0x80000002, 0}, Leaf{0x20444D41, 0x657A7952, 0x2035206E, 0x30303637}},
{{0x80000003, 0}, Leaf{0x2D362058, 0x65726F43, 0x6F725020, 0x73736563}},
{{0x80000004, 0}, Leaf{0x2020726F, 0x20202020, 0x20202020, 0x00202020}},
{{0x80000021, 0}, Leaf{0x00062FCF, 0x0000015C, 0x00000000, 0x00000000}},
});
const auto info = GetX86Info();
@ -939,9 +957,26 @@ TEST_F(CpuidX86Test, AMD_K19_ZEN4_RAPHAEL)
EXPECT_EQ(info.model, 0x61);
EXPECT_STREQ(info.brand_string,
"AMD Ryzen 5 7600X 6-Core Processor ");
EXPECT_TRUE(info.features.uai);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A70F41_K19_Phoenix_03_CPUID.txt
TEST_F(CpuidX86Test, AMD_K19_ZEN4_PHOENIX)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00A70F41, 0x00100800, 0x7EF8320B, 0x178BFBFF}},
{{0x80000000, 0}, Leaf{0x80000028, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x80000001, 0}, Leaf{0x00A70F41, 0x50000000, 0x75C237FF, 0x2FD3FBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
EXPECT_EQ(info.family, 0x19);
EXPECT_EQ(info.model, 0x74);
}
// http://users.atw.hu/instlatx64/HygonGenuine/HygonGenuine0900F11_Hygon_01_CPUID.txt
TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250)
{
@ -964,6 +999,36 @@ TEST_F(CpuidX86Test, AMD_K18_ZEN_DHYANA_OCTAL_CORE_C86_3250)
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD08A0F00_K17_Mendocino_01_CPUID.txt
TEST_F(CpuidX86Test, AMD_ZEN2_MENDOCINO)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x008A0F00, 0x00080800, 0x7EF8320B, 0x178BFBFF}},
});
const auto info = GetX86Info();
EXPECT_EQ(info.model, 0xA0);
EXPECT_EQ(info.family, 0x17);
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN2);
}
// http://users.atw.hu/instlatx64/AuthenticAMD/AuthenticAMD0A10F11_K19_Genoa_02_CPUID.txt
TEST_F(CpuidX86Test, AMD_K19_ZEN4_GENOA)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000010, 0x68747541, 0x444D4163, 0x69746E65}},
{{0x00000001, 0}, Leaf{0x00A10F11, 0x00200800, 0x7EFA320B, 0x178BFBFF}},
});
const auto info = GetX86Info();
EXPECT_EQ(info.model, 0x11);
EXPECT_EQ(info.family, 0x19);
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_AUTHENTIC_AMD);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::AMD_ZEN4);
}
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00906A4_AlderLakeP_00_CPUID.txt
TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_AVX_VNNI)
{
@ -1742,6 +1807,20 @@ TEST_F(CpuidX86Test, INTEL_RAPTOR_LAKE_S)
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_RPL);
}
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00B06E0_AlderLakeN_03_CPUID.txt
TEST_F(CpuidX86Test, INTEL_ALDER_LAKE_N)
{
cpu().SetLeaves({
{{0x00000000, 0}, Leaf{0x00000020, 0x756E6547, 0x6C65746E, 0x49656E69}},
{{0x00000001, 0}, Leaf{0x000B06E0, 0x00800800, 0x7FFAFBBF, 0xBFEBFBFF}},
});
const auto info = GetX86Info();
EXPECT_STREQ(info.vendor, CPU_FEATURES_VENDOR_GENUINE_INTEL);
EXPECT_EQ(info.family, 0x06);
EXPECT_EQ(info.model, 0xBE);
EXPECT_EQ(GetX86Microarchitecture(&info), X86Microarchitecture::INTEL_ADL);
}
// https://github.com/google/cpu_features/issues/200
// http://users.atw.hu/instlatx64/GenuineIntel/GenuineIntel00206F2_Eagleton_CPUID.txt

View File

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

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());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << " dB-Hz" << std::endl;
std::cout << std::setprecision(default_precision); // restore defaults
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl;
}
if (d_nav.have_new_utc_model() == true)
{
@ -310,7 +313,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
const std::shared_ptr<Beidou_Dnav_Utc_Model> tmp_obj = std::make_shared<Beidou_Dnav_Utc_Model>(d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV UTC Model data have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV utc model message received in channel "
<< d_channel
<< ": UTC model parameters from satellite " << d_satellite
@ -323,7 +330,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
const std::shared_ptr<Beidou_Dnav_Iono> tmp_obj = std::make_shared<Beidou_Dnav_Iono>(d_nav.get_iono());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Iono data have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV Iono message received in channel " << d_channel
<< ": Iono model parameters from satellite " << d_satellite
<< " with CN0=" << cn0 << std::setprecision(default_precision)
@ -335,7 +346,11 @@ void beidou_b1i_telemetry_decoder_gs::decode_subframe(float *frame_symbols, doub
// std::shared_ptr<Beidou_Dnav_Almanac> tmp_obj = std::make_shared<Beidou_Dnav_Almanac>(d_nav.get_almanac(slot_nbr));
// this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "BEIDOU DNAV Almanac data have been received in channel" << d_channel << " from satellite " << d_satellite << " with CN0=" << cn0 << " dB-Hz";
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New BEIDOU B1I DNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)

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

View File

@ -440,7 +440,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_inav_nav.get_ephemeris());
if (d_band == '1')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -448,7 +452,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
}
else if (d_band == '7')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE
<< "New Galileo E5b I/NAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite << " with CN0="
@ -465,7 +473,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
{
const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_inav_nav.get_reduced_ced());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV reduced CED message received in channel "
<< d_channel << " from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -480,7 +492,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
if (d_band == '1')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
<< ": iono/GST model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -488,7 +504,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
}
else if (d_band == '7')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel "
<< d_channel << ": iono/GST model parameters from satellite "
<< d_satellite << " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -503,7 +523,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
if (d_band == '1')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New Galileo E1 I/NAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -511,7 +535,11 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
}
else if (d_band == '7')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New Galileo E5b I/NAV message received in channel "
<< d_channel
<< ": UTC model parameters from satellite " << d_satellite
@ -530,14 +558,22 @@ void galileo_telemetry_decoder_gs::decode_INAV_word(float *page_part_symbols, in
// debug
if (d_band == '1')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "Galileo E1 I/NAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz" << std::endl;
}
else if (d_band == '7')
{
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "Galileo E5b I/NAV almanac received in channel "
<< d_channel << " from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -612,7 +648,11 @@ void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t
{
const std::shared_ptr<Galileo_Ephemeris> tmp_obj = std::make_shared<Galileo_Ephemeris>(d_fnav_nav.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
<< d_channel << ": ephemeris from satellite " << d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -623,7 +663,11 @@ void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t
{
const std::shared_ptr<Galileo_Iono> tmp_obj = std::make_shared<Galileo_Iono>(d_fnav_nav.get_iono());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
<< d_channel << ": iono/GST model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -634,7 +678,11 @@ void galileo_telemetry_decoder_gs::decode_FNAV_word(float *page_symbols, int32_t
{
const std::shared_ptr<Galileo_Utc_Model> tmp_obj = std::make_shared<Galileo_Utc_Model>(d_fnav_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New Galileo E5a F/NAV message received in channel "
<< d_channel << ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -695,8 +743,13 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float *
if (is_page_dummy != d_cnav_dummy_page)
{
d_cnav_dummy_page = is_page_dummy;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel " << d_channel << " from satellite "
#endif
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 CNAV dummy pages in channel "
<< d_channel << " from satellite "
<< d_satellite << " with CN0="
<< std::setprecision(2) << cn0 << std::setprecision(default_precision) << " dB-Hz"
<< TEXT_RESET << std::endl;
@ -713,7 +766,11 @@ void galileo_telemetry_decoder_gs::decode_CNAV_word(uint64_t time_stamp, float *
if (d_print_cnav_page == true)
{
d_print_cnav_page = false; // only print the first page
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "Receiving Galileo E6 HAS pages"
<< (d_cnav_nav.is_HAS_in_test_mode() == true ? " (test mode) " : " ")
<< "in channel " << d_channel << " from satellite " << d_satellite

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());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -251,7 +255,11 @@ void glonass_l1_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
const std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV UTC Model data have been received in channel" << d_channel << " from satellite " << d_satellite;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GLONASS L1 GNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -264,7 +272,11 @@ void glonass_l1_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
tmp_obj = std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac(slot_nbr));
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV Almanac data have been received in channel" << d_channel << " in slot number " << slot_nbr;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << "New GLONASS L1 GNAV almanac received in channel " << d_channel << " from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
<< " dB-Hz" << std::endl;

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());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV Ephemeris have been received in channel" << d_channel << " from satellite " << d_satellite;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -251,7 +255,11 @@ void glonass_l2_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
const std::shared_ptr<Glonass_Gnav_Utc_Model> tmp_obj = std::make_shared<Glonass_Gnav_Utc_Model>(d_nav.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV UTC Model data have been received in channel" << d_channel << " from satellite " << d_satellite;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)
@ -263,7 +271,11 @@ void glonass_l2_ca_telemetry_decoder_gs::decode_string(const double *frame_symbo
const std::shared_ptr<Glonass_Gnav_Almanac> tmp_obj = std::make_shared<Glonass_Gnav_Almanac>(d_nav.get_almanac(slot_nbr));
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
LOG(INFO) << "GLONASS GNAV Almanac data have been received in channel" << d_channel << " in slot number " << slot_nbr;
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_CYAN << "New GLONASS L2 GNAV almanac received in channel " << d_channel
<< " from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << cn0 << std::setprecision(default_precision)

View File

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

View File

@ -259,7 +259,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
// get ephemeris object for this SV
const std::shared_ptr<Gps_CNAV_Ephemeris> tmp_obj = std::make_shared<Gps_CNAV_Ephemeris>(d_CNAV_Message.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
@ -269,7 +273,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
{
const std::shared_ptr<Gps_CNAV_Iono> tmp_obj = std::make_shared<Gps_CNAV_Iono>(d_CNAV_Message.get_iono());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
<< ": iono model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
@ -280,7 +288,11 @@ int gps_l2c_telemetry_decoder_gs::general_work(int noutput_items __attribute__((
{
const std::shared_ptr<Gps_CNAV_Utc_Model> tmp_obj = std::make_shared<Gps_CNAV_Utc_Model>(d_CNAV_Message.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_BLUE << "New GPS CNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)

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
const std::shared_ptr<Gps_CNAV_Ephemeris> tmp_obj = std::make_shared<Gps_CNAV_Ephemeris>(d_CNAV_Message.get_ephemeris());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
<< ": ephemeris from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz
@ -266,7 +270,11 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
{
const std::shared_ptr<Gps_CNAV_Iono> tmp_obj = std::make_shared<Gps_CNAV_Iono>(d_CNAV_Message.get_iono());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
<< ": iono model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz << std::setprecision(default_precision)
@ -277,7 +285,11 @@ int gps_l5_telemetry_decoder_gs::general_work(int noutput_items __attribute__((u
{
const std::shared_ptr<Gps_CNAV_Utc_Model> tmp_obj = std::make_shared<Gps_CNAV_Utc_Model>(d_CNAV_Message.get_utc_model());
this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj));
#if __cplusplus == 201103L
const int default_precision = std::cout.precision();
#else
const auto default_precision{std::cout.precision()};
#endif
std::cout << TEXT_MAGENTA << "New GPS L5 CNAV message received in channel " << d_channel
<< ": UTC model parameters from satellite " << d_satellite
<< " with CN0=" << std::setprecision(2) << current_synchro_data.CN0_dB_hz