https://gcc.gnu.org/g:b246ed50fbc1114f13bc67893fa7dc2e324b3b7c

commit r17-5487-gb246ed50fbc1114f13bc67893fa7dc2e324b3b7c
Author: Peter Damianov <[email protected]>
Date:   Wed Oct 21 18:09:32 2026 -0500

    mingw: Make -mpc32, -mpc64 and -mpc80 work
    
    On other x86 targets, -mpc32, -mpc64 and -mpc80 link crtprec32.o,
    crtprec64.o or crtprec80.o, whose constructor sets the x87 precision
    control.  The mingw-w64 targets accept the options but link nothing for
    them, so the options have no effect.
    
    The mingw-w64 runtime already chooses the x87 precision at link time.
    Program startup and fesetenv (FE_DFL_ENV) call _fpreset, and the
    _fpreset that is linked decides the precision: CRT_fp4.o sets 24 bits,
    CRT_fp8.o 53 bits and CRT_fp10.o 64 bits.  CRT_fp10.o is also in
    libmingw32.a, so it is the default.
    
    Link CRT_fp4.o, CRT_fp8.o or CRT_fp10.o for -mpc32, -mpc64 or -mpc80.
    They go in STARTFILE_SPEC so that they come before libmingw32.a.
    
    A DLL does not call _fpreset when it is loaded, so loading a DLL built
    with these options does not change the precision.  Only
    fesetenv (FE_DFL_ENV) called from the DLL uses it.
    
    Unlike on Linux, a new thread on Windows does not inherit the x87
    control word of the thread that created it.  Threads created with
    pthread_create still get the setting, because winpthreads passes the
    creating thread's floating-point environment to new threads.  Threads
    created with CreateThread or _beginthreadex start with the Windows
    default of 53-bit precision, as with MSVC.  Document this.
    
    gcc/ChangeLog:
    
            * config/i386/mingw-w64.h (STARTFILE_SPEC): Link CRT_fp4.o,
            CRT_fp8.o or CRT_fp10.o for -mpc32, -mpc64 or -mpc80.
            * doc/invoke.texi (x86 Options): Describe -mpc32, -mpc64 and
            -mpc80 on MinGW targets.
    
    Signed-off-by: Peter Damianov <[email protected]>
    Signed-off-by: Jonathan Yong <[email protected]>

Diff:
---
 gcc/config/i386/mingw-w64.h | 7 +++++++
 gcc/doc/invoke.texi         | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/gcc/config/i386/mingw-w64.h b/gcc/config/i386/mingw-w64.h
index 5d71aa5358fe..7cd5e31b1029 100644
--- a/gcc/config/i386/mingw-w64.h
+++ b/gcc/config/i386/mingw-w64.h
@@ -49,12 +49,19 @@ along with GCC; see the file COPYING3.  If not see
    -lmingwex %{!mcrtdll=*:-lmsvcrt} %{mcrtdll=*:-l%*} \
    -lkernel32 " MCFGTHREAD_SPEC
 
+/* For -mpc32, -mpc64 and -mpc80, link the mingw-w64 runtime's CRT_fp4.o,
+   CRT_fp8.o or CRT_fp10.o.  Each provides an _fpreset that sets the x87
+   precision; the CRT calls it at startup and from fesetenv (FE_DFL_ENV).
+   They must come before libmingw32.a, which contains CRT_fp10.o.  */
 #undef STARTFILE_SPEC
 #define STARTFILE_SPEC "%{shared|mdll:dllcrt2%O%s} \
   %{!shared:%{!mdll:%{!municode:crt2%O%s}}} \
   %{!shared:%{!mdll:%{municode:crt2u%O%s}}} \
   %{pg:gcrt2%O%s} \
   crtbegin.o%s \
+  %{mpc32:CRT_fp4.o%s} \
+  %{mpc64:CRT_fp8.o%s} \
+  %{mpc80:CRT_fp10.o%s} \
   %{fvtable-verify=none:%s; \
     fvtable-verify=preinit:vtv_start.o%s; \
     fvtable-verify=std:vtv_start.o%s}"
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 66d80f17e740..0e3ef3813534 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -36679,6 +36679,13 @@ are enabled by default; routines in such libraries 
could suffer significant
 loss of accuracy, typically through so-called ``catastrophic cancellation'',
 when this option is used to set the precision to less than extended precision.
 
+On MinGW targets, the precision is set when the program starts and is
+restored by @code{fesetenv (FE_DFL_ENV)}.  Threads created with
+@code{pthread_create} inherit it from the creating thread, but threads
+created with @code{CreateThread} or @code{_beginthreadex} start with the
+Windows default of 53-bit precision.  Loading a DLL built with these
+options does not change the precision.
+
 @opindex mdaz-ftz
 @opindex mno-daz-ftz
 @item -mdaz-ftz

Reply via email to