diff --git a/CMakeLists.txt b/CMakeLists.txt index 996712c13..9a6f63392 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -486,6 +486,10 @@ if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")) include(TestForARM) endif() endif() +else() + if(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") + set(IS_ARM TRUE) + endif() endif() ################################################################################ @@ -3174,17 +3178,13 @@ if((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") AND NOT WIN32) endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") if(NOT ENABLE_GENERIC_ARCH) - if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - add_compile_options(-march=native) - else() - if(IS_ARM) - # ARM-specific options - if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE) - add_compile_options(-mcpu=native) - endif() - else() - add_compile_options(-march=native) + if(IS_ARM) + # ARM-specific options + if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_TOOLCHAIN_FILE) + add_compile_options(-mcpu=native) endif() + else() + add_compile_options(-march=native) endif() endif() endif() diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 4043f33bb..8069b0485 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -71,6 +71,7 @@ All notable changes to GNSS-SDR will be documented in this file. 3.8. - If the Matio library is not found, now it is configured and built by CMake instead of using autotools. +- Added support for Apple M1 AArch64 architecture processor. ### Improvements in Reliability diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt index d8e76d1a0..54dcf88cc 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/CMakeLists.txt @@ -8,7 +8,7 @@ ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 2.8.12...3.20) +cmake_minimum_required(VERSION 2.8.12...3.21) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release") endif() @@ -253,9 +253,9 @@ endif() set(SUPPORTED_CPU_FEATURES_ARCH FALSE) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") set(SUPPORTED_CPU_FEATURES_ARCH TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") set(SUPPORTED_CPU_FEATURES_ARCH TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") set(SUPPORTED_CPU_FEATURES_ARCH TRUE) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") set(SUPPORTED_CPU_FEATURES_ARCH TRUE) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt index 0aa941f68..2feca7715 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/CMakeLists.txt @@ -63,10 +63,10 @@ set(PROCESSOR_IS_POWER FALSE) if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") set(PROCESSOR_IS_MIPS TRUE) +elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(arm64)") + set(PROCESSOR_IS_AARCH64 TRUE) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") set(PROCESSOR_IS_ARM TRUE) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^aarch64") - set(PROCESSOR_IS_AARCH64 TRUE) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64|amd64)|(^i.86$)") set(PROCESSOR_IS_X86 TRUE) elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)") @@ -152,10 +152,8 @@ set_property(TARGET cpu_features PROPERTY POSITION_INDEPENDENT_CODE ${BUILD_PIC} target_include_directories(cpu_features PUBLIC $ ) -if(PROCESSOR_IS_X86) - if(APPLE) - target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) - endif() +if(APPLE AND (PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64)) + target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) endif() add_library(CpuFeature::cpu_features ALIAS cpu_features) diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md index bbbf966ec..638e62874 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/README.md @@ -162,7 +162,7 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3 | Android | yes² | yes¹ | yes¹ | yes¹ | N/A | | iOS | N/A | not yet | not yet | N/A | N/A | | Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | -| MacOs | yes² | N/A | not yet | N/A | no | +| MacOS | yes² | N/A | yes² | N/A | no | | Windows | yes² | not yet | not yet | N/A | N/A | 1. **Features revealed from Linux.** We gather data from several sources diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h index 5cad8743d..a36629a06 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/include/cpu_features_macros.h @@ -29,7 +29,7 @@ #define CPU_FEATURES_ARCH_ARM #endif -#if defined(__aarch64__) +#if (defined(__aarch64__) || (defined(__APPLE__) && defined(__arm64__))) #define CPU_FEATURES_ARCH_AARCH64 #endif diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c index 62cdb403d..8d16acaa6 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/src/cpuinfo_aarch64.c @@ -9,6 +9,33 @@ #include #include +#if defined(CPU_FEATURES_OS_DARWIN) +#if !defined(HAVE_SYSCTLBYNAME) +#error "Darwin needs support for sysctlbyname" +#endif +#include + +#if defined(CPU_FEATURES_MOCK_CPUID_ARM64) +extern bool GetDarwinSysCtlByName(const char*); +extern int GetDarwinSysCtlByNameValue(const char*); +#else // CPU_FEATURES_MOCK_CPUID_ARM64 +static bool GetDarwinSysCtlByName(const char* name) +{ + int enabled; + size_t enabled_len = sizeof(enabled); + const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); + return failure ? false : enabled; +} +static int GetDarwinSysCtlByNameValue(const char* name) +{ + int enabled; + size_t enabled_len = sizeof(enabled); + const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0); + return failure ? 0 : enabled; +} +#endif +#endif // CPU_FEATURES_OS_DARWIN + // Generation of feature's getters/setters functions and kGetters, kSetters, // kCpuInfoFlags and kHardwareCapabilities global tables. #define DEFINE_TABLE_FEATURES \ @@ -67,6 +94,8 @@ #define DEFINE_TABLE_FEATURE_TYPE Aarch64Features #include "define_tables.h" +#if !defined(CPU_FEATURES_OS_DARWIN) + static bool HandleAarch64Line(const LineResult result, Aarch64Info* const info) { @@ -120,6 +149,8 @@ static void FillProcCpuInfoData(Aarch64Info* const info) } } +#endif /* !CPU_FEATURES_OS_DARWIN */ + static const Aarch64Info kEmptyAarch64Info; Aarch64Info GetAarch64Info(void) @@ -129,6 +160,24 @@ Aarch64Info GetAarch64Info(void) // /proc/cpuinfo). Aarch64Info info = kEmptyAarch64Info; +#if defined(CPU_FEATURES_OS_DARWIN) + + // Handling Darwin platform through sysctlbyname + info.implementer = GetDarwinSysCtlByNameValue("hw.cputype"); + info.variant = GetDarwinSysCtlByNameValue("hw.cpusubtype"); + info.part = GetDarwinSysCtlByNameValue("hw.cpufamily"); + info.revision = GetDarwinSysCtlByNameValue("hw.cpusubfamily"); + + info.features.fp = GetDarwinSysCtlByName("hw.optional.floatingpoint"); + info.features.fphp = GetDarwinSysCtlByName("hw.optional.neon_hpfp"); + info.features.sha512 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha512"); + info.features.atomics = GetDarwinSysCtlByName("hw.optional.armv8_1_atomics"); + info.features.asimdfhm = GetDarwinSysCtlByName("hw.optional.armv8_2_fhm"); + info.features.sha3 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha3"); + info.features.crc32 = GetDarwinSysCtlByName("hw.optional.armv8_crc32"); + +#else + FillProcCpuInfoData(&info); const HardwareCapabilities hwcaps = CpuFeatures_GetHardwareCapabilities(); for (size_t i = 0; i < AARCH64_LAST_; ++i) @@ -139,6 +188,8 @@ Aarch64Info GetAarch64Info(void) } } +#endif + return info; } diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt index aa30768d5..6f8f2f397 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/CMakeLists.txt @@ -69,6 +69,10 @@ endif() ## cpuinfo_aarch64_test if(PROCESSOR_IS_AARCH64) add_executable(cpuinfo_aarch64_test cpuinfo_aarch64_test.cc ../src/cpuinfo_aarch64.c) + if(APPLE) + target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_ARM64) + target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME) + endif() target_link_libraries(cpuinfo_aarch64_test all_libraries) add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) endif() diff --git a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc index bb2aa6a0a..40c9c2f90 100644 --- a/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc +++ b/src/algorithms/libs/volk_gnsssdr_module/volk_gnsssdr/cpu_features/test/cpuinfo_aarch64_test.cc @@ -10,7 +10,130 @@ namespace cpu_features { namespace { -void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } +#if defined(CPU_FEATURES_OS_DARWIN) + +class FakeCpu +{ +public: + bool GetDarwinSysCtlByName(std::string name) const + { + return darwin_sysctlbyname_.count(name); + } + + int GetDarwinSysCtlByNameValue(std::string name) const + { + std::map::const_iterator iter = + darwin_sysctlbynamevalue_.find(name); + if (iter != std::end(darwin_sysctlbynamevalue_)) + { + 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; + } + +private: + std::set darwin_sysctlbyname_; + std::map darwin_sysctlbynamevalue_; +}; + +FakeCpu* g_fake_cpu = nullptr; + +extern "C" bool GetDarwinSysCtlByName(const char* name) +{ + return g_fake_cpu->GetDarwinSysCtlByName(name); +} + +extern "C" int GetDarwinSysCtlByNameValue(const char* name) +{ + return g_fake_cpu->GetDarwinSysCtlByNameValue(name); +} + +class CpuinfoAarch64Test : public ::testing::Test +{ +protected: + void SetUp() override { g_fake_cpu = new FakeCpu(); } + void TearDown() override { delete g_fake_cpu; } +}; + +TEST_F(CpuinfoAarch64Test, FromDarwinSysctlFromName) +{ + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.floatingpoint"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.neon"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.neon_hpfp"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.neon_fp16"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_1_atomics"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_crc32"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_2_fhm"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_2_sha512"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.armv8_2_sha3"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.amx_version"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.ucnormal_mem"); + g_fake_cpu->SetDarwinSysCtlByName("hw.optional.arm64"); + + g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cputype", 16777228); + g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpusubtype", 2); + g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpu64bit", 1); + g_fake_cpu->SetDarwinSysCtlByNameValue("hw.cpufamily", 458787763); + g_fake_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); +} + +#else + +void DisableHardwareCapabilities() +{ + SetHardwareCapabilities(0, 0); +} TEST(CpuinfoAarch64Test, FromHardwareCap) { @@ -160,5 +283,7 @@ CPU revision : 3)"); EXPECT_FALSE(info.features.mte); } +#endif + } // namespace } // namespace cpu_features