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