Browse Source

SDL_mslibc: Implement _ftoul2_legacy()

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.
nmlgc 6 days ago
parent
commit
f39e49a3dd
1 changed files with 33 additions and 0 deletions
  1. 33 0
      src/stdlib/SDL_mslibc.c

+ 33 - 0
src/stdlib/SDL_mslibc.c

@@ -95,6 +95,39 @@ void _ftol2()
     _ftol();
     _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
 // 64-bit math operators for 32-bit systems
 void __declspec(naked) _allmul()
 void __declspec(naked) _allmul()
 {
 {