ARM: Create configure option --enable-arm-simd to govern assembly optimizations SDL-1.2
authorBen Avison <bavison@riscosopen.org>
Thu, 31 Oct 2019 14:00:28 +0300
branchSDL-1.2
changeset 132123d6dc20a0974
parent 13154 af5e8b6a3c70
child 13213 db77604e083d
ARM: Create configure option --enable-arm-simd to govern assembly optimizations
---
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(-)
configure.in
include/SDL_config.h.in
include/SDL_cpuinfo.h
src/cpuinfo/SDL_cpuinfo.c
     1.1 --- a/configure.in	Mon Oct 21 22:21:56 2019 +0300
     1.2 +++ b/configure.in	Thu Oct 31 14:00:28 2019 +0300
     1.3 @@ -893,6 +893,42 @@
     1.4      fi
     1.5  }
     1.6  
     1.7 +dnl Check for ARM instruction support using gas syntax
     1.8 +CheckARM()
     1.9 +{
    1.10 +    AC_ARG_ENABLE(arm-simd,
    1.11 +AC_HELP_STRING([--enable-arm-simd], [use SIMD assembly blitters on ARM [[default=yes]]]),
    1.12 +                  enable_arm_simd=$enableval, enable_arm_simd=yes)
    1.13 +    if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_arm_simd = xyes; then
    1.14 +        save_CFLAGS="$CFLAGS"
    1.15 +        have_arm_simd=no
    1.16 +        CFLAGS="-x assembler-with-cpp $CFLAGS"
    1.17 +        
    1.18 +        AC_MSG_CHECKING(for ARM SIMD)
    1.19 +        AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
    1.20 +        .text
    1.21 +        .arch armv6
    1.22 +        .object_arch armv4
    1.23 +        .arm
    1.24 +        .altmacro
    1.25 +        #ifndef __ARM_EABI__
    1.26 +        #error EABI is required (to be sure that calling conventions are compatible)
    1.27 +        #endif
    1.28 +        pld [r0]
    1.29 +        uqadd8 r0, r0, r0
    1.30 +        ]])], have_arm_simd=yes)
    1.31 +        AC_MSG_RESULT($have_arm_simd)
    1.32 +        
    1.33 +        CFLAGS="$save_CFLAGS"
    1.34 +        
    1.35 +        if test x$have_arm_simd = xyes; then
    1.36 +            AC_DEFINE(SDL_ARM_SIMD_BLITTERS)
    1.37 +dnl            SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.c"
    1.38 +            SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-simd*.S"
    1.39 +        fi
    1.40 +    fi
    1.41 +}
    1.42 +
    1.43  dnl See if GCC's -fvisibility=hidden is supported (gcc4 and later, usually).
    1.44  dnl  Details of this flag are here: http://gcc.gnu.org/wiki/Visibility
    1.45  CheckVisibilityHidden()
    1.46 @@ -2436,6 +2472,7 @@
    1.47          CheckDLOPEN
    1.48          CheckNASM
    1.49          CheckAltivec
    1.50 +        CheckARM
    1.51          CheckOSS
    1.52          CheckDMEDIA
    1.53          CheckMME
     2.1 --- a/include/SDL_config.h.in	Mon Oct 21 22:21:56 2019 +0300
     2.2 +++ b/include/SDL_config.h.in	Thu Oct 31 14:00:28 2019 +0300
     2.3 @@ -312,5 +312,6 @@
     2.4  #undef SDL_ASSEMBLY_ROUTINES
     2.5  #undef SDL_HERMES_BLITTERS
     2.6  #undef SDL_ALTIVEC_BLITTERS
     2.7 +#undef SDL_ARM_SIMD_BLITTERS
     2.8  
     2.9  #endif /* _SDL_config_h */
     3.1 --- a/include/SDL_cpuinfo.h	Mon Oct 21 22:21:56 2019 +0300
     3.2 +++ b/include/SDL_cpuinfo.h	Thu Oct 31 14:00:28 2019 +0300
     3.3 @@ -60,6 +60,9 @@
     3.4  /** This function returns true if the CPU has AltiVec features */
     3.5  extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(void);
     3.6  
     3.7 +/** This function returns true if the CPU has ARM SIMD (ARMv6) features */
     3.8 +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void);
     3.9 +
    3.10  /* Ends C function definitions when using C++ */
    3.11  #ifdef __cplusplus
    3.12  }
     4.1 --- a/src/cpuinfo/SDL_cpuinfo.c	Mon Oct 21 22:21:56 2019 +0300
     4.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Oct 31 14:00:28 2019 +0300
     4.3 @@ -45,6 +45,7 @@
     4.4  #define CPU_HAS_SSE	0x00000040
     4.5  #define CPU_HAS_SSE2	0x00000080
     4.6  #define CPU_HAS_ALTIVEC	0x00000100
     4.7 +#define CPU_HAS_ARM_SIMD 0x00000200
     4.8  
     4.9  #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    4.10  /* This is the brute force way of detecting instruction sets...
    4.11 @@ -390,6 +391,46 @@
    4.12  	return altivec; 
    4.13  }
    4.14  
    4.15 +#ifdef __linux__
    4.16 +
    4.17 +#include <unistd.h>
    4.18 +#include <sys/types.h>
    4.19 +#include <sys/stat.h>
    4.20 +#include <fcntl.h>
    4.21 +#include <elf.h>
    4.22 +
    4.23 +static __inline__ int CPU_haveARMSIMD(void)
    4.24 +{
    4.25 +	int arm_simd = 0;
    4.26 +	int fd;
    4.27 +
    4.28 +	fd = open("/proc/self/auxv", O_RDONLY);
    4.29 +	if (fd >= 0)
    4.30 +	{
    4.31 +		Elf32_auxv_t aux;
    4.32 +		while (read(fd, &aux, sizeof aux) == sizeof aux)
    4.33 +		{
    4.34 +			if (aux.a_type == AT_PLATFORM)
    4.35 +			{
    4.36 +				const char *plat = (const char *) aux.a_un.a_val;
    4.37 +				arm_simd = strncmp(plat, "v6l", 3) == 0 ||
    4.38 +				           strncmp(plat, "v7l", 3) == 0;
    4.39 +			}
    4.40 +		}
    4.41 +		close(fd);
    4.42 +	}
    4.43 +	return arm_simd;
    4.44 +}
    4.45 +
    4.46 +#else
    4.47 +
    4.48 +static __inline__ int CPU_haveARMSIMD(void)
    4.49 +{
    4.50 +	return 0;
    4.51 +}
    4.52 +
    4.53 +#endif
    4.54 +
    4.55  static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
    4.56  
    4.57  static Uint32 SDL_GetCPUFeatures(void)
    4.58 @@ -420,6 +461,9 @@
    4.59  		if ( CPU_haveAltiVec() ) {
    4.60  			SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
    4.61  		}
    4.62 +		if ( CPU_haveARMSIMD() ) {
    4.63 +			SDL_CPUFeatures |= CPU_HAS_ARM_SIMD;
    4.64 +		}
    4.65  	}
    4.66  	return SDL_CPUFeatures;
    4.67  }
    4.68 @@ -488,6 +532,14 @@
    4.69  	return SDL_FALSE;
    4.70  }
    4.71  
    4.72 +SDL_bool SDL_HasARMSIMD(void)
    4.73 +{
    4.74 +	if ( SDL_GetCPUFeatures() & CPU_HAS_ARM_SIMD ) {
    4.75 +		return SDL_TRUE;
    4.76 +	}
    4.77 +	return SDL_FALSE;
    4.78 +}
    4.79 +
    4.80  #ifdef TEST_MAIN
    4.81  
    4.82  #include <stdio.h>
    4.83 @@ -502,6 +554,7 @@
    4.84  	printf("SSE: %d\n", SDL_HasSSE());
    4.85  	printf("SSE2: %d\n", SDL_HasSSE2());
    4.86  	printf("AltiVec: %d\n", SDL_HasAltiVec());
    4.87 +	printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
    4.88  	return 0;
    4.89  }
    4.90