Skip to content

Commit 256b214

Browse files
committed
[builtins][arm64] Implement __init_cpu_features_resolver on Apple platforms (#75636)
This is a re-land of #73685
1 parent 9237cfa commit 256b214

File tree

2 files changed

+72
-1
lines changed

2 files changed

+72
-1
lines changed

compiler-rt/lib/builtins/cpu_model/aarch64.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ struct {
123123

124124
// The formatter wants to re-order these includes, but doing so is incorrect:
125125
// clang-format off
126-
#if defined(__FreeBSD__)
126+
#if defined(__APPLE__)
127+
#include "aarch64/fmv/apple.inc"
128+
#elif defined(__FreeBSD__)
127129
#include "aarch64/fmv/mrs.inc"
128130
#include "aarch64/fmv/freebsd.inc"
129131
#elif defined(__Fuchsia__)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <TargetConditionals.h>
2+
#if TARGET_OS_OSX || TARGET_OS_IPHONE
3+
#include <dispatch/dispatch.h>
4+
#include <sys/sysctl.h>
5+
6+
static bool isKnownAndSupported(const char *name) {
7+
int32_t val = 0;
8+
size_t size = sizeof(val);
9+
if (sysctlbyname(name, &val, &size, NULL, 0))
10+
return false;
11+
return val;
12+
}
13+
14+
void __init_cpu_features_resolver(void) {
15+
// On Darwin platforms, this may be called concurrently by multiple threads
16+
// because the resolvers that use it are called lazily at runtime (unlike on
17+
// ELF platforms, where IFuncs are resolved serially at load time). This
18+
// function's effect on __aarch64_cpu_features should be idempotent, but even
19+
// so we need dispatch_once to resolve the race condition. Dispatch is
20+
// available through libSystem, which we need anyway for the sysctl, so this
21+
// does not add a new dependency.
22+
23+
static dispatch_once_t onceToken = 0;
24+
dispatch_once(&onceToken, ^{
25+
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
26+
static struct {
27+
const char *sysctl_name;
28+
enum CPUFeatures feature;
29+
} features[] = {
30+
{"hw.optional.arm.FEAT_FlagM", FEAT_FLAGM},
31+
{"hw.optional.arm.FEAT_FlagM2", FEAT_FLAGM2},
32+
{"hw.optional.arm.FEAT_FHM", FEAT_FP16FML},
33+
{"hw.optional.arm.FEAT_DotProd", FEAT_DOTPROD},
34+
{"hw.optional.arm.FEAT_RDM", FEAT_RDM},
35+
{"hw.optional.arm.FEAT_LSE", FEAT_LSE},
36+
{"hw.optional.floatingpoint", FEAT_FP},
37+
{"hw.optional.AdvSIMD", FEAT_SIMD},
38+
{"hw.optional.armv8_crc32", FEAT_CRC},
39+
{"hw.optional.arm.FEAT_SHA1", FEAT_SHA1},
40+
{"hw.optional.arm.FEAT_SHA256", FEAT_SHA2},
41+
{"hw.optional.arm.FEAT_SHA3", FEAT_SHA3},
42+
{"hw.optional.arm.FEAT_AES", FEAT_AES},
43+
{"hw.optional.arm.FEAT_PMULL", FEAT_PMULL},
44+
{"hw.optional.arm.FEAT_FP16", FEAT_FP16},
45+
{"hw.optional.arm.FEAT_DIT", FEAT_DIT},
46+
{"hw.optional.arm.FEAT_DPB", FEAT_DPB},
47+
{"hw.optional.arm.FEAT_DPB2", FEAT_DPB2},
48+
{"hw.optional.arm.FEAT_JSCVT", FEAT_JSCVT},
49+
{"hw.optional.arm.FEAT_FCMA", FEAT_FCMA},
50+
{"hw.optional.arm.FEAT_LRCPC", FEAT_RCPC},
51+
{"hw.optional.arm.FEAT_LRCPC2", FEAT_RCPC2},
52+
{"hw.optional.arm.FEAT_FRINTTS", FEAT_FRINTTS},
53+
{"hw.optional.arm.FEAT_I8MM", FEAT_I8MM},
54+
{"hw.optional.arm.FEAT_BF16", FEAT_BF16},
55+
{"hw.optional.arm.FEAT_SB", FEAT_SB},
56+
{"hw.optional.arm.FEAT_SPECRES", FEAT_PREDRES},
57+
{"hw.optional.arm.FEAT_SSBS", FEAT_SSBS2},
58+
{"hw.optional.arm.FEAT_BTI", FEAT_BTI},
59+
};
60+
61+
for (size_t I = 0, E = sizeof(features) / sizeof(features[0]); I != E; ++I)
62+
if (isKnownAndSupported(features[I].sysctl_name))
63+
__aarch64_cpu_features.features |= (1ULL << features[I].feature);
64+
65+
__aarch64_cpu_features.features |= (1ULL << FEAT_INIT);
66+
});
67+
}
68+
69+
#endif // TARGET_OS_OSX || TARGET_OS_IPHONE

0 commit comments

Comments
 (0)