From 03f8528315fa46c95991a34f3325d7b33ae5538c Mon Sep 17 00:00:00 2001
From: Edward Rudd <urkle@outoforder.cc>
Date: Sat, 02 May 2020 21:48:36 +0000
Subject: [PATCH] Update source to SDL2 2.0.12

---
 source/src/cpuinfo/SDL_cpuinfo.c |  177 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 161 insertions(+), 16 deletions(-)

diff --git a/source/src/cpuinfo/SDL_cpuinfo.c b/source/src/cpuinfo/SDL_cpuinfo.c
index 4410358..9cecb4f 100644
--- a/source/src/cpuinfo/SDL_cpuinfo.c
+++ b/source/src/cpuinfo/SDL_cpuinfo.c
@@ -1,6 +1,6 @@
 /*
   Simple DirectMedia Layer
-  Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
 
   This software is provided 'as-is', without any express or implied
   warranty.  In no event will the authors be held liable for any damages
@@ -22,10 +22,9 @@
 #include "SDL_config.h"
 #else
 #include "../SDL_internal.h"
-#include "SDL_simd.h"
 #endif
 
-#if defined(__WIN32__)
+#if defined(__WIN32__) || defined(__WINRT__)
 #include "../core/windows/SDL_windows.h"
 #endif
 #if defined(__OS2__)
@@ -68,6 +67,13 @@
 #ifndef AT_HWCAP
 #define AT_HWCAP 16
 #endif
+#ifndef AT_PLATFORM
+#define AT_PLATFORM 15
+#endif
+/* Prevent compilation error when including elf.h would also try to define AT_* as an enum */
+#ifndef AT_NULL
+#define AT_NULL 0
+#endif
 #ifndef HWCAP_NEON
 #define HWCAP_NEON (1 << 12)
 #endif
@@ -76,6 +82,17 @@
 #else
 #include <fcntl.h>
 #endif
+#endif
+
+#if defined(__ANDROID__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
+#if __ARM_ARCH < 8
+#include <cpu-features.h>
+#endif
+#endif
+
+#ifdef __RISCOS__
+#include <kernel.h>
+#include <swis.h>
 #endif
 
 #define CPU_HAS_RDTSC   (1 << 0)
@@ -91,6 +108,7 @@
 #define CPU_HAS_AVX2    (1 << 10)
 #define CPU_HAS_NEON    (1 << 11)
 #define CPU_HAS_AVX512F (1 << 12)
+#define CPU_HAS_ARM_SIMD (1 << 13)
 
 #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
 /* This is the brute force way of detecting instruction sets...
@@ -320,7 +338,84 @@
     return altivec;
 }
 
-#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
+#if defined(__ARM_ARCH) && (__ARM_ARCH >= 6)
+static int
+CPU_haveARMSIMD(void)
+{
+	return 1;
+}
+
+#elif !defined(__arm__)
+static int
+CPU_haveARMSIMD(void)
+{
+	return 0;
+}
+
+#elif defined(__LINUX__)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <elf.h>
+
+static 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;
+                if (plat) {
+                    arm_simd = strncmp(plat, "v6l", 3) == 0 ||
+                               strncmp(plat, "v7l", 3) == 0;
+                }
+            }
+        }
+        close(fd);
+    }
+    return arm_simd;
+}
+
+#elif defined(__RISCOS__)
+
+static int
+CPU_haveARMSIMD(void)
+{
+	_kernel_swi_regs regs;
+	regs.r[0] = 0;
+	if (_kernel_swi(OS_PlatformFeatures, &regs, &regs) != NULL)
+		return 0;
+
+	if (!(regs.r[0] & (1<<31)))
+		return 0;
+
+	regs.r[0] = 34;
+	regs.r[1] = 29;
+	if (_kernel_swi(OS_PlatformFeatures, &regs, &regs) != NULL)
+		return 0;
+
+	return regs.r[0];
+}
+
+#else
+static int
+CPU_haveARMSIMD(void)
+{
+#warning SDL_HasARMSIMD is not implemented for this ARM platform. Write me.
+    return 0;
+}
+#endif
+
+#if defined(__LINUX__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
 static int
 readProcAuxvForNeon(void)
 {
@@ -340,30 +435,60 @@
 }
 #endif
 
-
 static int
 CPU_haveNEON(void)
 {
 /* The way you detect NEON is a privileged instruction on ARM, so you have
    query the OS kernel in a platform-specific way. :/ */
-#if defined(SDL_CPUINFO_DISABLED) || !defined(__ARM_ARCH)
-    return 0;  /* disabled or not an ARM CPU at all. */
-#elif __ARM_ARCH >= 8
+#if defined(SDL_CPUINFO_DISABLED)
+   return 0; /* disabled */
+#elif (defined(__WINDOWS__) || defined(__WINRT__)) && (defined(_M_ARM) || defined(_M_ARM64))
+/* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */
+/* Seems to have been removed */
+#  if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)
+#    define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19
+#  endif
+/* All WinRT ARM devices are required to support NEON, but just in case. */
+    return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
+#elif defined(__ARM_ARCH) && (__ARM_ARCH >= 8)
     return 1;  /* ARMv8 always has non-optional NEON support. */
-#elif defined(__APPLE__) && (__ARM_ARCH >= 7)
+#elif defined(__APPLE__) && defined(__ARM_ARCH) && (__ARM_ARCH >= 7)
     /* (note that sysctlbyname("hw.optional.neon") doesn't work!) */
     return 1;  /* all Apple ARMv7 chips and later have NEON. */
 #elif defined(__APPLE__)
     return 0;  /* assume anything else from Apple doesn't have NEON. */
+#elif !defined(__arm__)
+    return 0;  /* not an ARM CPU at all. */
 #elif defined(__QNXNTO__)
     return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON;
 #elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL)
     return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON);
-#elif (defined(__LINUX__) || defined(__ANDROID__))
-    return readProcAuxvForNeon();   /* Android offers a static library for this, but it just parses /proc/self/auxv */
-#elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
-    /* All WinRT ARM devices are required to support NEON, but just in case. */
-    return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
+#elif defined(__LINUX__)
+    return readProcAuxvForNeon();
+#elif defined(__ANDROID__)
+    /* Use NDK cpufeatures to read either /proc/self/auxv or /proc/cpuinfo */
+    {
+        AndroidCpuFamily cpu_family = android_getCpuFamily();
+        if (cpu_family == ANDROID_CPU_FAMILY_ARM) {
+            uint64_t cpu_features = android_getCpuFeatures();
+            if ((cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
+                return 1;
+            }
+        }
+        return 0;
+    }
+#elif defined(__RISCOS__)
+    /* Use the VFPSupport_Features SWI to access the MVFR registers */
+    {
+        _kernel_swi_regs regs;
+	regs.r[0] = 0;
+        if (_kernel_swi(VFPSupport_Features, &regs, &regs) == NULL) {
+            if ((regs.r[2] & 0xFFF000) == 0x111000) {
+                return 1;
+            }
+        }
+        return 0;
+    }
 #else
 #warning SDL_HasNEON is not implemented for this ARM platform. Write me.
     return 0;
@@ -578,7 +703,7 @@
     if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
         cpuid(0x00000001, a, b, c, d);
         return (((b >> 8) & 0xff) * 8);
-    } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
+    } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0 || SDL_strcmp(cpuType, "HygonGenuine") == 0) {
         cpuid(0x80000005, a, b, c, d);
         return (c & 0xff);
     } else {
@@ -596,7 +721,7 @@
     if (SDL_CPUFeatures == 0xFFFFFFFF) {
         CPU_calcCPUIDFeatures();
         SDL_CPUFeatures = 0;
-        SDL_SIMDAlignment = 4;  /* a good safe base value */
+        SDL_SIMDAlignment = sizeof(void *);  /* a good safe base value */
         if (CPU_haveRDTSC()) {
             SDL_CPUFeatures |= CPU_HAS_RDTSC;
         }
@@ -643,6 +768,10 @@
         if (CPU_haveAVX512F()) {
             SDL_CPUFeatures |= CPU_HAS_AVX512F;
             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 64);
+        }
+        if (CPU_haveARMSIMD()) {
+            SDL_CPUFeatures |= CPU_HAS_ARM_SIMD;
+            SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
         }
         if (CPU_haveNEON()) {
             SDL_CPUFeatures |= CPU_HAS_NEON;
@@ -726,6 +855,12 @@
 }
 
 SDL_bool
+SDL_HasARMSIMD(void)
+{
+    return CPU_FEATURE_AVAILABLE(CPU_HAS_ARM_SIMD);
+}
+
+SDL_bool
 SDL_HasNEON(void)
 {
     return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
@@ -777,6 +912,15 @@
             Uint32 sysram = 0;
             DosQuerySysInfo(QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, &sysram, 4);
             SDL_SystemRAM = (int) (sysram / 0x100000U);
+        }
+#endif
+#ifdef __RISCOS__
+        if (SDL_SystemRAM <= 0) {
+            _kernel_swi_regs regs;
+            regs.r[0] = 0x108;
+            if (_kernel_swi(OS_Memory, &regs, &regs) == NULL) {
+                SDL_SystemRAM = (int)(regs.r[1] * regs.r[2] / (1024 * 1024));
+            }
         }
 #endif
 #endif
@@ -846,6 +990,7 @@
     printf("AVX: %d\n", SDL_HasAVX());
     printf("AVX2: %d\n", SDL_HasAVX2());
     printf("AVX-512F: %d\n", SDL_HasAVX512F());
+    printf("ARM SIMD: %d\n", SDL_HasARMSIMD());
     printf("NEON: %d\n", SDL_HasNEON());
     printf("RAM: %d MB\n", SDL_GetSystemRAM());
     return 0;

--
Gitblit v1.9.3