ARM: Create configure option --enable-arm-simd to govern assembly optimizations
authorBen Avison <bavison@riscosopen.org>
Thu, 24 Oct 2019 21:12:08 -0400
changeset 13173de3493dacdaf
parent 13172 d62dcbe19211
child 13174 924cc078b2a0
ARM: Create configure option --enable-arm-simd to govern assembly optimizations
configure.ac
include/SDL_config.h.in
include/SDL_cpuinfo.h
src/cpuinfo/SDL_cpuinfo.c
     1.1 --- a/configure.ac	Thu Oct 24 20:15:54 2019 -0300
     1.2 +++ b/configure.ac	Thu Oct 24 21:12:08 2019 -0400
     1.3 @@ -1303,6 +1303,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 @@ -3396,6 +3432,7 @@
    1.47          CheckDiskAudio
    1.48          CheckDummyAudio
    1.49          CheckDLOPEN
    1.50 +        CheckARM
    1.51          CheckOSS
    1.52          CheckALSA
    1.53          CheckPulseAudio
     2.1 --- a/include/SDL_config.h.in	Thu Oct 24 20:15:54 2019 -0300
     2.2 +++ b/include/SDL_config.h.in	Thu Oct 24 21:12:08 2019 -0400
     2.3 @@ -407,6 +407,7 @@
     2.4  /* Enable assembly routines */
     2.5  #undef SDL_ASSEMBLY_ROUTINES
     2.6  #undef SDL_ALTIVEC_BLITTERS
     2.7 +#undef SDL_ARM_SIMD_BLITTERS
     2.8  
     2.9  /* Enable ime support */
    2.10  #undef SDL_USE_IME
     3.1 --- a/include/SDL_cpuinfo.h	Thu Oct 24 20:15:54 2019 -0300
     3.2 +++ b/include/SDL_cpuinfo.h	Thu Oct 24 21:12:08 2019 -0400
     3.3 @@ -187,6 +187,11 @@
     3.4  extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void);
     3.5  
     3.6  /**
     3.7 + *  This function returns true if the CPU has ARM SIMD (ARMv6) features.
     3.8 + */
     3.9 +extern DECLSPEC SDL_bool SDLCALL SDL_HasARMSIMD(void);
    3.10 +
    3.11 +/**
    3.12   *  This function returns true if the CPU has NEON (ARM SIMD) features.
    3.13   */
    3.14  extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
     4.1 --- a/src/cpuinfo/SDL_cpuinfo.c	Thu Oct 24 20:15:54 2019 -0300
     4.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Oct 24 21:12:08 2019 -0400
     4.3 @@ -96,6 +96,7 @@
     4.4  #define CPU_HAS_AVX2    (1 << 10)
     4.5  #define CPU_HAS_NEON    (1 << 11)
     4.6  #define CPU_HAS_AVX512F (1 << 12)
     4.7 +#define CPU_HAS_ARM_SIMD (1 << 13)
     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 @@ -325,7 +326,50 @@
    4.12      return altivec;
    4.13  }
    4.14  
    4.15 -#if defined(__LINUX__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
    4.16 +#ifdef __linux__
    4.17 +
    4.18 +#include <unistd.h>
    4.19 +#include <sys/types.h>
    4.20 +#include <sys/stat.h>
    4.21 +#include <fcntl.h>
    4.22 +#include <elf.h>
    4.23 +
    4.24 +static SDL_bool
    4.25 +CPU_haveARMSIMD(void)
    4.26 +{
    4.27 +    int arm_simd = 0;
    4.28 +    int fd;
    4.29 +
    4.30 +    fd = open("/proc/self/auxv", O_RDONLY);
    4.31 +    if (fd >= 0)
    4.32 +    {
    4.33 +        Elf32_auxv_t aux;
    4.34 +        while (read(fd, &aux, sizeof aux) == sizeof aux)
    4.35 +        {
    4.36 +            if (aux.a_type == AT_PLATFORM)
    4.37 +            {
    4.38 +                const char *plat = (const char *) aux.a_un.a_val;
    4.39 +                arm_simd = strncmp(plat, "v6l", 3) == 0 ||
    4.40 +                           strncmp(plat, "v7l", 3) == 0;
    4.41 +            }
    4.42 +        }
    4.43 +        close(fd);
    4.44 +    }
    4.45 +    return arm_simd;
    4.46 +}
    4.47 +
    4.48 +#else
    4.49 +
    4.50 +static SDL_bool
    4.51 +CPU_haveARMSIMD(void)
    4.52 +{
    4.53 +#warning SDL_HasARMSIMD is not implemented for this ARM platform. Write me.
    4.54 +    return 0;
    4.55 +}
    4.56 +
    4.57 +#endif
    4.58 +
    4.59 +#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
    4.60  static int
    4.61  readProcAuxvForNeon(void)
    4.62  {
    4.63 @@ -668,6 +712,10 @@
    4.64              SDL_CPUFeatures |= CPU_HAS_AVX512F;
    4.65              SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 64);
    4.66          }
    4.67 +        if (CPU_haveARMSIMD()) {
    4.68 +            SDL_CPUFeatures |= CPU_HAS_ARM_SIMD;
    4.69 +            SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
    4.70 +        }
    4.71          if (CPU_haveNEON()) {
    4.72              SDL_CPUFeatures |= CPU_HAS_NEON;
    4.73              SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
    4.74 @@ -750,6 +798,12 @@
    4.75  }
    4.76  
    4.77  SDL_bool
    4.78 +SDL_HasARMSIMD(void)
    4.79 +{
    4.80 +    return CPU_FEATURE_AVAILABLE(CPU_HAS_ARM_SIMD);
    4.81 +}
    4.82 +
    4.83 +SDL_bool
    4.84  SDL_HasNEON(void)
    4.85  {
    4.86      return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
    4.87 @@ -870,6 +924,7 @@
    4.88      printf("AVX: %d\n", SDL_HasAVX());
    4.89      printf("AVX2: %d\n", SDL_HasAVX2());
    4.90      printf("AVX-512F: %d\n", SDL_HasAVX512F());
    4.91 +    printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
    4.92      printf("NEON: %d\n", SDL_HasNEON());
    4.93      printf("RAM: %d MB\n", SDL_GetSystemRAM());
    4.94      return 0;