mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 20:14:23 +08:00
Crc: Detect support for pmull and crc instructions on Apple AArch64
With a newer clang, we can use __builtin_cpu_supports which caches all the feature bits. If we are using an older clang, we fall back to querying sysctlbyname for the relevant processor features. PiperOrigin-RevId: 715153229 Change-Id: I570fa349f96829d5da3b32c928480ddf67176cad
This commit is contained in:
committed by
Copybara-Service
parent
d498bf66ef
commit
6effb000ca
@@ -42,6 +42,7 @@ cc_library(
|
||||
deps = [
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/types:optional",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ absl_cc_library(
|
||||
DEPS
|
||||
absl::base
|
||||
absl::config
|
||||
absl::optional
|
||||
)
|
||||
|
||||
# Internal-only target, do not depend on directly.
|
||||
|
||||
@@ -18,12 +18,21 @@
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/types/optional.h" // IWYU pragma: keep
|
||||
|
||||
#if defined(__aarch64__) && defined(__linux__)
|
||||
#include <asm/hwcap.h>
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__) && defined(__APPLE__)
|
||||
#if defined(__has_include) && __has_include(<arm/cpu_capabilities_public.h>)
|
||||
#include <arm/cpu_capabilities_public.h>
|
||||
#endif
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
@@ -277,6 +286,61 @@ bool SupportsArmCRC32PMULL() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#elif defined(__aarch64__) && defined(__APPLE__)
|
||||
|
||||
CpuType GetCpuType() { return CpuType::kUnknown; }
|
||||
|
||||
template <typename T>
|
||||
static absl::optional<T> ReadSysctlByName(const char* name) {
|
||||
T val;
|
||||
size_t val_size = sizeof(T);
|
||||
int ret = sysctlbyname(name, &val, &val_size, nullptr, 0);
|
||||
if (ret == -1) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
bool SupportsArmCRC32PMULL() {
|
||||
#if ABSL_HAVE_BUILTIN(__builtin_cpu_supports)
|
||||
// Support for the AES and PMULL instructions are tied together:
|
||||
// "When Cryptographic extensions are implemented and enabled then AESE, AESD,
|
||||
// AESMC, and AESIMC instructions are implemented and also PMULL/PMULL2
|
||||
// instructions operating on 64-bit data quantities."
|
||||
//
|
||||
// __builtin_cpu_supports expects users of PMULL to check for AES.
|
||||
//
|
||||
// https://developer.arm.com/documentation/101800/0201/AArch64-registers/AArch64-Identification-register-summary/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0
|
||||
return __builtin_cpu_supports("crc+aes");
|
||||
#endif
|
||||
|
||||
// Newer XNU kernels support querying all capabilities in a single
|
||||
// sysctlbyname.
|
||||
#if defined(CAP_BIT_CRC32) && defined(CAP_BIT_FEAT_PMULL)
|
||||
static const absl::optional<uint64_t> caps =
|
||||
ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
|
||||
if (caps.has_value()) {
|
||||
constexpr uint64_t kCrc32AndPmullCaps =
|
||||
(uint64_t{1} << CAP_BIT_CRC32) | (uint64_t{1} << CAP_BIT_FEAT_PMULL);
|
||||
return (*caps & kCrc32AndPmullCaps) == kCrc32AndPmullCaps;
|
||||
}
|
||||
#endif
|
||||
|
||||
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3915619
|
||||
static const absl::optional<int> armv8_crc32 =
|
||||
ReadSysctlByName<int>("hw.optional.armv8_crc32");
|
||||
if (armv8_crc32.value_or(0) == 0) {
|
||||
return false;
|
||||
}
|
||||
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
|
||||
static const absl::optional<int> feat_pmull =
|
||||
ReadSysctlByName<int>("hw.optional.arm.FEAT_PMULL");
|
||||
if (feat_pmull.value_or(0) == 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
CpuType GetCpuType() { return CpuType::kUnknown; }
|
||||
|
||||
Reference in New Issue
Block a user