33#define HAVE_SYS_AUXV_H
44#endif
55
6-
7-
86static void __init_cpu_features_constructor (unsigned long hwcap,
97 const __ifunc_arg_t *arg) {
10- #define setCPUFeature (F ) __aarch64_cpu_features.features |= 1ULL << F
8+ unsigned long long feat = 0 ;
9+ #define setCPUFeature (F ) feat |= 1ULL << F
1110#define getCPUFeature (id, ftr ) __asm__ (" mrs %0, " #id : " =r" (ftr))
1211#define extractBits (val, start, number ) \
1312 (val & ((1ULL << number) - 1ULL ) << start) >> start
@@ -20,26 +19,20 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
2019 setCPUFeature (FEAT_PMULL);
2120 if (hwcap & HWCAP_FLAGM)
2221 setCPUFeature (FEAT_FLAGM);
23- if (hwcap2 & HWCAP2_FLAGM2) {
24- setCPUFeature (FEAT_FLAGM);
22+ if (hwcap2 & HWCAP2_FLAGM2)
2523 setCPUFeature (FEAT_FLAGM2);
26- }
27- if (hwcap & HWCAP_SM3 && hwcap & HWCAP_SM4)
24+ if (hwcap & HWCAP_SM4)
2825 setCPUFeature (FEAT_SM4);
2926 if (hwcap & HWCAP_ASIMDDP)
3027 setCPUFeature (FEAT_DOTPROD);
3128 if (hwcap & HWCAP_ASIMDFHM)
3229 setCPUFeature (FEAT_FP16FML);
33- if (hwcap & HWCAP_FPHP) {
30+ if (hwcap & HWCAP_FPHP)
3431 setCPUFeature (FEAT_FP16);
35- setCPUFeature (FEAT_FP);
36- }
3732 if (hwcap & HWCAP_DIT)
3833 setCPUFeature (FEAT_DIT);
3934 if (hwcap & HWCAP_ASIMDRDM)
4035 setCPUFeature (FEAT_RDM);
41- if (hwcap & HWCAP_ILRCPC)
42- setCPUFeature (FEAT_RCPC2);
4336 if (hwcap & HWCAP_AES)
4437 setCPUFeature (FEAT_AES);
4538 if (hwcap & HWCAP_SHA1)
@@ -52,23 +45,20 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
5245 setCPUFeature (FEAT_FCMA);
5346 if (hwcap & HWCAP_SB)
5447 setCPUFeature (FEAT_SB);
55- if (hwcap & HWCAP_SSBS)
48+ if (hwcap & HWCAP_SSBS) {
49+ setCPUFeature (FEAT_SSBS);
5650 setCPUFeature (FEAT_SSBS2);
51+ }
5752 if (hwcap2 & HWCAP2_MTE) {
5853 setCPUFeature (FEAT_MEMTAG);
5954 setCPUFeature (FEAT_MEMTAG2);
6055 }
61- if (hwcap2 & HWCAP2_MTE3) {
62- setCPUFeature (FEAT_MEMTAG);
63- setCPUFeature (FEAT_MEMTAG2);
56+ if (hwcap2 & HWCAP2_MTE3)
6457 setCPUFeature (FEAT_MEMTAG3);
65- }
6658 if (hwcap2 & HWCAP2_SVEAES)
6759 setCPUFeature (FEAT_SVE_AES);
68- if (hwcap2 & HWCAP2_SVEPMULL) {
69- setCPUFeature (FEAT_SVE_AES);
60+ if (hwcap2 & HWCAP2_SVEPMULL)
7061 setCPUFeature (FEAT_SVE_PMULL128);
71- }
7262 if (hwcap2 & HWCAP2_SVEBITPERM)
7363 setCPUFeature (FEAT_SVE_BITPERM);
7464 if (hwcap2 & HWCAP2_SVESHA3)
@@ -105,6 +95,8 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
10595 setCPUFeature (FEAT_WFXT);
10696 if (hwcap2 & HWCAP2_SME)
10797 setCPUFeature (FEAT_SME);
98+ if (hwcap2 & HWCAP2_SME2)
99+ setCPUFeature (FEAT_SME2);
108100 if (hwcap2 & HWCAP2_SME_I16I64)
109101 setCPUFeature (FEAT_SME_I64);
110102 if (hwcap2 & HWCAP2_SME_F64F64)
@@ -113,86 +105,45 @@ static void __init_cpu_features_constructor(unsigned long hwcap,
113105 setCPUFeature (FEAT_MOPS);
114106 if (hwcap & HWCAP_CPUID) {
115107 unsigned long ftr;
116- getCPUFeature (ID_AA64PFR1_EL1, ftr);
117- // ID_AA64PFR1_EL1.MTE >= 0b0001
118- if (extractBits (ftr, 8 , 4 ) >= 0x1 )
119- setCPUFeature (FEAT_MEMTAG);
120- // ID_AA64PFR1_EL1.SSBS == 0b0001
121- if (extractBits (ftr, 4 , 4 ) == 0x1 )
122- setCPUFeature (FEAT_SSBS);
123- // ID_AA64PFR1_EL1.SME == 0b0010
124- if (extractBits (ftr, 24 , 4 ) == 0x2 )
125- setCPUFeature (FEAT_SME2);
126- getCPUFeature (ID_AA64PFR0_EL1, ftr);
127- // ID_AA64PFR0_EL1.FP != 0b1111
128- if (extractBits (ftr, 16 , 4 ) != 0xF ) {
129- setCPUFeature (FEAT_FP);
130- // ID_AA64PFR0_EL1.AdvSIMD has the same value as ID_AA64PFR0_EL1.FP
131- setCPUFeature (FEAT_SIMD);
132- }
133- // ID_AA64PFR0_EL1.SVE != 0b0000
134- if (extractBits (ftr, 32 , 4 ) != 0x0 ) {
135- // get ID_AA64ZFR0_EL1, that name supported
136- // if sve enabled only
137- getCPUFeature (S3_0_C0_C4_4, ftr);
138- // ID_AA64ZFR0_EL1.SVEver == 0b0000
139- if (extractBits (ftr, 0 , 4 ) == 0x0 )
140- setCPUFeature (FEAT_SVE);
141- // ID_AA64ZFR0_EL1.SVEver == 0b0001
142- if (extractBits (ftr, 0 , 4 ) == 0x1 )
143- setCPUFeature (FEAT_SVE2);
144- // ID_AA64ZFR0_EL1.BF16 != 0b0000
145- if (extractBits (ftr, 20 , 4 ) != 0x0 )
146- setCPUFeature (FEAT_SVE_BF16);
147- }
148- getCPUFeature (ID_AA64ISAR0_EL1, ftr);
149- // ID_AA64ISAR0_EL1.SHA3 != 0b0000
150- if (extractBits (ftr, 32 , 4 ) != 0x0 )
151- setCPUFeature (FEAT_SHA3);
108+
152109 getCPUFeature (ID_AA64ISAR1_EL1, ftr);
153- // ID_AA64ISAR1_EL1.DPB >= 0b0001
154- if (extractBits (ftr, 0 , 4 ) >= 0x1 )
155- setCPUFeature (FEAT_DPB);
156- // ID_AA64ISAR1_EL1.LRCPC != 0b0000
157- if (extractBits (ftr, 20 , 4 ) != 0x0 )
158- setCPUFeature (FEAT_RCPC);
159- // ID_AA64ISAR1_EL1.LRCPC == 0b0011
160- if (extractBits (ftr, 20 , 4 ) == 0x3 )
161- setCPUFeature (FEAT_RCPC3);
162- // ID_AA64ISAR1_EL1.SPECRES == 0b0001
163- if (extractBits (ftr, 40 , 4 ) == 0x2 )
110+ /* ID_AA64ISAR1_EL1.SPECRES >= 0b0001 */
111+ if (extractBits (ftr, 40 , 4 ) >= 0x1 )
164112 setCPUFeature (FEAT_PREDRES);
165- // ID_AA64ISAR1_EL1.BF16 != 0b0000
166- if (extractBits (ftr, 44 , 4 ) != 0x0 )
167- setCPUFeature (FEAT_BF16);
168- // ID_AA64ISAR1_EL1.LS64 >= 0b0001
113+ /* ID_AA64ISAR1_EL1.LS64 >= 0b0001 */
169114 if (extractBits (ftr, 60 , 4 ) >= 0x1 )
170115 setCPUFeature (FEAT_LS64);
171- // ID_AA64ISAR1_EL1.LS64 >= 0b0010
116+ /* ID_AA64ISAR1_EL1.LS64 >= 0b0010 */
172117 if (extractBits (ftr, 60 , 4 ) >= 0x2 )
173118 setCPUFeature (FEAT_LS64_V);
174- // ID_AA64ISAR1_EL1.LS64 >= 0b0011
119+ /* ID_AA64ISAR1_EL1.LS64 >= 0b0011 */
175120 if (extractBits (ftr, 60 , 4 ) >= 0x3 )
176121 setCPUFeature (FEAT_LS64_ACCDATA);
177- } else {
178- // Set some features in case of no CPUID support
179- if (hwcap & (HWCAP_FP | HWCAP_FPHP)) {
180- setCPUFeature (FEAT_FP);
181- // FP and AdvSIMD fields have the same value
182- setCPUFeature (FEAT_SIMD);
183- }
184- if (hwcap & HWCAP_DCPOP || hwcap2 & HWCAP2_DCPODP)
185- setCPUFeature (FEAT_DPB);
186- if (hwcap & HWCAP_LRCPC || hwcap & HWCAP_ILRCPC)
187- setCPUFeature (FEAT_RCPC);
188- if (hwcap2 & HWCAP2_BF16 || hwcap2 & HWCAP2_EBF16)
189- setCPUFeature (FEAT_BF16);
190- if (hwcap2 & HWCAP2_SVEBF16)
191- setCPUFeature (FEAT_SVE_BF16);
192- if (hwcap2 & HWCAP2_SVE2 && hwcap & HWCAP_SVE)
193- setCPUFeature (FEAT_SVE2);
194- if (hwcap & HWCAP_SHA3)
195- setCPUFeature (FEAT_SHA3);
196122 }
123+ if (hwcap & HWCAP_FP) {
124+ setCPUFeature (FEAT_FP);
125+ // FP and AdvSIMD fields have the same value
126+ setCPUFeature (FEAT_SIMD);
127+ }
128+ if (hwcap & HWCAP_DCPOP)
129+ setCPUFeature (FEAT_DPB);
130+ if (hwcap & HWCAP_LRCPC)
131+ setCPUFeature (FEAT_RCPC);
132+ if (hwcap & HWCAP_ILRCPC)
133+ setCPUFeature (FEAT_RCPC2);
134+ if (hwcap2 & HWCAP2_LRCPC3)
135+ setCPUFeature (FEAT_RCPC3);
136+ if (hwcap2 & HWCAP2_BF16)
137+ setCPUFeature (FEAT_BF16);
138+ if (hwcap2 & HWCAP2_SVEBF16)
139+ setCPUFeature (FEAT_SVE_BF16);
140+ if (hwcap & HWCAP_SVE)
141+ setCPUFeature (FEAT_SVE);
142+ if (hwcap2 & HWCAP2_SVE2)
143+ setCPUFeature (FEAT_SVE2);
144+ if (hwcap & HWCAP_SHA3)
145+ setCPUFeature (FEAT_SHA3);
197146 setCPUFeature (FEAT_INIT);
147+
148+ __atomic_store_n (&__aarch64_cpu_features.features , feat, __ATOMIC_RELAXED);
198149}
0 commit comments