Skip to content

Commit

Permalink
[builtins] Fix CPU feature detection for Zircon (#76276)
Browse files Browse the repository at this point in the history
This is a follow up to #75635 which broke the build on Fuchsia. We don't
support ifunc on Fuchsia so we shouldn't define __init_cpu_features. For
__init_cpu_features_resolver we have to use _zx_system_get_features as a
Zircon native solution.
  • Loading branch information
petrhosek authored Dec 24, 2023
1 parent 4c1bc8e commit 09e6f12
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 16 deletions.
1 change: 0 additions & 1 deletion compiler-rt/lib/builtins/cpu_model/aarch64.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ struct {
#include "aarch64/fmv/mrs.inc"
#include "aarch64/fmv/freebsd.inc"
#elif defined(__Fuchsia__)
#include "aarch64/fmv/mrs.inc"
#include "aarch64/fmv/fuchsia.inc"
#elif defined(__ANDROID__)
#include "aarch64/fmv/mrs.inc"
Expand Down
59 changes: 44 additions & 15 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fuchsia.inc
Original file line number Diff line number Diff line change
@@ -1,22 +1,51 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
#include <zircon/features.h>
#include <zircon/syscalls.h>

void __init_cpu_features_resolver() {
if (__aarch64_cpu_features.features)
return;

__init_cpu_features_constructor(hwcap, arg);
}

void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
// CPU features already initialized.
if (__aarch64_cpu_features.features)
// This ensures the vDSO is a direct link-time dependency of anything that
// needs this initializer code.
#pragma comment(lib, "zircon")
uint32_t features;
zx_status_t status = _zx_system_get_features(ZX_FEATURE_KIND_CPU, &features);
if (status != ZX_OK)
return;

unsigned long hwcap = getauxval(AT_HWCAP);
unsigned long hwcap2 = getauxval(AT_HWCAP2);
#define setCPUFeature(cpu_feature) \
__aarch64_cpu_features.features |= 1ULL << cpu_feature

if (features & ZX_ARM64_FEATURE_ISA_FP)
setCPUFeature(FEAT_FP);
if (features & ZX_ARM64_FEATURE_ISA_ASIMD)
setCPUFeature(FEAT_SIMD);
if (features & ZX_ARM64_FEATURE_ISA_AES)
setCPUFeature(FEAT_AES);
if (features & ZX_ARM64_FEATURE_ISA_PMULL)
setCPUFeature(FEAT_PMULL);
if (features & ZX_ARM64_FEATURE_ISA_SHA1)
setCPUFeature(FEAT_SHA1);
if (features & ZX_ARM64_FEATURE_ISA_SHA256)
setCPUFeature(FEAT_SHA2);
if (features & ZX_ARM64_FEATURE_ISA_CRC32)
setCPUFeature(FEAT_CRC);
if (features & ZX_ARM64_FEATURE_ISA_RDM)
setCPUFeature(FEAT_RDM);
if (features & ZX_ARM64_FEATURE_ISA_SHA3)
setCPUFeature(FEAT_SHA3);
if (features & ZX_ARM64_FEATURE_ISA_SM4)
setCPUFeature(FEAT_SM4);
if (features & ZX_ARM64_FEATURE_ISA_DP)
setCPUFeature(FEAT_DOTPROD);
if (features & ZX_ARM64_FEATURE_ISA_FHM)
setCPUFeature(FEAT_FP16FML);
if (features & ZX_ARM64_FEATURE_ISA_SHA512)
setCPUFeature(FEAT_SHA3);
if (features & ZX_ARM64_FEATURE_ISA_I8MM)
setCPUFeature(FEAT_I8MM);
if (features & ZX_ARM64_FEATURE_ISA_SVE)
setCPUFeature(FEAT_SVE);

__ifunc_arg_t arg;
arg._size = sizeof(__ifunc_arg_t);
arg._hwcap = hwcap;
arg._hwcap2 = hwcap2;
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
setCPUFeature(FEAT_INIT);
}

0 comments on commit 09e6f12

Please sign in to comment.