Fixed bug 5418 - Add system features detection for Elbrus (E2K) Ivan Kuzmenko MCST Elbrus 2000 (E2K, https://en.wikipedia.org/wiki/Elbrus_2000) is a russian processor architecture based on VLIW/EPIC instruction set (like Intel Itanium (IA-64) architecture). Architecture has half native / half software support of most Intel/AMD SIMD (e.g. MMX/SSE/SSE2/SSE3/SSSE3/SSE4.1/SSE4.2/AES/AVX/AVX2 & 3DNow!/SSE4a/XOP/FMA4). It also has built-in x86/x86_64 <-> e2k binary translators (RTC, http://www.mcst.ru/rtc and Lintel, http://www.mcst.ru/lintel) that can run code for x86/x86_64 architecture (Transmeta did something similiar with their Crusoe series) with SIMD extensions support. Attached patch allows SDL2 to detect extensions supported by E2K like MMX, 3dNOW!, AVX etc. (test/testplatform log: https://termbin.com/7qs3).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index b529a6d..9b70f50 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -509,6 +509,17 @@ CPU_haveNEON(void)
#endif
}
+#if defined(__e2k__)
+inline int
+CPU_have3DNow(void)
+{
+#if defined(__3dNOW__)
+ return 1;
+#else
+ return 0;
+#endif
+}
+#else
static int
CPU_have3DNow(void)
{
@@ -522,7 +533,46 @@ CPU_have3DNow(void)
}
return 0;
}
+#endif
+#if defined(__e2k__)
+#define CPU_haveRDTSC() (0)
+#if defined(__MMX__)
+#define CPU_haveMMX() (1)
+#else
+#define CPU_haveMMX() (0)
+#endif
+#if defined(__SSE__)
+#define CPU_haveSSE() (1)
+#else
+#define CPU_haveSSE() (0)
+#endif
+#if defined(__SSE2__)
+#define CPU_haveSSE2() (1)
+#else
+#define CPU_haveSSE2() (0)
+#endif
+#if defined(__SSE3__)
+#define CPU_haveSSE3() (1)
+#else
+#define CPU_haveSSE3() (0)
+#endif
+#if defined(__SSE4_1__)
+#define CPU_haveSSE41() (1)
+#else
+#define CPU_haveSSE41() (0)
+#endif
+#if defined(__SSE4_2__)
+#define CPU_haveSSE42() (1)
+#else
+#define CPU_haveSSE42() (0)
+#endif
+#if defined(__AVX__)
+#define CPU_haveAVX() (1)
+#else
+#define CPU_haveAVX() (0)
+#endif
+#else
#define CPU_haveRDTSC() (CPU_CPUIDFeatures[3] & 0x00000010)
#define CPU_haveMMX() (CPU_CPUIDFeatures[3] & 0x00800000)
#define CPU_haveSSE() (CPU_CPUIDFeatures[3] & 0x02000000)
@@ -531,7 +581,19 @@ CPU_have3DNow(void)
#define CPU_haveSSE41() (CPU_CPUIDFeatures[2] & 0x00080000)
#define CPU_haveSSE42() (CPU_CPUIDFeatures[2] & 0x00100000)
#define CPU_haveAVX() (CPU_OSSavesYMM && (CPU_CPUIDFeatures[2] & 0x10000000))
+#endif
+#if defined(__e2k__)
+inline int
+CPU_haveAVX2(void)
+{
+#if defined(__AVX2__)
+ return 1;
+#else
+ return 0;
+#endif
+}
+#else
static int
CPU_haveAVX2(void)
{
@@ -543,7 +605,15 @@ CPU_haveAVX2(void)
}
return 0;
}
+#endif
+#if defined(__e2k__)
+inline int
+CPU_haveAVX512F(void)
+{
+ return 0;
+}
+#else
static int
CPU_haveAVX512F(void)
{
@@ -555,6 +625,7 @@ CPU_haveAVX512F(void)
}
return 0;
}
+#endif
static int SDL_CPUCount = 0;
@@ -596,6 +667,17 @@ SDL_GetCPUCount(void)
return SDL_CPUCount;
}
+#if defined(__e2k__)
+inline const char *
+SDL_GetCPUType(void)
+{
+ static char SDL_CPUType[13];
+
+ SDL_strlcpy(SDL_CPUType, "E2K MACHINE", sizeof(SDL_CPUType));
+
+ return SDL_CPUType;
+}
+#else
/* Oh, such a sweet sweet trick, just not very useful. :) */
static const char *
SDL_GetCPUType(void)
@@ -631,9 +713,21 @@ SDL_GetCPUType(void)
}
return SDL_CPUType;
}
+#endif
#ifdef TEST_MAIN /* !!! FIXME: only used for test at the moment. */
+#if defined(__e2k__)
+inline const char *
+SDL_GetCPUName(void)
+{
+ static char SDL_CPUName[48];
+
+ SDL_strlcpy(SDL_CPUName, __builtin_cpu_name(), sizeof(SDL_CPUName));
+
+ return SDL_CPUName;
+}
+#else
static const char *
SDL_GetCPUName(void)
{
@@ -707,6 +801,7 @@ SDL_GetCPUName(void)
return SDL_CPUName;
}
#endif
+#endif
int
SDL_GetCPUCacheLineSize(void)