eina+evas cpu - add theoretical SVE support
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>
Thu, 22 Nov 2018 16:59:47 +0000 (16:59 +0000)
committerHermet Park <hermetpark@gmail.com>
Wed, 5 Dec 2018 05:52:40 +0000 (14:52 +0900)
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
src/lib/eina/eina_cpu.h
src/lib/evas/common/evas_cpu.c
src/lib/evas/include/evas_common_private.h

index f12bec0..45b3b92 100644 (file)
@@ -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 <sys/auxv.h>
 # include <asm/hwcap.h>
 #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
 
index 6235b7b..6426017 100644 (file)
  */
 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;
 
 /**
index 5551775..d9215e1 100644 (file)
@@ -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 <signal.h>
@@ -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"
@@ -85,6 +91,15 @@ evas_common_cpu_neon_test(void)
 }
 
 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)
 {
 # ifdef __SPARC__
@@ -165,6 +180,10 @@ evas_common_cpu_feature_test(void (*feature)(void))
    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
index 0dc6d1e..18ac67b 100755 (executable)
@@ -535,7 +535,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;
 
 /*****************************************************************************/