diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index 44cefc10a..c064a77f9 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -762,6 +762,9 @@
+
+
+
NotUsing
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index 4414dd92f..2767954b1 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -145,6 +145,9 @@
+
+
+
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj
index f4760087a..37188a009 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj
+++ b/VisualC-WinRT/SDL-UWP.vcxproj
@@ -424,6 +424,9 @@
+
+
+
NotUsing
diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters
index 789ec30d3..784f5961b 100644
--- a/VisualC-WinRT/SDL-UWP.vcxproj.filters
+++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters
@@ -714,6 +714,15 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
Source Files
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index b7840a4c4..6a79e1f2e 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -616,8 +616,11 @@
+
+
+
-
+
NotUsing
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index 6517484f4..6971749d5 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -822,6 +822,13 @@
render\direct3d12
+
+
+
+
+
+
+
@@ -1197,9 +1204,6 @@
video\dummy
-
- video\yuv2rgb
-
video\windows
@@ -1281,6 +1285,15 @@
stdlib
+
+ stdlib
+
+
+ stdlib
+
+
+ stdlib
+
stdlib
@@ -1381,9 +1394,10 @@
stdlib
-
- stdlib
-
+
+
+
+
diff --git a/Xcode/SDL/SDL.xcodeproj/project.pbxproj b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
index a2af9d4da..a846955a6 100644
--- a/Xcode/SDL/SDL.xcodeproj/project.pbxproj
+++ b/Xcode/SDL/SDL.xcodeproj/project.pbxproj
@@ -372,6 +372,9 @@
E4F7981C2AD8D85500669F54 /* SDL_dynapi_unsupported.h in Headers */ = {isa = PBXBuildFile; fileRef = E4F7981B2AD8D85500669F54 /* SDL_dynapi_unsupported.h */; };
E4F7981E2AD8D86A00669F54 /* SDL_render_unsupported.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F7981D2AD8D86A00669F54 /* SDL_render_unsupported.c */; };
E4F798202AD8D87F00669F54 /* SDL_video_unsupported.c in Sources */ = {isa = PBXBuildFile; fileRef = E4F7981F2AD8D87F00669F54 /* SDL_video_unsupported.c */; };
+ F316ABD82B5C3185002EF551 /* SDL_memset.c in Sources */ = {isa = PBXBuildFile; fileRef = F316ABD62B5C3185002EF551 /* SDL_memset.c */; };
+ F316ABD92B5C3185002EF551 /* SDL_memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = F316ABD72B5C3185002EF551 /* SDL_memcpy.c */; };
+ F316ABDB2B5CA721002EF551 /* SDL_memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = F316ABDA2B5CA721002EF551 /* SDL_memmove.c */; };
F31A92C828D4CB39003BFD6A /* SDL_offscreenopengles.h in Headers */ = {isa = PBXBuildFile; fileRef = F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */; };
F31A92D228D4CB39003BFD6A /* SDL_offscreenopengles.c in Sources */ = {isa = PBXBuildFile; fileRef = F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */; };
F32305FF28939F6400E66D30 /* SDL_hidapi_combined.c in Sources */ = {isa = PBXBuildFile; fileRef = F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */; };
@@ -878,6 +881,9 @@
E4F7981B2AD8D85500669F54 /* SDL_dynapi_unsupported.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_dynapi_unsupported.h; sourceTree = ""; };
E4F7981D2AD8D86A00669F54 /* SDL_render_unsupported.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render_unsupported.c; sourceTree = ""; };
E4F7981F2AD8D87F00669F54 /* SDL_video_unsupported.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_video_unsupported.c; sourceTree = ""; };
+ F316ABD62B5C3185002EF551 /* SDL_memset.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_memset.c; sourceTree = ""; };
+ F316ABD72B5C3185002EF551 /* SDL_memcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_memcpy.c; sourceTree = ""; };
+ F316ABDA2B5CA721002EF551 /* SDL_memmove.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_memmove.c; sourceTree = ""; };
F31A92C628D4CB39003BFD6A /* SDL_offscreenopengles.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_offscreenopengles.h; sourceTree = ""; };
F31A92C728D4CB39003BFD6A /* SDL_offscreenopengles.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_offscreenopengles.c; sourceTree = ""; };
F32305FE28939F6400E66D30 /* SDL_hidapi_combined.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapi_combined.c; sourceTree = ""; };
@@ -1941,6 +1947,9 @@
A7D8A8D423E2514000DCD162 /* SDL_getenv.c */,
A7D8A8D323E2514000DCD162 /* SDL_iconv.c */,
A7D8A8D923E2514000DCD162 /* SDL_malloc.c */,
+ F316ABD72B5C3185002EF551 /* SDL_memcpy.c */,
+ F316ABDA2B5CA721002EF551 /* SDL_memmove.c */,
+ F316ABD62B5C3185002EF551 /* SDL_memset.c */,
A7D8A8D723E2514000DCD162 /* SDL_qsort.c */,
A7D8A8D823E2514000DCD162 /* SDL_stdlib.c */,
A7D8A8D523E2514000DCD162 /* SDL_string.c */,
@@ -2559,6 +2568,7 @@
A7D8B9DD23E2514400DCD162 /* SDL_blendpoint.c in Sources */,
A7D8B4EE23E2514300DCD162 /* SDL_gamepad.c in Sources */,
E4A568B62AF763940062EEC4 /* SDL_sysmain_callbacks.c in Sources */,
+ F316ABD82B5C3185002EF551 /* SDL_memset.c in Sources */,
A7D8BA1323E2514400DCD162 /* SDL_render_sw.c in Sources */,
A7D8B42223E2514300DCD162 /* SDL_syssem.c in Sources */,
A7D8B53923E2514300DCD162 /* SDL_hidapi_xbox360.c in Sources */,
@@ -2610,6 +2620,7 @@
A7D8B76A23E2514300DCD162 /* SDL_wave.c in Sources */,
5616CA4C252BB2A6005D5928 /* SDL_url.c in Sources */,
A7D8BAD323E2514500DCD162 /* s_tan.c in Sources */,
+ F316ABDB2B5CA721002EF551 /* SDL_memmove.c in Sources */,
A7D8AA6523E2514000DCD162 /* SDL_hints.c in Sources */,
A7D8B53F23E2514300DCD162 /* SDL_hidapi_ps4.c in Sources */,
F362B91C2B3349E200D30B94 /* SDL_steam_virtual_gamepad.c in Sources */,
@@ -2623,6 +2634,7 @@
F395C1B12569C6A000942BFF /* SDL_mfijoystick.m in Sources */,
A7D8B99223E2514400DCD162 /* SDL_shaders_metal.metal in Sources */,
F3990DF52A787C10000D8759 /* SDL_sysurl.m in Sources */,
+ F316ABD92B5C3185002EF551 /* SDL_memcpy.c in Sources */,
A7D8B97A23E2514400DCD162 /* SDL_render.c in Sources */,
A7D8ABD323E2514100DCD162 /* SDL_stretch.c in Sources */,
A7D8BAFD23E2514500DCD162 /* s_floor.c in Sources */,
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 6b3b3b85a..23ea2d1f2 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -1249,6 +1249,9 @@ M_PI is no longer defined in SDL_stdinc.h, you can use the new symbols SDL_PI_D
The following functions have been renamed:
* SDL_strtokr() => SDL_strtok_r()
+The following functions have been removed:
+* SDL_memcpy4()
+
## SDL_surface.h
The userdata member of SDL_Surface has been replaced with a more general properties interface, which can be queried with SDL_GetSurfaceProperties()
diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index 4f864873e..4cc8480b2 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -522,22 +522,45 @@ extern DECLSPEC int SDLCALL SDL_tolower(int x);
extern DECLSPEC Uint16 SDLCALL SDL_crc16(Uint16 crc, const void *data, size_t len);
extern DECLSPEC Uint32 SDLCALL SDL_crc32(Uint32 crc, const void *data, size_t len);
+extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
+
+/* Take advantage of compiler optimizations for memcpy */
+#ifndef SDL_SLOW_MEMCPY
+#ifdef SDL_memcpy
+#undef SDL_memcpy
+#endif
+#define SDL_memcpy memcpy
+#endif
+
+#define SDL_copyp(dst, src) \
+ { SDL_COMPILE_TIME_ASSERT(SDL_copyp, sizeof (*(dst)) == sizeof (*(src))); } \
+ SDL_memcpy((dst), (src), sizeof(*(src)))
+
+extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
+
+/* Take advantage of compiler optimizations for memmove */
+#ifndef SDL_SLOW_MEMMOVE
+#ifdef SDL_memmove
+#undef SDL_memmove
+#endif
+#define SDL_memmove memmove
+#endif
+
extern DECLSPEC void *SDLCALL SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len);
extern DECLSPEC void *SDLCALL SDL_memset4(void *dst, Uint32 val, size_t dwords);
+/* Take advantage of compiler optimizations for memset */
+#ifndef SDL_SLOW_MEMSET
+#ifdef SDL_memset
+#undef SDL_memset
+#endif
+#define SDL_memset memset
+#endif
+
#define SDL_zero(x) SDL_memset(&(x), 0, sizeof((x)))
#define SDL_zerop(x) SDL_memset((x), 0, sizeof(*(x)))
#define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x)))
-#define SDL_copyp(dst, src) \
- { SDL_COMPILE_TIME_ASSERT(SDL_copyp, sizeof (*(dst)) == sizeof (*(src))); } \
- SDL_memcpy((dst), (src), sizeof (*(src)))
-
-
-
-extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
-
-extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
@@ -730,9 +753,15 @@ size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size);
#define SDL_calloc calloc
#define SDL_realloc realloc
#define SDL_free free
-#define SDL_memset memset
+#ifndef SDL_memcpy
#define SDL_memcpy memcpy
+#endif
+#ifndef SDL_memmove
#define SDL_memmove memmove
+#endif
+#ifndef SDL_memset
+#define SDL_memset memset
+#endif
#define SDL_memcmp memcmp
#define SDL_strlcpy strlcpy
#define SDL_strlcat strlcat
@@ -759,11 +788,6 @@ size_t wcslcat(wchar_t *dst, const wchar_t *src, size_t size);
#define SDL_vsnprintf vsnprintf
#endif
-SDL_FORCE_INLINE void *SDL_memcpy4(SDL_OUT_BYTECAP(dwords*4) void *dst, SDL_IN_BYTECAP(dwords*4) const void *src, size_t dwords)
-{
- return SDL_memcpy(dst, src, dwords * 4);
-}
-
/**
* If a * b would overflow, return -1. Otherwise store a * b via ret
* and return 0.
diff --git a/src/dynapi/SDL_dynapi.c b/src/dynapi/SDL_dynapi.c
index 08c18b910..5edc6aa94 100644
--- a/src/dynapi/SDL_dynapi.c
+++ b/src/dynapi/SDL_dynapi.c
@@ -26,6 +26,9 @@
#if SDL_DYNAMIC_API
#define SDL_DYNAMIC_API_ENVVAR "SDL3_DYNAMIC_API"
+#define SDL_SLOW_MEMCPY
+#define SDL_SLOW_MEMMOVE
+#define SDL_SLOW_MEMSET
#ifdef HAVE_STDIO_H
#include
diff --git a/src/stdlib/SDL_memcpy.c b/src/stdlib/SDL_memcpy.c
new file mode 100644
index 000000000..456b1d032
--- /dev/null
+++ b/src/stdlib/SDL_memcpy.c
@@ -0,0 +1,99 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2024 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_internal.h"
+
+
+#ifdef SDL_memcpy
+#undef SDL_memcpy
+#endif
+#if SDL_DYNAMIC_API
+#define SDL_memcpy SDL_memcpy_REAL
+#endif
+void *SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
+{
+#ifdef __GNUC__
+ /* Presumably this is well tuned for speed.
+ On my machine this is twice as fast as the C code below.
+ */
+ return __builtin_memcpy(dst, src, len);
+#elif defined(HAVE_MEMCPY)
+ return memcpy(dst, src, len);
+#elif defined(HAVE_BCOPY)
+ bcopy(src, dst, len);
+ return dst;
+#else
+ /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop
+ using Uint32* pointers, so we need to make sure the pointers are
+ aligned before we loop using them.
+ */
+ if (((uintptr_t)src & 0x3) || ((uintptr_t)dst & 0x3)) {
+ /* Do an unaligned byte copy */
+ Uint8 *srcp1 = (Uint8 *)src;
+ Uint8 *dstp1 = (Uint8 *)dst;
+
+ while (len--) {
+ *dstp1++ = *srcp1++;
+ }
+ } else {
+ size_t left = (len % 4);
+ Uint32 *srcp4, *dstp4;
+ Uint8 *srcp1, *dstp1;
+
+ srcp4 = (Uint32 *)src;
+ dstp4 = (Uint32 *)dst;
+ len /= 4;
+ while (len--) {
+ *dstp4++ = *srcp4++;
+ }
+
+ srcp1 = (Uint8 *)srcp4;
+ dstp1 = (Uint8 *)dstp4;
+ switch (left) {
+ case 3:
+ *dstp1++ = *srcp1++;
+ case 2:
+ *dstp1++ = *srcp1++;
+ case 1:
+ *dstp1++ = *srcp1++;
+ }
+ }
+ return dst;
+#endif /* __GNUC__ */
+}
+
+/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls.
+ Always provide it for the SDL3 DLL, but skip it when building static lib w/ static runtime. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT))
+/* NOLINTNEXTLINE(readability-redundant-declaration) */
+extern void *memcpy(void *dst, const void *src, size_t len);
+#ifndef __INTEL_LLVM_COMPILER
+#pragma intrinsic(memcpy)
+#endif
+
+#ifndef __clang__
+#pragma function(memcpy)
+#endif
+/* NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name) */
+void *memcpy(void *dst, const void *src, size_t len)
+{
+ return SDL_memcpy(dst, src, len);
+}
+#endif /* (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) */
diff --git a/src/stdlib/SDL_memmove.c b/src/stdlib/SDL_memmove.c
new file mode 100644
index 000000000..1daed2ffb
--- /dev/null
+++ b/src/stdlib/SDL_memmove.c
@@ -0,0 +1,55 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2024 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_internal.h"
+
+
+#ifdef SDL_memmove
+#undef SDL_memmove
+#endif
+#if SDL_DYNAMIC_API
+#define SDL_memmove SDL_memmove_REAL
+#endif
+void *SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
+{
+#ifdef __GNUC__
+ /* Presumably this is well tuned for speed. */
+ return __builtin_memmove(dst, src, len);
+#elif defined(HAVE_MEMMOVE)
+ return memmove(dst, src, len);
+#else
+ char *srcp = (char *)src;
+ char *dstp = (char *)dst;
+
+ if (src < dst) {
+ srcp += len - 1;
+ dstp += len - 1;
+ while (len--) {
+ *dstp-- = *srcp--;
+ }
+ } else {
+ while (len--) {
+ *dstp++ = *srcp++;
+ }
+ }
+ return dst;
+#endif /* HAVE_MEMMOVE */
+}
+
diff --git a/src/stdlib/SDL_memset.c b/src/stdlib/SDL_memset.c
new file mode 100644
index 000000000..30d2d6a57
--- /dev/null
+++ b/src/stdlib/SDL_memset.c
@@ -0,0 +1,137 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2024 Sam Lantinga
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "SDL_internal.h"
+
+
+#ifdef SDL_memset
+#undef SDL_memset
+#endif
+#if SDL_DYNAMIC_API
+#define SDL_memset SDL_memset_REAL
+#endif
+void *SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
+{
+#ifdef __GNUC__
+ return __builtin_memset(dst, c, len);
+#elif defined(HAVE_MEMSET)
+ return memset(dst, c, len);
+#else
+ size_t left;
+ Uint32 *dstp4;
+ Uint8 *dstp1 = (Uint8 *)dst;
+ Uint8 value1;
+ Uint32 value4;
+
+ /* The value used in memset() is a byte, passed as an int */
+ c &= 0xff;
+
+ /* The destination pointer needs to be aligned on a 4-byte boundary to
+ * execute a 32-bit set. Set first bytes manually if needed until it is
+ * aligned. */
+ value1 = (Uint8)c;
+ while ((uintptr_t)dstp1 & 0x3) {
+ if (len--) {
+ *dstp1++ = value1;
+ } else {
+ return dst;
+ }
+ }
+
+ value4 = ((Uint32)c | ((Uint32)c << 8) | ((Uint32)c << 16) | ((Uint32)c << 24));
+ dstp4 = (Uint32 *)dstp1;
+ left = (len % 4);
+ len /= 4;
+ while (len--) {
+ *dstp4++ = value4;
+ }
+
+ dstp1 = (Uint8 *)dstp4;
+ switch (left) {
+ case 3:
+ *dstp1++ = value1;
+ case 2:
+ *dstp1++ = value1;
+ case 1:
+ *dstp1++ = value1;
+ }
+
+ return dst;
+#endif /* HAVE_MEMSET */
+}
+
+/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */
+void *SDL_memset4(void *dst, Uint32 val, size_t dwords)
+{
+#if defined(__APPLE__) && defined(HAVE_STRING_H)
+ memset_pattern4(dst, &val, dwords * 4);
+#elif defined(__GNUC__) && defined(__i386__)
+ int u0, u1, u2;
+ __asm__ __volatile__(
+ "cld \n\t"
+ "rep ; stosl \n\t"
+ : "=&D"(u0), "=&a"(u1), "=&c"(u2)
+ : "0"(dst), "1"(val), "2"(SDL_static_cast(Uint32, dwords))
+ : "memory");
+#else
+ size_t _n = (dwords + 3) / 4;
+ Uint32 *_p = SDL_static_cast(Uint32 *, dst);
+ Uint32 _val = (val);
+ if (dwords == 0) {
+ return dst;
+ }
+ switch (dwords % 4) {
+ case 0:
+ do {
+ *_p++ = _val;
+ SDL_FALLTHROUGH;
+ case 3:
+ *_p++ = _val;
+ SDL_FALLTHROUGH;
+ case 2:
+ *_p++ = _val;
+ SDL_FALLTHROUGH;
+ case 1:
+ *_p++ = _val;
+ } while (--_n);
+ }
+#endif
+ return dst;
+}
+
+/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls.
+ Always provide it for the SDL3 DLL, but skip it when building static lib w/ static runtime. */
+#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT))
+/* NOLINTNEXTLINE(readability-redundant-declaration) */
+extern void *memset(void *dst, int c, size_t len);
+#ifndef __INTEL_LLVM_COMPILER
+#pragma intrinsic(memset)
+#endif
+
+#ifndef __clang__
+#pragma function(memset)
+#endif
+/* NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name) */
+void *memset(void *dst, int c, size_t len)
+{
+ return SDL_memset(dst, c, len);
+}
+#endif /* (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) */
+
diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c
index eac162dce..43fec0974 100644
--- a/src/stdlib/SDL_mslibc.c
+++ b/src/stdlib/SDL_mslibc.c
@@ -33,40 +33,6 @@
__declspec(selectany) int _fltused = 1;
#endif
-/* The optimizer on Visual Studio 2005 and later generates memcpy() and memset() calls.
- Always provide it for the SDL3 DLL, but skip it when building static lib w/ static runtime. */
-#if (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT))
-/* NOLINTNEXTLINE(readability-redundant-declaration) */
-extern void *memcpy(void *dst, const void *src, size_t len);
-#ifndef __INTEL_LLVM_COMPILER
-#pragma intrinsic(memcpy)
-#endif
-
-#ifndef __clang__
-#pragma function(memcpy)
-#endif
-/* NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name) */
-void *memcpy(void *dst, const void *src, size_t len)
-{
- return SDL_memcpy(dst, src, len);
-}
-
-/* NOLINTNEXTLINE(readability-redundant-declaration) */
-extern void *memset(void *dst, int c, size_t len);
-#ifndef __INTEL_LLVM_COMPILER
-#pragma intrinsic(memset)
-#endif
-
-#ifndef __clang__
-#pragma function(memset)
-#endif
-/* NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name) */
-void *memset(void *dst, int c, size_t len)
-{
- return SDL_memset(dst, c, len);
-}
-#endif /* (_MSC_VER >= 1400) && (!defined(_MT) || defined(DLL_EXPORT)) */
-
#ifdef _M_IX86
/* Float to long */
diff --git a/src/stdlib/SDL_stdlib.c b/src/stdlib/SDL_stdlib.c
index 97cab4c52..edce6e4ae 100644
--- a/src/stdlib/SDL_stdlib.c
+++ b/src/stdlib/SDL_stdlib.c
@@ -510,147 +510,6 @@ int SDL_toupper(int x) { return ((x) >= 'a') && ((x) <= 'z') ? ('A' + ((x) - 'a'
int SDL_tolower(int x) { return ((x) >= 'A') && ((x) <= 'Z') ? ('a' + ((x) - 'A')) : (x); }
#endif
-/* This file contains a portable memcpy manipulation function for SDL */
-
-void *SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
-{
-#ifdef __GNUC__
- /* Presumably this is well tuned for speed.
- On my machine this is twice as fast as the C code below.
- */
- return __builtin_memcpy(dst, src, len);
-#elif defined(HAVE_MEMCPY)
- return memcpy(dst, src, len);
-#elif defined(HAVE_BCOPY)
- bcopy(src, dst, len);
- return dst;
-#else
- /* GCC 4.9.0 with -O3 will generate movaps instructions with the loop
- using Uint32* pointers, so we need to make sure the pointers are
- aligned before we loop using them.
- */
- if (((uintptr_t)src & 0x3) || ((uintptr_t)dst & 0x3)) {
- /* Do an unaligned byte copy */
- Uint8 *srcp1 = (Uint8 *)src;
- Uint8 *dstp1 = (Uint8 *)dst;
-
- while (len--) {
- *dstp1++ = *srcp1++;
- }
- } else {
- size_t left = (len % 4);
- Uint32 *srcp4, *dstp4;
- Uint8 *srcp1, *dstp1;
-
- srcp4 = (Uint32 *)src;
- dstp4 = (Uint32 *)dst;
- len /= 4;
- while (len--) {
- *dstp4++ = *srcp4++;
- }
-
- srcp1 = (Uint8 *)srcp4;
- dstp1 = (Uint8 *)dstp4;
- switch (left) {
- case 3:
- *dstp1++ = *srcp1++;
- case 2:
- *dstp1++ = *srcp1++;
- case 1:
- *dstp1++ = *srcp1++;
- }
- }
- return dst;
-#endif /* __GNUC__ */
-}
-
-void *SDL_memset(SDL_OUT_BYTECAP(len) void *dst, int c, size_t len)
-{
-#ifdef HAVE_MEMSET
- return memset(dst, c, len);
-#else
- size_t left;
- Uint32 *dstp4;
- Uint8 *dstp1 = (Uint8 *)dst;
- Uint8 value1;
- Uint32 value4;
-
- /* The value used in memset() is a byte, passed as an int */
- c &= 0xff;
-
- /* The destination pointer needs to be aligned on a 4-byte boundary to
- * execute a 32-bit set. Set first bytes manually if needed until it is
- * aligned. */
- value1 = (Uint8)c;
- while ((uintptr_t)dstp1 & 0x3) {
- if (len--) {
- *dstp1++ = value1;
- } else {
- return dst;
- }
- }
-
- value4 = ((Uint32)c | ((Uint32)c << 8) | ((Uint32)c << 16) | ((Uint32)c << 24));
- dstp4 = (Uint32 *)dstp1;
- left = (len % 4);
- len /= 4;
- while (len--) {
- *dstp4++ = value4;
- }
-
- dstp1 = (Uint8 *)dstp4;
- switch (left) {
- case 3:
- *dstp1++ = value1;
- case 2:
- *dstp1++ = value1;
- case 1:
- *dstp1++ = value1;
- }
-
- return dst;
-#endif /* HAVE_MEMSET */
-}
-
-/* Note that memset() is a byte assignment and this is a 32-bit assignment, so they're not directly equivalent. */
-void *SDL_memset4(void *dst, Uint32 val, size_t dwords)
-{
-#if defined(__APPLE__) && defined(HAVE_STRING_H)
- memset_pattern4(dst, &val, dwords * 4);
-#elif defined(__GNUC__) && defined(__i386__)
- int u0, u1, u2;
- __asm__ __volatile__(
- "cld \n\t"
- "rep ; stosl \n\t"
- : "=&D"(u0), "=&a"(u1), "=&c"(u2)
- : "0"(dst), "1"(val), "2"(SDL_static_cast(Uint32, dwords))
- : "memory");
-#else
- size_t _n = (dwords + 3) / 4;
- Uint32 *_p = SDL_static_cast(Uint32 *, dst);
- Uint32 _val = (val);
- if (dwords == 0) {
- return dst;
- }
- switch (dwords % 4) {
- case 0:
- do {
- *_p++ = _val;
- SDL_FALLTHROUGH;
- case 3:
- *_p++ = _val;
- SDL_FALLTHROUGH;
- case 2:
- *_p++ = _val;
- SDL_FALLTHROUGH;
- case 1:
- *_p++ = _val;
- } while (--_n);
- }
-#endif
- return dst;
-}
-
#if defined(HAVE_CTYPE_H) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
int SDL_isblank(int x)
{
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index 0a88b4ede..3a54e2553 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -325,29 +325,6 @@ static size_t SDL_ScanFloat(const char *text, double *valuep)
}
#endif
-void *SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len)
-{
-#ifdef HAVE_MEMMOVE
- return memmove(dst, src, len);
-#else
- char *srcp = (char *)src;
- char *dstp = (char *)dst;
-
- if (src < dst) {
- srcp += len - 1;
- dstp += len - 1;
- while (len--) {
- *dstp-- = *srcp--;
- }
- } else {
- while (len--) {
- *dstp++ = *srcp++;
- }
- }
- return dst;
-#endif /* HAVE_MEMMOVE */
-}
-
int SDL_memcmp(const void *s1, const void *s2, size_t len)
{
#ifdef __vita__