1
0
mirror of https://github.com/google/cpu_features.git synced 2025-08-16 11:14:35 +02:00

Add support for Apple M1 AArch64 SoCs (#204)

* Add support for Apple M1 AArch64 SoCs

Completely based on #150. Thanks to @sbehnke!
+ Refactoring to accomodate the new source tree
+ Adding more feature flags

* revert minimum version to 3.0

* Update introspection table

* Simplify logic for Apple HAVE_SYSCTLBYNAME

---------

Co-authored-by: Guillaume Chatelet <gchatelet@google.com>
This commit is contained in:
arkivm
2023-08-28 02:16:41 -07:00
committed by GitHub
parent 0d5f398c58
commit c5ece5e8cc
7 changed files with 331 additions and 127 deletions

View File

@@ -63,7 +63,7 @@ set(PROCESSOR_IS_LOONGARCH FALSE)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips") if(CMAKE_SYSTEM_PROCESSOR MATCHES "^mips")
set(PROCESSOR_IS_MIPS TRUE) set(PROCESSOR_IS_MIPS TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64|arm64)") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(^aarch64)|(^arm64)")
set(PROCESSOR_IS_AARCH64 TRUE) set(PROCESSOR_IS_AARCH64 TRUE)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm") elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set(PROCESSOR_IS_ARM TRUE) set(PROCESSOR_IS_ARM TRUE)
@@ -160,10 +160,9 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
target_include_directories(cpu_features target_include_directories(cpu_features
PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features> PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
) )
if(PROCESSOR_IS_X86)
if(APPLE) if(APPLE)
target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME) target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
endif()
endif() endif()
add_library(CpuFeature::cpu_features ALIAS cpu_features) add_library(CpuFeature::cpu_features ALIAS cpu_features)

View File

@@ -182,7 +182,7 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
|---------|:----:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:| |---------|:----:|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:|
| Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | | Linux | yes² | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ | yes¹ |
| FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet | | FreeBSD | yes² | not yet | not yet | not yet | not yet | N/A | not yet |
| MacOs | yes² | not yet | N/A | N/A | no | N/A | no | | MacOs | yes² | yes⁵ | N/A | N/A | N/A | N/A | N/A |
| Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A | | Windows | yes² | not yet | not yet | N/A | N/A | N/A | N/A |
| Android | yes² | yes¹ | yes¹ | yes¹ | 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 | | iOS | N/A | not yet | not yet | N/A | N/A | N/A | N/A |
@@ -200,6 +200,8 @@ flags : aes,avx,cx16,smx,sse4_1,sse4_2,ssse3
microarchitecture allows the client to reject particular microarchitectures. microarchitecture allows the client to reject particular microarchitectures.
4. All flavors of Mips are supported, little and big endian as well as 32/64 4. All flavors of Mips are supported, little and big endian as well as 32/64
bits. bits.
5. **Features revealed from sysctl.** features are retrieved by the `sysctl`
instruction.
<a name="ndk"></a> <a name="ndk"></a>
## Android NDK's drop in replacement ## Android NDK's drop in replacement

View File

@@ -0,0 +1,118 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdbool.h>
#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"
#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

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

View File

@@ -0,0 +1,88 @@
// Copyright 2021 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#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

@@ -74,8 +74,15 @@ if(PROCESSOR_IS_AARCH64)
add_executable(cpuinfo_aarch64_test add_executable(cpuinfo_aarch64_test
cpuinfo_aarch64_test.cc cpuinfo_aarch64_test.cc
../src/impl_aarch64_linux_or_android.c ../src/impl_aarch64_linux_or_android.c
../src/impl_aarch64_windows.c) ../src/impl_aarch64_windows.c
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_AARCH64) ../src/impl_aarch64_macos_or_iphone.c
)
if(APPLE)
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_SYSCTL_AARCH64)
target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME)
else()
target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_AARCH64)
endif()
target_link_libraries(cpuinfo_aarch64_test all_libraries) target_link_libraries(cpuinfo_aarch64_test all_libraries)
add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test) add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
endif() endif()

View File

@@ -25,8 +25,35 @@
namespace cpu_features { namespace cpu_features {
class FakeCpuAarch64 { class FakeCpuAarch64 {
#if defined(CPU_FEATURES_OS_LINUX)
// No particular implementation for Linux as we use /proc/cpuinfo
#elif defined(CPU_FEATURES_OS_MACOS)
std::set<std::string> darwin_sysctlbyname_;
std::map<std::string, int> darwin_sysctlbynamevalue_;
public:
bool GetDarwinSysCtlByName(std::string name) const {
return darwin_sysctlbyname_.count(name);
}
int GetDarwinSysCtlByNameValue(std::string name) const {
const auto iter = darwin_sysctlbynamevalue_.find(name);
if (iter != darwin_sysctlbynamevalue_.end()) return iter->second;
return 0;
}
void SetDarwinSysCtlByName(std::string name) {
darwin_sysctlbyname_.insert(name);
}
void SetDarwinSysCtlByNameValue(std::string name, int value) {
darwin_sysctlbynamevalue_[name] = value;
}
#elif defined(CPU_FEATURES_OS_WINDOWS)
std::set<DWORD> windows_isprocessorfeaturepresent_;
WORD processor_revision_{};
public: public:
#if defined(CPU_FEATURES_OS_WINDOWS)
bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) { bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) {
return windows_isprocessorfeaturepresent_.count(dwProcessorFeature); return windows_isprocessorfeaturepresent_.count(dwProcessorFeature);
} }
@@ -42,11 +69,7 @@ class FakeCpuAarch64 {
void SetWindowsNativeSystemInfoProcessorRevision(WORD wProcessorRevision) { void SetWindowsNativeSystemInfoProcessorRevision(WORD wProcessorRevision) {
processor_revision_ = wProcessorRevision; processor_revision_ = wProcessorRevision;
} }
#endif
private:
std::set<DWORD> windows_isprocessorfeaturepresent_;
WORD processor_revision_{};
#endif // CPU_FEATURES_OS_WINDOWS
}; };
static FakeCpuAarch64* g_fake_cpu_instance = nullptr; static FakeCpuAarch64* g_fake_cpu_instance = nullptr;
@@ -56,7 +79,18 @@ static FakeCpuAarch64& cpu() {
return *g_fake_cpu_instance; return *g_fake_cpu_instance;
} }
#if defined(CPU_FEATURES_OS_WINDOWS) // Define OS dependent mock functions
#if defined(CPU_FEATURES_OS_LINUX)
// No particular functions to implement for Linux as we use /proc/cpuinfo
#elif defined(CPU_FEATURES_OS_MACOS)
extern "C" bool GetDarwinSysCtlByName(const char* name) {
return cpu().GetDarwinSysCtlByName(name);
}
extern "C" int GetDarwinSysCtlByNameValue(const char* name) {
return cpu().GetDarwinSysCtlByNameValue(name);
}
#elif defined(CPU_FEATURES_OS_WINDOWS)
extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) { extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) {
return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature); return cpu().GetWindowsIsProcessorFeaturePresent(dwProcessorFeature);
} }
@@ -64,7 +98,7 @@ extern "C" bool GetWindowsIsProcessorFeaturePresent(DWORD dwProcessorFeature) {
extern "C" WORD GetWindowsNativeSystemInfoProcessorRevision() { extern "C" WORD GetWindowsNativeSystemInfoProcessorRevision() {
return cpu().GetWindowsNativeSystemInfoProcessorRevision(); return cpu().GetWindowsNativeSystemInfoProcessorRevision();
} }
#endif // CPU_FEATURES_OS_WINDOWS #endif
namespace { namespace {
@@ -80,7 +114,7 @@ class CpuidAarch64Test : public ::testing::Test {
} }
}; };
TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum) { TEST_F(CpuidAarch64Test, Aarch64FeaturesEnum) {
const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_); const char* last_name = GetAarch64FeaturesEnumName(AARCH64_LAST_);
EXPECT_STREQ(last_name, "unknown_feature"); EXPECT_STREQ(last_name, "unknown_feature");
for (int i = static_cast<int>(AARCH64_FP); for (int i = static_cast<int>(AARCH64_FP);
@@ -93,10 +127,11 @@ TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum) {
} }
} }
// OS dependent tests
#if defined(CPU_FEATURES_OS_LINUX) #if defined(CPU_FEATURES_OS_LINUX)
void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); } void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
TEST(CpuinfoAarch64Test, FromHardwareCap) { TEST_F(CpuidAarch64Test, FromHardwareCap) {
ResetHwcaps(); ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0); SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
GetEmptyFilesystem(); // disabling /proc/cpuinfo GetEmptyFilesystem(); // disabling /proc/cpuinfo
@@ -135,7 +170,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap) {
EXPECT_FALSE(info.features.pacg); EXPECT_FALSE(info.features.pacg);
} }
TEST(CpuinfoAarch64Test, FromHardwareCap2) { TEST_F(CpuidAarch64Test, FromHardwareCap2) {
ResetHwcaps(); ResetHwcaps();
SetHardwareCapabilities(AARCH64_HWCAP_FP, SetHardwareCapabilities(AARCH64_HWCAP_FP,
AARCH64_HWCAP2_SVE2 | AARCH64_HWCAP2_BTI); AARCH64_HWCAP2_SVE2 | AARCH64_HWCAP2_BTI);
@@ -164,7 +199,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap2) {
EXPECT_FALSE(info.features.rng); EXPECT_FALSE(info.features.rng);
} }
TEST(CpuinfoAarch64Test, ARMCortexA53) { TEST_F(CpuidAarch64Test, ARMCortexA53) {
ResetHwcaps(); ResetHwcaps();
auto& fs = GetEmptyFilesystem(); auto& fs = GetEmptyFilesystem();
fs.CreateFile("/proc/cpuinfo", fs.CreateFile("/proc/cpuinfo",
@@ -266,9 +301,68 @@ CPU revision : 3)");
EXPECT_FALSE(info.features.smeb16b16); EXPECT_FALSE(info.features.smeb16b16);
EXPECT_FALSE(info.features.smef16f16); EXPECT_FALSE(info.features.smef16f16);
} }
#endif // CPU_FEATURES_OS_LINUX #elif defined(CPU_FEATURES_OS_MACOS)
TEST_F(CpuidAarch64Test, FromDarwinSysctlFromName) {
cpu().SetDarwinSysCtlByName("hw.optional.floatingpoint");
cpu().SetDarwinSysCtlByName("hw.optional.neon");
cpu().SetDarwinSysCtlByName("hw.optional.AdvSIMD_HPFPCvt");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_FP16");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_LSE");
cpu().SetDarwinSysCtlByName("hw.optional.armv8_crc32");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_FHM");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA512");
cpu().SetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA3");
cpu().SetDarwinSysCtlByName("hw.optional.amx_version");
cpu().SetDarwinSysCtlByName("hw.optional.ucnormal_mem");
cpu().SetDarwinSysCtlByName("hw.optional.arm64");
#if defined(CPU_FEATURES_OS_WINDOWS) cpu().SetDarwinSysCtlByNameValue("hw.cputype", 16777228);
cpu().SetDarwinSysCtlByNameValue("hw.cpusubtype", 2);
cpu().SetDarwinSysCtlByNameValue("hw.cpu64bit", 1);
cpu().SetDarwinSysCtlByNameValue("hw.cpufamily", 458787763);
cpu().SetDarwinSysCtlByNameValue("hw.cpusubfamily", 2);
const auto info = GetAarch64Info();
EXPECT_EQ(info.implementer, 0x100000C);
EXPECT_EQ(info.variant, 2);
EXPECT_EQ(info.part, 0x1B588BB3);
EXPECT_EQ(info.revision, 2);
EXPECT_TRUE(info.features.fp);
EXPECT_FALSE(info.features.asimd);
EXPECT_FALSE(info.features.evtstrm);
EXPECT_FALSE(info.features.aes);
EXPECT_FALSE(info.features.pmull);
EXPECT_FALSE(info.features.sha1);
EXPECT_FALSE(info.features.sha2);
EXPECT_TRUE(info.features.crc32);
EXPECT_TRUE(info.features.atomics);
EXPECT_TRUE(info.features.fphp);
EXPECT_FALSE(info.features.asimdhp);
EXPECT_FALSE(info.features.cpuid);
EXPECT_FALSE(info.features.asimdrdm);
EXPECT_FALSE(info.features.jscvt);
EXPECT_FALSE(info.features.fcma);
EXPECT_FALSE(info.features.lrcpc);
EXPECT_FALSE(info.features.dcpop);
EXPECT_TRUE(info.features.sha3);
EXPECT_FALSE(info.features.sm3);
EXPECT_FALSE(info.features.sm4);
EXPECT_FALSE(info.features.asimddp);
EXPECT_TRUE(info.features.sha512);
EXPECT_FALSE(info.features.sve);
EXPECT_TRUE(info.features.asimdfhm);
EXPECT_FALSE(info.features.dit);
EXPECT_FALSE(info.features.uscat);
EXPECT_FALSE(info.features.ilrcpc);
EXPECT_FALSE(info.features.flagm);
EXPECT_FALSE(info.features.ssbs);
EXPECT_FALSE(info.features.sb);
EXPECT_FALSE(info.features.paca);
EXPECT_FALSE(info.features.pacg);
}
#elif defined(CPU_FEATURES_OS_WINDOWS)
TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4) { TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4) {
cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03); cpu().SetWindowsNativeSystemInfoProcessorRevision(0x03);
cpu().SetWindowsIsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE); cpu().SetWindowsIsProcessorFeaturePresent(PF_ARM_VFP_32_REGISTERS_AVAILABLE);
@@ -292,6 +386,5 @@ TEST_F(CpuidAarch64Test, WINDOWS_AARCH64_RPI4) {
EXPECT_FALSE(info.features.lrcpc); EXPECT_FALSE(info.features.lrcpc);
} }
#endif // CPU_FEATURES_OS_WINDOWS #endif // CPU_FEATURES_OS_WINDOWS
} // namespace } // namespace
} // namespace cpu_features } // namespace cpu_features