The MinGW.org Windows System Libraries
Revisión | 571d98ec8e36bff2636531788d61fe2c3ac490ae (tree) |
---|---|
Tiempo | 2017-02-28 02:46:27 |
Autor | Keith Marshall <keithmarshall@user...> |
Commiter | Keith Marshall |
Make floating point environment more robust.
@@ -0,0 +1,63 @@ | ||
1 | +/* | |
2 | + * CRT_fenv.c | |
3 | + * | |
4 | + * Specifies the default FPU configuration, in terms of one of the | |
5 | + * predefined floating point environments defined in <fenv.h>, via | |
6 | + * a global variable assignment, whence the specified selection will | |
7 | + * be copied to FE_DFL_ENV at application start-up. | |
8 | + * | |
9 | + * $Id$ | |
10 | + * | |
11 | + * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
12 | + * Copyright (C) 2017, MinGW.org Project. | |
13 | + * | |
14 | + * | |
15 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
16 | + * copy of this software and associated documentation files (the "Software"), | |
17 | + * to deal in the Software without restriction, including without limitation | |
18 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
19 | + * and/or sell copies of the Software, and to permit persons to whom the | |
20 | + * Software is furnished to do so, subject to the following conditions: | |
21 | + * | |
22 | + * The above copyright notice, this permission notice, and the following | |
23 | + * disclaimer shall be included in all copies or substantial portions of | |
24 | + * the Software. | |
25 | + * | |
26 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
27 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
28 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
29 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
30 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
31 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER | |
32 | + * DEALINGS IN THE SOFTWARE. | |
33 | + * | |
34 | + * | |
35 | + * This file replaces the two original files CRT_fp8.c, and CRT_fp10.c; | |
36 | + * compile it using each of the two commands: | |
37 | + * | |
38 | + * gcc -c -D_CRT_FE_DFL_ENV=8 CRT_fenv.c -o CRT_fp8.o | |
39 | + * gcc -c -D_CRT_FE_DFL_ENV=10 CRT_fenv.c -o CRT_fp10.o | |
40 | + * | |
41 | + * to create the complementary pair of object files, reproducing the | |
42 | + * intended effect of the original similarly named object file pair. | |
43 | + * | |
44 | + */ | |
45 | +#include <fenv.h> | |
46 | + | |
47 | +#ifndef _CRT_FE_DFL_ENV | |
48 | +/* If the user neglects to specify this, assume that the intention is | |
49 | + * to reproduce, in FE_DFL_ENV, the effect of the original CRT_fp10.o | |
50 | + * object file. | |
51 | + */ | |
52 | +# define _CRT_FE_DFL_ENV 10 | |
53 | +#endif | |
54 | + | |
55 | +/* Initialize the "_CRT_fenv" global variable, based on compile time | |
56 | + * selection, to map FE_DFL_ENV to FE_PC53_env, (precision configured | |
57 | + * to 53-bits), or to FE_PC64_ENV, (precision configured to 64-bits), | |
58 | + * via initial FPU configuration to FE_PD53_ENV, (precision default | |
59 | + * 53-bits), or FE_PD64_ENV, (precision default 64-bits). | |
60 | + */ | |
61 | +const fenv_t *_CRT_fenv = (_CRT_FE_DFL_ENV == 8) ? FE_PD53_ENV : FE_PD64_ENV; | |
62 | + | |
63 | +/* $RCSfile$: end of file */ |
@@ -1,20 +0,0 @@ | ||
1 | -/* | |
2 | - * CRT_FP10.c | |
3 | - * | |
4 | - * This defines _fpreset as asm ("fnint"). Calls to _fpreset | |
5 | - * will set default floating point precesion to 64-bit mantissa | |
6 | - * at app startup. | |
7 | - * | |
8 | - * Linking in CRT_FP10.o before libmingw.a will override the definition | |
9 | - * set in CRT_FP8.o. | |
10 | - */ | |
11 | - | |
12 | -/* Override library _fpreset() with asm fninit */ | |
13 | -void _fpreset (void) | |
14 | - { __asm__ ( "fninit" ) ;} | |
15 | - | |
16 | -#if defined(__PCC__) | |
17 | -void _Pragma("alias _fpreset") fpreset(void); | |
18 | -#else | |
19 | -void __attribute__ ((alias ("_fpreset"))) fpreset(void); | |
20 | -#endif |
@@ -1,22 +0,0 @@ | ||
1 | -/* | |
2 | - * CRT_FP8.c | |
3 | - * | |
4 | - * This forces calls of _fpreset to the MSVCRT function | |
5 | - * exported from dll. Effectively it make default | |
6 | - * precison same as apps built with MSVC (53-bit mantissa). | |
7 | - | |
8 | - * | |
9 | - * To change to 64-bit mantissa, link in CRT_FP10.o before libmingw.a. | |
10 | - */ | |
11 | - | |
12 | -/* Link against the _fpreset visible in import lib */ | |
13 | - | |
14 | -extern void (*_imp___fpreset)(void) ; | |
15 | -void _fpreset (void) | |
16 | -{ (*_imp___fpreset)(); } | |
17 | - | |
18 | -#if defined(__PCC__) | |
19 | -void _Pragma("alias _fpreset") fpreset(void); | |
20 | -#else | |
21 | -void __attribute__ ((alias ("_fpreset"))) fpreset(void); | |
22 | -#endif |
@@ -1,3 +1,51 @@ | ||
1 | +2017-02-24 Keith Marshall <keithmarshall@users.sourceforge.net> | |
2 | + | |
3 | + Make floating point environment more robust. | |
4 | + | |
5 | + * CRT_fp8.c CRT_fp10.c: Delete them; both are replaced by... | |
6 | + * CRT_fenv.c: ...this new common source file; it implements... | |
7 | + (_CRT_fenv): ...this new global variable, with alternative definitions | |
8 | + evaluated during application start-up, to assign one or other of... | |
9 | + [FE_PC53_ENV, FE_PC64_ENV]: ...these, as the preferred default... | |
10 | + [FE_DFL_ENV]: ...represented by this; replacement linkage for... | |
11 | + (_fpreset): ...this MSVCRT.DLL function is no longer supported. | |
12 | + | |
13 | + * Makefile.in: Add new static pattern rule, for compiling... | |
14 | + (CRT_fp8.$OBJEXT, CRT_fp10.$OBJEXT): ...each of these, from CRT_env.c | |
15 | + | |
16 | + * crt1.c (_gnu_exception_handler, __mingw_CRTStartup): Do not call... | |
17 | + (_fpreset): ...this; its linkage was non-deterministically ambiguous. | |
18 | + (fesetenv): Use this, unambiguously, instead; initially configure the | |
19 | + floating point environment to the predefined state, as assigned to... | |
20 | + [_CRT_fenv]: ...this new global variable; thereafter, reset to... | |
21 | + [FE_DFL_ENV]: ...this ISO-C99 mandatory configuration. | |
22 | + | |
23 | + * include/float.h: Assert copyright; tidy layout. | |
24 | + [_MINGW_FLOAT_H_]: Retain, but replace in guard macro usage by... | |
25 | + [_MINGW_FLOAT_H]: ...this, conforming to preferred naming convention. | |
26 | + [_BEGIN_C_DECLS, _END_C_DECLS]: Use them, as appropriate. | |
27 | + (_fpreset): Add _CRTIMP attribute; it is resolved by MSVCRT.DLL | |
28 | + (fpreset): Deprecate it; provide inline __LIBIMPL__ fall-back. | |
29 | + | |
30 | + * include/fenv.h: Assert copyright; tidy layout. | |
31 | + [_FENV_H_]: Rename multiple inclusion guard macro, adopting... | |
32 | + [_FENV_H]: ...this preferred stylistic naming convention. | |
33 | + [_BEGIN_C_DECLS, _END_C_DECLS]: Use them, as appropriate. | |
34 | + (FE_INVALID, FE_DENORMAL, FE_DIVBYZERO, FE_OVERFLOW, FE_UNDERFLOW) | |
35 | + (FE_INEXACT, FE_ALL_EXCEPT, FE_TONEAREST, FE_DOWNWARD, FE_UPWARD) | |
36 | + (FE_TOWARDZERO): Redefine them, in terms of enumerated bit positions. | |
37 | + (FE_PD53_ENV, FE_PD64_ENV): New predefined environment selectors; they | |
38 | + serve as initialization-time aliases, causing redefinition of... | |
39 | + [FE_DFL_ENV]: ...this, as run-time alias for one or other of... | |
40 | + [FE_PC53_ENV, FE_PC64_ENV]: ...these, respectively. | |
41 | + | |
42 | + * mingwex/fesetenv.c: Assert copyright; tidy layout. | |
43 | + (fesetenv) [FE_PD53_ENV || FE_PD64_ENV]: Handle them, assigning to... | |
44 | + (FE_DFL_ENV): ...this ISO-C99 mandatory configuration, representing... | |
45 | + (fenv_default): ...the value of this new static variable. | |
46 | + (_fpreset): Call it directly; now always resolved by MSVCRT.DLL, so... | |
47 | + (*_imp__fpreset): ...this indirection becomes unnecessary. | |
48 | + | |
1 | 49 | 2017-02-21 Keith Marshall <keithmarshall@users.sourceforge.net> |
2 | 50 | |
3 | 51 | Make mingwrt and w32api test suites consistent. |
@@ -236,11 +236,18 @@ $(addsuffix .$(OBJEXT), crt1 dllcrt1): %.$(OBJEXT): %.c | ||
236 | 236 | $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D__CRTDLL__ -o $@ $< |
237 | 237 | |
238 | 238 | # ...while, for the current build case, we need an explicit mapping |
239 | -# to identify the disparately named source file. | |
239 | +# to identify the disparately named source file... | |
240 | 240 | # |
241 | 241 | $(addsuffix .$(OBJEXT), crt2 dllcrt2): %2.$(OBJEXT): %1.c |
242 | 242 | $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -o $@ $< |
243 | 243 | |
244 | +# ...and for the pair of default FPU configuration selectors, we | |
245 | +# need to pass the configuration specification to the compiler, when | |
246 | +# compiling the common source for each of the two cases. | |
247 | +# | |
248 | +CRT_fp8.$(OBJEXT) CRT_fp10.$(OBJEXT): CRT_fp%.$(OBJEXT): CRT_fenv.c | |
249 | + $(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) -D_CRT_FE_DFL_ENV=$* -o $@ $< | |
250 | + | |
244 | 251 | # The initialization hook for profiling code is inherited from Cygwin, |
245 | 252 | # where it is built as gcrt0.$(OBJEXT); we build it, unmodified, as each |
246 | 253 | # of gcrt1.$(OBJEXT) and gcrt2.$(OBJEXT), to satisfy the differing GCC |
@@ -1,23 +1,46 @@ | ||
1 | 1 | /* |
2 | 2 | * crt1.c |
3 | - * This file has no copyright assigned and is placed in the Public Domain. | |
4 | - * This file is a part of the mingw-runtime package. | |
5 | - * No warranty is given; refer to the file DISCLAIMER within the package. | |
6 | 3 | * |
7 | - * Source code for the startup proceedures used by all programs. This code | |
8 | - * is compiled to make crt1.o, which should be located in the library path. | |
4 | + * Source code for the startup procedures used by all programs. This | |
5 | + * code is compiled to crt1.o, which is located in the library path. | |
6 | + * | |
7 | + * $Id$ | |
8 | + * | |
9 | + * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> | |
10 | + * Copyright (C) 1997, 1999, 2002-2007, 2009, 2010, 2014, 2016, | |
11 | + * 2017, MinGW.org Project. | |
12 | + * | |
13 | + * | |
14 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
15 | + * copy of this software and associated documentation files (the "Software"), | |
16 | + * to deal in the Software without restriction, including without limitation | |
17 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
18 | + * and/or sell copies of the Software, and to permit persons to whom the | |
19 | + * Software is furnished to do so, subject to the following conditions: | |
20 | + * | |
21 | + * The above copyright notice, this permission notice, and the following | |
22 | + * disclaimer shall be included in all copies or substantial portions of | |
23 | + * the Software. | |
24 | + * | |
25 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
26 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
27 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
28 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
29 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
30 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER | |
31 | + * DEALINGS IN THE SOFTWARE. | |
9 | 32 | * |
10 | - */ | |
11 | - | |
12 | -/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to | |
13 | - * avoid problems with older GCC. | |
14 | 33 | */ |
15 | 34 | #define __IN_MINGW_RUNTIME |
35 | +/* Hide the declaration of _fmode(), with its dllimport attribute in | |
36 | + * <stdlib.h>, to avoid problems with older GCC. | |
37 | + */ | |
16 | 38 | #include <stdlib.h> |
17 | 39 | #include <stdio.h> |
18 | 40 | #include <io.h> |
19 | 41 | #include <process.h> |
20 | -#include <float.h> | |
42 | +#include <fenv.h> | |
43 | + | |
21 | 44 | #define WIN32_LEAN_AND_MEAN |
22 | 45 | #include <windows.h> |
23 | 46 | #include <signal.h> |
@@ -83,8 +106,7 @@ extern void __GetMainArgs( int *, char ***, char ***, int ); | ||
83 | 106 | #endif |
84 | 107 | |
85 | 108 | void _mingw32_init_mainargs() |
86 | -{ | |
87 | - /* This is the old start-up mechanism, in which we use a start-up | |
109 | +{ /* This is the old start-up mechanism, in which we use a start-up | |
88 | 110 | * hook provided by Microsoft's runtime library to initialize the |
89 | 111 | * argument and environment vectors. |
90 | 112 | * |
@@ -98,17 +120,17 @@ void _mingw32_init_mainargs() | ||
98 | 120 | |
99 | 121 | # define _CRT_GLOB_OPT _CRT_glob & __CRT_GLOB_USE_MSVCRT__ |
100 | 122 | # ifdef __MSVCRT__ |
101 | - /* The MSVCRT.DLL start-up hook requires this invocation | |
102 | - * protocol... | |
103 | - */ | |
104 | - _startupinfo start_info = { 0 }; | |
105 | - __getmainargs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT, &start_info ); | |
123 | + /* The MSVCRT.DLL start-up hook requires this invocation | |
124 | + * protocol... | |
125 | + */ | |
126 | + _startupinfo start_info = { 0 }; | |
127 | + __getmainargs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT, &start_info ); | |
106 | 128 | |
107 | 129 | # else |
108 | - /* ...while a somewhat simpler protocol is applicable, in | |
109 | - * the case of the CRTDLL.DLL version. | |
110 | - */ | |
111 | - __GetMainArgs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT ); | |
130 | + /* ...while a somewhat simpler protocol is applicable, in | |
131 | + * the case of the CRTDLL.DLL version. | |
132 | + */ | |
133 | + __GetMainArgs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT ); | |
112 | 134 | # endif |
113 | 135 | } |
114 | 136 |
@@ -138,16 +160,15 @@ extern int _fmode; | ||
138 | 160 | extern int* __p__fmode(void); /* To access the dll _fmode */ |
139 | 161 | #endif |
140 | 162 | |
141 | -/* | |
142 | - * Setup the default file handles to have the _CRT_fmode mode, as well as | |
143 | - * any new files created by the user. | |
163 | +/* Setup the default file handles to have the _CRT_fmode mode, | |
164 | + * as well as any new files created by the user. | |
144 | 165 | */ |
145 | 166 | extern int _CRT_fmode; |
146 | 167 | |
147 | 168 | static void |
148 | 169 | _mingw32_init_fmode (void) |
149 | -{ | |
150 | - /* Don't set the std file mode if the user hasn't set any value for it. | |
170 | +{ /* Don't set the std file mode if the user hasn't set any | |
171 | + * value for it. | |
151 | 172 | */ |
152 | 173 | if (_CRT_fmode) |
153 | 174 | { |
@@ -167,9 +188,9 @@ _mingw32_init_fmode (void) | ||
167 | 188 | /* Now sync the dll _fmode to the one for this .exe. |
168 | 189 | */ |
169 | 190 | # ifdef __MSVCRT__ |
170 | - *__p__fmode() = _fmode; | |
191 | + *__p__fmode() = _fmode; | |
171 | 192 | # else |
172 | - *_imp___fmode_dll = _fmode; | |
193 | + *_imp___fmode_dll = _fmode; | |
173 | 194 | # endif |
174 | 195 | } |
175 | 196 |
@@ -184,42 +205,46 @@ _gnu_exception_handler (EXCEPTION_POINTERS * exception_data) | ||
184 | 205 | int reset_fpu = 0; |
185 | 206 | |
186 | 207 | switch (exception_data->ExceptionRecord->ExceptionCode) |
187 | - { | |
208 | + { | |
188 | 209 | case EXCEPTION_ACCESS_VIOLATION: |
189 | - /* test if the user has set SIGSEGV */ | |
210 | + /* Test if the user has set SIGSEGV | |
211 | + */ | |
190 | 212 | old_handler = signal (SIGSEGV, SIG_DFL); |
191 | 213 | if (old_handler == SIG_IGN) |
192 | - { | |
193 | - /* this is undefined if the signal was raised by anything other | |
194 | - than raise (). */ | |
195 | - signal (SIGSEGV, SIG_IGN); | |
196 | - action = EXCEPTION_CONTINUE_EXECUTION; | |
197 | - } | |
214 | + { /* This is undefined if the signal was raised by | |
215 | + * anything other than raise() | |
216 | + */ | |
217 | + signal (SIGSEGV, SIG_IGN); | |
218 | + action = EXCEPTION_CONTINUE_EXECUTION; | |
219 | + } | |
198 | 220 | else if (old_handler != SIG_DFL) |
199 | - { | |
200 | - /* This means 'old' is a user defined function. Call it */ | |
201 | - (*old_handler) (SIGSEGV); | |
202 | - action = EXCEPTION_CONTINUE_EXECUTION; | |
203 | - } | |
221 | + { /* This means 'old_handler' is a user defined | |
222 | + * function. Call it | |
223 | + */ | |
224 | + (*old_handler) (SIGSEGV); | |
225 | + action = EXCEPTION_CONTINUE_EXECUTION; | |
226 | + } | |
204 | 227 | break; |
205 | 228 | |
206 | 229 | case EXCEPTION_ILLEGAL_INSTRUCTION: |
207 | 230 | case EXCEPTION_PRIV_INSTRUCTION: |
208 | - /* test if the user has set SIGILL */ | |
231 | + /* Test if the user has set SIGILL | |
232 | + */ | |
209 | 233 | old_handler = signal (SIGILL, SIG_DFL); |
210 | 234 | if (old_handler == SIG_IGN) |
211 | - { | |
212 | - /* this is undefined if the signal was raised by anything other | |
213 | - than raise (). */ | |
214 | - signal (SIGILL, SIG_IGN); | |
215 | - action = EXCEPTION_CONTINUE_EXECUTION; | |
216 | - } | |
235 | + { /* This is undefined if the signal was raised by | |
236 | + * anything other than raise() | |
237 | + */ | |
238 | + signal (SIGILL, SIG_IGN); | |
239 | + action = EXCEPTION_CONTINUE_EXECUTION; | |
240 | + } | |
217 | 241 | else if (old_handler != SIG_DFL) |
218 | - { | |
219 | - /* This means 'old' is a user defined function. Call it */ | |
220 | - (*old_handler) (SIGILL); | |
221 | - action = EXCEPTION_CONTINUE_EXECUTION; | |
222 | - } | |
242 | + { /* This means 'old_handler' is a user defined | |
243 | + * function. Call it | |
244 | + */ | |
245 | + (*old_handler) (SIGILL); | |
246 | + action = EXCEPTION_CONTINUE_EXECUTION; | |
247 | + } | |
223 | 248 | break; |
224 | 249 | |
225 | 250 | case EXCEPTION_FLT_INVALID_OPERATION: |
@@ -232,33 +257,57 @@ _gnu_exception_handler (EXCEPTION_POINTERS * exception_data) | ||
232 | 257 | /* fall through. */ |
233 | 258 | |
234 | 259 | case EXCEPTION_INT_DIVIDE_BY_ZERO: |
235 | - /* test if the user has set SIGFPE */ | |
260 | + /* Test if the user has set SIGFPE | |
261 | + */ | |
236 | 262 | old_handler = signal (SIGFPE, SIG_DFL); |
237 | 263 | if (old_handler == SIG_IGN) |
238 | - { | |
239 | - signal (SIGFPE, SIG_IGN); | |
240 | - if (reset_fpu) | |
241 | - _fpreset (); | |
242 | - action = EXCEPTION_CONTINUE_EXECUTION; | |
243 | - } | |
264 | + { | |
265 | + signal (SIGFPE, SIG_IGN); | |
266 | + if (reset_fpu) | |
267 | + fesetenv (FE_DFL_ENV); | |
268 | + action = EXCEPTION_CONTINUE_EXECUTION; | |
269 | + } | |
244 | 270 | else if (old_handler != SIG_DFL) |
245 | - { | |
246 | - /* This means 'old' is a user defined function. Call it */ | |
247 | - (*old_handler) (SIGFPE); | |
248 | - action = EXCEPTION_CONTINUE_EXECUTION; | |
249 | - } | |
250 | - break; | |
251 | - | |
252 | - default: | |
253 | - break; | |
254 | - } | |
271 | + { /* This means 'old_handler' is a user defined | |
272 | + * function. Call it | |
273 | + */ | |
274 | + (*old_handler) (SIGFPE); | |
275 | + action = EXCEPTION_CONTINUE_EXECUTION; | |
276 | + } | |
277 | + } | |
255 | 278 | return action; |
256 | 279 | } |
257 | 280 | |
258 | -/* The function mainCRTStartup is the entry point for all console programs. | |
281 | +/* During application start-up, we establish the default configuration | |
282 | + * for the FPU. MSVCRT.DLL provides the _fpreset() function to perform | |
283 | + * the appropriate initialization, but it sets the default operation to | |
284 | + * be in IEEE-754 8-byte mode, whereas we prefer IEEE-754 10-byte mode, | |
285 | + * to better support GCC's 10-byte long doubles; nevertheless, we offer | |
286 | + * the option, via the _CRT_fenv global variable, to establish either | |
287 | + * one of these modes as initial default, it should be set to either | |
288 | + * FE_PD64_ENV, (defined in <fenv.h>, reflecting the 64-bit precision | |
289 | + * of the 10-byte mode, and established as default for _CRT_fenv within | |
290 | + * the runtime library), or overridden by a setting of FE_PD53_ENV, in | |
291 | + * user code, like this: | |
292 | + * | |
293 | + * #include <fenv.h> | |
294 | + * const fenv_t *_CRT_fenv = FE_PD53_ENV; | |
295 | + * | |
296 | + * (or by linking with CRT_fp8.o), to select the 53-bit precision of | |
297 | + * the 8-byte mode. | |
298 | + * | |
299 | + * Whichever of these assignments, i.e. FE_PD64_ENV or FE_PD53_ENV, is | |
300 | + * in effect when the following __mingw_CRTStartup() function is invoked, | |
301 | + * will cause FE_DFL_ENV to be mapped to one or other of the predefined | |
302 | + * environments, FE_PC64_ENV or FE_PC53_ENV, respectively. | |
303 | + */ | |
304 | +extern const fenv_t *_CRT_fenv; | |
305 | + | |
306 | +/* The function mainCRTStartup(), (defined below), is the entry point | |
307 | + * for all console programs, it is, primarily, a wrapper around the | |
308 | + * following __mingw_CRTStartup() helper function. | |
259 | 309 | */ |
260 | -static void __MINGW_ATTRIB_NORETURN | |
261 | -__mingw_CRTStartup (void) | |
310 | +static __MINGW_ATTRIB_NORETURN void __mingw_CRTStartup (void) | |
262 | 311 | { |
263 | 312 | int nRet; |
264 | 313 |
@@ -274,19 +323,18 @@ __mingw_CRTStartup (void) | ||
274 | 323 | */ |
275 | 324 | SetUnhandledExceptionFilter (_gnu_exception_handler); |
276 | 325 | |
277 | - /* Initialize floating point unit. | |
326 | + /* Initialize the floating point unit. | |
278 | 327 | */ |
279 | - __cpu_features_init (); /* Do we have SSE, etc.*/ | |
280 | - _fpreset (); /* Supplied by the runtime library. */ | |
328 | + __cpu_features_init (); /* Do we have SSE, etc. */ | |
329 | + fesetenv (_CRT_fenv); /* Supplied by the runtime library. */ | |
281 | 330 | |
282 | 331 | /* Set up __argc, __argv and _environ. |
283 | 332 | */ |
284 | 333 | _setargv (); |
285 | 334 | |
286 | - /* Sets the default file mode. | |
287 | - * If _CRT_fmode is set, also set mode for stdin, stdout | |
288 | - * and stderr, as well | |
289 | - * NOTE: DLLs don't do this because that would be rude! | |
335 | + /* Set the default file mode. If _CRT_fmode is set, also set mode | |
336 | + * for stdin, stdout and stderr, as well. NOTE: DLLs don't do this | |
337 | + * because that would be rude! | |
290 | 338 | */ |
291 | 339 | _mingw32_init_fmode (); |
292 | 340 |
@@ -299,31 +347,32 @@ __mingw_CRTStartup (void) | ||
299 | 347 | */ |
300 | 348 | asm __volatile__ ("andl $-16, %%esp" : : : "%esp"); |
301 | 349 | |
302 | - /* From libgcc.a, __main calls global class constructors via | |
303 | - __do_global_ctors, This in turn registers __do_global_dtors | |
304 | - as the first entry of the app's atexit table. We do this | |
305 | - explicitly at app startup rather than rely on gcc to generate | |
306 | - the call in main's prologue, since main may be imported from a dll | |
307 | - which has its own __do_global_ctors. */ | |
308 | - __main (); | |
350 | + /* From libgcc.a, __main() calls global class constructors via | |
351 | + * __do_global_ctors(); this in turn registers __do_global_dtors() | |
352 | + * as the first entry of the application's atexit() table. We do | |
353 | + * this explicitly at application startup rather than rely on GCC | |
354 | + * to generate the call in main()'s prologue, since main() may be | |
355 | + * imported from a DLL which has its own __do_global_ctors() | |
356 | + */ | |
357 | + __main (); | |
309 | 358 | |
310 | - /* Call the main function. If the user does not supply one | |
359 | + /* Call the main() function. If the user does not supply one | |
311 | 360 | * the one in the 'libmingw32.a' library will be linked in, and |
312 | - * that one calls WinMain. See main.c in the 'lib' dir | |
361 | + * that one calls WinMain(). See main.c in the 'lib' directory | |
313 | 362 | * for more details. |
314 | 363 | */ |
315 | 364 | nRet = main (_argc, _argv, environ); |
316 | 365 | |
317 | - /* Perform exit processing for the C library. This means | |
318 | - * flushing output and calling 'atexit' registered functions. | |
366 | + /* Perform exit processing for the C library. This means flushing | |
367 | + * output and calling atexit() registered functions. | |
319 | 368 | */ |
320 | 369 | _cexit (); |
321 | 370 | |
322 | 371 | ExitProcess (nRet); |
323 | 372 | } |
324 | 373 | |
325 | -/* | |
326 | - * The function mainCRTStartup is the entry point for all console programs. | |
374 | +/* The function mainCRTStartup() is the entry point for all console | |
375 | + * programs. | |
327 | 376 | */ |
328 | 377 | void |
329 | 378 | mainCRTStartup (void) |
@@ -334,8 +383,7 @@ mainCRTStartup (void) | ||
334 | 383 | __mingw_CRTStartup (); |
335 | 384 | } |
336 | 385 | |
337 | -/* | |
338 | - * For now the GUI startup function is the same as the console one. | |
386 | +/* For now the GUI startup function is the same as the console one. | |
339 | 387 | * This simply gets rid of the annoying warning about not being able |
340 | 388 | * to find WinMainCRTStartup when linking GUI applications. |
341 | 389 | */ |
@@ -348,20 +396,15 @@ WinMainCRTStartup (void) | ||
348 | 396 | __mingw_CRTStartup (); |
349 | 397 | } |
350 | 398 | |
351 | -/* | |
352 | - * We force use of library version of atexit, which is only | |
353 | - * visible in import lib as _imp__atexit | |
399 | +/* We force use of library version of atexit(), which is only | |
400 | + * visible in import lib as _imp__atexit | |
354 | 401 | */ |
355 | 402 | extern int (*_imp__atexit)(void (*)(void)); |
356 | -int atexit (void (* pfn )(void) ) | |
357 | -{ | |
358 | - return ( (*_imp__atexit)(pfn)); | |
359 | -} | |
403 | +int atexit (void (* pfn )(void)){ return (*_imp__atexit)(pfn); } | |
360 | 404 | |
361 | -/* Likewise for non-ANSI _onexit */ | |
405 | +/* Likewise for non-ANSI _onexit() | |
406 | + */ | |
362 | 407 | extern _onexit_t (*_imp___onexit)(_onexit_t); |
363 | -_onexit_t | |
364 | -_onexit (_onexit_t pfn ) | |
365 | -{ | |
366 | - return (*_imp___onexit)(pfn); | |
367 | -} | |
408 | +_onexit_t _onexit (_onexit_t pfn){ return (*_imp___onexit)(pfn); } | |
409 | + | |
410 | +/* $RCSfile$: end of file */ |
@@ -1,107 +1,197 @@ | ||
1 | -#ifndef _FENV_H_ | |
2 | -#define _FENV_H_ | |
3 | - | |
1 | +/* | |
2 | + * fenv.h | |
3 | + * | |
4 | + * Structures and constants defining, and functions for management of, | |
5 | + * the floating point environment. | |
6 | + * | |
7 | + * $Id$ | |
8 | + * | |
9 | + * Written by Danny Smith <dannysmith@users.sourceforge.net> | |
10 | + * Copyright (C) 2002, 2003, 2005-2007, 2017, MinGW.org Project | |
11 | + * | |
12 | + * | |
13 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
14 | + * copy of this software and associated documentation files (the "Software"), | |
15 | + * to deal in the Software without restriction, including without limitation | |
16 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
17 | + * and/or sell copies of the Software, and to permit persons to whom the | |
18 | + * Software is furnished to do so, subject to the following conditions: | |
19 | + * | |
20 | + * The above copyright notice, this permission notice, and the following | |
21 | + * disclaimer shall be included in all copies or substantial portions of | |
22 | + * the Software. | |
23 | + * | |
24 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
25 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
26 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
27 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
28 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
29 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER | |
30 | + * DEALINGS IN THE SOFTWARE. | |
31 | + * | |
32 | + */ | |
33 | +#ifndef _FENV_H | |
34 | +#pragma GCC system_header | |
35 | +#define _FENV_H | |
36 | + | |
37 | +/* All MinGW headers are required to include <_mingw.h> | |
38 | + */ | |
4 | 39 | #include <_mingw.h> |
5 | 40 | |
6 | -/* FPU status word exception flags */ | |
7 | -#define FE_INVALID 0x01 | |
8 | -#define FE_DENORMAL 0x02 | |
9 | -#define FE_DIVBYZERO 0x04 | |
10 | -#define FE_OVERFLOW 0x08 | |
11 | -#define FE_UNDERFLOW 0x10 | |
12 | -#define FE_INEXACT 0x20 | |
13 | -#define FE_ALL_EXCEPT (FE_INVALID | FE_DENORMAL | FE_DIVBYZERO \ | |
14 | - | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) | |
15 | - | |
16 | -/* FPU control word rounding flags */ | |
17 | -#define FE_TONEAREST 0x0000 | |
18 | -#define FE_DOWNWARD 0x0400 | |
19 | -#define FE_UPWARD 0x0800 | |
20 | -#define FE_TOWARDZERO 0x0c00 | |
21 | - | |
22 | -/* The MXCSR exception flags are the same as the | |
23 | - FE flags. */ | |
24 | -#define __MXCSR_EXCEPT_FLAG_SHIFT 0 | |
25 | - | |
26 | -/* How much to shift FE status word exception flags | |
27 | - to get the MXCSR exeptions masks, */ | |
28 | -#define __MXCSR_EXCEPT_MASK_SHIFT 7 | |
29 | - | |
30 | -/* How much to shift FE control word rounding flags | |
31 | - to get MXCSR rounding flags, */ | |
32 | -#define __MXCSR_ROUND_FLAG_SHIFT 3 | |
41 | +/* FPU status word flags indicating exceptions. Each is represented | |
42 | + * by a single bit, sequentially and contiguously assigned to the low | |
43 | + * order bits of the status word, enumerated from lowest: | |
44 | + */ | |
45 | +enum | |
46 | +{ __FE_INVALID_EXCEPT_FLAG_SHIFT, | |
47 | + __FE_DENORMAL_EXCEPT_FLAG_SHIFT, | |
48 | + __FE_DIVBYZERO_EXCEPT_FLAG_SHIFT, | |
49 | + __FE_OVERFLOW_EXCEPT_FLAG_SHIFT, | |
50 | + __FE_UNDERFLOW_EXCEPT_FLAG_SHIFT, | |
51 | + __FE_INEXACT_EXCEPT_FLAG_SHIFT, | |
52 | + | |
53 | + /* The final entry in the shift enumeration represents the order | |
54 | + * of the rightmost bit which does NOT represent an exception flag; | |
55 | + * we use it as a high water mark, for generation of the aggregate | |
56 | + * mask for ALL exception flags; arithmetically, this becomes the | |
57 | + * numeric value of a pseudo-flag placed at the high water mark, | |
58 | + * less one. | |
59 | + */ | |
60 | + __FE_ALL_EXCEPT_HWM_SHIFT | |
61 | +# define FE_ALL_EXCEPT ((0x01 << __FE_ALL_EXCEPT_HWM_SHIFT) - 1) | |
62 | +}; | |
63 | + | |
64 | +#define __FE_EXCEPT(__NAME__) (0x01 << __FE_##__NAME__##_EXCEPT_FLAG_SHIFT) | |
65 | + | |
66 | +#define FE_INVALID __FE_EXCEPT(INVALID) | |
67 | +#define FE_DENORMAL __FE_EXCEPT(DENORMAL) | |
68 | +#define FE_DIVBYZERO __FE_EXCEPT(DIVBYZERO) | |
69 | +#define FE_OVERFLOW __FE_EXCEPT(OVERFLOW) | |
70 | +#define FE_UNDERFLOW __FE_EXCEPT(UNDERFLOW) | |
71 | +#define FE_INEXACT __FE_EXCEPT(INEXACT) | |
72 | + | |
73 | +/* FPU control word flags to specify rounding mode; this may be | |
74 | + * represented as a selection from a four-way enumeration... | |
75 | + */ | |
76 | +enum | |
77 | +{ __FE_ROUND_TONEAREST, | |
78 | + __FE_ROUND_DOWNWARD, | |
79 | + __FE_ROUND_UPWARD, | |
80 | + __FE_ROUND_TOWARDZERO | |
81 | +}; | |
82 | +/* ...with the actual flag bits offset 10-bits from the rightmost | |
83 | + * bit in the control word; hence, the rounding mode macros become: | |
84 | + */ | |
85 | +#define __FE_ROUND(__MODE__) (__FE_ROUND_##__MODE__ << 10) | |
86 | + | |
87 | +#define FE_TONEAREST __FE_ROUND(TONEAREST) | |
88 | +#define FE_DOWNWARD __FE_ROUND(DOWNWARD) | |
89 | +#define FE_UPWARD __FE_ROUND(UPWARD) | |
90 | +#define FE_TOWARDZERO __FE_ROUND(TOWARDZERO) | |
91 | + | |
92 | +/* The MXCSR exception flags are the same as those for the FPU... | |
93 | + */ | |
94 | +#define __MXCSR_EXCEPT_FLAG_SHIFT 0 | |
95 | + | |
96 | +/* ...and the corresponding mask bits are offset by a further 7-bit | |
97 | + * shift to the left... | |
98 | + */ | |
99 | +#define __MXCSR_EXCEPT_MASK_SHIFT 7 | |
100 | + | |
101 | +/* ...while the MXCSR rounding mode flags adopt the same enumeration, | |
102 | + * but are offset a further 3-bits to the left of those representing | |
103 | + * the FPU rounding mode selection flags. | |
104 | + */ | |
105 | +#define __MXCSR_ROUND_FLAG_SHIFT 3 | |
33 | 106 | |
34 | 107 | #ifndef RC_INVOKED |
35 | -/* | |
36 | - For now, support only for the basic abstraction of flags that are | |
37 | - either set or clear. fexcept_t could be structure that holds more | |
38 | - info about the fp environment. | |
39 | -*/ | |
108 | +/* For now, support only for the basic abstraction of flags that are | |
109 | + * either set or clear; fexcept_t could be a structure that holds more | |
110 | + * info about the fp environment. | |
111 | + */ | |
40 | 112 | typedef unsigned short fexcept_t; |
41 | 113 | |
42 | -/* This 32-byte struct represents the entire floating point | |
43 | - environment as stored by fnstenv or fstenv, augmented by | |
44 | - the contents of the MXCSR register, as stored by stmxcsr | |
45 | - (if CPU supports it). */ | |
46 | -typedef struct | |
47 | -{ | |
48 | - unsigned short __control_word; | |
49 | - unsigned short __unused0; | |
50 | - unsigned short __status_word; | |
51 | - unsigned short __unused1; | |
52 | - unsigned short __tag_word; | |
53 | - unsigned short __unused2; | |
54 | - unsigned int __ip_offset; /* instruction pointer offset */ | |
55 | - unsigned short __ip_selector; | |
56 | - unsigned short __opcode; | |
57 | - unsigned int __data_offset; | |
58 | - unsigned short __data_selector; | |
59 | - unsigned short __unused3; | |
60 | - unsigned int __mxcsr; /* contents of the MXCSR register */ | |
114 | +typedef struct __fenv_t | |
115 | +{ /* This 28-byte structure represents the entire floating point | |
116 | + * environment of the FPU, as stored by either the "fnstenv", or | |
117 | + * the "fstenv" instruction. | |
118 | + */ | |
119 | + unsigned short __control_word; | |
120 | + unsigned short __unused0; | |
121 | + unsigned short __status_word; | |
122 | + unsigned short __unused1; | |
123 | + unsigned short __tag_word; | |
124 | + unsigned short __unused2; | |
125 | + unsigned int __ip_offset; /* instruction pointer offset */ | |
126 | + unsigned short __ip_selector; | |
127 | + unsigned short __opcode; | |
128 | + unsigned int __data_offset; | |
129 | + unsigned short __data_selector; | |
130 | + unsigned short __unused3; | |
131 | + | |
132 | + /* The structure is extended, beyond the 28 byte requirement to | |
133 | + * store the FPU state, by 4 additional bytes, which then makes it | |
134 | + * sufficient to also store the contents of the MXCSR register, as | |
135 | + * stored by the "stmxcsr" instruction, (if the CPU supports it). | |
136 | + */ | |
137 | + unsigned int __mxcsr; /* content of the MXCSR register */ | |
61 | 138 | } fenv_t; |
62 | 139 | |
63 | - | |
64 | -/*The C99 standard (7.6.9) allows us to define implementation-specific macros for | |
65 | - different fp environments */ | |
66 | - | |
67 | -/* The default Intel x87 floating point environment (64-bit mantissa) */ | |
68 | -#define FE_PC64_ENV ((const fenv_t *)-1) | |
69 | - | |
70 | -/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */ | |
71 | -#define FE_PC53_ENV ((const fenv_t *)-2) | |
72 | - | |
73 | -/* The FE_DFL_ENV macro is required by standard. | |
74 | - fesetenv will use the environment set at app startup.*/ | |
75 | -#define FE_DFL_ENV ((const fenv_t *) 0) | |
76 | - | |
77 | -#ifdef __cplusplus | |
78 | -extern "C" { | |
79 | -#endif | |
140 | +/* The ISO-C99 standard, section 7.6 paragraph 8 requires us to define | |
141 | + * the FE_DFL_ENV macro; it specifies restoration of the FPU environment | |
142 | + * to its default state, as established at application start-up. | |
143 | + */ | |
144 | +#define FE_DFL_ENV ((const fenv_t *)(0)) | |
145 | + | |
146 | +/* Paragraph 9 of the same section of ISO-C99 provides for the definition | |
147 | + * of implementation-specific macros to identify alternative predefined | |
148 | + * FPU environment configuration; we exploit this licence to offer: | |
149 | + * | |
150 | + * FP_PC64_ENV -- Intel standard 80-bit (64-bit precision); this is | |
151 | + * consistent with IEEE-754 extended precision, and | |
152 | + * the configuration preferred by MinGW, because it | |
153 | + * matches the format of GCC's 80-bit long doubles. | |
154 | + * | |
155 | + * FP_PC53_ENV -- IEEE-754 64-bit (53-bit precision); consistent | |
156 | + * with Microsoft's preferred FPU configuration; | |
157 | + * (they offer no better than 64-bit long doubles). | |
158 | + */ | |
159 | +#define FE_PC64_ENV ((const fenv_t *)(-1)) | |
160 | +#define FE_PC53_ENV ((const fenv_t *)(-2)) | |
161 | + | |
162 | +/* The following pair of additional predefined environment macros serve | |
163 | + * as aliases for the preceding pair, respectively, with the added side | |
164 | + * effect that, when passed to fesetenv(), each causes its respective | |
165 | + * alias to become associated with FE_DFL_ENV in subsequent calls. | |
166 | + */ | |
167 | +#define FE_PD64_ENV ((const fenv_t *)(-3)) | |
168 | +#define FE_PD53_ENV ((const fenv_t *)(-4)) | |
169 | + | |
170 | +_BEGIN_C_DECLS | |
80 | 171 | |
81 | 172 | /*TODO: Some of these could be inlined */ |
82 | -/* 7.6.2 Exception */ | |
83 | - | |
84 | -extern int __cdecl __MINGW_NOTHROW feclearexcept (int); | |
85 | -extern int __cdecl __MINGW_NOTHROW fegetexceptflag (fexcept_t * flagp, int excepts); | |
86 | -extern int __cdecl __MINGW_NOTHROW feraiseexcept (int excepts ); | |
87 | -extern int __cdecl __MINGW_NOTHROW fesetexceptflag (const fexcept_t *, int); | |
88 | -extern int __cdecl __MINGW_NOTHROW fetestexcept (int excepts); | |
89 | - | |
90 | -/* 7.6.3 Rounding */ | |
91 | - | |
92 | -extern int __cdecl __MINGW_NOTHROW fegetround (void); | |
93 | -extern int __cdecl __MINGW_NOTHROW fesetround (int mode); | |
94 | - | |
95 | -/* 7.6.4 Environment */ | |
96 | - | |
97 | -extern int __cdecl __MINGW_NOTHROW fegetenv (fenv_t * envp); | |
98 | -extern int __cdecl __MINGW_NOTHROW fesetenv (const fenv_t * ); | |
99 | -extern int __cdecl __MINGW_NOTHROW feupdateenv (const fenv_t *); | |
100 | -extern int __cdecl __MINGW_NOTHROW feholdexcept (fenv_t *); | |
101 | - | |
102 | -#ifdef __cplusplus | |
103 | -} | |
104 | -#endif | |
105 | -#endif /* Not RC_INVOKED */ | |
106 | 173 | |
107 | -#endif /* ndef _FENV_H */ | |
174 | +/* ISO-C99 section 7.6.2 -- Floating Point Exception Handling | |
175 | + */ | |
176 | +extern __cdecl __MINGW_NOTHROW int feclearexcept (int); | |
177 | +extern __cdecl __MINGW_NOTHROW int fegetexceptflag (fexcept_t *, int); | |
178 | +extern __cdecl __MINGW_NOTHROW int feraiseexcept (int); | |
179 | +extern __cdecl __MINGW_NOTHROW int fesetexceptflag (const fexcept_t *, int); | |
180 | +extern __cdecl __MINGW_NOTHROW int fetestexcept (int); | |
181 | + | |
182 | +/* ISO-C99 section 7.6.3 -- Floating Point Rounding Mode Control | |
183 | + */ | |
184 | +extern __cdecl __MINGW_NOTHROW int fegetround (void); | |
185 | +extern __cdecl __MINGW_NOTHROW int fesetround (int); | |
186 | + | |
187 | +/* ISO-C99 section 7.6.4 -- Floating Point Environment Configuration | |
188 | + */ | |
189 | +extern __cdecl __MINGW_NOTHROW int fegetenv (fenv_t *); | |
190 | +extern __cdecl __MINGW_NOTHROW int fesetenv (const fenv_t *); | |
191 | +extern __cdecl __MINGW_NOTHROW int feupdateenv (const fenv_t *); | |
192 | +extern __cdecl __MINGW_NOTHROW int feholdexcept (fenv_t *); | |
193 | + | |
194 | +_END_C_DECLS | |
195 | + | |
196 | +#endif /* ! RC_INVOKED */ | |
197 | +#endif /* !_FENV_H: $RCSfile$: end of file */ |
@@ -1,18 +1,38 @@ | ||
1 | -#ifndef _MINGW_FLOAT_H_ | |
2 | 1 | /* |
3 | 2 | * float.h |
4 | 3 | * |
5 | - * This file has no copyright assigned and is placed in the Public Domain. | |
6 | - * This file is a part of the mingw-runtime package. | |
7 | - * No warranty is given; refer to the file DISCLAIMER within the package. | |
4 | + * Constants related to floating point arithmetic. Also included here are | |
5 | + * some non-ANSI mechanisms for accessing the floating point controller. | |
8 | 6 | * |
9 | - * Constants related to floating point arithmetic. | |
7 | + * $Id$ | |
10 | 8 | * |
11 | - * Also included here are some non-ANSI bits for accessing the floating | |
12 | - * point controller. | |
9 | + * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp> | |
10 | + * Copyright (C) 1997, 1999-2005, 2007, 2010, 2011, 2017, MinGW.org Project | |
11 | + * | |
12 | + * | |
13 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
14 | + * copy of this software and associated documentation files (the "Software"), | |
15 | + * to deal in the Software without restriction, including without limitation | |
16 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
17 | + * and/or sell copies of the Software, and to permit persons to whom the | |
18 | + * Software is furnished to do so, subject to the following conditions: | |
19 | + * | |
20 | + * The above copyright notice, this permission notice, and the following | |
21 | + * disclaimer shall be included in all copies or substantial portions of | |
22 | + * the Software. | |
23 | + * | |
24 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
25 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
26 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
27 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
28 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
29 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER | |
30 | + * DEALINGS IN THE SOFTWARE. | |
13 | 31 | * |
14 | 32 | */ |
15 | -#define _MINGW_FLOAT_H_ | |
33 | +#ifndef _MINGW_FLOAT_H | |
34 | +#pragma GCC system_header | |
35 | +#define _MINGW_FLOAT_H | |
16 | 36 | /* |
17 | 37 | * NOTE: |
18 | 38 | * |
@@ -23,147 +43,185 @@ | ||
23 | 43 | * In a MinGW standard Win32 hosted environment, this should be the float.h |
24 | 44 | * found by a system include path search, but this can't be guaranteed; for |
25 | 45 | * a cross-compiler setup, the GCC-supplied header, which is guarded by the |
26 | - * _FLOAT_H___ macro, may be found first, thus... | |
46 | + * _FLOAT_H___ macro, may be found first, thus, except when compiling any | |
47 | + * __LIBIMPL__ stub... | |
27 | 48 | * |
28 | 49 | */ |
29 | 50 | #if !defined(_FLOAT_H___) && !defined(__FLOAT_H) |
30 | - | |
31 | - /* | |
32 | - * ...when we didn't find the GCC-supplied header first, we want to pull | |
51 | + /* ...when we didn't find the GCC-supplied header first, we want to pull | |
33 | 52 | * it in now; include_next should achieve this, (and we must rely on the |
34 | 53 | * GCC header maintainers to extend us the same courtesy, to get this one |
35 | 54 | * pulled in, when the GCC-supplied header is found first). |
36 | - * | |
37 | 55 | */ |
38 | -# include_next <float.h> | |
56 | +# define _MINGW_FLOAT_H_ 1 /* GCC's <float.h> needs to see this */ | |
57 | +# include_next <float.h> /* !__CRT_ALIAS __LIBIMPL__( FUNCTION = fpreset ) */ | |
39 | 58 | #endif |
40 | 59 | |
41 | -/* All the headers include this file. */ | |
60 | +/* All MinGW headers are required to include <_mingw.h> | |
61 | + */ | |
42 | 62 | #include <_mingw.h> |
43 | 63 | |
44 | -/* | |
45 | - * Functions and definitions for controlling the FPU. | |
64 | +/* Functions and definitions for controlling the FPU. | |
46 | 65 | */ |
47 | -#ifndef __STRICT_ANSI__ | |
66 | +#ifndef __STRICT_ANSI__ | |
48 | 67 | |
49 | 68 | /* TODO: These constants are only valid for x86 machines */ |
50 | 69 | |
51 | -/* Control word masks for unMask */ | |
52 | -#define _MCW_EM 0x0008001F /* Error masks */ | |
53 | -#define _MCW_IC 0x00040000 /* Infinity */ | |
54 | -#define _MCW_RC 0x00000300 /* Rounding */ | |
55 | -#define _MCW_PC 0x00030000 /* Precision */ | |
56 | - | |
57 | -/* Control word values for unNew (use with related unMask above) */ | |
58 | -#define _EM_INVALID 0x00000010 | |
59 | -#define _EM_DENORMAL 0x00080000 | |
60 | -#define _EM_ZERODIVIDE 0x00000008 | |
61 | -#define _EM_OVERFLOW 0x00000004 | |
62 | -#define _EM_UNDERFLOW 0x00000002 | |
63 | -#define _EM_INEXACT 0x00000001 | |
64 | -#define _IC_AFFINE 0x00040000 | |
65 | -#define _IC_PROJECTIVE 0x00000000 | |
66 | -#define _RC_CHOP 0x00000300 | |
67 | -#define _RC_UP 0x00000200 | |
68 | -#define _RC_DOWN 0x00000100 | |
69 | -#define _RC_NEAR 0x00000000 | |
70 | -#define _PC_24 0x00020000 | |
71 | -#define _PC_53 0x00010000 | |
72 | -#define _PC_64 0x00000000 | |
73 | - | |
74 | -/* These are also defined in Mingw math.h, needed to work around | |
75 | - GCC build issues. */ | |
76 | -/* Return values for fpclass. */ | |
70 | +/* Control word masks for unMask | |
71 | + */ | |
72 | +#define _MCW_EM 0x0008001F /* Error masks */ | |
73 | +#define _MCW_IC 0x00040000 /* Infinity */ | |
74 | +#define _MCW_RC 0x00000300 /* Rounding */ | |
75 | +#define _MCW_PC 0x00030000 /* Precision */ | |
76 | + | |
77 | +/* Control word values for unNew (use with related unMask above) | |
78 | + */ | |
79 | +#define _EM_INVALID 0x00000010 | |
80 | +#define _EM_DENORMAL 0x00080000 | |
81 | +#define _EM_ZERODIVIDE 0x00000008 | |
82 | +#define _EM_OVERFLOW 0x00000004 | |
83 | +#define _EM_UNDERFLOW 0x00000002 | |
84 | +#define _EM_INEXACT 0x00000001 | |
85 | +#define _IC_AFFINE 0x00040000 | |
86 | +#define _IC_PROJECTIVE 0x00000000 | |
87 | +#define _RC_CHOP 0x00000300 | |
88 | +#define _RC_UP 0x00000200 | |
89 | +#define _RC_DOWN 0x00000100 | |
90 | +#define _RC_NEAR 0x00000000 | |
91 | +#define _PC_24 0x00020000 | |
92 | +#define _PC_53 0x00010000 | |
93 | +#define _PC_64 0x00000000 | |
94 | + | |
77 | 95 | #ifndef __MINGW_FPCLASS_DEFINED |
78 | -#define __MINGW_FPCLASS_DEFINED 1 | |
79 | -#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ | |
80 | -#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ | |
81 | -#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ | |
82 | -#define _FPCLASS_NN 0x0008 /* Negative Normal */ | |
83 | -#define _FPCLASS_ND 0x0010 /* Negative Denormal */ | |
84 | -#define _FPCLASS_NZ 0x0020 /* Negative Zero */ | |
85 | -#define _FPCLASS_PZ 0x0040 /* Positive Zero */ | |
86 | -#define _FPCLASS_PD 0x0080 /* Positive Denormal */ | |
87 | -#define _FPCLASS_PN 0x0100 /* Positive Normal */ | |
88 | -#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ | |
96 | +#define __MINGW_FPCLASS_DEFINED 1 | |
97 | +/* These are also defined in MinGW <math.h>; these duplicates are | |
98 | + * needed here, to work around GCC build issues. FIXME: we should | |
99 | + * be able to factor this, at least to avoid any potential for the | |
100 | + * introduction of inconsistent definitions. | |
101 | + * | |
102 | + * | |
103 | + * Return values for fpclass. | |
104 | + */ | |
105 | +#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */ | |
106 | +#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */ | |
107 | +#define _FPCLASS_NINF 0x0004 /* Negative Infinity */ | |
108 | +#define _FPCLASS_NN 0x0008 /* Negative Normal */ | |
109 | +#define _FPCLASS_ND 0x0010 /* Negative Denormal */ | |
110 | +#define _FPCLASS_NZ 0x0020 /* Negative Zero */ | |
111 | +#define _FPCLASS_PZ 0x0040 /* Positive Zero */ | |
112 | +#define _FPCLASS_PD 0x0080 /* Positive Denormal */ | |
113 | +#define _FPCLASS_PN 0x0100 /* Positive Normal */ | |
114 | +#define _FPCLASS_PINF 0x0200 /* Positive Infinity */ | |
115 | + | |
89 | 116 | #endif /* __MINGW_FPCLASS_DEFINED */ |
90 | 117 | |
91 | -/* invalid subconditions (_SW_INVALID also set) */ | |
92 | -#define _SW_UNEMULATED 0x0040 /* unemulated instruction */ | |
93 | -#define _SW_SQRTNEG 0x0080 /* square root of a neg number */ | |
94 | -#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ | |
95 | -#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ | |
96 | - | |
97 | -/* Floating point error signals and return codes */ | |
98 | -#define _FPE_INVALID 0x81 | |
99 | -#define _FPE_DENORMAL 0x82 | |
100 | -#define _FPE_ZERODIVIDE 0x83 | |
101 | -#define _FPE_OVERFLOW 0x84 | |
102 | -#define _FPE_UNDERFLOW 0x85 | |
103 | -#define _FPE_INEXACT 0x86 | |
104 | -#define _FPE_UNEMULATED 0x87 | |
105 | -#define _FPE_SQRTNEG 0x88 | |
106 | -#define _FPE_STACKOVERFLOW 0x8a | |
107 | -#define _FPE_STACKUNDERFLOW 0x8b | |
108 | -#define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */ | |
118 | +/* Invalid subconditions (_SW_INVALID also set) | |
119 | + */ | |
120 | +#define _SW_UNEMULATED 0x0040 /* unemulated instruction */ | |
121 | +#define _SW_SQRTNEG 0x0080 /* square root of a neg number */ | |
122 | +#define _SW_STACKOVERFLOW 0x0200 /* FP stack overflow */ | |
123 | +#define _SW_STACKUNDERFLOW 0x0400 /* FP stack underflow */ | |
124 | + | |
125 | +/* Floating point error signals and return codes | |
126 | + */ | |
127 | +#define _FPE_INVALID 0x81 | |
128 | +#define _FPE_DENORMAL 0x82 | |
129 | +#define _FPE_ZERODIVIDE 0x83 | |
130 | +#define _FPE_OVERFLOW 0x84 | |
131 | +#define _FPE_UNDERFLOW 0x85 | |
132 | +#define _FPE_INEXACT 0x86 | |
133 | +#define _FPE_UNEMULATED 0x87 | |
134 | +#define _FPE_SQRTNEG 0x88 | |
135 | +#define _FPE_STACKOVERFLOW 0x8A | |
136 | +#define _FPE_STACKUNDERFLOW 0x8B | |
137 | +#define _FPE_EXPLICITGEN 0x8C /* raise SIGFPE */ | |
109 | 138 | |
110 | 139 | #ifndef RC_INVOKED |
111 | 140 | |
112 | -#ifdef __cplusplus | |
113 | -extern "C" { | |
114 | -#endif | |
141 | +_BEGIN_C_DECLS | |
115 | 142 | |
116 | 143 | /* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask), |
117 | 144 | * i.e. change the bits in unMask to have the values they have in unNew, |
118 | - * leaving other bits unchanged. */ | |
119 | -_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _controlfp (unsigned int unNew, unsigned int unMask); | |
120 | -_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _control87 (unsigned int unNew, unsigned int unMask); | |
121 | - | |
145 | + * leaving other bits unchanged. | |
146 | + */ | |
147 | +_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _controlfp (unsigned int unNew, unsigned int unMask); | |
148 | +_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _control87 (unsigned int unNew, unsigned int unMask); | |
122 | 149 | |
123 | -_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _clearfp (void); /* Clear the FPU status word */ | |
124 | -_CRTIMP unsigned int __cdecl __MINGW_NOTHROW _statusfp (void); /* Report the FPU status word */ | |
125 | -#define _clear87 _clearfp | |
126 | -#define _status87 _statusfp | |
150 | +#define _clear87 _clearfp | |
151 | +#define _status87 _statusfp | |
127 | 152 | |
153 | +_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _clearfp (void); /* Clear the FPU status word */ | |
154 | +_CRTIMP __cdecl __MINGW_NOTHROW unsigned int _statusfp (void); /* Report the FPU status word */ | |
128 | 155 | |
129 | -/* | |
130 | - MSVCRT.dll _fpreset initializes the control register to 0x27f, | |
131 | - the status register to zero and the tag word to 0FFFFh. | |
132 | - This differs from asm instruction finit/fninit which set control | |
133 | - word to 0x37f (64 bit mantissa precison rather than 53 bit). | |
134 | - By default, the mingw version of _fpreset sets fp control as | |
135 | - per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when | |
136 | - building your application. | |
137 | -*/ | |
138 | -void __cdecl __MINGW_NOTHROW _fpreset (void); | |
139 | -void __cdecl __MINGW_NOTHROW fpreset (void); | |
140 | - | |
141 | -/* Global 'variable' for the current floating point error code. */ | |
142 | -_CRTIMP int * __cdecl __MINGW_NOTHROW __fpecode(void); | |
143 | -#define _fpecode (*(__fpecode())) | |
144 | 156 | |
145 | -/* | |
146 | - * IEEE recommended functions. MS puts them in float.h | |
147 | - * but they really belong in math.h. | |
157 | +/* MSVCRT.DLL provides _fpreset() to initialize the FPU; it initializes | |
158 | + * the control register to 0x27F, (thus selecting 53-bit precision), the | |
159 | + * status register to zero and the tag word to 0FFFFh. This differs from | |
160 | + * Intel's default configuration, (as established by the asm instructions | |
161 | + * "finit" and "fninit"), which set the control word to 0x37F, (yielding | |
162 | + * 64-bit precison rather than 53-bit). | |
163 | + * | |
164 | + * Nominally, MinGW prefers to configure the FPU for 64-bit precision, as | |
165 | + * that is a better fit for support of GCC's 10-byte long doubles. This | |
166 | + * was formerly achieved by provision of an alternative implementation of | |
167 | + * _fpreset(), intended to be statically linked into MinGW applications, | |
168 | + * (with variants enabling 64-bit precision by default, or alternatively, | |
169 | + * when the application is explicitly linked with CRT_fp8.o, providing | |
170 | + * 53-bit precision instead). Unfortunately, this linking strategy may | |
171 | + * lead to non-deterministic ambiguity over which _fpreset() variant is | |
172 | + * called, in the event of the call originating in any user implemented, | |
173 | + * or third party DLL. Consequently, support for this strategy has been | |
174 | + * withdrawn. _fpreset() now ALWAYS refers to the MSVCRT.DLL function, | |
175 | + * (and thus ALWAYS selects 53-bit precision); MinGW applications should | |
176 | + * now use the ISO-C99 standard fesetenv() function to configure the FPU, | |
177 | + * (as the start-up code now does, to enable 64-bit precision by default, | |
178 | + * but continuing to support linking with CRT_fp8.o, to initialize the | |
179 | + * configuration to 53-bit precision). | |
148 | 180 | */ |
181 | +_CRTIMP __cdecl __MINGW_NOTHROW void _fpreset (void); | |
149 | 182 | |
150 | -_CRTIMP double __cdecl __MINGW_NOTHROW _chgsign (double); | |
151 | -_CRTIMP double __cdecl __MINGW_NOTHROW _copysign (double, double); | |
152 | -_CRTIMP double __cdecl __MINGW_NOTHROW _logb (double); | |
153 | -_CRTIMP double __cdecl __MINGW_NOTHROW _nextafter (double, double); | |
154 | -_CRTIMP double __cdecl __MINGW_NOTHROW _scalb (double, long); | |
183 | +/* Former MinGW releases also provided fpreset(), implemented as an alias | |
184 | + * for _fpreset(), (in whichever guise it was deployed); deprecate this, | |
185 | + * but retain the association for backward compatibility, (noting that it | |
186 | + * will now redirect the call to fesetenv(), as recommended above, with | |
187 | + * the configuration selection set to FE_DFL_ENV). | |
188 | + */ | |
189 | +__cdecl __MINGW_NOTHROW void fpreset (void) __MINGW_ATTRIB_DEPRECATED; | |
155 | 190 | |
156 | -_CRTIMP int __cdecl __MINGW_NOTHROW _finite (double); | |
157 | -_CRTIMP int __cdecl __MINGW_NOTHROW _fpclass (double); | |
158 | -_CRTIMP int __cdecl __MINGW_NOTHROW _isnan (double); | |
191 | +#ifndef __NO_INLINE__ | |
192 | +/* Provide the implementation of fpreset() as an inline stub; for this, | |
193 | + * we need to expose a minimal opaque subset of <fenv.h>, and we assume | |
194 | + * that FE_DFL_ENV is equivalent to (const fenv_t *)(0), (as it is, in | |
195 | + * the MinGW implementation of <fenv.h>). | |
196 | + */ | |
197 | +typedef struct __fenv_t fenv_t; | |
198 | +__cdecl __MINGW_NOTHROW int fesetenv (const fenv_t *); | |
159 | 199 | |
160 | -#ifdef __cplusplus | |
161 | -} | |
200 | +__CRT_ALIAS __LIBIMPL__( FUNCTION = fpreset ) | |
201 | +void fpreset (void){ fesetenv ((const fenv_t *)(0)); } | |
162 | 202 | #endif |
163 | 203 | |
164 | -#endif /* Not RC_INVOKED */ | |
204 | +/* Global 'variable' for the current floating point error code. | |
205 | + */ | |
206 | +#define _fpecode (*(__fpecode())) | |
207 | +_CRTIMP __cdecl __MINGW_NOTHROW int *__fpecode (void); | |
208 | + | |
209 | +/* IEEE recommended functions. Microsoft puts them in <float.h>, | |
210 | + * but they really belong in math.h. | |
211 | + */ | |
212 | +_CRTIMP __cdecl __MINGW_NOTHROW double _chgsign (double); | |
213 | +_CRTIMP __cdecl __MINGW_NOTHROW double _copysign (double, double); | |
214 | +_CRTIMP __cdecl __MINGW_NOTHROW double _logb (double); | |
215 | +_CRTIMP __cdecl __MINGW_NOTHROW double _nextafter (double, double); | |
216 | +_CRTIMP __cdecl __MINGW_NOTHROW double _scalb (double, long); | |
217 | + | |
218 | +_CRTIMP __cdecl __MINGW_NOTHROW int _finite (double); | |
219 | +_CRTIMP __cdecl __MINGW_NOTHROW int _fpclass (double); | |
220 | +_CRTIMP __cdecl __MINGW_NOTHROW int _isnan (double); | |
165 | 221 | |
166 | -#endif /* Not __STRICT_ANSI__ */ | |
222 | +_END_C_DECLS | |
167 | 223 | |
168 | -#endif /* _MINGW_FLOAT_H_ */ | |
224 | +#endif /* ! RC_INVOKED */ | |
225 | +#endif /* !__STRICT_ANSI__ */ | |
169 | 226 | |
227 | +#endif /* _MINGW_FLOAT_H: $RCSfile$: end of file */ |
@@ -1,57 +1,130 @@ | ||
1 | +/* | |
2 | + * fesetenv.c | |
3 | + * | |
4 | + * Implements the fesetenv(3) function, per ISO-C99 section 7.6.4.3 | |
5 | + * | |
6 | + * $Id$ | |
7 | + * | |
8 | + * Written by Danny Smith <dannysmith@users.sourceforge.net> | |
9 | + * Copyright (C) 2002, 2005, 2006, 2017, MinGW.org Project. | |
10 | + * | |
11 | + * | |
12 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
13 | + * copy of this software and associated documentation files (the "Software"), | |
14 | + * to deal in the Software without restriction, including without limitation | |
15 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
16 | + * and/or sell copies of the Software, and to permit persons to whom the | |
17 | + * Software is furnished to do so, subject to the following conditions: | |
18 | + * | |
19 | + * The above copyright notice, this permission notice, and the following | |
20 | + * disclaimer shall be included in all copies or substantial portions of | |
21 | + * the Software. | |
22 | + * | |
23 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
24 | + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
25 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
26 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
27 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
28 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER | |
29 | + * DEALINGS IN THE SOFTWARE. | |
30 | + * | |
31 | + */ | |
32 | +#define __USE_CRTIMP | |
33 | + | |
1 | 34 | #include <fenv.h> |
2 | 35 | #include <float.h> |
3 | 36 | #include "cpu_features.h" |
4 | 37 | |
5 | -/* 7.6.4.3 | |
6 | - The fesetenv function establishes the floating-point environment | |
7 | - represented by the object pointed to by envp. The argument envp | |
8 | - points to an object set by a call to fegetenv or feholdexcept, or | |
9 | - equal the macro FE_DFL_ENV or an implementation-defined environment | |
10 | - macro. Note that fesetenv merely installs the state of the exception | |
11 | - flags represented through its argument, and does not raise these | |
12 | - exceptions. | |
13 | - */ | |
38 | +int fesetenv( const fenv_t *fenvp ) | |
39 | +{ | |
40 | + /* Specified by ISO-C99 section 7.6.4.3 | |
41 | + * | |
42 | + * The fesetenv() function establishes the floating-point environment | |
43 | + * represented by the object pointed to by "envp". The argument "envp" | |
44 | + * points to an object set by a call to fegetenv() or feholdexcept(), or | |
45 | + * equals the macro, FE_DFL_ENV, or an implementation-defined environment | |
46 | + * macro. Note that fesetenv() merely sets the state of the exception | |
47 | + * flags represented through its argument; it does not raise these | |
48 | + * exceptions. | |
49 | + * | |
50 | + * | |
51 | + * The following static variable stores the predefined environment | |
52 | + * which is associated with FE_DFL_ENV; initialize it to represent | |
53 | + * the Intel X87 default configuration. | |
54 | + */ | |
55 | + static const fenv_t *fenv_default = FE_PC64_ENV; | |
14 | 56 | |
15 | -extern void (*_imp___fpreset)( void ) ; | |
57 | + /* Before anything else, establish a default exception handling | |
58 | + * policy for SSE instructions, to be used in conjunction with the | |
59 | + * predefined FPU state macros, (establishing an effective default | |
60 | + * MXCSR status value of 0x1F80, so masking all exceptions, while | |
61 | + * leaving all other bits as zero), in the event that SSE support | |
62 | + * is available. | |
63 | + */ | |
64 | + unsigned fenv_mxcsr = FE_ALL_EXCEPT << __MXCSR_EXCEPT_MASK_SHIFT; | |
16 | 65 | |
17 | -int fesetenv (const fenv_t * envp) | |
18 | -{ | |
19 | - /* Default mxcsr status is to mask all exceptions. All other bits | |
20 | - are zero. */ | |
21 | - | |
22 | - unsigned int _csr = FE_ALL_EXCEPT << __MXCSR_EXCEPT_MASK_SHIFT /*= 0x1f80 */; | |
23 | - | |
24 | - if (envp == FE_PC64_ENV) | |
25 | - /* | |
26 | - * fninit initializes the control register to 0x37f, | |
27 | - * the status register to zero and the tag word to 0FFFFh. | |
28 | - * The other registers are unaffected. | |
29 | - */ | |
30 | - __asm__ ("fninit"); | |
31 | - | |
32 | - else if (envp == FE_PC53_ENV) | |
33 | - /* | |
34 | - * MS _fpreset() does same *except* it sets control word | |
35 | - * to 0x27f (53-bit precison). | |
36 | - * We force calling _fpreset in msvcrt.dll | |
37 | - */ | |
38 | - | |
39 | - (*_imp___fpreset)(); | |
40 | - | |
41 | - else if (envp == FE_DFL_ENV) | |
42 | - /* Use the choice made at app startup */ | |
66 | + if( fenvp == FE_PD64_ENV ) | |
67 | + /* This is a request to both initialize the FPU state, to the | |
68 | + * FE_PC64_ENV predefined state, and to store that state as the | |
69 | + * application default. | |
70 | + */ | |
71 | + fenvp = fenv_default = FE_PC64_ENV; | |
72 | + | |
73 | + else if( fenvp == FE_PD53_ENV ) | |
74 | + /* Conversely, this requests initialization of FPU state to the | |
75 | + * FE_PC53_ENV predefined state, and to store that state as the | |
76 | + * new application default. | |
77 | + */ | |
78 | + fenvp = fenv_default = FE_PC53_ENV; | |
79 | + | |
80 | + else if( fenvp == FE_DFL_ENV ) | |
81 | + /* This simply requests initialization of FPU state to whichever | |
82 | + * of the two preceding predefined states has been previously set | |
83 | + * as the application default. | |
84 | + */ | |
85 | + fenvp = fenv_default; | |
86 | + | |
87 | + if( fenvp == FE_PC64_ENV ) | |
88 | + /* The FPU's "fninit" instruction initializes the FPU control | |
89 | + * word register to 0x37F, the status register to zero and the | |
90 | + * tag word to 0xFFFF. The other registers are unaffected. | |
91 | + */ | |
92 | + __asm__( "fninit" ); | |
93 | + | |
94 | + else if( fenvp == FE_PC53_ENV ) | |
95 | + /* Microsoft's _fpreset() does the same, EXCEPT that it sets | |
96 | + * the control word to 0x27F (53-bit precison). Here, we want | |
97 | + * to force a call to _fpreset() in MSVCRT.DLL | |
98 | + */ | |
43 | 99 | _fpreset(); |
44 | 100 | |
45 | 101 | else |
46 | - { | |
47 | - __asm__ ("fldenv %0;" : : "m" (*envp)); | |
48 | - /* Setting the reserved high order bits of MXCSR causes a segfault */ | |
49 | - _csr = envp ->__mxcsr & 0xffff; | |
50 | - } | |
102 | + { /* The requested FPU state is not represented by any of the | |
103 | + * predefined state macros; assume it is a properly constructed | |
104 | + * fenv_t structure, and load it to the FPU as is. | |
105 | + */ | |
106 | + __asm__( "fldenv %0" :: "m" (*fenvp) ); | |
51 | 107 | |
52 | - /* Set MXCSR */ | |
53 | - if (__HAS_SSE) | |
54 | - __asm__ volatile ("ldmxcsr %0" : : "m" (_csr)); | |
108 | + /* Also, in the event that SSE instructions may be supported, | |
109 | + * extract the MXCSR flags from this same structure, to be used | |
110 | + * instead of the defaults which have been established for use | |
111 | + * in conjunction with the predefined state macros, noting that | |
112 | + * attempting to set any of the reserved high-order flags will | |
113 | + * induce a segmentation fault, so mask them off. | |
114 | + */ | |
115 | + fenv_mxcsr = fenvp->__mxcsr & 0xFFFF; | |
116 | + } | |
55 | 117 | |
118 | + if( __HAS_SSE ) | |
119 | + /* Finally, if SSE instructions are supported, set the MXCSR | |
120 | + * exception handling policy flags... | |
121 | + */ | |
122 | + __asm__( "ldmxcsr %0" :: "m" (fenv_mxcsr) ); | |
123 | + | |
124 | + /* ...and we are done; there is no mechanism for us to detect | |
125 | + * failure, so simply return zero, indicating success. | |
126 | + */ | |
56 | 127 | return 0; |
57 | 128 | } |
129 | + | |
130 | +/* $RCSfile$: end of file */ |