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 Workerstatic 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 Workerstatic 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 Workerstatic 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 Workerstatic 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 Workerint 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