2
2
#if TARGET_OS_OSX || TARGET_OS_IPHONE
3
3
#include < sys/sysctl.h>
4
4
5
+ #if __has_include(<arm/cpu_capabilities_public.h>)
6
+ #include < arm/cpu_capabilities_public.h>
7
+ #define HAS_CPU_CAPABILITIES_PUBLIC_H 1
8
+ #endif
9
+
5
10
static bool isKnownAndSupported (const char *name) {
6
11
int32_t val = 0 ;
7
12
size_t size = sizeof (val);
@@ -10,6 +15,19 @@ static bool isKnownAndSupported(const char *name) {
10
15
return val;
11
16
}
12
17
18
+ static uint64_t deriveImplicitFeatures (uint64_t features) {
19
+ // FEAT_SSBS2 implies FEAT_SSBS
20
+ if ((1ULL << FEAT_SSBS2) & features)
21
+ features |= (1ULL << FEAT_SSBS);
22
+
23
+ // FEAT_FP is always enabled
24
+ features |= (1ULL << FEAT_FP);
25
+
26
+ features |= (1ULL << FEAT_INIT);
27
+
28
+ return features;
29
+ }
30
+
13
31
void __init_cpu_features_resolver (void ) {
14
32
// On Darwin platforms, this may be called concurrently by multiple threads
15
33
// because the resolvers that use it are called lazily at runtime (unlike on
@@ -21,6 +39,62 @@ void __init_cpu_features_resolver(void) {
21
39
22
40
uint64_t features = 0 ;
23
41
42
+ #ifdef HAS_CPU_CAPABILITIES_PUBLIC_H
43
+ uint8_t feats_bitvec[(CAP_BIT_NB + 7 ) / 8 ] = {0 };
44
+ size_t len = sizeof (feats_bitvec);
45
+ // When hw.optional.arm.feats is available (macOS 15.0+, iOS 18.0+), use the
46
+ // fast path to get all the feature bits, otherwise fall back to the slow
47
+ // ~20-something sysctls path.
48
+ if (!sysctlbyname (" hw.optional.arm.caps" , &feats_bitvec, &len, 0 , 0 )) {
49
+
50
+ #define CHECK_BIT (FROM, TO ) \
51
+ do { \
52
+ if (feats_bitvec[FROM / 8 ] & (1u << ((FROM) & 7 ))) { \
53
+ features |= (1ULL << TO); \
54
+ } \
55
+ } while (0 )
56
+
57
+ CHECK_BIT (CAP_BIT_FEAT_FlagM, FEAT_FLAGM);
58
+ CHECK_BIT (CAP_BIT_FEAT_FlagM2, FEAT_FLAGM2);
59
+ CHECK_BIT (CAP_BIT_FEAT_FHM, FEAT_FP16FML);
60
+ CHECK_BIT (CAP_BIT_FEAT_DotProd, FEAT_DOTPROD);
61
+ CHECK_BIT (CAP_BIT_FEAT_SHA3, FEAT_SHA3);
62
+ CHECK_BIT (CAP_BIT_FEAT_RDM, FEAT_RDM);
63
+ CHECK_BIT (CAP_BIT_FEAT_LSE, FEAT_LSE);
64
+ CHECK_BIT (CAP_BIT_FEAT_SHA256, FEAT_SHA2);
65
+ CHECK_BIT (CAP_BIT_FEAT_SHA1, FEAT_SHA1);
66
+ CHECK_BIT (CAP_BIT_FEAT_AES, FEAT_AES);
67
+ CHECK_BIT (CAP_BIT_FEAT_PMULL, FEAT_PMULL);
68
+ CHECK_BIT (CAP_BIT_FEAT_SPECRES, FEAT_PREDRES);
69
+ CHECK_BIT (CAP_BIT_FEAT_SB, FEAT_SB);
70
+ CHECK_BIT (CAP_BIT_FEAT_FRINTTS, FEAT_FRINTTS);
71
+ CHECK_BIT (CAP_BIT_FEAT_LRCPC, FEAT_RCPC);
72
+ CHECK_BIT (CAP_BIT_FEAT_LRCPC2, FEAT_RCPC2);
73
+ CHECK_BIT (CAP_BIT_FEAT_FCMA, FEAT_FCMA);
74
+ CHECK_BIT (CAP_BIT_FEAT_JSCVT, FEAT_JSCVT);
75
+ CHECK_BIT (CAP_BIT_FEAT_DPB, FEAT_DPB);
76
+ CHECK_BIT (CAP_BIT_FEAT_DPB2, FEAT_DPB2);
77
+ CHECK_BIT (CAP_BIT_FEAT_BF16, FEAT_BF16);
78
+ CHECK_BIT (CAP_BIT_FEAT_I8MM, FEAT_I8MM);
79
+ CHECK_BIT (CAP_BIT_FEAT_DIT, FEAT_DIT);
80
+ CHECK_BIT (CAP_BIT_FEAT_FP16, FEAT_FP16);
81
+ CHECK_BIT (CAP_BIT_FEAT_SSBS, FEAT_SSBS2);
82
+ CHECK_BIT (CAP_BIT_FEAT_BTI, FEAT_BTI);
83
+ CHECK_BIT (CAP_BIT_AdvSIMD, FEAT_SIMD);
84
+ CHECK_BIT (CAP_BIT_CRC32, FEAT_CRC);
85
+ CHECK_BIT (CAP_BIT_FEAT_SME, FEAT_SME);
86
+ CHECK_BIT (CAP_BIT_FEAT_SME2, FEAT_SME2);
87
+ CHECK_BIT (CAP_BIT_FEAT_SME_F64F64, FEAT_SME_F64);
88
+ CHECK_BIT (CAP_BIT_FEAT_SME_I16I64, FEAT_SME_I64);
89
+
90
+ features = deriveImplicitFeatures (features);
91
+
92
+ __atomic_store (&__aarch64_cpu_features.features , &features,
93
+ __ATOMIC_RELAXED);
94
+ return ;
95
+ }
96
+ #endif
97
+
24
98
// https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
25
99
static const struct {
26
100
const char *sysctl_name;
@@ -32,7 +106,6 @@ void __init_cpu_features_resolver(void) {
32
106
{" hw.optional.arm.FEAT_DotProd" , FEAT_DOTPROD},
33
107
{" hw.optional.arm.FEAT_RDM" , FEAT_RDM},
34
108
{" hw.optional.arm.FEAT_LSE" , FEAT_LSE},
35
- {" hw.optional.floatingpoint" , FEAT_FP},
36
109
{" hw.optional.AdvSIMD" , FEAT_SIMD},
37
110
{" hw.optional.armv8_crc32" , FEAT_CRC},
38
111
{" hw.optional.arm.FEAT_SHA1" , FEAT_SHA1},
@@ -62,7 +135,7 @@ void __init_cpu_features_resolver(void) {
62
135
if (isKnownAndSupported (feature_checks[I].sysctl_name ))
63
136
features |= (1ULL << feature_checks[I].feature );
64
137
65
- features |= ( 1ULL << FEAT_INIT );
138
+ features = deriveImplicitFeatures (features );
66
139
67
140
__atomic_store (&__aarch64_cpu_features.features , &features,
68
141
__ATOMIC_RELAXED);
0 commit comments