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)17static 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)30static 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)49static 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)68static 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)84int 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