diff options
Diffstat (limited to 'media/libopus/celt')
-rw-r--r-- | media/libopus/celt/arm/armcpu.c | 52 | ||||
-rw-r--r-- | media/libopus/celt/x86/x86cpu.h | 18 |
2 files changed, 66 insertions, 4 deletions
diff --git a/media/libopus/celt/arm/armcpu.c b/media/libopus/celt/arm/armcpu.c index 06a53435b8..6785121ac9 100644 --- a/media/libopus/celt/arm/armcpu.c +++ b/media/libopus/celt/arm/armcpu.c @@ -96,7 +96,7 @@ static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ /* Linux based */ #include <stdio.h> -opus_uint32 opus_cpu_capabilities(void) +static opus_uint32 opus_cpu_capabilities(void) { opus_uint32 flags = 0; FILE *cpuinfo; @@ -169,7 +169,7 @@ opus_uint32 opus_cpu_capabilities(void) #include <sys/types.h> #include <sys/sysctl.h> -opus_uint32 opus_cpu_capabilities(void) +static opus_uint32 opus_cpu_capabilities(void) { opus_uint32 flags = 0; @@ -191,6 +191,54 @@ opus_uint32 opus_cpu_capabilities(void) return flags; } +#elif defined(__FreeBSD__) +#include <sys/auxv.h> + +static opus_uint32 opus_cpu_capabilities(void) +{ + long hwcap = 0; + opus_uint32 flags = 0; + +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \ + || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) + /* FreeBSD requires armv6+, which always supports media instructions */ + flags |= OPUS_CPU_ARM_MEDIA_FLAG; +# endif + + elf_aux_info(AT_HWCAP, &hwcap, sizeof hwcap); + +# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \ + || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) +# ifdef HWCAP_EDSP + if (hwcap & HWCAP_EDSP) + flags |= OPUS_CPU_ARM_EDSP_FLAG; +# endif + +# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR) +# ifdef HWCAP_NEON + if (hwcap & HWCAP_NEON) + flags |= OPUS_CPU_ARM_NEON_FLAG; +# elif defined(HWCAP_ASIMD) + if (hwcap & HWCAP_ASIMD) + flags |= OPUS_CPU_ARM_NEON_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_EDSP_FLAG; +# endif +# endif +# if defined(OPUS_ARM_MAY_HAVE_DOTPROD) && defined(HWCAP_ASIMDDP) + if (hwcap & HWCAP_ASIMDDP) + flags |= OPUS_CPU_ARM_DOTPROD_FLAG; +# endif +# endif + +#if defined(OPUS_ARM_PRESUME_AARCH64_NEON_INTR) + flags |= OPUS_CPU_ARM_EDSP_FLAG | OPUS_CPU_ARM_MEDIA_FLAG | OPUS_CPU_ARM_NEON_FLAG; +# if defined(OPUS_ARM_PRESUME_DOTPROD) + flags |= OPUS_CPU_ARM_DOTPROD_FLAG; +# endif +#endif + + return (flags); +} + #else /* The feature registers which can tell us what the processor supports are * accessible in priveleged modes only, so we can't have a general user-space diff --git a/media/libopus/celt/x86/x86cpu.h b/media/libopus/celt/x86/x86cpu.h index 8ae9be8d8f..1e5b6a4cb3 100644 --- a/media/libopus/celt/x86/x86cpu.h +++ b/media/libopus/celt/x86/x86cpu.h @@ -68,8 +68,22 @@ int opus_select_arch(void); Use this to work around those restrictions (which should hopefully all get optimized to a single MOVD instruction). GCC implemented _mm_loadu_si32() since GCC 11; HOWEVER, there is a bug! - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99754 */ -# if !defined(_MSC_VER) && !OPUS_GNUC_PREREQ(11,3) && !(defined(__clang__) && (__clang_major__ >= 8)) + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99754 + LLVM implemented _mm_loadu_si32() since Clang 8.0, however the + __clang_major__ version number macro is unreliable, as vendors + (specifically, Apple) will use different numbering schemes than upstream. + Clang's advice is "use feature detection", but they do not provide feature + detection support for specific SIMD functions. + We follow the approach from the SIMDe project and instead detect unrelated + features that should be available in the version we want (see + <https://github.com/simd-everywhere/simde/blob/master/simde/simde-detect-clang.h>).*/ +# if defined(__clang__) +# if __has_warning("-Wextra-semi-stmt") || \ + __has_builtin(__builtin_rotateleft32) +# define OPUS_CLANG_8 (1) +# endif +# endif +# if !defined(_MSC_VER) && !OPUS_GNUC_PREREQ(11,3) && !defined(OPUS_CLANG_8) # include <string.h> # include <emmintrin.h> |