diff options
author | Jean-Marc Valin <jmvalin@amazon.com> | 2023-11-23 08:35:08 +0300 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@amazon.com> | 2023-11-23 12:02:36 +0300 |
commit | 4451c2f0235d7d5e29effd2a0c2b46e91f80eb51 (patch) | |
tree | 31d82f1244ebf5a10f082af94b9ab129ca9a514e | |
parent | 64eff6bee9109b8a43d9f670e0976d18a64110a1 (diff) |
Update detection code for AArch64/Neon and dotprod
-rw-r--r-- | celt/arm/armcpu.c | 30 | ||||
-rw-r--r-- | celt/arm/armcpu.h | 13 | ||||
-rw-r--r-- | celt/cpu_support.h | 5 |
3 files changed, 45 insertions, 3 deletions
diff --git a/celt/arm/armcpu.c b/celt/arm/armcpu.c index c7d16e6d..716f8e8f 100644 --- a/celt/arm/armcpu.c +++ b/celt/arm/armcpu.c @@ -43,6 +43,7 @@ #define OPUS_CPU_ARM_EDSP_FLAG (1<<OPUS_ARCH_ARM_EDSP) #define OPUS_CPU_ARM_MEDIA_FLAG (1<<OPUS_ARCH_ARM_MEDIA) #define OPUS_CPU_ARM_NEON_FLAG (1<<OPUS_ARCH_ARM_NEON) +#define OPUS_CPU_ARM_DOTPROD_FLAG (1<<OPUS_ARCH_ARM_DOTPROD) #if defined(_MSC_VER) /*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/ @@ -95,6 +96,15 @@ static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ /* Linux based */ #include <stdio.h> +#if defined(OPUS_ARM_MAY_HAVE_DOTPROD) && !defined(OPUS_ARM_PRESUME_DOTPROD) +static int dotprod_supported(void) +{ + unsigned long long id_aa64isar0; + __asm ("MRS %x0, ID_AA64ISAR0_EL1 \n" : "=r" (id_aa64isar0) ); + return !!(id_aa64isar0 & 0x0000100000000000ULL); +} +#endif + opus_uint32 opus_cpu_capabilities(void) { opus_uint32 flags = 0; @@ -144,6 +154,18 @@ opus_uint32 opus_cpu_capabilities(void) # 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_MAY_HAVE_DOTPROD) +# if defined(OPUS_ARM_PRESUME_DOTPROD) + flags |= OPUS_CPU_ARM_DOTPROD_FLAG; +# else + if (dotprod_supported()) + flags |= OPUS_CPU_ARM_DOTPROD_FLAG; +# endif +# endif +#endif + fclose(cpuinfo); } return flags; @@ -180,7 +202,13 @@ static int opus_select_arch_impl(void) } arch++; - celt_assert(arch == OPUS_ARCH_ARM_NEON); + if(!(flags & OPUS_CPU_ARM_DOTPROD_FLAG)) { + celt_assert(arch == OPUS_ARCH_ARM_NEON); + return arch; + } + arch++; + + celt_assert(arch == OPUS_ARCH_ARM_DOTPROD); return arch; } diff --git a/celt/arm/armcpu.h b/celt/arm/armcpu.h index 820262ff..6d5803d8 100644 --- a/celt/arm/armcpu.h +++ b/celt/arm/armcpu.h @@ -46,6 +46,12 @@ # define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name) # endif +# if defined(OPUS_ARM_MAY_HAVE_DOTPROD) +# define MAY_HAVE_DOTPROD(name) name ## _dotprod +# else +# define MAY_HAVE_DOTPROD(name) MAY_HAVE_NEON(name) +# endif + # if defined(OPUS_ARM_PRESUME_EDSP) # define PRESUME_EDSP(name) name ## _edsp # else @@ -64,6 +70,12 @@ # define PRESUME_NEON(name) PRESUME_MEDIA(name) # endif +# if defined(OPUS_ARM_PRESUME_DOTPROD) +# define PRESUME_DOTPROD(name) name ## _dotprod +# else +# define PRESUME_DOTPROD(name) PRESUME_NEON(name) +# endif + # if defined(OPUS_HAVE_RTCD) int opus_select_arch(void); @@ -71,6 +83,7 @@ int opus_select_arch(void); #define OPUS_ARCH_ARM_EDSP (1) #define OPUS_ARCH_ARM_MEDIA (2) #define OPUS_ARCH_ARM_NEON (3) +#define OPUS_ARCH_ARM_DOTPROD (4) # endif diff --git a/celt/cpu_support.h b/celt/cpu_support.h index fdd9fb64..9f13d8ae 100644 --- a/celt/cpu_support.h +++ b/celt/cpu_support.h @@ -35,13 +35,14 @@ (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)) #include "arm/armcpu.h" -/* We currently support 4 ARM variants: +/* We currently support 5 ARM variants: * arch[0] -> ARMv4 * arch[1] -> ARMv5E * arch[2] -> ARMv6 * arch[3] -> NEON + * arch[4] -> NEON+DOTPROD */ -#define OPUS_ARCHMASK 3 +#define OPUS_ARCHMASK 7 #elif defined(OPUS_HAVE_RTCD) && \ ((defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \ |