Skip to content

Commit edb4319

Browse files
authored
[FMV][AArch64] Add initial AT_HWCAP3 / AT_HWCAP4 support (#161595)
Add support for AT_HWCAP3 / AT_HWCAP4 which is supported by glibc, musl, Android and FreeBSD 15/-current. Stop using sys/ifunc.h as libgcc has done. This is more portable as older glibc will not have the hwcap3/4 fields.
1 parent 879f861 commit edb4319

File tree

5 files changed

+35
-23
lines changed

5 files changed

+35
-23
lines changed

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,13 @@
1919
#error This file is intended only for aarch64-based targets
2020
#endif
2121

22-
#if __has_include(<sys/ifunc.h>)
23-
#include <sys/ifunc.h>
24-
#else
2522
typedef struct __ifunc_arg_t {
2623
unsigned long _size;
2724
unsigned long _hwcap;
2825
unsigned long _hwcap2;
26+
unsigned long _hwcap3;
27+
unsigned long _hwcap4;
2928
} __ifunc_arg_t;
30-
#endif // __has_include(<sys/ifunc.h>)
3129

3230
// LSE support detection for out-of-line atomics
3331
// using HWCAP and Auxiliary vector

compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,11 @@ void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
2525
if (__isExynos9810())
2626
return;
2727

28-
unsigned long hwcap = getauxval(AT_HWCAP);
29-
unsigned long hwcap2 = getauxval(AT_HWCAP2);
30-
3128
__ifunc_arg_t arg;
3229
arg._size = sizeof(__ifunc_arg_t);
33-
arg._hwcap = hwcap;
34-
arg._hwcap2 = hwcap2;
30+
arg._hwcap = getauxval(AT_HWCAP);
31+
arg._hwcap2 = getauxval(AT_HWCAP2);
32+
arg._hwcap3 = getauxval(AT_HWCAP3);
33+
arg._hwcap4 = getauxval(AT_HWCAP4);
3534
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
3635
}

compiler-rt/lib/builtins/cpu_model/aarch64/fmv/elf_aux_info.inc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,21 @@ void __init_cpu_features_resolver(unsigned long hwcap,
77
}
88

99
void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
10-
unsigned long hwcap = 0;
11-
unsigned long hwcap2 = 0;
10+
unsigned long hwcap, hwcap2, hwcap3, hwcap4 = 0;
1211
// CPU features already initialized.
1312
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
1413
return;
1514

16-
int res = 0;
17-
res = elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
18-
res |= elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2);
19-
if (res)
20-
return;
15+
elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap);
16+
elf_aux_info(AT_HWCAP2, &hwcap2, sizeof hwcap2);
17+
elf_aux_info(AT_HWCAP3, &hwcap3, sizeof hwcap3);
18+
elf_aux_info(AT_HWCAP4, &hwcap4, sizeof hwcap4);
2119

2220
__ifunc_arg_t arg;
2321
arg._size = sizeof(__ifunc_arg_t);
2422
arg._hwcap = hwcap;
2523
arg._hwcap2 = hwcap2;
24+
arg._hwcap3 = hwcap3;
25+
arg._hwcap4 = hwcap4;
2626
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
2727
}

compiler-rt/lib/builtins/cpu_model/aarch64/fmv/getauxval.inc

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@ void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) {
1010
if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED))
1111
return;
1212

13-
unsigned long hwcap = getauxval(AT_HWCAP);
14-
unsigned long hwcap2 = getauxval(AT_HWCAP2);
15-
1613
__ifunc_arg_t arg;
1714
arg._size = sizeof(__ifunc_arg_t);
18-
arg._hwcap = hwcap;
19-
arg._hwcap2 = hwcap2;
15+
arg._hwcap = getauxval(AT_HWCAP);
16+
arg._hwcap2 = getauxval(AT_HWCAP2);
17+
arg._hwcap3 = getauxval(AT_HWCAP3);
18+
arg._hwcap4 = getauxval(AT_HWCAP4);
2019
__init_cpu_features_constructor(hwcap | _IFUNC_ARG_HWCAP, &arg);
2120
}

compiler-rt/lib/builtins/cpu_model/aarch64/hwcap.inc

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#define _IFUNC_ARG_HWCAP (1ULL << 62)
88
#endif
99
#ifndef AT_HWCAP
10-
#define AT_HWCAP 16
10+
#define AT_HWCAP 16 // Linux value
1111
#endif
1212
#ifndef HWCAP_CPUID
1313
#define HWCAP_CPUID (1 << 11)
@@ -95,7 +95,7 @@
9595
#endif
9696

9797
#ifndef AT_HWCAP2
98-
#define AT_HWCAP2 26
98+
#define AT_HWCAP2 26 // Linux value
9999
#endif
100100
#ifndef HWCAP2_DCPODP
101101
#define HWCAP2_DCPODP (1 << 0)
@@ -190,3 +190,19 @@
190190
#ifndef HWCAP2_CSSC
191191
#define HWCAP2_CSSC (1UL << 34)
192192
#endif
193+
194+
#ifndef AT_HWCAP3
195+
#ifdef __linux__
196+
#define AT_HWCAP3 29 // Linux value
197+
#else
198+
#define AT_HWCAP3 38 // BSD value
199+
#endif
200+
#endif
201+
202+
#ifndef AT_HWCAP4
203+
#ifdef __linux__
204+
#define AT_HWCAP4 30 // Linux value
205+
#else
206+
#define AT_HWCAP4 39 // BSD value
207+
#endif
208+
#endif

0 commit comments

Comments
 (0)