xref: /aosp_15_r20/external/libvpx/vpx_ports/aarch32_cpudetect.c (revision fb1b10ab9aebc7c7068eedab379b749d7e3900be)
1 /*
2  *  Copyright (c) 2023 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 // Feature detection code for Armv7-A / AArch32.
11 
12 #include "./vpx_config.h"
13 #include "arm_cpudetect.h"
14 
15 #if !CONFIG_RUNTIME_CPU_DETECT
16 
arm_get_cpu_caps(void)17 static int arm_get_cpu_caps(void) {
18   // This function should actually be a no-op. There is no way to adjust any of
19   // these because the RTCD tables do not exist: the functions are called
20   // statically.
21   int flags = 0;
22 #if HAVE_NEON
23   flags |= HAS_NEON;
24 #endif  // HAVE_NEON
25   return flags;
26 }
27 
28 #elif defined(_MSC_VER)  // end !CONFIG_RUNTIME_CPU_DETECT
29 
arm_get_cpu_caps(void)30 static int arm_get_cpu_caps(void) {
31   int flags = 0;
32 #if HAVE_NEON || HAVE_NEON_ASM
33   // MSVC has no inline __asm support for Arm, but it does let you __emit
34   // instructions via their assembled hex code.
35   // All of these instructions should be essentially nops.
36   __try {
37     // VORR q0,q0,q0
38     __emit(0xF2200150);
39     flags |= HAS_NEON;
40   } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
41     // Ignore exception.
42   }
43 #endif  // HAVE_NEON || HAVE_NEON_ASM
44   return flags;
45 }
46 
47 #elif defined(VPX_USE_ANDROID_CPU_FEATURES)
48 
arm_get_cpu_caps(void)49 static int arm_get_cpu_caps(void) {
50   int flags = 0;
51 #if HAVE_NEON || HAVE_NEON_ASM
52   uint64_t features = android_getCpuFeatures();
53   if (features & ANDROID_CPU_ARM_FEATURE_NEON) {
54     flags |= HAS_NEON;
55   }
56 #endif  // HAVE_NEON || HAVE_NEON_ASM
57   return flags;
58 }
59 
60 #elif defined(__linux__)  // end defined(VPX_USE_ANDROID_CPU_FEATURES)
61 
62 #include <sys/auxv.h>
63 
64 // Define hwcap values ourselves: building with an old auxv header where these
65 // hwcap values are not defined should not prevent features from being enabled.
66 #define VPX_AARCH32_HWCAP_NEON (1 << 12)
67 
arm_get_cpu_caps(void)68 static int arm_get_cpu_caps(void) {
69   int flags = 0;
70   unsigned long hwcap = getauxval(AT_HWCAP);
71 #if HAVE_NEON || HAVE_NEON_ASM
72   if (hwcap & VPX_AARCH32_HWCAP_NEON) {
73     flags |= HAS_NEON;
74   }
75 #endif  // HAVE_NEON || HAVE_NEON_ASM
76   return flags;
77 }
78 #else   // end __linux__
79 #error \
80     "Runtime CPU detection selected, but no CPU detection method available" \
81 "for your platform. Rerun configure with --disable-runtime-cpu-detect."
82 #endif
83 
arm_cpu_caps(void)84 int arm_cpu_caps(void) {
85   int flags = 0;
86   if (arm_cpu_env_flags(&flags)) {
87     return flags;
88   }
89   return arm_get_cpu_caps() & arm_cpu_env_mask();
90 }
91