This allows compiling optimised functions for features not enabled in the core build and selecting these at runtime if the system has the necessary support.
Signed-off-by: Mans Rullgard <[email protected]> --- configure | 9 +++++++- libavutil/arm/cpu.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 99b0e71..6af598f 100755 --- a/configure +++ b/configure @@ -1193,6 +1193,7 @@ HAVE_LIST=" asm_mod_y attribute_may_alias attribute_packed + asm_hwcap_h closesocket cmov CommandLineToArgvW @@ -1211,6 +1212,7 @@ HAVE_LIST=" dxva_h ebp_available ebx_available + Elf32_auxv_t fast_64bit fast_clz fast_cmov @@ -3164,7 +3166,12 @@ EOF enabled neon && check_insn neon 'vadd.i16 q0, q0, q0' enabled vfpv3 && check_insn vfpv3 'vmov.f32 s0, #1.0' - map 'enabled_any ${v}_external ${v}_inline || disable $v' $ARCH_EXT_LIST_ARM + check_type elf.h Elf32_auxv_t + check_header asm/hwcap.h + + enabled_all asm_hwcap_h Elf32_auxv_t || + map 'enabled_any ${v}_external ${v}_inline || disable $v' \ + $ARCH_EXT_LIST_ARM check_inline_asm asm_mod_q '"add r0, %Q0, %R0" :: "r"((long long)0)' check_inline_asm asm_mod_y '"vmul.i32 d0, d0, %y0" :: "x"(0)' diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c index 33dca1c..c41a048 100644 --- a/libavutil/arm/cpu.c +++ b/libavutil/arm/cpu.c @@ -19,6 +19,64 @@ #include "libavutil/cpu.h" #include "config.h" +#if HAVE_ELF32_AUXV_T && HAVE_ASM_HWCAP_H +#include <stdio.h> +#include <elf.h> +#include <asm/hwcap.h> + +static int get_hwcap(Elf32_auxv_t *auxv) +{ + FILE *f = fopen("/proc/self/auxv", "r"); + int err = -1; + + if (!f) + return -1; + + while (fread(auxv, sizeof(*auxv), 1, f) > 0) { + if (auxv->a_type == AT_HWCAP) { + err = 0; + break; + } + } + + fclose(f); + return err; +} + +int ff_get_cpu_flags_arm(void) +{ + Elf32_auxv_t auxv; + int flags = 0; + + if (get_hwcap(&auxv) < 0) + return 0; + +#define check_cap(cap, flag) do { \ + if (auxv.a_un.a_val & HWCAP_ ## cap) \ + flags |= AV_CPU_FLAG_ ## flag; \ + } while (0) + + /* No flags explicitly indicate v6 or v6T2 so check others which + imply support. */ + check_cap(EDSP, ARMV5TE); + check_cap(TLS, ARMV6); + check_cap(THUMBEE, ARMV6T2); + check_cap(VFP, VFP); + check_cap(VFPv3, VFPV3); + check_cap(NEON, NEON); + + /* The v6 checks above are not reliable so let higher flags + trickle down. */ + if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)) + flags |= AV_CPU_FLAG_ARMV6T2; + if (flags & AV_CPU_FLAG_ARMV6T2) + flags |= AV_CPU_FLAG_ARMV6; + + return flags; +} + +#else + int ff_get_cpu_flags_arm(void) { return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE | @@ -28,3 +86,5 @@ int ff_get_cpu_flags_arm(void) AV_CPU_FLAG_VFPV3 * HAVE_VFPV3 | AV_CPU_FLAG_NEON * HAVE_NEON; } + +#endif -- 1.8.0 _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
