diff --git a/CMakeLists.txt b/CMakeLists.txt index 0baea1903..6edba99fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -486,6 +486,18 @@ sdl_glob_sources( "${SDL3_SOURCE_DIR}/src/video/*.c" "${SDL3_SOURCE_DIR}/src/video/yuv2rgb/*.c" ) +if(MSVC AND TARGET SDL3-shared) + if(SDL_CPU_X64) + enable_language(ASM_MASM) + set(asm_src "${SDL3_SOURCE_DIR}/src/stdlib/SDL_mslibc_x64.asm") + target_compile_options(SDL3-shared PRIVATE "$<$:/nologo>") + set_property(SOURCE "${asm_src}" PROPERTY LANGUAGE "ASM_MASM") + target_sources(SDL3-shared PRIVATE "${asm_src}") + elseif(SDL_CPU_ARM32 OR DL_CPU_ARM64) + # FIXME: ARM assembler (armasm.exe/armasm64.exe) is NOT ASM_MASM, and does currently not work with CMake + # (https://gitlab.kitware.com/cmake/cmake/-/issues/18912) + endif() +endif() if(USE_INTELCC) # warning #39: division by zero @@ -985,12 +997,21 @@ if(NOT HAVE_ARMNEON) set(SDL_DISABLE_NEON 1) endif() +set(SDL_DISABLE_ALLOCA 0) +check_include_file("alloca.h" "HAVE_ALLOCA_H") +if(MSVC) + check_include_file("malloc.h" "HAVE_MALLOC") + check_symbol_exists("_alloca" "malloc.h" _ALLOCA_IN_MALLOC_H) + if(NOT HAVE_ALLOCA_H AND NOT _ALLOCA_IN_MALLOC_H) + set(SDL_DISABLE_ALLOCA 1) + endif() +endif() + # TODO: Can't deactivate on FreeBSD? w/o LIBC, SDL_stdinc.h can't define anything. if(SDL_LIBC) set(available_headers) set(HAVE_LIBC TRUE) set(headers_to_check - alloca.h ctype.h float.h iconv.h @@ -1022,7 +1043,7 @@ if(SDL_LIBC) endforeach() set(symbols_to_check - abs acos acosf alloca asin asinf atan atan2 atan2f atanf atof atoi + abs acos acosf asin asinf atan atan2 atan2f atanf atof atoi bcopy bsearch calloc ceil ceilf copysign copysignf cos cosf _Exit exp expf @@ -1717,7 +1738,7 @@ elseif(WINDOWS) if(TARGET SDL3-shared AND MSVC AND NOT SDL_LIBC) # Prevent codegen that would use the VC runtime libraries. - target_compile_options(SDL3-shared PRIVATE "/GS-" "/Gs1048576") + target_compile_options(SDL3-shared PRIVATE $<$:/GS-> $<$:/Gs1048576>) if(SDL_CPU_X86) target_compile_options(SDL3-shared PRIVATE "/arch:SSE") endif() diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj index bb003d0f0..70b625b37 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj +++ b/VisualC-GDK/SDL/SDL.vcxproj @@ -59,6 +59,7 @@ + @@ -729,6 +730,9 @@ + + NotUsing + @@ -793,5 +797,6 @@ + diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters index bbdc75985..a530ef1bf 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj.filters +++ b/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -1388,6 +1388,9 @@ stdlib + + stdlib + core\gdk diff --git a/VisualC-WinRT/SDL-UWP.vcxproj b/VisualC-WinRT/SDL-UWP.vcxproj index 372a28339..21c5e7ebb 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj +++ b/VisualC-WinRT/SDL-UWP.vcxproj @@ -413,6 +413,9 @@ + + NotUsing + @@ -668,6 +671,7 @@ + @@ -867,5 +871,6 @@ + diff --git a/VisualC-WinRT/SDL-UWP.vcxproj.filters b/VisualC-WinRT/SDL-UWP.vcxproj.filters index 92e6f4a8d..430babceb 100644 --- a/VisualC-WinRT/SDL-UWP.vcxproj.filters +++ b/VisualC-WinRT/SDL-UWP.vcxproj.filters @@ -875,6 +875,9 @@ Source Files + + stdlib + Source Files diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index a40d5acb5..84e774521 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -43,6 +43,7 @@ + @@ -609,6 +610,9 @@ + + NotUsing + @@ -669,5 +673,6 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index f72a3a0fc..23fa7b2e3 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -1375,6 +1375,9 @@ stdlib + + stdlib + diff --git a/cmake/sdlcompilers.cmake b/cmake/sdlcompilers.cmake index 40bb3b6dc..5fd3081b4 100644 --- a/cmake/sdlcompilers.cmake +++ b/cmake/sdlcompilers.cmake @@ -49,12 +49,12 @@ function(SDL_AddCommonCompilerFlags TARGET) check_c_compiler_flag(-Wundef HAVE_GCC_WUNDEF) if(HAVE_GCC_WUNDEF) - target_compile_options(${TARGET} PRIVATE "-Wundef") + target_compile_options(${TARGET} PRIVATE "$<$:-Wundef>") endif() check_c_compiler_flag(-fno-strict-aliasing HAVE_GCC_NO_STRICT_ALIASING) if(HAVE_GCC_NO_STRICT_ALIASING) - target_compile_options(${TARGET} PRIVATE "-fno-strict-aliasing") + target_compile_options(${TARGET} PRIVATE "$<$:-fno-strict-aliasing>") endif() check_c_compiler_flag(-Wdocumentation HAVE_GCC_WDOCUMENTATION) @@ -62,10 +62,10 @@ function(SDL_AddCommonCompilerFlags TARGET) if(SDL_WERROR) check_c_compiler_flag(-Werror=documentation HAVE_GCC_WERROR_DOCUMENTATION) if(HAVE_GCC_WERROR_DOCUMENTATION) - target_compile_options(${TARGET} PRIVATE "-Werror=documentation") + target_compile_options(${TARGET} PRIVATE "$<$:-Werror=documentation>") endif() endif() - target_compile_options(${TARGET} PRIVATE "-Wdocumentation") + target_compile_options(${TARGET} PRIVATE "$<$:-Wdocumentation>") endif() check_c_compiler_flag(-Wdocumentation-unknown-command HAVE_GCC_WDOCUMENTATION_UNKNOWN_COMMAND) @@ -73,30 +73,30 @@ function(SDL_AddCommonCompilerFlags TARGET) if(SDL_WERROR) check_c_compiler_flag(-Werror=documentation-unknown-command HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND) if(HAVE_GCC_WERROR_DOCUMENTATION_UNKNOWN_COMMAND) - target_compile_options(${TARGET} PRIVATE "-Werror=documentation-unknown-command") + target_compile_options(${TARGET} PRIVATE "$<$:-Werror=documentation-unknown-command>") endif() endif() - target_compile_options(${TARGET} PRIVATE "-Wdocumentation-unknown-command") + target_compile_options(${TARGET} PRIVATE "$<$:-Wdocumentation-unknown-command>") endif() check_c_compiler_flag(-fcomment-block-commands=threadsafety HAVE_GCC_COMMENT_BLOCK_COMMANDS) if(HAVE_GCC_COMMENT_BLOCK_COMMANDS) - target_compile_options(${TARGET} PRIVATE "-fcomment-block-commands=threadsafety") + target_compile_options(${TARGET} PRIVATE "$<$:-fcomment-block-commands=threadsafety>") else() check_c_compiler_flag(/clang:-fcomment-block-commands=threadsafety HAVE_CLANG_COMMENT_BLOCK_COMMANDS) if(HAVE_CLANG_COMMENT_BLOCK_COMMANDS) - target_compile_options(${TARGET} PRIVATE "/clang:-fcomment-block-commands=threadsafety") + target_compile_options(${TARGET} PRIVATE "$<$:/clang:-fcomment-block-commands=threadsafety>") endif() endif() check_c_compiler_flag(-Wshadow HAVE_GCC_WSHADOW) if(HAVE_GCC_WSHADOW) - target_compile_options(${TARGET} PRIVATE "-Wshadow") + target_compile_options(${TARGET} PRIVATE "$<$:-Wshadow>") endif() check_c_compiler_flag(-Wunused-local-typedefs HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS) if(HAVE_GCC_WUNUSED_LOCAL_TYPEDEFS) - target_compile_options(${TARGET} PRIVATE "-Wno-unused-local-typedefs") + target_compile_options(${TARGET} PRIVATE "$<$:-Wno-unused-local-typedefs>") endif() endif() @@ -109,7 +109,7 @@ function(SDL_AddCommonCompilerFlags TARGET) elseif(USE_GCC OR USE_CLANG OR USE_INTELCC OR USE_QNX) check_c_compiler_flag(-Werror HAVE_WERROR) if(HAVE_WERROR) - target_compile_options(${TARGET} PRIVATE "-Werror") + target_compile_options(${TARGET} PRIVATE "$<$:-Werror>") endif() endif() endif() @@ -117,12 +117,12 @@ function(SDL_AddCommonCompilerFlags TARGET) if(USE_CLANG) check_c_compiler_flag("-fcolor-diagnostics" COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS) if(COMPILER_SUPPORTS_FCOLOR_DIAGNOSTICS) - target_compile_options(${TARGET} PRIVATE "-fcolor-diagnostics") + target_compile_options(${TARGET} PRIVATE "$<$:-fcolor-diagnostics>") endif() else() check_c_compiler_flag("-fdiagnostics-color=always" COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS) if(COMPILER_SUPPORTS_FDIAGNOSTICS_COLOR_ALWAYS) - target_compile_options(${TARGET} PRIVATE "-fdiagnostics-color=always") + target_compile_options(${TARGET} PRIVATE "$<$:-fdiagnostics-color=always>") endif() endif() endfunction() diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h index 3643bb60f..a3d63325c 100644 --- a/include/SDL3/SDL_stdinc.h +++ b/include/SDL3/SDL_stdinc.h @@ -37,26 +37,28 @@ #include #include -#ifndef alloca -# ifdef HAVE_ALLOCA_H -# include -# elif defined(__GNUC__) -# define alloca __builtin_alloca -# elif defined(_MSC_VER) -# include -# define alloca _alloca -# elif defined(__WATCOMC__) -# include -# elif defined(__BORLANDC__) -# include -# elif defined(__DMC__) -# include -# elif defined(__AIX__) -#pragma alloca -# elif defined(__MRC__) +#ifndef SDL_DISABLE_ALLOCA +# ifndef alloca +# ifdef HAVE_ALLOCA_H +# include +# elif defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined(_MSC_VER) +# include +# define alloca _alloca +# elif defined(__WATCOMC__) +# include +# elif defined(__BORLANDC__) +# include +# elif defined(__DMC__) +# include +# elif defined(__AIX__) +# pragma alloca +# elif defined(__MRC__) void *alloca(unsigned); -# else +# else char *alloca(); +# endif # endif #endif @@ -379,7 +381,7 @@ SDL_COMPILE_TIME_ASSERT(enum, sizeof(SDL_DUMMY_ENUM) == sizeof(int)); extern "C" { #endif -#ifdef HAVE_ALLOCA +#ifndef SDL_DISABLE_ALLOCA #define SDL_stack_alloc(type, count) (type*)alloca(sizeof(type)*(count)) #define SDL_stack_free(data) #else diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index 017e06b06..35b5e5857 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -42,6 +42,8 @@ #cmakedefine HAVE_GCC_ATOMICS @HAVE_GCC_ATOMICS@ #cmakedefine HAVE_GCC_SYNC_LOCK_TEST_AND_SET @HAVE_GCC_SYNC_LOCK_TEST_AND_SET@ +#cmakedefine SDL_DISABLE_ALLOCA + /* Comment this if you want to build without any C library requirements */ #cmakedefine HAVE_LIBC 1 #ifdef HAVE_LIBC @@ -74,7 +76,6 @@ #cmakedefine HAVE_CALLOC 1 #cmakedefine HAVE_REALLOC 1 #cmakedefine HAVE_FREE 1 -#cmakedefine HAVE_ALLOCA 1 #ifndef __WIN32__ /* Don't use C runtime versions of these on Windows */ #cmakedefine HAVE_GETENV 1 #cmakedefine HAVE_SETENV 1 diff --git a/include/build_config/SDL_build_config_android.h b/include/build_config/SDL_build_config_android.h index 1f8c3ef8f..99a7ab7de 100644 --- a/include/build_config/SDL_build_config_android.h +++ b/include/build_config/SDL_build_config_android.h @@ -57,7 +57,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_GETENV 1 #define HAVE_SETENV 1 #define HAVE_PUTENV 1 diff --git a/include/build_config/SDL_build_config_emscripten.h b/include/build_config/SDL_build_config_emscripten.h index 2503e98df..afa4e16e1 100644 --- a/include/build_config/SDL_build_config_emscripten.h +++ b/include/build_config/SDL_build_config_emscripten.h @@ -60,7 +60,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_GETENV 1 #define HAVE_SETENV 1 #define HAVE_PUTENV 1 diff --git a/include/build_config/SDL_build_config_ios.h b/include/build_config/SDL_build_config_ios.h index c180ef849..96391f848 100644 --- a/include/build_config/SDL_build_config_ios.h +++ b/include/build_config/SDL_build_config_ios.h @@ -49,7 +49,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_GETENV 1 #define HAVE_SETENV 1 #define HAVE_PUTENV 1 diff --git a/include/build_config/SDL_build_config_macos.h b/include/build_config/SDL_build_config_macos.h index ed3f83a64..43400d3f6 100644 --- a/include/build_config/SDL_build_config_macos.h +++ b/include/build_config/SDL_build_config_macos.h @@ -54,7 +54,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_GETENV 1 #define HAVE_SETENV 1 #define HAVE_PUTENV 1 diff --git a/include/build_config/SDL_build_config_windows.h b/include/build_config/SDL_build_config_windows.h index 8a29bab17..4d7242e5b 100644 --- a/include/build_config/SDL_build_config_windows.h +++ b/include/build_config/SDL_build_config_windows.h @@ -131,7 +131,6 @@ typedef unsigned int uintptr_t; #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_QSORT 1 #define HAVE_BSEARCH 1 #define HAVE_ABS 1 diff --git a/include/build_config/SDL_build_config_wingdk.h b/include/build_config/SDL_build_config_wingdk.h index 47adef506..8d587e555 100644 --- a/include/build_config/SDL_build_config_wingdk.h +++ b/include/build_config/SDL_build_config_wingdk.h @@ -77,7 +77,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_QSORT 1 #define HAVE_BSEARCH 1 #define HAVE_ABS 1 diff --git a/include/build_config/SDL_build_config_winrt.h b/include/build_config/SDL_build_config_winrt.h index 73d467145..bc65ffea2 100644 --- a/include/build_config/SDL_build_config_winrt.h +++ b/include/build_config/SDL_build_config_winrt.h @@ -75,7 +75,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_QSORT 1 #define HAVE_BSEARCH 1 #define HAVE_ABS 1 diff --git a/include/build_config/SDL_build_config_xbox.h b/include/build_config/SDL_build_config_xbox.h index 622a8bc4a..08def0c01 100644 --- a/include/build_config/SDL_build_config_xbox.h +++ b/include/build_config/SDL_build_config_xbox.h @@ -77,7 +77,6 @@ #define HAVE_CALLOC 1 #define HAVE_REALLOC 1 #define HAVE_FREE 1 -#define HAVE_ALLOCA 1 #define HAVE_QSORT 1 #define HAVE_BSEARCH 1 #define HAVE_ABS 1 diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c index 111842754..184b7e2d1 100644 --- a/src/stdlib/SDL_mslibc.c +++ b/src/stdlib/SDL_mslibc.c @@ -696,8 +696,80 @@ RETZERO: /* *INDENT-ON* */ } +void __declspec(naked) _chkstk(void) +{ + __asm { + push ecx + mov ecx,esp ; lea ecx,dword ptr [esp]+4 + add ecx,4 + sub ecx,eax + sbb eax,eax + not eax + and ecx,eax + mov eax,esp + and eax,0xfffff000 +L1: + cmp ecx,eax + jb short L2 + mov eax,ecx + pop ecx + xchg esp,eax + mov eax,dword ptr [eax] + mov dword ptr [esp],eax + ret +L2: + sub eax,0x1000 + test dword ptr [eax],eax + jmp short L1 + } +} + +void __declspec(naked) _alloca_probe_8(void) +{ + /* *INDENT-OFF* */ + __asm { + push ecx + mov ecx,esp ; lea ecx,dword ptr [esp]+8 + add ecx,8 + sub ecx,eax + and ecx,0x7 + add eax,ecx + sbb ecx,ecx + or eax,ecx + pop ecx + jmp _chkstk + } + /* *INDENT-ON* */ +} + +void __declspec(naked) _alloca_probe_16(void) +{ + /* *INDENT-OFF* */ + __asm { + push ecx + mov ecx,esp ; lea ecx,dword ptr [esp]+8 + add ecx,8 + sub ecx,eax + and ecx,0xf + add eax,ecx + sbb ecx,ecx + or eax,ecx + pop ecx + jmp _chkstk + } + /* *INDENT-ON* */ +} + #endif /* _M_IX86 */ +#ifdef _M_ARM64 + +void __chkstk(void); +void __chkstk() { +} + +#endif + #endif /* MSC_VER */ #ifdef __ICL diff --git a/src/stdlib/SDL_mslibc_x64.asm b/src/stdlib/SDL_mslibc_x64.asm new file mode 100644 index 000000000..1590d88ae --- /dev/null +++ b/src/stdlib/SDL_mslibc_x64.asm @@ -0,0 +1,29 @@ +include ksamd64.inc + +text SEGMENT EXECUTE + +public __chkstk + +__chkstk: + sub rsp,010h + mov QWORD PTR [rsp],r10 + mov QWORD PTR [rsp+08h],r11 + xor r11,r11 + lea r10,[rsp+018h] + sub r10,rax + cmovb r10,r11 + mov r11,QWORD PTR gs:[TeStackLimit] + cmp r10,r11 + jae chkstk_finish + and r10w,0f000h +chkstk_loop: + lea r11,[r11-PAGE_SIZE] + mov BYTE PTR [r11],0h + cmp r10,r11 + jne chkstk_loop +chkstk_finish: + mov r10,QWORD PTR [rsp] + mov r11,QWORD PTR [rsp+08h] + add rsp,010h + ret +end