aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc')
-rw-r--r--contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc36
1 files changed, 36 insertions, 0 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc b/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc
new file mode 100644
index 000000000000..f711431489cc
--- /dev/null
+++ b/contrib/llvm-project/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/android.inc
@@ -0,0 +1,36 @@
+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) {
+ // 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;
+
+ unsigned long hwcap = getauxval(AT_HWCAP);
+ unsigned long hwcap2 = getauxval(AT_HWCAP2);
+
+ __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);
+}