From 168fec6995d526764126080d46e7890aff2a6e7b Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Thu, 22 Nov 2018 16:59:47 +0000 Subject: [PATCH] eina+evas cpu - add theoretical SVE support SVE is a new-ish ARM vector instruction set like neon... but with wider vectors (and variable vector sizes). this adds the flags and hwcaps checks. --- src/lib/eina/eina_cpu.c | 17 +++++++--- src/lib/eina/eina_cpu.h | 19 ++++++----- src/lib/evas/common/evas_cpu.c | 38 +++++++++++++++++++++- src/lib/evas/include/evas_common_private.h | 3 +- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/lib/eina/eina_cpu.c b/src/lib/eina/eina_cpu.c index f12bec0fa8..45b3b9295d 100644 --- a/src/lib/eina/eina_cpu.c +++ b/src/lib/eina/eina_cpu.c @@ -49,7 +49,7 @@ #include "eina_log.h" #include "eina_cpu.h" -#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && defined(__arm__) && defined(__linux__) +#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && (defined(__arm__) || defined(__aarch64__)) && defined(__linux__) # include # include #endif @@ -126,7 +126,7 @@ void _x86_simd(Eina_Cpu_Features *features) } #endif -#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && defined(__arm__) && defined(__linux__) +#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && (defined(__arm__) || defined(__aarch64__)) && defined(__linux__) static void _arm_cpu_features(Eina_Cpu_Features *features) { @@ -134,8 +134,15 @@ _arm_cpu_features(Eina_Cpu_Features *features) aux = getauxval(AT_HWCAP); - if (aux & HWCAP_NEON) - *features |= EINA_CPU_NEON; +# if defined(__aarch64__) + *features |= EINA_CPU_NEON; +# endif +# ifdef HWCAP_NEON + if (aux & HWCAP_NEON) *features |= EINA_CPU_NEON; +# endif +# ifdef HWCAP_SVE + if (aux & HWCAP_SVE) *features |= EINA_CPU_SVE; +# endif } #endif @@ -157,7 +164,7 @@ eina_cpu_init(void) { #if defined(__i386__) || defined(__x86_64__) _x86_simd(&eina_cpu_features); -#elif defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && defined(__arm__) && defined(__linux__) +#elif defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && (defined(__arm__) || defined(__aarch64__)) && defined(__linux__) _arm_cpu_features(&eina_cpu_features); #endif diff --git a/src/lib/eina/eina_cpu.h b/src/lib/eina/eina_cpu.h index 6235b7b939..6426017be6 100644 --- a/src/lib/eina/eina_cpu.h +++ b/src/lib/eina/eina_cpu.h @@ -45,17 +45,18 @@ */ typedef enum _Eina_Cpu_Features { - EINA_CPU_MMX = 0x00000001, - EINA_CPU_SSE = 0x00000002, - EINA_CPU_SSE2 = 0x00000004, - EINA_CPU_SSE3 = 0x00000008, + EINA_CPU_MMX = 0x00000001, + EINA_CPU_SSE = 0x00000002, + EINA_CPU_SSE2 = 0x00000004, + EINA_CPU_SSE3 = 0x00000008, /* TODO 3DNow! */ EINA_CPU_ALTIVEC = 0x00000010, - EINA_CPU_VIS = 0x00000020, - EINA_CPU_NEON = 0x00000040, - EINA_CPU_SSSE3 = 0x00000080, - EINA_CPU_SSE41 = 0x00000100, - EINA_CPU_SSE42 = 0x00000200 + EINA_CPU_VIS = 0x00000020, + EINA_CPU_NEON = 0x00000040, + EINA_CPU_SSSE3 = 0x00000080, + EINA_CPU_SSE41 = 0x00000100, + EINA_CPU_SSE42 = 0x00000200, + EINA_CPU_SVE = 0x00000400 } Eina_Cpu_Features; /** diff --git a/src/lib/evas/common/evas_cpu.c b/src/lib/evas/common/evas_cpu.c index 5551775733..d9215e1140 100644 --- a/src/lib/evas/common/evas_cpu.c +++ b/src/lib/evas/common/evas_cpu.c @@ -7,7 +7,6 @@ static int cpu_feature_mask = 0; - #ifdef BUILD_ALTIVEC # ifdef __POWERPC__ # ifdef __VEC__ @@ -26,6 +25,12 @@ static int cpu_feature_mask = 0; # endif #endif +#if defined(__aarch64__) +# ifdef BUILD_NEON +# define NEED_FEATURE_TEST +# endif +#endif + #ifdef NEED_FEATURE_TEST # ifdef HAVE_SIGLONGJMP # include @@ -70,6 +75,7 @@ evas_common_cpu_neon_test(void) # ifdef BUILD_NEON # ifdef BUILD_NEON_INTRINSICS volatile uint32x4_t temp = vdupq_n_u32(0x1); + vaddq_u32(temp, temp); # else asm volatile ( ".fpu neon \n\t" @@ -84,6 +90,15 @@ evas_common_cpu_neon_test(void) //#endif } +void +evas_common_cpu_sve_test(void) +{ +#if defined(__aarch64__) + volatile int result = 123; + asm("movz %w[res], #10" : [res] "=r" (result)); +#endif +} + void evas_common_cpu_vis_test(void) { @@ -164,6 +179,10 @@ evas_common_cpu_feature_test(void (*feature)(void)) # ifdef BUILD_NEON if (feature == evas_common_cpu_neon_test) return _cpu_check(EINA_CPU_NEON); +# endif +# if defined(__aarch64__) + if (feature == evas_common_cpu_sve_test) + return _cpu_check(EINA_CPU_SVE); # endif return 0; # endif @@ -249,6 +268,23 @@ evas_common_cpu_init(void) else cpu_feature_mask |= CPU_FEATURE_NEON; #endif + +#if defined(__aarch64__) + if (getenv("EVAS_CPU_NO_SVE")) + cpu_feature_mask &= ~CPU_FEATURE_SVE; + else + { +# if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ASM_HWCAP_H) && defined(__arm__) && defined(__linux__) +#error "xx" + cpu_feature_mask |= CPU_FEATURE_SVE * + !!(eina_cpu_features_get() & EINA_CPU_SVE); +# else + cpu_feature_mask |= CPU_FEATURE_SVE * + evas_common_cpu_feature_test(evas_common_cpu_sve_test); + evas_common_cpu_end_opt(); +# endif + } +#endif } int diff --git a/src/lib/evas/include/evas_common_private.h b/src/lib/evas/include/evas_common_private.h index d0354347fc..7fe19b7b9a 100644 --- a/src/lib/evas/include/evas_common_private.h +++ b/src/lib/evas/include/evas_common_private.h @@ -503,7 +503,8 @@ typedef enum _CPU_Features CPU_FEATURE_VIS = (1 << 4), CPU_FEATURE_VIS2 = (1 << 5), CPU_FEATURE_NEON = (1 << 6), - CPU_FEATURE_SSE3 = (1 << 7) + CPU_FEATURE_SSE3 = (1 << 7), + CPU_FEATURE_SVE = (1 << 8) } CPU_Features; /*****************************************************************************/