Skip to content
Permalink
Browse files

ARM: Create configure option --enable-arm-simd to govern assembly opt…

…imizations

---
 configure.in              | 60 +++++++++++++++++++--------------------
 include/SDL_config.h.in   |  1 +
 include/SDL_cpuinfo.h     |  3 ++
 src/cpuinfo/SDL_cpuinfo.c | 53 ++++++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+), 30 deletions(-)
  • Loading branch information
bavison committed Oct 31, 2019
1 parent 9c7648d commit 36c7b0c69798c3a3e0a3a5ae88517f4a96b42839
Showing with 94 additions and 0 deletions.
  1. +37 −0 configure.in
  2. +1 −0 include/SDL_config.h.in
  3. +3 −0 include/SDL_cpuinfo.h
  4. +53 −0 src/cpuinfo/SDL_cpuinfo.c
@@ -893,6 +893,42 @@ AC_HELP_STRING([--enable-altivec], [use altivec assembly blitters on PPC [[defau
fi
}

dnl Check for ARM instruction support using gas syntax
CheckARM()
{
AC_ARG_ENABLE(arm-simd,
AC_HELP_STRING([--enable-arm-simd], [use SIMD assembly blitters on ARM [[default=yes]]]),
enable_arm_simd=$enableval, enable_arm_simd=yes)
if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_arm_simd = xyes; then
save_CFLAGS="$CFLAGS"
have_arm_simd=no
CFLAGS="-x assembler-with-cpp $CFLAGS"

AC_MSG_CHECKING(for ARM SIMD)
AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
.text
.arch armv6
.object_arch armv4
.arm
.altmacro
#ifndef __ARM_EABI__
#error EABI is required (to be sure that calling conventions are compatible)
#endif
pld [r0]
uqadd8 r0, r0, r0
]])], have_arm_simd=yes)
AC_MSG_RESULT($have_arm_simd)

CFLAGS="$save_CFLAGS"

if test x$have_arm_simd = xyes; then
AC_DEFINE(SDL_ARM_SIMD_BLITTERS)
dnl SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.c"
SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.S"
fi
fi
}

dnl See if GCC's -fvisibility=hidden is supported (gcc4 and later, usually).
dnl Details of this flag are here: http://gcc.gnu.org/wiki/Visibility
CheckVisibilityHidden()
@@ -2436,6 +2472,7 @@ case "$host" in
CheckDLOPEN
CheckNASM
CheckAltivec
CheckARM
CheckOSS
CheckDMEDIA
CheckMME
@@ -312,5 +312,6 @@
#undef SDL_ASSEMBLY_ROUTINES
#undef SDL_HERMES_BLITTERS
#undef SDL_ALTIVEC_BLITTERS
#undef SDL_ARM_SIMD_BLITTERS

#endif /* _SDL_config_h */
@@ -60,6 +60,9 @@ extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(void);
/** This function returns true if the CPU has AltiVec features */
extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void);

/** This function returns true if the CPU has ARM SIMD (ARMv6) features */
extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
@@ -45,6 +45,7 @@
#define CPU_HAS_SSE 0x00000040
#define CPU_HAS_SSE2 0x00000080
#define CPU_HAS_ALTIVEC 0x00000100
#define CPU_HAS_ARM_SIMD 0x00000200

#if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
/* This is the brute force way of detecting instruction sets...
@@ -390,6 +391,46 @@ static __inline__ int CPU_haveAltiVec(void)
return altivec;
}

#ifdef __linux__

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <elf.h>

static __inline__ int CPU_haveARMSIMD(void)
{
int arm_simd = 0;
int fd;

fd = open("/proc/self/auxv", O_RDONLY);
if (fd >= 0)
{
Elf32_auxv_t aux;
while (read(fd, &aux, sizeof aux) == sizeof aux)
{
if (aux.a_type == AT_PLATFORM)
{
const char *plat = (const char *) aux.a_un.a_val;
arm_simd = strncmp(plat, "v6l", 3) == 0 ||
strncmp(plat, "v7l", 3) == 0;
}
}
close(fd);
}
return arm_simd;
}

#else

static __inline__ int CPU_haveARMSIMD(void)
{
return 0;
}

#endif

static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;

static Uint32 SDL_GetCPUFeatures(void)
@@ -420,6 +461,9 @@ static Uint32 SDL_GetCPUFeatures(void)
if ( CPU_haveAltiVec() ) {
SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
}
if ( CPU_haveARMSIMD() ) {
SDL_CPUFeatures |= CPU_HAS_ARM_SIMD;
}
}
return SDL_CPUFeatures;
}
@@ -488,6 +532,14 @@ SDL_bool SDL_HasAltiVec(void)
return SDL_FALSE;
}

SDL_bool SDL_HasARMSIMD(void)
{
if ( SDL_GetCPUFeatures() & CPU_HAS_ARM_SIMD ) {
return SDL_TRUE;
}
return SDL_FALSE;
}

#ifdef TEST_MAIN

#include <stdio.h>
@@ -502,6 +554,7 @@ int main()
printf("SSE: %d\n", SDL_HasSSE());
printf("SSE2: %d\n", SDL_HasSSE2());
printf("AltiVec: %d\n", SDL_HasAltiVec());
printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
return 0;
}

0 comments on commit 36c7b0c

Please sign in to comment.