From f39e49a3ddddbdd1c5903a7639342ec884bf40f9 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Fri, 3 Oct 2025 03:44:04 +0200 Subject: [PATCH] SDL_mslibc: Implement _ftoul2_legacy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cl.exe versions ≥v19.41 call this builtin for double → uint64_t conversions on x86. SDL currently needs such conversions in: * MainCallbackRateHintChanged() * SDL_PrintFloat() * WIN_ApplyWindowProgress() This seems enough to justify implementing this function rather than trying to work around it, as it was done in sdl12-compat: https://github.com/libsdl-org/sdl12-compat/issues/352 This implementation was taken from ReactOS: https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f637e6b809adb5e0ae420ef4f80c73b19172a2e7 Passes the stdlib testautomation, and also matches the behavior of Microsoft's 64-bit libc for the currently implementation-defined case of calling SDL_PrintFloat() with values >SDL_MAX_UINT64. --- src/stdlib/SDL_mslibc.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c index 6698403fe8..1dfc76166b 100644 --- a/src/stdlib/SDL_mslibc.c +++ b/src/stdlib/SDL_mslibc.c @@ -95,6 +95,39 @@ void _ftol2() _ftol(); } +void __declspec(naked) _ftoul2_legacy() +{ + static const Uint64 LLONG_MAX_PLUS_ONE = 0x43e0000000000000ULL; + /* *INDENT-OFF* */ + __asm { + fld qword ptr [LLONG_MAX_PLUS_ONE] + fcom + fnstsw ax + test ah, 41h + jnp greater_than_int64 + + fstp st(0) + jmp _ftol + +greater_than_int64: + fsub st(1), st(0) + fcomp + fnstsw ax + test ah, 41h + jnz greater_than_uint64 + + call _ftol + add edx, 80000000h + ret + +greater_than_uint64: + xor eax, eax + mov edx, 80000000h + ret + } + /* *INDENT-ON* */ +} + // 64-bit math operators for 32-bit systems void __declspec(naked) _allmul() {