xref: /aosp_15_r20/external/libaom/aom_ports/aarch32_cpudetect.c (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2023, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker // Feature detection code for Armv7-A / AArch32.
12*77c1e3ccSAndroid Build Coastguard Worker 
13*77c1e3ccSAndroid Build Coastguard Worker #include "arm_cpudetect.h"
14*77c1e3ccSAndroid Build Coastguard Worker 
15*77c1e3ccSAndroid Build Coastguard Worker #if !CONFIG_RUNTIME_CPU_DETECT
16*77c1e3ccSAndroid Build Coastguard Worker 
arm_get_cpu_caps(void)17*77c1e3ccSAndroid Build Coastguard Worker static int arm_get_cpu_caps(void) {
18*77c1e3ccSAndroid Build Coastguard Worker   // This function should actually be a no-op. There is no way to adjust any of
19*77c1e3ccSAndroid Build Coastguard Worker   // these because the RTCD tables do not exist: the functions are called
20*77c1e3ccSAndroid Build Coastguard Worker   // statically.
21*77c1e3ccSAndroid Build Coastguard Worker   int flags = 0;
22*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_NEON
23*77c1e3ccSAndroid Build Coastguard Worker   flags |= HAS_NEON;
24*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_NEON
25*77c1e3ccSAndroid Build Coastguard Worker   return flags;
26*77c1e3ccSAndroid Build Coastguard Worker }
27*77c1e3ccSAndroid Build Coastguard Worker 
28*77c1e3ccSAndroid Build Coastguard Worker #elif defined(_MSC_VER)  // end !CONFIG_RUNTIME_CPU_DETECT
29*77c1e3ccSAndroid Build Coastguard Worker 
arm_get_cpu_caps(void)30*77c1e3ccSAndroid Build Coastguard Worker static int arm_get_cpu_caps(void) {
31*77c1e3ccSAndroid Build Coastguard Worker   int flags = 0;
32*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_NEON
33*77c1e3ccSAndroid Build Coastguard Worker   // MSVC has no inline __asm support for Arm, but it does let you __emit
34*77c1e3ccSAndroid Build Coastguard Worker   // instructions via their assembled hex code.
35*77c1e3ccSAndroid Build Coastguard Worker   // All of these instructions should be essentially nops.
36*77c1e3ccSAndroid Build Coastguard Worker   __try {
37*77c1e3ccSAndroid Build Coastguard Worker     // VORR q0,q0,q0
38*77c1e3ccSAndroid Build Coastguard Worker     __emit(0xF2200150);
39*77c1e3ccSAndroid Build Coastguard Worker     flags |= HAS_NEON;
40*77c1e3ccSAndroid Build Coastguard Worker   } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
41*77c1e3ccSAndroid Build Coastguard Worker     // Ignore exception.
42*77c1e3ccSAndroid Build Coastguard Worker   }
43*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_NEON
44*77c1e3ccSAndroid Build Coastguard Worker   return flags;
45*77c1e3ccSAndroid Build Coastguard Worker }
46*77c1e3ccSAndroid Build Coastguard Worker 
47*77c1e3ccSAndroid Build Coastguard Worker #elif defined(AOM_USE_ANDROID_CPU_FEATURES)
48*77c1e3ccSAndroid Build Coastguard Worker 
arm_get_cpu_caps(void)49*77c1e3ccSAndroid Build Coastguard Worker static int arm_get_cpu_caps(void) {
50*77c1e3ccSAndroid Build Coastguard Worker   int flags = 0;
51*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_NEON
52*77c1e3ccSAndroid Build Coastguard Worker   uint64_t features = android_getCpuFeatures();
53*77c1e3ccSAndroid Build Coastguard Worker   if (features & ANDROID_CPU_ARM_FEATURE_NEON) flags |= HAS_NEON;
54*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_NEON
55*77c1e3ccSAndroid Build Coastguard Worker   return flags;
56*77c1e3ccSAndroid Build Coastguard Worker }
57*77c1e3ccSAndroid Build Coastguard Worker 
58*77c1e3ccSAndroid Build Coastguard Worker #elif defined(__linux__)  // end defined(AOM_USE_ANDROID_CPU_FEATURES)
59*77c1e3ccSAndroid Build Coastguard Worker 
60*77c1e3ccSAndroid Build Coastguard Worker #include <sys/auxv.h>
61*77c1e3ccSAndroid Build Coastguard Worker 
62*77c1e3ccSAndroid Build Coastguard Worker // Define hwcap values ourselves: building with an old auxv header where these
63*77c1e3ccSAndroid Build Coastguard Worker // hwcap values are not defined should not prevent features from being enabled.
64*77c1e3ccSAndroid Build Coastguard Worker #define AOM_AARCH32_HWCAP_NEON (1 << 12)
65*77c1e3ccSAndroid Build Coastguard Worker 
arm_get_cpu_caps(void)66*77c1e3ccSAndroid Build Coastguard Worker static int arm_get_cpu_caps(void) {
67*77c1e3ccSAndroid Build Coastguard Worker   int flags = 0;
68*77c1e3ccSAndroid Build Coastguard Worker   unsigned long hwcap = getauxval(AT_HWCAP);
69*77c1e3ccSAndroid Build Coastguard Worker #if HAVE_NEON
70*77c1e3ccSAndroid Build Coastguard Worker   if (hwcap & AOM_AARCH32_HWCAP_NEON) flags |= HAS_NEON;
71*77c1e3ccSAndroid Build Coastguard Worker #endif  // HAVE_NEON
72*77c1e3ccSAndroid Build Coastguard Worker   return flags;
73*77c1e3ccSAndroid Build Coastguard Worker }
74*77c1e3ccSAndroid Build Coastguard Worker #else   // end __linux__
75*77c1e3ccSAndroid Build Coastguard Worker #error \
76*77c1e3ccSAndroid Build Coastguard Worker     "Runtime CPU detection selected, but no CPU detection method " \
77*77c1e3ccSAndroid Build Coastguard Worker "available for your platform. Rerun cmake with -DCONFIG_RUNTIME_CPU_DETECT=0."
78*77c1e3ccSAndroid Build Coastguard Worker #endif
79*77c1e3ccSAndroid Build Coastguard Worker 
aom_arm_cpu_caps(void)80*77c1e3ccSAndroid Build Coastguard Worker int aom_arm_cpu_caps(void) {
81*77c1e3ccSAndroid Build Coastguard Worker   int flags = 0;
82*77c1e3ccSAndroid Build Coastguard Worker   if (arm_cpu_env_flags(&flags)) {
83*77c1e3ccSAndroid Build Coastguard Worker     return flags;
84*77c1e3ccSAndroid Build Coastguard Worker   }
85*77c1e3ccSAndroid Build Coastguard Worker   return arm_get_cpu_caps() & arm_cpu_env_mask();
86*77c1e3ccSAndroid Build Coastguard Worker }
87