Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[builtins] Refactor cpu_model support to reduce #if nesting. NFCI #75635

Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions compiler-rt/lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ endif()

# These files are used on 32-bit and 64-bit x86.
set(x86_ARCH_SOURCES
cpu_model.c
cpu_model/x86.c
)

if (NOT MSVC)
Expand Down Expand Up @@ -556,7 +556,7 @@ endif()
set(aarch64_SOURCES
${GENERIC_TF_SOURCES}
${GENERIC_SOURCES}
cpu_model.c
cpu_model/aarch64.c
aarch64/fp_mode.c
)

Expand Down
142 changes: 142 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//===-- cpu_model_aarch64.c - Support for __cpu_model builtin ----*- C -*-===//
jroelofs marked this conversation as resolved.
Show resolved Hide resolved
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is based on LLVM's lib/Support/Host.cpp.
// It implements __aarch64_have_lse_atomics, __aarch64_cpu_features for AArch64.
//
//===----------------------------------------------------------------------===//

#include "cpu_model.h"

#if !defined(__aarch64__)
# error This file is intended only for aarch64-based targets
#endif


#if __has_include(<sys/ifunc.h>)
#include <sys/ifunc.h>
#else
typedef struct __ifunc_arg_t {
unsigned long _size;
unsigned long _hwcap;
unsigned long _hwcap2;
} __ifunc_arg_t;
#endif // __has_include(<sys/ifunc.h>)


// LSE support detection for out-of-line atomics
// using HWCAP and Auxiliary vector
_Bool __aarch64_have_lse_atomics
__attribute__((visibility("hidden"), nocommon)) = false;

#if defined(__FreeBSD__)
# include "lse_atomics/freebsd.inc"
#elif defined(__Fucsia__)
# include "lse_atomics/fucsia.inc"
#elif defined(__ANDROID__)
# include "lse_atomics/android.inc"
#elif __has_include(<sys/auxv.h>)
# include "lse_atomics/sysauxv.inc"
#else
// When unimplemented, we leave __aarch64_have_lse_atomics initialized to false.
#endif


#if !defined(DISABLE_AARCH64_FMV)
// CPUFeatures must correspond to the same AArch64 features in
// AArch64TargetParser.h
enum CPUFeatures {
FEAT_RNG,
FEAT_FLAGM,
FEAT_FLAGM2,
FEAT_FP16FML,
FEAT_DOTPROD,
FEAT_SM4,
FEAT_RDM,
FEAT_LSE,
FEAT_FP,
FEAT_SIMD,
FEAT_CRC,
FEAT_SHA1,
FEAT_SHA2,
FEAT_SHA3,
FEAT_AES,
FEAT_PMULL,
FEAT_FP16,
FEAT_DIT,
FEAT_DPB,
FEAT_DPB2,
FEAT_JSCVT,
FEAT_FCMA,
FEAT_RCPC,
FEAT_RCPC2,
FEAT_FRINTTS,
FEAT_DGH,
FEAT_I8MM,
FEAT_BF16,
FEAT_EBF16,
FEAT_RPRES,
FEAT_SVE,
FEAT_SVE_BF16,
FEAT_SVE_EBF16,
FEAT_SVE_I8MM,
FEAT_SVE_F32MM,
FEAT_SVE_F64MM,
FEAT_SVE2,
FEAT_SVE_AES,
FEAT_SVE_PMULL128,
FEAT_SVE_BITPERM,
FEAT_SVE_SHA3,
FEAT_SVE_SM4,
FEAT_SME,
FEAT_MEMTAG,
FEAT_MEMTAG2,
FEAT_MEMTAG3,
FEAT_SB,
FEAT_PREDRES,
FEAT_SSBS,
FEAT_SSBS2,
FEAT_BTI,
FEAT_LS64,
FEAT_LS64_V,
FEAT_LS64_ACCDATA,
FEAT_WFXT,
FEAT_SME_F64,
FEAT_SME_I64,
FEAT_SME2,
FEAT_RCPC3,
FEAT_MAX,
FEAT_EXT = 62, // Reserved to indicate presence of additional features field
// in __aarch64_cpu_features
FEAT_INIT // Used as flag of features initialization completion
};

// Architecture features used
// in Function Multi Versioning
struct {
unsigned long long features;
// As features grows new fields could be added
} __aarch64_cpu_features __attribute__((visibility("hidden"), nocommon));

#if defined(__FreeBSD__)
# include "aarch64/fmv/mrs.inc"
# include "aarch64/fmv/freebsd.inc"
#elif defined(__Fucsia__)
Copy link
Member

Choose a reason for hiding this comment

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

I believe you've misspelled Fuchsia consistently :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

🤦‍♂️ thanks

# include "aarch64/fmv/mrs.inc"
# include "aarch64/fmv/fucsia.inc"
#elif defined(__ANDROID__)
# include "aarch64/fmv/mrs.inc"
# include "aarch64/fmv/android.inc"
#elif __has_include(<sys/auxv.h>)
# include "aarch64/fmv/mrs.inc"
# include "aarch64/fmv/sysauxv.inc"
#else
# include "aarch64/fmv/unimplemented.inc"
#endif

#endif // !defined(DISABLE_AARCH64_FMV)
jroelofs marked this conversation as resolved.
Show resolved Hide resolved
35 changes: 35 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
if (__aarch64_cpu_features.features)
return;

// ifunc resolvers don't have hwcaps in arguments on Android API lower
// than 30. If so, set feature detection done and keep all CPU features
// unsupported (zeros). To detect this case in runtime we check existence
// of memfd_create function from Standard C library which was introduced in
// Android API 30.
int memfd_create(const char *, unsigned int) __attribute__((weak));
if (!memfd_create)
return;

__init_cpu_features_constructor(hwcap, arg);
}

void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
unsigned long hwcap = 0;
jroelofs marked this conversation as resolved.
Show resolved Hide resolved
unsigned long hwcap2 = 0;
// CPU features already initialized.
if (__aarch64_cpu_features.features)
return;

// Don't set any CPU features,
// detection could be wrong on Exynos 9810.
if (__isExynos9810())
return;

__ifunc_arg_t arg;
arg._size = sizeof(__ifunc_arg_t);
arg._hwcap = getauxval(AT_HWCAP);
arg._hwcap2 = getauxval(AT_HWCAP2);
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
}
27 changes: 27 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/freebsd.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
if (__aarch64_cpu_features.features)
return;

__init_cpu_features_constructor(hwcap, arg);
}

void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
unsigned long hwcap = 0;
unsigned long hwcap2 = 0;
// CPU features already initialized.
if (__aarch64_cpu_features.features)
return;

int res = 0;
res = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
res |= elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2);
if (res)
return;

__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);
}
19 changes: 19 additions & 0 deletions compiler-rt/lib/builtins/cpu_model/aarch64/fmv/fucsia.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
void __init_cpu_features_resolver(unsigned long hwcap,
const __ifunc_arg_t *arg) {
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)
return;

__ifunc_arg_t arg;
arg._size = sizeof(__ifunc_arg_t);
arg._hwcap = getauxval(AT_HWCAP);
arg._hwcap2 = getauxval(AT_HWCAP2);
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
}
Loading
Loading