Skip to content
Merged
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
139 changes: 23 additions & 116 deletions src/native/minipal/cpufeatures.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,21 @@
#include "minipalconfig.h"

#if HAVE_AUXV_HWCAP_H

#include <sys/auxv.h>
#include <asm/hwcap.h>

// Light-up for hardware capabilities that are not present in older headers used by the portable build.
#ifndef HWCAP_ASIMDRDM
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do similar light-up in other places, e.g. here:

// Ensure __NR_membarrier is defined for portable builds.

#define HWCAP_ASIMDRDM (1 << 12)
#endif
#ifndef HWCAP_LRCPC
#define HWCAP_LRCPC (1 << 15)
#endif
#ifndef HWCAP_ASIMDDP
#define HWCAP_ASIMDDP (1 << 20)
#endif

#endif

#if HAVE_SYSCTLBYNAME
Expand Down Expand Up @@ -306,142 +319,36 @@ int minipal_getcpufeatures(void)

#if defined(TARGET_ARM64)
#if defined(TARGET_UNIX)
#if HAVE_AUXV_HWCAP_H
unsigned long hwCap = getauxval(AT_HWCAP);

// HWCAP_* flags are introduced by ARM into the Linux kernel as new extensions are published.
// For a given kernel, some of these flags may not be present yet.
// Use ifdef for each to allow for compilation with any vintage kernel.
// From a single binary distribution perspective, compiling with latest kernel asm/hwcap.h should
// include all published flags. Given flags are merged to kernel and published before silicon is
// available, using the latest kernel for release should be sufficient.
#if HAVE_AUXV_HWCAP_H
unsigned long hwCap = getauxval(AT_HWCAP);

#ifdef HWCAP_AES
if (hwCap & HWCAP_AES)
result |= ARM64IntrinsicConstants_Aes;
#endif
#ifdef HWCAP_ATOMICS

if (hwCap & HWCAP_ATOMICS)
result |= ARM64IntrinsicConstants_Atomics;
#endif
#ifdef HWCAP_CRC32

if (hwCap & HWCAP_CRC32)
result |= ARM64IntrinsicConstants_Crc32;
#endif
#ifdef HWCAP_DCPOP
// if (hwCap & HWCAP_DCPOP)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_ASIMDDP

if (hwCap & HWCAP_ASIMDDP)
result |= ARM64IntrinsicConstants_Dp;
#endif
#ifdef HWCAP_FCMA
// if (hwCap & HWCAP_FCMA)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_FP
// if (hwCap & HWCAP_FP)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_FPHP
// if (hwCap & HWCAP_FPHP)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_JSCVT
// if (hwCap & HWCAP_JSCVT)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_LRCPC

if (hwCap & HWCAP_LRCPC)
result |= ARM64IntrinsicConstants_Rcpc;
#endif
#ifdef HWCAP_PMULL
// if (hwCap & HWCAP_PMULL)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_SHA1

if (hwCap & HWCAP_SHA1)
result |= ARM64IntrinsicConstants_Sha1;
#endif
#ifdef HWCAP_SHA2

if (hwCap & HWCAP_SHA2)
result |= ARM64IntrinsicConstants_Sha256;
#endif
#ifdef HWCAP_SHA512
// if (hwCap & HWCAP_SHA512)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_SHA3
// if (hwCap & HWCAP_SHA3)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_ASIMD

if (hwCap & HWCAP_ASIMD)
result |= ARM64IntrinsicConstants_AdvSimd | ARM64IntrinsicConstants_VectorT128;
#endif
#ifdef HWCAP_ASIMDRDM

if (hwCap & HWCAP_ASIMDRDM)
result |= ARM64IntrinsicConstants_Rdm;
#endif
#ifdef HWCAP_ASIMDHP
// if (hwCap & HWCAP_ASIMDHP)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_SM3
// if (hwCap & HWCAP_SM3)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_SM4
// if (hwCap & HWCAP_SM4)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP_SVE
// if (hwCap & HWCAP_SVE)
// result |= ARM64IntrinsicConstants_???;
#endif

#ifdef AT_HWCAP2
unsigned long hwCap2 = getauxval(AT_HWCAP2);

#ifdef HWCAP2_DCPODP
// if (hwCap2 & HWCAP2_DCPODP)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_SVE2
// if (hwCap2 & HWCAP2_SVE2)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_SVEAES
// if (hwCap2 & HWCAP2_SVEAES)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_SVEPMULL
// if (hwCap2 & HWCAP2_SVEPMULL)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_SVEBITPERM
// if (hwCap2 & HWCAP2_SVEBITPERM)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_SVESHA3
// if (hwCap2 & HWCAP2_SVESHA3)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_SVESM4
// if (hwCap2 & HWCAP2_SVESM4)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_FLAGM2
// if (hwCap2 & HWCAP2_FLAGM2)
// result |= ARM64IntrinsicConstants_???;
#endif
#ifdef HWCAP2_FRINT
// if (hwCap2 & HWCAP2_FRINT)
// result |= ARM64IntrinsicConstants_???;
#endif

#endif // AT_HWCAP2

#else // !HAVE_AUXV_HWCAP_H

Expand Down