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