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.
This commit is contained in:
Carsten Haitzler 2018-11-22 16:59:47 +00:00
parent e2972420c1
commit 168fec6995
4 changed files with 61 additions and 16 deletions

View 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

View File

@ -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;
/**

View 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"
@ -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

View File

@ -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;
/*****************************************************************************/