fenv: Use MSVC-compatible ABI for fenv.h functions.

Since the current mingw-w64 uses a different layout for fenv_t and constant
values, this changes the ABI.

Based on Wine code by Piotr Caban, Alexandre Julliard and Martin Storsjö, who
granted permission to use it under the mingw-w64 license.

Unlike earlier versions, msvcr120 and UCRT implement fenv.h, but their
representation differs from what mingw-w64 has used so far. fenv_t has a
target-independent layout and flags, requiring translation to and from
machine-specific flags. Generic helpers handle this conversion.

On Windows x86_64, these functions operate only on SSE registers, ignoring x87.
Since mingw long doubles use x87 and some mingw-w64-crt math functions are
implemented in terms of x87, they would be unaffected by these calls. This
patch does not follow that behavior; instead, it modifies x87 registers as well,
effectively following the 32-bit x86 code path.

Additionally, in 32-bit versions older than msvcr71, functions like _control87,
__control87_2, and _statusfp did not support SSE, even though they would
otherwise be useful as helpers. This patch provides variants that operate on
both SSE and x87 for x86 and x86_64 (though we could still consider a different
approach for ARM targets).

I left FE_*_ENV handling unchanged, but we could consider making them proper
pointers to structs filled with the appropriate values instead.

This patch also adds support for ARM64EC. The ARM64EC version currently ignores
x87, as 80-bit long doubles are not supported anyway.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
16 files changed