Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions absl/base/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,15 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_SCHED_YIELD 1
#endif

// ABSL_HAVE_ELF_AUX_INFO
//
// Checks whether the platform implements elf_aux_info(3).
#ifdef ABSL_HAVE_ELF_AUX_INFO
#error ABSL_HAVE_ELF_AUX_INFO cannot be directly set
#elif (defined(__FreeBSD__) || defined(__OpenBSD__)) && __has_include(<sys/auxv.h>)
#define ABSL_HAVE_ELF_AUX_INFO 1
#endif

// ABSL_HAVE_SEMAPHORE_H
//
// Checks whether the platform supports the <semaphore.h> header and sem_init(3)
Expand Down
24 changes: 20 additions & 4 deletions absl/base/internal/cpu_detect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@

#include "absl/base/config.h"

#if defined(__aarch64__) && defined(__linux__)
#if defined(__aarch64__) && \
(defined(__linux__) || defined(ABSL_HAVE_ELF_AUX_INFO))
#if defined(__linux__)
#include <asm/hwcap.h>
#endif
#include <sys/auxv.h>
#endif

Expand Down Expand Up @@ -265,7 +268,8 @@ bool SupportsBmi2() {
return (cpu_info[1] & (1 << 8)) != 0;
}

#elif defined(__aarch64__) && defined(__linux__)
#elif defined(__aarch64__) && \
(defined(__linux__) || defined(ABSL_HAVE_ELF_AUX_INFO))

#ifndef HWCAP_CPUID
#define HWCAP_CPUID (1 << 11)
Expand All @@ -276,12 +280,18 @@ bool SupportsBmi2() {

CpuType GetCpuType() {
// MIDR_EL1 is not visible to EL0, however the access will be emulated by
// linux if AT_HWCAP has HWCAP_CPUID set.
// Linux, FreeBSD and OpenBSD if AT_HWCAP has HWCAP_CPUID set.
//
// This method will be unreliable on heterogeneous computing systems (ex:
// big.LITTLE) since the value of MIDR_EL1 will change based on the calling
// thread.
#if defined(ABSL_HAVE_ELF_AUX_INFO)
uint64_t hwcaps;
if (elf_aux_info(AT_HWCAP, &hwcaps, sizeof(hwcaps)) != 0)
return CpuType::kUnknown;
#else
uint64_t hwcaps = getauxval(AT_HWCAP);
#endif
if (hwcaps & HWCAP_CPUID) {
uint64_t midr = 0;
ABSL_INTERNAL_AARCH64_ID_REG_READ(MIDR_EL1, midr);
Expand Down Expand Up @@ -328,7 +338,13 @@ CpuType GetCpuType() {
}

bool SupportsArmCRC32PMULL() {
#if defined(HWCAP_CRC32) && defined(HWCAP_PMULL)
#if defined(ABSL_HAVE_ELF_AUX_INFO)
uint64_t hwcaps;
bool ret = false;
if (elf_aux_info(AT_HWCAP, &hwcaps, sizeof(hwcaps)) == 0)
ret = (hwcaps & HWCAP_CRC32) && (hwcaps & HWCAP_PMULL);
return ret;
#elif defined(HWCAP_CRC32) && defined(HWCAP_PMULL)
uint64_t hwcaps = getauxval(AT_HWCAP);
return (hwcaps & HWCAP_CRC32) && (hwcaps & HWCAP_PMULL);
#else
Expand Down