1 /* 2 * Copyright (c) 2023, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 // Feature detection code for Armv7-A / AArch32. 12 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 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 44 return flags; 45 } 46 47 #elif defined(AOM_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 52 uint64_t features = android_getCpuFeatures(); 53 if (features & ANDROID_CPU_ARM_FEATURE_NEON) flags |= HAS_NEON; 54 #endif // HAVE_NEON 55 return flags; 56 } 57 58 #elif defined(__linux__) // end defined(AOM_USE_ANDROID_CPU_FEATURES) 59 60 #include <sys/auxv.h> 61 62 // Define hwcap values ourselves: building with an old auxv header where these 63 // hwcap values are not defined should not prevent features from being enabled. 64 #define AOM_AARCH32_HWCAP_NEON (1 << 12) 65 arm_get_cpu_caps(void)66static int arm_get_cpu_caps(void) { 67 int flags = 0; 68 unsigned long hwcap = getauxval(AT_HWCAP); 69 #if HAVE_NEON 70 if (hwcap & AOM_AARCH32_HWCAP_NEON) flags |= HAS_NEON; 71 #endif // HAVE_NEON 72 return flags; 73 } 74 #else // end __linux__ 75 #error \ 76 "Runtime CPU detection selected, but no CPU detection method " \ 77 "available for your platform. Rerun cmake with -DCONFIG_RUNTIME_CPU_DETECT=0." 78 #endif 79 aom_arm_cpu_caps(void)80int aom_arm_cpu_caps(void) { 81 int flags = 0; 82 if (arm_cpu_env_flags(&flags)) { 83 return flags; 84 } 85 return arm_get_cpu_caps() & arm_cpu_env_mask(); 86 } 87