ARM: Create configure option --enable-arm-neon to govern assembly optimizations SDL-1.2
authorBen Avison <bavison@riscosopen.org>
Thu, 31 Oct 2019 14:00:28 +0300
branchSDL-1.2
changeset 132194f88e197acad
parent 13218 8a6c0f0319d4
child 13220 0ae1ddca5e85
ARM: Create configure option --enable-arm-neon to govern assembly optimizations
---
configure.in | 39 +++++++++++++++++++++++++++++++++++++++
include/SDL_config.h.in | 1 +
include/SDL_cpuinfo.h | 3 +++
src/cpuinfo/SDL_cpuinfo.c | 37 +++++++++++++++++++++++++++++++++++++
4 files changed, 80 insertions(+)
configure.in
include/SDL_config.h.in
include/SDL_cpuinfo.h
src/cpuinfo/SDL_cpuinfo.c
     1.1 --- a/configure.in	Thu Oct 31 14:00:28 2019 +0300
     1.2 +++ b/configure.in	Thu Oct 31 14:00:28 2019 +0300
     1.3 @@ -929,6 +929,44 @@
     1.4      fi
     1.5  }
     1.6  
     1.7 +dnl Check for ARM NEON instruction support using gas syntax
     1.8 +CheckNEON()
     1.9 +{
    1.10 +    AC_ARG_ENABLE(arm-neon,
    1.11 +AC_HELP_STRING([--enable-arm-neon], [use NEON assembly blitters on ARM [[default=yes]]]),
    1.12 +                  enable_arm_neon=$enableval, enable_arm_neon=yes)
    1.13 +    if test x$enable_video = xyes -a x$enable_assembly = xyes -a x$enable_arm_neon = xyes; then
    1.14 +        save_CFLAGS="$CFLAGS"
    1.15 +        have_arm_neon=no
    1.16 +        CFLAGS="-x assembler-with-cpp $CFLAGS"
    1.17 +        
    1.18 +        AC_MSG_CHECKING(for ARM NEON)
    1.19 +        AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
    1.20 +        .text
    1.21 +        .fpu neon
    1.22 +        .arch armv7a
    1.23 +        .object_arch armv4
    1.24 +        .eabi_attribute 10, 0
    1.25 +        .arm
    1.26 +        .altmacro
    1.27 +        #ifndef __ARM_EABI__
    1.28 +        #error EABI is required (to be sure that calling conventions are compatible)
    1.29 +        #endif
    1.30 +        pld [r0]
    1.31 +        vmovn.u16 d0, q0
    1.32 +        ]])], have_arm_neon=yes)
    1.33 +        AC_MSG_RESULT($have_arm_neon)
    1.34 +        
    1.35 +        CFLAGS="$save_CFLAGS"
    1.36 +        
    1.37 +        if test x$have_arm_neon = xyes; then
    1.38 +            AC_DEFINE(SDL_ARM_NEON_BLITTERS)
    1.39 +dnl            SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-neon*.c"
    1.40 +            SOURCES="$SOURCES $srcdir/src/video/arm/pixman-arm-neon*.S"
    1.41 +        fi
    1.42 +    fi
    1.43 +}
    1.44 +
    1.45  dnl See if GCC's -fvisibility=hidden is supported (gcc4 and later, usually).
    1.46  dnl  Details of this flag are here: http://gcc.gnu.org/wiki/Visibility
    1.47  CheckVisibilityHidden()
    1.48 @@ -2473,6 +2511,7 @@
    1.49          CheckNASM
    1.50          CheckAltivec
    1.51          CheckARM
    1.52 +        CheckNEON
    1.53          CheckOSS
    1.54          CheckDMEDIA
    1.55          CheckMME
     2.1 --- a/include/SDL_config.h.in	Thu Oct 31 14:00:28 2019 +0300
     2.2 +++ b/include/SDL_config.h.in	Thu Oct 31 14:00:28 2019 +0300
     2.3 @@ -313,5 +313,6 @@
     2.4  #undef SDL_HERMES_BLITTERS
     2.5  #undef SDL_ALTIVEC_BLITTERS
     2.6  #undef SDL_ARM_SIMD_BLITTERS
     2.7 +#undef SDL_ARM_NEON_BLITTERS
     2.8  
     2.9  #endif /* _SDL_config_h */
     3.1 --- a/include/SDL_cpuinfo.h	Thu Oct 31 14:00:28 2019 +0300
     3.2 +++ b/include/SDL_cpuinfo.h	Thu Oct 31 14:00:28 2019 +0300
     3.3 @@ -63,6 +63,9 @@
     3.4  /** This function returns true if the CPU has ARM SIMD (ARMv6) features */
     3.5  extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void);
     3.6  
     3.7 +/** This function returns true if the CPU has ARM NEON features */
     3.8 +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMNEON(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	Thu Oct 31 14:00:28 2019 +0300
     4.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Oct 31 14:00:28 2019 +0300
     4.3 @@ -46,6 +46,7 @@
     4.4  #define CPU_HAS_SSE2	0x00000080
     4.5  #define CPU_HAS_ALTIVEC	0x00000100
     4.6  #define CPU_HAS_ARM_SIMD 0x00000200
     4.7 +#define CPU_HAS_ARM_NEON 0x00000400
     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 @@ -422,6 +423,25 @@
    4.12  	return arm_simd;
    4.13  }
    4.14  
    4.15 +static __inline__ int CPU_haveARMNEON(void)
    4.16 +{
    4.17 +	int arm_neon = 0;
    4.18 +	int fd;
    4.19 +
    4.20 +	fd = open("/proc/self/auxv", O_RDONLY);
    4.21 +	if (fd >= 0)
    4.22 +	{
    4.23 +		Elf32_auxv_t aux;
    4.24 +		while (read(fd, &aux, sizeof aux) == sizeof aux)
    4.25 +		{
    4.26 +			if (aux.a_type == AT_HWCAP)
    4.27 +				arm_neon = (aux.a_un.a_val & 4096) != 0;
    4.28 +		}
    4.29 +		close(fd);
    4.30 +	}
    4.31 +	return arm_neon;
    4.32 +}
    4.33 +
    4.34  #else
    4.35  
    4.36  static __inline__ int CPU_haveARMSIMD(void)
    4.37 @@ -429,6 +449,11 @@
    4.38  	return 0;
    4.39  }
    4.40  
    4.41 +static __inline__ int CPU_haveARMNEON(void)
    4.42 +{
    4.43 +	return 0;
    4.44 +}
    4.45 +
    4.46  #endif
    4.47  
    4.48  static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
    4.49 @@ -464,6 +489,9 @@
    4.50  		if ( CPU_haveARMSIMD() ) {
    4.51  			SDL_CPUFeatures |= CPU_HAS_ARM_SIMD;
    4.52  		}
    4.53 +		if ( CPU_haveARMNEON() ) {
    4.54 +			SDL_CPUFeatures |= CPU_HAS_ARM_NEON;
    4.55 +		}
    4.56  	}
    4.57  	return SDL_CPUFeatures;
    4.58  }
    4.59 @@ -540,6 +568,14 @@
    4.60  	return SDL_FALSE;
    4.61  }
    4.62  
    4.63 +SDL_bool SDL_HasARMNEON(void)
    4.64 +{
    4.65 +	if ( SDL_GetCPUFeatures() & CPU_HAS_ARM_NEON ) {
    4.66 +		return SDL_TRUE;
    4.67 +	}
    4.68 +	return SDL_FALSE;
    4.69 +}
    4.70 +
    4.71  #ifdef TEST_MAIN
    4.72  
    4.73  #include <stdio.h>
    4.74 @@ -555,6 +591,7 @@
    4.75  	printf("SSE2: %d\n", SDL_HasSSE2());
    4.76  	printf("AltiVec: %d\n", SDL_HasAltiVec());
    4.77  	printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
    4.78 +	printf("ARM NEON: %d\n", SDL_HasARMNEON());
    4.79  	return 0;
    4.80  }
    4.81