--- /dev/null
+/*
+ * CRT_fenv.c
+ *
+ * Specifies the default FPU configuration, in terms of one of the
+ * predefined floating point environments defined in <fenv.h>, via
+ * a global variable assignment, whence the specified selection will
+ * be copied to FE_DFL_ENV at application start-up.
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
+ * Copyright (C) 2017, MinGW.org Project.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * This file replaces the two original files CRT_fp8.c, and CRT_fp10.c;
+ * compile it using each of the two commands:
+ *
+ * gcc -c -D_CRT_FE_DFL_ENV=8 CRT_fenv.c -o CRT_fp8.o
+ * gcc -c -D_CRT_FE_DFL_ENV=10 CRT_fenv.c -o CRT_fp10.o
+ *
+ * to create the complementary pair of object files, reproducing the
+ * intended effect of the original similarly named object file pair.
+ *
+ */
+#include <fenv.h>
+
+#ifndef _CRT_FE_DFL_ENV
+/* If the user neglects to specify this, assume that the intention is
+ * to reproduce, in FE_DFL_ENV, the effect of the original CRT_fp10.o
+ * object file.
+ */
+# define _CRT_FE_DFL_ENV 10
+#endif
+
+/* Initialize the "_CRT_fenv" global variable, based on compile time
+ * selection, to map FE_DFL_ENV to FE_PC53_env, (precision configured
+ * to 53-bits), or to FE_PC64_ENV, (precision configured to 64-bits),
+ * via initial FPU configuration to FE_PD53_ENV, (precision default
+ * 53-bits), or FE_PD64_ENV, (precision default 64-bits).
+ */
+const fenv_t *_CRT_fenv = (_CRT_FE_DFL_ENV == 8) ? FE_PD53_ENV : FE_PD64_ENV;
+
+/* $RCSfile$: end of file */
+++ /dev/null
-/*
- * CRT_FP10.c
- *
- * This defines _fpreset as asm ("fnint"). Calls to _fpreset
- * will set default floating point precesion to 64-bit mantissa
- * at app startup.
- *
- * Linking in CRT_FP10.o before libmingw.a will override the definition
- * set in CRT_FP8.o.
- */
-
-/* Override library _fpreset() with asm fninit */
-void _fpreset (void)
- { __asm__ ( "fninit" ) ;}
-
-#if defined(__PCC__)
-void _Pragma("alias _fpreset") fpreset(void);
-#else
-void __attribute__ ((alias ("_fpreset"))) fpreset(void);
-#endif
+++ /dev/null
-/*
- * CRT_FP8.c
- *
- * This forces calls of _fpreset to the MSVCRT function
- * exported from dll. Effectively it make default
- * precison same as apps built with MSVC (53-bit mantissa).
-
- *
- * To change to 64-bit mantissa, link in CRT_FP10.o before libmingw.a.
- */
-
-/* Link against the _fpreset visible in import lib */
-
-extern void (*_imp___fpreset)(void) ;
-void _fpreset (void)
-{ (*_imp___fpreset)(); }
-
-#if defined(__PCC__)
-void _Pragma("alias _fpreset") fpreset(void);
-#else
-void __attribute__ ((alias ("_fpreset"))) fpreset(void);
-#endif
+2017-02-24 Keith Marshall <keithmarshall@users.sourceforge.net>
+
+ Make floating point environment more robust.
+
+ * CRT_fp8.c CRT_fp10.c: Delete them; both are replaced by...
+ * CRT_fenv.c: ...this new common source file; it implements...
+ (_CRT_fenv): ...this new global variable, with alternative definitions
+ evaluated during application start-up, to assign one or other of...
+ [FE_PC53_ENV, FE_PC64_ENV]: ...these, as the preferred default...
+ [FE_DFL_ENV]: ...represented by this; replacement linkage for...
+ (_fpreset): ...this MSVCRT.DLL function is no longer supported.
+
+ * Makefile.in: Add new static pattern rule, for compiling...
+ (CRT_fp8.$OBJEXT, CRT_fp10.$OBJEXT): ...each of these, from CRT_env.c
+
+ * crt1.c (_gnu_exception_handler, __mingw_CRTStartup): Do not call...
+ (_fpreset): ...this; its linkage was non-deterministically ambiguous.
+ (fesetenv): Use this, unambiguously, instead; initially configure the
+ floating point environment to the predefined state, as assigned to...
+ [_CRT_fenv]: ...this new global variable; thereafter, reset to...
+ [FE_DFL_ENV]: ...this ISO-C99 mandatory configuration.
+
+ * include/float.h: Assert copyright; tidy layout.
+ [_MINGW_FLOAT_H_]: Retain, but replace in guard macro usage by...
+ [_MINGW_FLOAT_H]: ...this, conforming to preferred naming convention.
+ [_BEGIN_C_DECLS, _END_C_DECLS]: Use them, as appropriate.
+ (_fpreset): Add _CRTIMP attribute; it is resolved by MSVCRT.DLL
+ (fpreset): Deprecate it; provide inline __LIBIMPL__ fall-back.
+
+ * include/fenv.h: Assert copyright; tidy layout.
+ [_FENV_H_]: Rename multiple inclusion guard macro, adopting...
+ [_FENV_H]: ...this preferred stylistic naming convention.
+ [_BEGIN_C_DECLS, _END_C_DECLS]: Use them, as appropriate.
+ (FE_INVALID, FE_DENORMAL, FE_DIVBYZERO, FE_OVERFLOW, FE_UNDERFLOW)
+ (FE_INEXACT, FE_ALL_EXCEPT, FE_TONEAREST, FE_DOWNWARD, FE_UPWARD)
+ (FE_TOWARDZERO): Redefine them, in terms of enumerated bit positions.
+ (FE_PD53_ENV, FE_PD64_ENV): New predefined environment selectors; they
+ serve as initialization-time aliases, causing redefinition of...
+ [FE_DFL_ENV]: ...this, as run-time alias for one or other of...
+ [FE_PC53_ENV, FE_PC64_ENV]: ...these, respectively.
+
+ * mingwex/fesetenv.c: Assert copyright; tidy layout.
+ (fesetenv) [FE_PD53_ENV || FE_PD64_ENV]: Handle them, assigning to...
+ (FE_DFL_ENV): ...this ISO-C99 mandatory configuration, representing...
+ (fenv_default): ...the value of this new static variable.
+ (_fpreset): Call it directly; now always resolved by MSVCRT.DLL, so...
+ (*_imp__fpreset): ...this indirection becomes unnecessary.
+
2017-02-21 Keith Marshall <keithmarshall@users.sourceforge.net>
Make mingwrt and w32api test suites consistent.
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D__CRTDLL__ -o $@ $<
# ...while, for the current build case, we need an explicit mapping
-# to identify the disparately named source file.
+# to identify the disparately named source file...
#
$(addsuffix .$(OBJEXT), crt2 dllcrt2): %2.$(OBJEXT): %1.c
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $<
+# ...and for the pair of default FPU configuration selectors, we
+# need to pass the configuration specification to the compiler, when
+# compiling the common source for each of the two cases.
+#
+CRT_fp8.$(OBJEXT) CRT_fp10.$(OBJEXT): CRT_fp%.$(OBJEXT): CRT_fenv.c
+ $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D_CRT_FE_DFL_ENV=$* -o $@ $<
+
# The initialization hook for profiling code is inherited from Cygwin,
# where it is built as gcrt0.$(OBJEXT); we build it, unmodified, as each
# of gcrt1.$(OBJEXT) and gcrt2.$(OBJEXT), to satisfy the differing GCC
/*
* crt1.c
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is a part of the mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within the package.
*
- * Source code for the startup proceedures used by all programs. This code
- * is compiled to make crt1.o, which should be located in the library path.
+ * Source code for the startup procedures used by all programs. This
+ * code is compiled to crt1.o, which is located in the library path.
+ *
+ * $Id$
+ *
+ * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * Copyright (C) 1997, 1999, 2002-2007, 2009, 2010, 2014, 2016,
+ * 2017, MinGW.org Project.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
- */
-
-/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
- * avoid problems with older GCC.
*/
#define __IN_MINGW_RUNTIME
+/* Hide the declaration of _fmode(), with its dllimport attribute in
+ * <stdlib.h>, to avoid problems with older GCC.
+ */
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <process.h>
-#include <float.h>
+#include <fenv.h>
+
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <signal.h>
#endif
void _mingw32_init_mainargs()
-{
- /* This is the old start-up mechanism, in which we use a start-up
+{ /* This is the old start-up mechanism, in which we use a start-up
* hook provided by Microsoft's runtime library to initialize the
* argument and environment vectors.
*
# define _CRT_GLOB_OPT _CRT_glob & __CRT_GLOB_USE_MSVCRT__
# ifdef __MSVCRT__
- /* The MSVCRT.DLL start-up hook requires this invocation
- * protocol...
- */
- _startupinfo start_info = { 0 };
- __getmainargs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT, &start_info );
+ /* The MSVCRT.DLL start-up hook requires this invocation
+ * protocol...
+ */
+ _startupinfo start_info = { 0 };
+ __getmainargs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT, &start_info );
# else
- /* ...while a somewhat simpler protocol is applicable, in
- * the case of the CRTDLL.DLL version.
- */
- __GetMainArgs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT );
+ /* ...while a somewhat simpler protocol is applicable, in
+ * the case of the CRTDLL.DLL version.
+ */
+ __GetMainArgs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT );
# endif
}
extern int* __p__fmode(void); /* To access the dll _fmode */
#endif
-/*
- * Setup the default file handles to have the _CRT_fmode mode, as well as
- * any new files created by the user.
+/* Setup the default file handles to have the _CRT_fmode mode,
+ * as well as any new files created by the user.
*/
extern int _CRT_fmode;
static void
_mingw32_init_fmode (void)
-{
- /* Don't set the std file mode if the user hasn't set any value for it.
+{ /* Don't set the std file mode if the user hasn't set any
+ * value for it.
*/
if (_CRT_fmode)
{
/* Now sync the dll _fmode to the one for this .exe.
*/
# ifdef __MSVCRT__
- *__p__fmode() = _fmode;
+ *__p__fmode() = _fmode;
# else
- *_imp___fmode_dll = _fmode;
+ *_imp___fmode_dll = _fmode;
# endif
}
int reset_fpu = 0;
switch (exception_data->ExceptionRecord->ExceptionCode)
- {
+ {
case EXCEPTION_ACCESS_VIOLATION:
- /* test if the user has set SIGSEGV */
+ /* Test if the user has set SIGSEGV
+ */
old_handler = signal (SIGSEGV, SIG_DFL);
if (old_handler == SIG_IGN)
- {
- /* this is undefined if the signal was raised by anything other
- than raise (). */
- signal (SIGSEGV, SIG_IGN);
- action = EXCEPTION_CONTINUE_EXECUTION;
- }
+ { /* This is undefined if the signal was raised by
+ * anything other than raise()
+ */
+ signal (SIGSEGV, SIG_IGN);
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ }
else if (old_handler != SIG_DFL)
- {
- /* This means 'old' is a user defined function. Call it */
- (*old_handler) (SIGSEGV);
- action = EXCEPTION_CONTINUE_EXECUTION;
- }
+ { /* This means 'old_handler' is a user defined
+ * function. Call it
+ */
+ (*old_handler) (SIGSEGV);
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ }
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_PRIV_INSTRUCTION:
- /* test if the user has set SIGILL */
+ /* Test if the user has set SIGILL
+ */
old_handler = signal (SIGILL, SIG_DFL);
if (old_handler == SIG_IGN)
- {
- /* this is undefined if the signal was raised by anything other
- than raise (). */
- signal (SIGILL, SIG_IGN);
- action = EXCEPTION_CONTINUE_EXECUTION;
- }
+ { /* This is undefined if the signal was raised by
+ * anything other than raise()
+ */
+ signal (SIGILL, SIG_IGN);
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ }
else if (old_handler != SIG_DFL)
- {
- /* This means 'old' is a user defined function. Call it */
- (*old_handler) (SIGILL);
- action = EXCEPTION_CONTINUE_EXECUTION;
- }
+ { /* This means 'old_handler' is a user defined
+ * function. Call it
+ */
+ (*old_handler) (SIGILL);
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ }
break;
case EXCEPTION_FLT_INVALID_OPERATION:
/* fall through. */
case EXCEPTION_INT_DIVIDE_BY_ZERO:
- /* test if the user has set SIGFPE */
+ /* Test if the user has set SIGFPE
+ */
old_handler = signal (SIGFPE, SIG_DFL);
if (old_handler == SIG_IGN)
- {
- signal (SIGFPE, SIG_IGN);
- if (reset_fpu)
- _fpreset ();
- action = EXCEPTION_CONTINUE_EXECUTION;
- }
+ {
+ signal (SIGFPE, SIG_IGN);
+ if (reset_fpu)
+ fesetenv (FE_DFL_ENV);
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ }
else if (old_handler != SIG_DFL)
- {
- /* This means 'old' is a user defined function. Call it */
- (*old_handler) (SIGFPE);
- action = EXCEPTION_CONTINUE_EXECUTION;
- }
- break;
-
- default:
- break;
- }
+ { /* This means 'old_handler' is a user defined
+ * function. Call it
+ */
+ (*old_handler) (SIGFPE);
+ action = EXCEPTION_CONTINUE_EXECUTION;
+ }
+ }
return action;
}
-/* The function mainCRTStartup is the entry point for all console programs.
+/* During application start-up, we establish the default configuration
+ * for the FPU. MSVCRT.DLL provides the _fpreset() function to perform
+ * the appropriate initialization, but it sets the default operation to
+ * be in IEEE-754 8-byte mode, whereas we prefer IEEE-754 10-byte mode,
+ * to better support GCC's 10-byte long doubles; nevertheless, we offer
+ * the option, via the _CRT_fenv global variable, to establish either
+ * one of these modes as initial default, it should be set to either
+ * FE_PD64_ENV, (defined in <fenv.h>, reflecting the 64-bit precision
+ * of the 10-byte mode, and established as default for _CRT_fenv within
+ * the runtime library), or overridden by a setting of FE_PD53_ENV, in
+ * user code, like this:
+ *
+ * #include <fenv.h>
+ * const fenv_t *_CRT_fenv = FE_PD53_ENV;
+ *
+ * (or by linking with CRT_fp8.o), to select the 53-bit precision of
+ * the 8-byte mode.
+ *
+ * Whichever of these assignments, i.e. FE_PD64_ENV or FE_PD53_ENV, is
+ * in effect when the following __mingw_CRTStartup() function is invoked,
+ * will cause FE_DFL_ENV to be mapped to one or other of the predefined
+ * environments, FE_PC64_ENV or FE_PC53_ENV, respectively.
+ */
+extern const fenv_t *_CRT_fenv;
+
+/* The function mainCRTStartup(), (defined below), is the entry point
+ * for all console programs, it is, primarily, a wrapper around the
+ * following __mingw_CRTStartup() helper function.
*/
-static void __MINGW_ATTRIB_NORETURN
-__mingw_CRTStartup (void)
+static __MINGW_ATTRIB_NORETURN void __mingw_CRTStartup (void)
{
int nRet;
*/
SetUnhandledExceptionFilter (_gnu_exception_handler);
- /* Initialize floating point unit.
+ /* Initialize the floating point unit.
*/
- __cpu_features_init (); /* Do we have SSE, etc.*/
- _fpreset (); /* Supplied by the runtime library. */
+ __cpu_features_init (); /* Do we have SSE, etc. */
+ fesetenv (_CRT_fenv); /* Supplied by the runtime library. */
/* Set up __argc, __argv and _environ.
*/
_setargv ();
- /* Sets the default file mode.
- * If _CRT_fmode is set, also set mode for stdin, stdout
- * and stderr, as well
- * NOTE: DLLs don't do this because that would be rude!
+ /* Set the default file mode. If _CRT_fmode is set, also set mode
+ * for stdin, stdout and stderr, as well. NOTE: DLLs don't do this
+ * because that would be rude!
*/
_mingw32_init_fmode ();
*/
asm __volatile__ ("andl $-16, %%esp" : : : "%esp");
- /* From libgcc.a, __main calls global class constructors via
- __do_global_ctors, This in turn registers __do_global_dtors
- as the first entry of the app's atexit table. We do this
- explicitly at app startup rather than rely on gcc to generate
- the call in main's prologue, since main may be imported from a dll
- which has its own __do_global_ctors. */
- __main ();
+ /* From libgcc.a, __main() calls global class constructors via
+ * __do_global_ctors(); this in turn registers __do_global_dtors()
+ * as the first entry of the application's atexit() table. We do
+ * this explicitly at application startup rather than rely on GCC
+ * to generate the call in main()'s prologue, since main() may be
+ * imported from a DLL which has its own __do_global_ctors()
+ */
+ __main ();
- /* Call the main function. If the user does not supply one
+ /* Call the main() function. If the user does not supply one
* the one in the 'libmingw32.a' library will be linked in, and
- * that one calls WinMain. See main.c in the 'lib' dir
+ * that one calls WinMain(). See main.c in the 'lib' directory
* for more details.
*/
nRet = main (_argc, _argv, environ);
- /* Perform exit processing for the C library. This means
- * flushing output and calling 'atexit' registered functions.
+ /* Perform exit processing for the C library. This means flushing
+ * output and calling atexit() registered functions.
*/
_cexit ();
ExitProcess (nRet);
}
-/*
- * The function mainCRTStartup is the entry point for all console programs.
+/* The function mainCRTStartup() is the entry point for all console
+ * programs.
*/
void
mainCRTStartup (void)
__mingw_CRTStartup ();
}
-/*
- * For now the GUI startup function is the same as the console one.
+/* For now the GUI startup function is the same as the console one.
* This simply gets rid of the annoying warning about not being able
* to find WinMainCRTStartup when linking GUI applications.
*/
__mingw_CRTStartup ();
}
-/*
- * We force use of library version of atexit, which is only
- * visible in import lib as _imp__atexit
+/* We force use of library version of atexit(), which is only
+ * visible in import lib as _imp__atexit
*/
extern int (*_imp__atexit)(void (*)(void));
-int atexit (void (* pfn )(void) )
-{
- return ( (*_imp__atexit)(pfn));
-}
+int atexit (void (* pfn )(void)){ return (*_imp__atexit)(pfn); }
-/* Likewise for non-ANSI _onexit */
+/* Likewise for non-ANSI _onexit()
+ */
extern _onexit_t (*_imp___onexit)(_onexit_t);
-_onexit_t
-_onexit (_onexit_t pfn )
-{
- return (*_imp___onexit)(pfn);
-}
+_onexit_t _onexit (_onexit_t pfn){ return (*_imp___onexit)(pfn); }
+
+/* $RCSfile$: end of file */
-#ifndef _FENV_H_
-#define _FENV_H_
-
+/*
+ * fenv.h
+ *
+ * Structures and constants defining, and functions for management of,
+ * the floating point environment.
+ *
+ * $Id$
+ *
+ * Written by Danny Smith <dannysmith@users.sourceforge.net>
+ * Copyright (C) 2002, 2003, 2005-2007, 2017, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+#ifndef _FENV_H
+#pragma GCC system_header
+#define _FENV_H
+
+/* All MinGW headers are required to include <_mingw.h>
+ */
#include <_mingw.h>
-/* FPU status word exception flags */
-#define FE_INVALID 0x01
-#define FE_DENORMAL 0x02
-#define FE_DIVBYZERO 0x04
-#define FE_OVERFLOW 0x08
-#define FE_UNDERFLOW 0x10
-#define FE_INEXACT 0x20
-#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \
- | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT)
-
-/* FPU control word rounding flags */
-#define FE_TONEAREST 0x0000
-#define FE_DOWNWARD 0x0400
-#define FE_UPWARD 0x0800
-#define FE_TOWARDZERO 0x0c00
-
-/* The MXCSR exception flags are the same as the
- FE flags. */
-#define __MXCSR_EXCEPT_FLAG_SHIFT 0
-
-/* How much to shift FE status word exception flags
- to get the MXCSR exeptions masks, */
-#define __MXCSR_EXCEPT_MASK_SHIFT 7
-
-/* How much to shift FE control word rounding flags
- to get MXCSR rounding flags, */
-#define __MXCSR_ROUND_FLAG_SHIFT 3
+/* FPU status word flags indicating exceptions. Each is represented
+ * by a single bit, sequentially and contiguously assigned to the low
+ * order bits of the status word, enumerated from lowest:
+ */
+enum
+{ __FE_INVALID_EXCEPT_FLAG_SHIFT,
+ __FE_DENORMAL_EXCEPT_FLAG_SHIFT,
+ __FE_DIVBYZERO_EXCEPT_FLAG_SHIFT,
+ __FE_OVERFLOW_EXCEPT_FLAG_SHIFT,
+ __FE_UNDERFLOW_EXCEPT_FLAG_SHIFT,
+ __FE_INEXACT_EXCEPT_FLAG_SHIFT,
+
+ /* The final entry in the shift enumeration represents the order
+ * of the rightmost bit which does NOT represent an exception flag;
+ * we use it as a high water mark, for generation of the aggregate
+ * mask for ALL exception flags; arithmetically, this becomes the
+ * numeric value of a pseudo-flag placed at the high water mark,
+ * less one.
+ */
+ __FE_ALL_EXCEPT_HWM_SHIFT
+# define FE_ALL_EXCEPT ((0x01 << __FE_ALL_EXCEPT_HWM_SHIFT) - 1)
+};
+
+#define __FE_EXCEPT(__NAME__) (0x01 << __FE_##__NAME__##_EXCEPT_FLAG_SHIFT)
+
+#define FE_INVALID __FE_EXCEPT(INVALID)
+#define FE_DENORMAL __FE_EXCEPT(DENORMAL)
+#define FE_DIVBYZERO __FE_EXCEPT(DIVBYZERO)
+#define FE_OVERFLOW __FE_EXCEPT(OVERFLOW)
+#define FE_UNDERFLOW __FE_EXCEPT(UNDERFLOW)
+#define FE_INEXACT __FE_EXCEPT(INEXACT)
+
+/* FPU control word flags to specify rounding mode; this may be
+ * represented as a selection from a four-way enumeration...
+ */
+enum
+{ __FE_ROUND_TONEAREST,
+ __FE_ROUND_DOWNWARD,
+ __FE_ROUND_UPWARD,
+ __FE_ROUND_TOWARDZERO
+};
+/* ...with the actual flag bits offset 10-bits from the rightmost
+ * bit in the control word; hence, the rounding mode macros become:
+ */
+#define __FE_ROUND(__MODE__) (__FE_ROUND_##__MODE__ << 10)
+
+#define FE_TONEAREST __FE_ROUND(TONEAREST)
+#define FE_DOWNWARD __FE_ROUND(DOWNWARD)
+#define FE_UPWARD __FE_ROUND(UPWARD)
+#define FE_TOWARDZERO __FE_ROUND(TOWARDZERO)
+
+/* The MXCSR exception flags are the same as those for the FPU...
+ */
+#define __MXCSR_EXCEPT_FLAG_SHIFT 0
+
+/* ...and the corresponding mask bits are offset by a further 7-bit
+ * shift to the left...
+ */
+#define __MXCSR_EXCEPT_MASK_SHIFT 7
+
+/* ...while the MXCSR rounding mode flags adopt the same enumeration,
+ * but are offset a further 3-bits to the left of those representing
+ * the FPU rounding mode selection flags.
+ */
+#define __MXCSR_ROUND_FLAG_SHIFT 3
#ifndef RC_INVOKED
-/*
- For now, support only for the basic abstraction of flags that are
- either set or clear. fexcept_t could be structure that holds more
- info about the fp environment.
-*/
+/* For now, support only for the basic abstraction of flags that are
+ * either set or clear; fexcept_t could be a structure that holds more
+ * info about the fp environment.
+ */
typedef unsigned short fexcept_t;
-/* This 32-byte struct represents the entire floating point
- environment as stored by fnstenv or fstenv, augmented by
- the contents of the MXCSR register, as stored by stmxcsr
- (if CPU supports it). */
-typedef struct
-{
- unsigned short __control_word;
- unsigned short __unused0;
- unsigned short __status_word;
- unsigned short __unused1;
- unsigned short __tag_word;
- unsigned short __unused2;
- unsigned int __ip_offset; /* instruction pointer offset */
- unsigned short __ip_selector;
- unsigned short __opcode;
- unsigned int __data_offset;
- unsigned short __data_selector;
- unsigned short __unused3;
- unsigned int __mxcsr; /* contents of the MXCSR register */
+typedef struct __fenv_t
+{ /* This 28-byte structure represents the entire floating point
+ * environment of the FPU, as stored by either the "fnstenv", or
+ * the "fstenv" instruction.
+ */
+ unsigned short __control_word;
+ unsigned short __unused0;
+ unsigned short __status_word;
+ unsigned short __unused1;
+ unsigned short __tag_word;
+ unsigned short __unused2;
+ unsigned int __ip_offset; /* instruction pointer offset */
+ unsigned short __ip_selector;
+ unsigned short __opcode;
+ unsigned int __data_offset;
+ unsigned short __data_selector;
+ unsigned short __unused3;
+
+ /* The structure is extended, beyond the 28 byte requirement to
+ * store the FPU state, by 4 additional bytes, which then makes it
+ * sufficient to also store the contents of the MXCSR register, as
+ * stored by the "stmxcsr" instruction, (if the CPU supports it).
+ */
+ unsigned int __mxcsr; /* content of the MXCSR register */
} fenv_t;
-
-/*The C99 standard (7.6.9) allows us to define implementation-specific macros for
- different fp environments */
-
-/* The default Intel x87 floating point environment (64-bit mantissa) */
-#define FE_PC64_ENV ((const fenv_t *)-1)
-
-/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */
-#define FE_PC53_ENV ((const fenv_t *)-2)
-
-/* The FE_DFL_ENV macro is required by standard.
- fesetenv will use the environment set at app startup.*/
-#define FE_DFL_ENV ((const fenv_t *) 0)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
+/* The ISO-C99 standard, section 7.6 paragraph 8 requires us to define
+ * the FE_DFL_ENV macro; it specifies restoration of the FPU environment
+ * to its default state, as established at application start-up.
+ */
+#define FE_DFL_ENV ((const fenv_t *)(0))
+
+/* Paragraph 9 of the same section of ISO-C99 provides for the definition
+ * of implementation-specific macros to identify alternative predefined
+ * FPU environment configuration; we exploit this licence to offer:
+ *
+ * FP_PC64_ENV -- Intel standard 80-bit (64-bit precision); this is
+ * consistent with IEEE-754 extended precision, and
+ * the configuration preferred by MinGW, because it
+ * matches the format of GCC's 80-bit long doubles.
+ *
+ * FP_PC53_ENV -- IEEE-754 64-bit (53-bit precision); consistent
+ * with Microsoft's preferred FPU configuration;
+ * (they offer no better than 64-bit long doubles).
+ */
+#define FE_PC64_ENV ((const fenv_t *)(-1))
+#define FE_PC53_ENV ((const fenv_t *)(-2))
+
+/* The following pair of additional predefined environment macros serve
+ * as aliases for the preceding pair, respectively, with the added side
+ * effect that, when passed to fesetenv(), each causes its respective
+ * alias to become associated with FE_DFL_ENV in subsequent calls.
+ */
+#define FE_PD64_ENV ((const fenv_t *)(-3))
+#define FE_PD53_ENV ((const fenv_t *)(-4))
+
+_BEGIN_C_DECLS
/*TODO: Some of these could be inlined */
-/* 7.6.2 Exception */
-
-extern int __cdecl __MINGW_NOTHROW feclearexcept (int);
-extern int __cdecl __MINGW_NOTHROW fegetexceptflag (fexcept_t * flagp, int excepts);
-extern int __cdecl __MINGW_NOTHROW feraiseexcept (int excepts );
-extern int __cdecl __MINGW_NOTHROW fesetexceptflag (const fexcept_t *, int);
-extern int __cdecl __MINGW_NOTHROW fetestexcept (int excepts);
-
-/* 7.6.3 Rounding */
-
-extern int __cdecl __MINGW_NOTHROW fegetround (void);
-extern int __cdecl __MINGW_NOTHROW fesetround (int mode);
-
-/* 7.6.4 Environment */
-
-extern int __cdecl __MINGW_NOTHROW fegetenv (fenv_t * envp);
-extern int __cdecl __MINGW_NOTHROW fesetenv (const fenv_t * );
-extern int __cdecl __MINGW_NOTHROW feupdateenv (const fenv_t *);
-extern int __cdecl __MINGW_NOTHROW feholdexcept (fenv_t *);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* Not RC_INVOKED */
-#endif /* ndef _FENV_H */
+/* ISO-C99 section 7.6.2 -- Floating Point Exception Handling
+ */
+extern __cdecl __MINGW_NOTHROW int feclearexcept (int);
+extern __cdecl __MINGW_NOTHROW int fegetexceptflag (fexcept_t *, int);
+extern __cdecl __MINGW_NOTHROW int feraiseexcept (int);
+extern __cdecl __MINGW_NOTHROW int fesetexceptflag (const fexcept_t *, int);
+extern __cdecl __MINGW_NOTHROW int fetestexcept (int);
+
+/* ISO-C99 section 7.6.3 -- Floating Point Rounding Mode Control
+ */
+extern __cdecl __MINGW_NOTHROW int fegetround (void);
+extern __cdecl __MINGW_NOTHROW int fesetround (int);
+
+/* ISO-C99 section 7.6.4 -- Floating Point Environment Configuration
+ */
+extern __cdecl __MINGW_NOTHROW int fegetenv (fenv_t *);
+extern __cdecl __MINGW_NOTHROW int fesetenv (const fenv_t *);
+extern __cdecl __MINGW_NOTHROW int feupdateenv (const fenv_t *);
+extern __cdecl __MINGW_NOTHROW int feholdexcept (fenv_t *);
+
+_END_C_DECLS
+
+#endif /* ! RC_INVOKED */
+#endif /* !_FENV_H: $RCSfile$: end of file */
-#ifndef _MINGW_FLOAT_H_
/*
* float.h
*
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is a part of the mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within the package.
+ * Constants related to floating point arithmetic. Also included here are
+ * some non-ANSI mechanisms for accessing the floating point controller.
*
- * Constants related to floating point arithmetic.
+ * $Id$
*
- * Also included here are some non-ANSI bits for accessing the floating
- * point controller.
+ * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * Copyright (C) 1997, 1999-2005, 2007, 2010, 2011, 2017, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
*
*/
-#define _MINGW_FLOAT_H_
+#ifndef _MINGW_FLOAT_H
+#pragma GCC system_header
+#define _MINGW_FLOAT_H
/*
* NOTE:
*
* In a MinGW standard Win32 hosted environment, this should be the float.h
* found by a system include path search, but this can't be guaranteed; for
* a cross-compiler setup, the GCC-supplied header, which is guarded by the
- * _FLOAT_H___ macro, may be found first, thus...
+ * _FLOAT_H___ macro, may be found first, thus, except when compiling any
+ * __LIBIMPL__ stub...
*
*/
#if !defined(_FLOAT_H___) && !defined(__FLOAT_H)
-
- /*
- * ...when we didn't find the GCC-supplied header first, we want to pull
+ /* ...when we didn't find the GCC-supplied header first, we want to pull
* it in now; include_next should achieve this, (and we must rely on the
* GCC header maintainers to extend us the same courtesy, to get this one
* pulled in, when the GCC-supplied header is found first).
- *
*/
-# include_next <float.h>
+# define _MINGW_FLOAT_H_ 1 /* GCC's <float.h> needs to see this */
+# include_next <float.h> /* !__CRT_ALIAS __LIBIMPL__( FUNCTION = fpreset ) */
#endif
-/* All the headers include this file. */
+/* All MinGW headers are required to include <_mingw.h>
+ */
#include <_mingw.h>
-/*
- * Functions and definitions for controlling the FPU.
+/* Functions and definitions for controlling the FPU.
*/
-#ifndef __STRICT_ANSI__
+#ifndef __STRICT_ANSI__
/* TODO: These constants are only valid for x86 machines */
-/* Control word masks for unMask */
-#define _MCW_EM 0x0008001F /* Error masks */
-#define _MCW_IC 0x00040000 /* Infinity */
-#define _MCW_RC 0x00000300 /* Rounding */
-#define _MCW_PC 0x00030000 /* Precision */
-
-/* Control word values for unNew (use with related unMask above) */
-#define _EM_INVALID 0x00000010
-#define _EM_DENORMAL 0x00080000
-#define _EM_ZERODIVIDE 0x00000008
-#define _EM_OVERFLOW 0x00000004
-#define _EM_UNDERFLOW 0x00000002
-#define _EM_INEXACT 0x00000001
-#define _IC_AFFINE 0x00040000
-#define _IC_PROJECTIVE 0x00000000
-#define _RC_CHOP 0x00000300
-#define _RC_UP 0x00000200
-#define _RC_DOWN 0x00000100
-#define _RC_NEAR 0x00000000
-#define _PC_24 0x00020000
-#define _PC_53 0x00010000
-#define _PC_64 0x00000000
-
-/* These are also defined in Mingw math.h, needed to work around
- GCC build issues. */
-/* Return values for fpclass. */
+/* Control word masks for unMask
+ */
+#define _MCW_EM 0x0008001F /* Error masks */
+#define _MCW_IC 0x00040000 /* Infinity */
+#define _MCW_RC 0x00000300 /* Rounding */
+#define _MCW_PC 0x00030000 /* Precision */
+
+/* Control word values for unNew (use with related unMask above)
+ */
+#define _EM_INVALID 0x00000010
+#define _EM_DENORMAL 0x00080000
+#define _EM_ZERODIVIDE 0x00000008
+#define _EM_OVERFLOW 0x00000004
+#define _EM_UNDERFLOW 0x00000002
+#define _EM_INEXACT 0x00000001
+#define _IC_AFFINE 0x00040000
+#define _IC_PROJECTIVE 0x00000000
+#define _RC_CHOP 0x00000300
+#define _RC_UP 0x00000200
+#define _RC_DOWN 0x00000100
+#define _RC_NEAR 0x00000000
+#define _PC_24 0x00020000
+#define _PC_53 0x00010000
+#define _PC_64 0x00000000
+
#ifndef __MINGW_FPCLASS_DEFINED
-#define __MINGW_FPCLASS_DEFINED 1
-#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
-#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
-#define _FPCLASS_NINF 0x0004 /* Negative Infinity */
-#define _FPCLASS_NN 0x0008 /* Negative Normal */
-#define _FPCLASS_ND 0x0010 /* Negative Denormal */
-#define _FPCLASS_NZ 0x0020 /* Negative Zero */
-#define _FPCLASS_PZ 0x0040 /* Positive Zero */
-#define _FPCLASS_PD 0x0080 /* Positive Denormal */
-#define _FPCLASS_PN 0x0100 /* Positive Normal */
-#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
+#define __MINGW_FPCLASS_DEFINED 1
+/* These are also defined in MinGW <math.h>; these duplicates are
+ * needed here, to work around GCC build issues. FIXME: we should
+ * be able to factor this, at least to avoid any potential for the
+ * introduction of inconsistent definitions.
+ *
+ *
+ * Return values for fpclass.
+ */
+#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
+#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
+#define _FPCLASS_NINF 0x0004 /* Negative Infinity */
+#define _FPCLASS_NN 0x0008 /* Negative Normal */
+#define _FPCLASS_ND 0x0010 /* Negative Denormal */
+#define _FPCLASS_NZ 0x0020 /* Negative Zero */
+#define _FPCLASS_PZ 0x0040 /* Positive Zero */
+#define _FPCLASS_PD 0x0080 /* Positive Denormal */
+#define _FPCLASS_PN 0x0100 /* Positive Normal */
+#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
+
#endif /* __MINGW_FPCLASS_DEFINED */
-/* invalid subconditions (_SW_INVALID also set) */
-#define _SW_UNEMULATED 0x0040 /* unemulated instruction */
-#define _SW_SQRTNEG 0x0080 /* square root of a neg number */
-#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */
-#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */
-
-/* Floating point error signals and return codes */
-#define _FPE_INVALID 0x81
-#define _FPE_DENORMAL 0x82
-#define _FPE_ZERODIVIDE 0x83
-#define _FPE_OVERFLOW 0x84
-#define _FPE_UNDERFLOW 0x85
-#define _FPE_INEXACT 0x86
-#define _FPE_UNEMULATED 0x87
-#define _FPE_SQRTNEG 0x88
-#define _FPE_STACKOVERFLOW 0x8a
-#define _FPE_STACKUNDERFLOW 0x8b
-#define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */
+/* Invalid subconditions (_SW_INVALID also set)
+ */
+#define _SW_UNEMULATED 0x0040 /* unemulated instruction */
+#define _SW_SQRTNEG 0x0080 /* square root of a neg number */
+#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */
+#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */
+
+/* Floating point error signals and return codes
+ */
+#define _FPE_INVALID 0x81
+#define _FPE_DENORMAL 0x82
+#define _FPE_ZERODIVIDE 0x83
+#define _FPE_OVERFLOW 0x84
+#define _FPE_UNDERFLOW 0x85
+#define _FPE_INEXACT 0x86
+#define _FPE_UNEMULATED 0x87
+#define _FPE_SQRTNEG 0x88
+#define _FPE_STACKOVERFLOW 0x8A
+#define _FPE_STACKUNDERFLOW 0x8B
+#define _FPE_EXPLICITGEN 0x8C /* raise SIGFPE */
#ifndef RC_INVOKED
-#ifdef __cplusplus
-extern "C" {
-#endif
+_BEGIN_C_DECLS
/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask),
* i.e. change the bits in unMask to have the values they have in unNew,
- * leaving other bits unchanged. */
-_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _controlfp (unsigned int unNew, unsigned int unMask);
-_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _control87 (unsigned int unNew, unsigned int unMask);
-
+ * leaving other bits unchanged.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _controlfp (unsigned int unNew, unsigned int unMask);
+_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _control87 (unsigned int unNew, unsigned int unMask);
-_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _clearfp (void); /* Clear the FPU status word */
-_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _statusfp (void); /* Report the FPU status word */
-#define _clear87 _clearfp
-#define _status87 _statusfp
+#define _clear87 _clearfp
+#define _status87 _statusfp
+_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _clearfp (void); /* Clear the FPU status word */
+_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _statusfp (void); /* Report the FPU status word */
-/*
- MSVCRT.dll _fpreset initializes the control register to 0x27f,
- the status register to zero and the tag word to 0FFFFh.
- This differs from asm instruction finit/fninit which set control
- word to 0x37f (64 bit mantissa precison rather than 53 bit).
- By default, the mingw version of _fpreset sets fp control as
- per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when
- building your application.
-*/
-void __cdecl __MINGW_NOTHROW _fpreset (void);
-void __cdecl __MINGW_NOTHROW fpreset (void);
-
-/* Global 'variable' for the current floating point error code. */
-_CRTIMP int * __cdecl __MINGW_NOTHROW __fpecode(void);
-#define _fpecode (*(__fpecode()))
-/*
- * IEEE recommended functions. MS puts them in float.h
- * but they really belong in math.h.
+/* MSVCRT.DLL provides _fpreset() to initialize the FPU; it initializes
+ * the control register to 0x27F, (thus selecting 53-bit precision), the
+ * status register to zero and the tag word to 0FFFFh. This differs from
+ * Intel's default configuration, (as established by the asm instructions
+ * "finit" and "fninit"), which set the control word to 0x37F, (yielding
+ * 64-bit precison rather than 53-bit).
+ *
+ * Nominally, MinGW prefers to configure the FPU for 64-bit precision, as
+ * that is a better fit for support of GCC's 10-byte long doubles. This
+ * was formerly achieved by provision of an alternative implementation of
+ * _fpreset(), intended to be statically linked into MinGW applications,
+ * (with variants enabling 64-bit precision by default, or alternatively,
+ * when the application is explicitly linked with CRT_fp8.o, providing
+ * 53-bit precision instead). Unfortunately, this linking strategy may
+ * lead to non-deterministic ambiguity over which _fpreset() variant is
+ * called, in the event of the call originating in any user implemented,
+ * or third party DLL. Consequently, support for this strategy has been
+ * withdrawn. _fpreset() now ALWAYS refers to the MSVCRT.DLL function,
+ * (and thus ALWAYS selects 53-bit precision); MinGW applications should
+ * now use the ISO-C99 standard fesetenv() function to configure the FPU,
+ * (as the start-up code now does, to enable 64-bit precision by default,
+ * but continuing to support linking with CRT_fp8.o, to initialize the
+ * configuration to 53-bit precision).
*/
+_CRTIMP __cdecl __MINGW_NOTHROW void _fpreset (void);
-_CRTIMP double __cdecl __MINGW_NOTHROW _chgsign (double);
-_CRTIMP double __cdecl __MINGW_NOTHROW _copysign (double, double);
-_CRTIMP double __cdecl __MINGW_NOTHROW _logb (double);
-_CRTIMP double __cdecl __MINGW_NOTHROW _nextafter (double, double);
-_CRTIMP double __cdecl __MINGW_NOTHROW _scalb (double, long);
+/* Former MinGW releases also provided fpreset(), implemented as an alias
+ * for _fpreset(), (in whichever guise it was deployed); deprecate this,
+ * but retain the association for backward compatibility, (noting that it
+ * will now redirect the call to fesetenv(), as recommended above, with
+ * the configuration selection set to FE_DFL_ENV).
+ */
+__cdecl __MINGW_NOTHROW void fpreset (void) __MINGW_ATTRIB_DEPRECATED;
-_CRTIMP int __cdecl __MINGW_NOTHROW _finite (double);
-_CRTIMP int __cdecl __MINGW_NOTHROW _fpclass (double);
-_CRTIMP int __cdecl __MINGW_NOTHROW _isnan (double);
+#ifndef __NO_INLINE__
+/* Provide the implementation of fpreset() as an inline stub; for this,
+ * we need to expose a minimal opaque subset of <fenv.h>, and we assume
+ * that FE_DFL_ENV is equivalent to (const fenv_t *)(0), (as it is, in
+ * the MinGW implementation of <fenv.h>).
+ */
+typedef struct __fenv_t fenv_t;
+__cdecl __MINGW_NOTHROW int fesetenv (const fenv_t *);
-#ifdef __cplusplus
-}
+__CRT_ALIAS __LIBIMPL__( FUNCTION = fpreset )
+void fpreset (void){ fesetenv ((const fenv_t *)(0)); }
#endif
-#endif /* Not RC_INVOKED */
+/* Global 'variable' for the current floating point error code.
+ */
+#define _fpecode (*(__fpecode()))
+_CRTIMP __cdecl __MINGW_NOTHROW int *__fpecode (void);
+
+/* IEEE recommended functions. Microsoft puts them in <float.h>,
+ * but they really belong in math.h.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW double _chgsign (double);
+_CRTIMP __cdecl __MINGW_NOTHROW double _copysign (double, double);
+_CRTIMP __cdecl __MINGW_NOTHROW double _logb (double);
+_CRTIMP __cdecl __MINGW_NOTHROW double _nextafter (double, double);
+_CRTIMP __cdecl __MINGW_NOTHROW double _scalb (double, long);
+
+_CRTIMP __cdecl __MINGW_NOTHROW int _finite (double);
+_CRTIMP __cdecl __MINGW_NOTHROW int _fpclass (double);
+_CRTIMP __cdecl __MINGW_NOTHROW int _isnan (double);
-#endif /* Not __STRICT_ANSI__ */
+_END_C_DECLS
-#endif /* _MINGW_FLOAT_H_ */
+#endif /* ! RC_INVOKED */
+#endif /* !__STRICT_ANSI__ */
+#endif /* _MINGW_FLOAT_H: $RCSfile$: end of file */
+/*
+ * fesetenv.c
+ *
+ * Implements the fesetenv(3) function, per ISO-C99 section 7.6.4.3
+ *
+ * $Id$
+ *
+ * Written by Danny Smith <dannysmith@users.sourceforge.net>
+ * Copyright (C) 2002, 2005, 2006, 2017, MinGW.org Project.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+#define __USE_CRTIMP
+
#include <fenv.h>
#include <float.h>
#include "cpu_features.h"
-/* 7.6.4.3
- The fesetenv function establishes the floating-point environment
- represented by the object pointed to by envp. The argument envp
- points to an object set by a call to fegetenv or feholdexcept, or
- equal the macro FE_DFL_ENV or an implementation-defined environment
- macro. Note that fesetenv merely installs the state of the exception
- flags represented through its argument, and does not raise these
- exceptions.
- */
+int fesetenv( const fenv_t *fenvp )
+{
+ /* Specified by ISO-C99 section 7.6.4.3
+ *
+ * The fesetenv() function establishes the floating-point environment
+ * represented by the object pointed to by "envp". The argument "envp"
+ * points to an object set by a call to fegetenv() or feholdexcept(), or
+ * equals the macro, FE_DFL_ENV, or an implementation-defined environment
+ * macro. Note that fesetenv() merely sets the state of the exception
+ * flags represented through its argument; it does not raise these
+ * exceptions.
+ *
+ *
+ * The following static variable stores the predefined environment
+ * which is associated with FE_DFL_ENV; initialize it to represent
+ * the Intel X87 default configuration.
+ */
+ static const fenv_t *fenv_default = FE_PC64_ENV;
-extern void (*_imp___fpreset)( void ) ;
+ /* Before anything else, establish a default exception handling
+ * policy for SSE instructions, to be used in conjunction with the
+ * predefined FPU state macros, (establishing an effective default
+ * MXCSR status value of 0x1F80, so masking all exceptions, while
+ * leaving all other bits as zero), in the event that SSE support
+ * is available.
+ */
+ unsigned fenv_mxcsr = FE_ALL_EXCEPT << __MXCSR_EXCEPT_MASK_SHIFT;
-int fesetenv (const fenv_t * envp)
-{
- /* Default mxcsr status is to mask all exceptions. All other bits
- are zero. */
-
- unsigned int _csr = FE_ALL_EXCEPT << __MXCSR_EXCEPT_MASK_SHIFT /*= 0x1f80 */;
-
- if (envp == FE_PC64_ENV)
- /*
- * fninit initializes the control register to 0x37f,
- * the status register to zero and the tag word to 0FFFFh.
- * The other registers are unaffected.
- */
- __asm__ ("fninit");
-
- else if (envp == FE_PC53_ENV)
- /*
- * MS _fpreset() does same *except* it sets control word
- * to 0x27f (53-bit precison).
- * We force calling _fpreset in msvcrt.dll
- */
-
- (*_imp___fpreset)();
-
- else if (envp == FE_DFL_ENV)
- /* Use the choice made at app startup */
+ if( fenvp == FE_PD64_ENV )
+ /* This is a request to both initialize the FPU state, to the
+ * FE_PC64_ENV predefined state, and to store that state as the
+ * application default.
+ */
+ fenvp = fenv_default = FE_PC64_ENV;
+
+ else if( fenvp == FE_PD53_ENV )
+ /* Conversely, this requests initialization of FPU state to the
+ * FE_PC53_ENV predefined state, and to store that state as the
+ * new application default.
+ */
+ fenvp = fenv_default = FE_PC53_ENV;
+
+ else if( fenvp == FE_DFL_ENV )
+ /* This simply requests initialization of FPU state to whichever
+ * of the two preceding predefined states has been previously set
+ * as the application default.
+ */
+ fenvp = fenv_default;
+
+ if( fenvp == FE_PC64_ENV )
+ /* The FPU's "fninit" instruction initializes the FPU control
+ * word register to 0x37F, the status register to zero and the
+ * tag word to 0xFFFF. The other registers are unaffected.
+ */
+ __asm__( "fninit" );
+
+ else if( fenvp == FE_PC53_ENV )
+ /* Microsoft's _fpreset() does the same, EXCEPT that it sets
+ * the control word to 0x27F (53-bit precison). Here, we want
+ * to force a call to _fpreset() in MSVCRT.DLL
+ */
_fpreset();
else
- {
- __asm__ ("fldenv %0;" : : "m" (*envp));
- /* Setting the reserved high order bits of MXCSR causes a segfault */
- _csr = envp ->__mxcsr & 0xffff;
- }
+ { /* The requested FPU state is not represented by any of the
+ * predefined state macros; assume it is a properly constructed
+ * fenv_t structure, and load it to the FPU as is.
+ */
+ __asm__( "fldenv %0" :: "m" (*fenvp) );
- /* Set MXCSR */
- if (__HAS_SSE)
- __asm__ volatile ("ldmxcsr %0" : : "m" (_csr));
+ /* Also, in the event that SSE instructions may be supported,
+ * extract the MXCSR flags from this same structure, to be used
+ * instead of the defaults which have been established for use
+ * in conjunction with the predefined state macros, noting that
+ * attempting to set any of the reserved high-order flags will
+ * induce a segmentation fault, so mask them off.
+ */
+ fenv_mxcsr = fenvp->__mxcsr & 0xFFFF;
+ }
+ if( __HAS_SSE )
+ /* Finally, if SSE instructions are supported, set the MXCSR
+ * exception handling policy flags...
+ */
+ __asm__( "ldmxcsr %0" :: "m" (fenv_mxcsr) );
+
+ /* ...and we are done; there is no mechanism for us to detect
+ * failure, so simply return zero, indicating success.
+ */
return 0;
}
+
+/* $RCSfile$: end of file */