The main motivation here is to unify the build configuration. This primarily impacts GCC MinGW, since Clang already defaults to using SSE. Additionally, downstream projects like Proton and CrossOver already use `-mfpmath=sse`.
This does slightly change the compatibility requirements, we now assume SSE support. That’s unlikely to be an issue today, but for those who need it, the behavior can still be overridden via `CROSSCFLAGS`. If needed, we could also add a `--disable-sse` configure option to make this easier to control.
From: Jacek Caban jacek@codeweavers.com
--- configure.ac | 1 + 1 file changed, 1 insertion(+)
diff --git a/configure.ac b/configure.ac index 79513e7b8d4..876ae1b0e53 100644 --- a/configure.ac +++ b/configure.ac @@ -579,6 +579,7 @@ This is an error since --enable-archs=$wine_arch was requested.])]) case $wine_arch in i386) WINE_TRY_PE_CFLAGS([-fno-omit-frame-pointer]) WINE_TRY_PE_CFLAGS([-mpreferred-stack-boundary=2]) + WINE_TRY_PE_CFLAGS([-msse -mfpmath=sse]) WINE_TRY_PE_CFLAGS([-Wl,--disable-stdcall-fixup], [AS_VAR_APPEND([${wine_arch}_LDFLAGS],[" -Wl,--disable-stdcall-fixup"])]) ;; x86_64) WINE_TRY_PE_CFLAGS([-Wformat-overflow])
FWIW I have an example of game (Re-Volt) which depends on ddraw.dll having x87 math. A game has a bug leaking x87 FP stack (same on Windows), which is mitigated by some (inessential in game context) viewport_activate() call (it is probably the same between implementation that setting a viewport does some amount of math operation). Which call hits the overflow instead of game and saves critical operations in game code from that. Proton was building 32 bit dlls as sse2 since start and this way it was discovered.
Is it maybe possible to keep select dlls as x87? (I only know about such issue with ddraw)
On Wed Jul 2 17:20:59 2025 +0000, Paul Gofman wrote:
FWIW I have an example of game (Re-Volt) which depends on ddraw.dll having x87 math. A game has a bug leaking x87 FP stack (same on Windows), which is mitigated by some (inessential in game context) viewport_activate() call (it is probably the same between implementation that setting a viewport does some amount of math operation). Which call hits the overflow instead of game and saves critical operations in game code from that. Proton was building 32 bit dlls as sse2 since start and this way it was discovered. Is it maybe possible to keep select dlls as x87? (I only know about such issue with ddraw)
Is the game calling into ddraw with a nonempty x87 stack? That not legal under stdcall abi.
But it wouldn't be the first time some random app violates the ABI rules.
In my opinion, it'd make more sense to keep math as SSE, and explicitly clear the x87 stack with asm at some select entry points. For example something like ``` fstsw ax again: test ax, 0x3800 je done fstp st(0) add ax, 0x0800 jmp again done: ```
On Wed Jul 2 17:20:59 2025 +0000, Alfred Agrell wrote:
Is the game calling into ddraw with a nonempty x87 stack? That not legal under stdcall abi. But it wouldn't be the first time some random app violates the ABI rules. In my opinion, it'd make more sense to keep math as SSE, and explicitly clear the x87 stack with asm at some select entry points. For example something like
fstsw ax again: test ax, 0x3800 je done fstp st(0) add ax, 0x0800 jmp again done:
I don't think such a hack, explicitly clearing FP stack in every function, is a good solution. Besides, I doubt this is one single game with single problem, some other may break elsewise (e. g., setting x87 state which will influence some math but only if x87 is used).
So I am wondering if we can keep some select dlls as x87 as needed.
On Wed Jul 2 17:23:44 2025 +0000, Paul Gofman wrote:
I don't think such a hack, explicitly clearing FP stack in every function, is a good solution. Besides, I doubt this is one single game with single problem, some other may break elsewise (e. g., setting x87 state which will influence some math but only if x87 is used). So I am wondering if we can keep some select dlls as x87 as needed.
I'm not sure what the best solution is. We could introduce a mechanism to specify the FP mode for selected modules, but technically there's no guarantee the result will be correct if we're called with an invalid x87 stack state. Maybe we could just use `fninit` (preserving the control word, if needed) in specific cases.
Do you remember if the Re-Volt issue was tied to a particular piece of functionality? I can’t reproduce it. The game runs fine and I can enter a race with SSE math enabled (tested with both GCC and Clang builds). Maybe the issue has been fixed in the game itself?
On Thu Jul 3 14:26:07 2025 +0000, Jacek Caban wrote:
I'm not sure what the best solution is. We could introduce a mechanism to specify the FP mode for selected modules, but technically there's no guarantee the result will be correct if we're called with an invalid x87 stack state. Maybe we could just use `fninit` (preserving the control word, if needed) in specific cases. Do you remember if the Re-Volt issue was tied to a particular piece of functionality? I can’t reproduce it. The game runs fine and I can enter a race with SSE math enabled (tested with both GCC and Clang builds). Maybe the issue has been fixed in the game itself?
I just checked Re-Volt from Steam (Steam iD 287310) with Proton with forcing x87 reverted and reproduced the issue: right on start it will show "Failed to set viewport" message box and refused to start (still works fine with x87 ddraw.dll).
Of course this specific issue with this specific game (which does a very rare and weird bug and works by chance only on Windows) can we worked around elsewise in some way. But I am afraid this is just a particular case. The most obvious one is that x87 fpu control word (which apps may set through msvcrt or directly) will stop affecting Wine dlls and, instead, sse2 control word (which apps may also set in a different way) will start affecting those.
ddraw specifically can have FPU setup / FPU preserve mode (controlled by a flag during d3d device creation). Note currently _FPUPreserve functions will save / setup default / restore x87 word (see d3d_fpu_setup). If that will stop using x87 at very least that FPU setup should be switched to saving / restore SSE state? And there is the mode without FPU setup, now it is affected with x87 word but will start be affected with sse.
Also, is the similar avoided in 32 bit msvcrt math anyhow?
The main motivation here is to unify the build configuration. This primarily impacts GCC MinGW, since Clang already defaults to using SSE.
Overall, doesn't it look like the right thing that 32 bit dlls using x87 on Windows and potentially dependent on that use the same on Wine. If the goal is to unify configuration, maybe we can instead make clang build x87? Or indeed have a way to override in some dlls (in Proton it is currently done only for ddraw with gcc-specific pragma).
On Thu Jul 3 18:21:34 2025 +0000, Paul Gofman wrote:
The main motivation here is to unify the build configuration. This
primarily impacts GCC MinGW, since Clang already defaults to using SSE. Overall, doesn't it look like the right thing that 32 bit dlls using x87 on Windows and potentially dependent on that use the same on Wine. If the goal is to unify configuration, maybe we can instead make clang build x87? Or indeed have a way to override in some dlls (in Proton it is currently done only for ddraw with gcc-specific pragma).
Yeah, it looks like we should aim to use x87 math instead. Closing for now, let's leave it up to packagers for the time being.
One reason for downstream to avoid x87 is that it's more tricky for CPU emulation, it hurts the performance on Rosetta. Hopefully it won't be an issue with wow-based emulation.
This merge request was closed by Jacek Caban.