master
 1/**
 2 * This file has no copyright assigned and is placed in the Public Domain.
 3 * This file is part of the mingw-w64 runtime package.
 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 5 */
 6
 7#include <internal.h>
 8
 9/* The FE_DFL_ENV macro is required by standard.
10   fesetenv will use the environment set at app startup.*/
11const fenv_t __mingw_fe_dfl_env = { 0, 0 };
12
13/* The C99 standard (7.6.9) allows us to define implementation-specific macros for
14   different fp environments */
15#if defined(__i386__) || defined(__x86_64__)
16
17/* The default Intel x87 floating point environment (64-bit mantissa) */
18const fenv_t __mingw_fe_pc64_env = { 0x3f3f003f, 0 };
19
20/* The floating point environment set by MSVCRT _fpreset (53-bit mantissa) */
21const fenv_t __mingw_fe_pc53_env = { 0x3f3f103f, 0 };
22
23#endif
24
25/* 7.6.4.3
26   The fesetenv function establishes the floating-point environment
27   represented by the object pointed to by envp. The argument envp
28   points to an object set by a call to fegetenv or feholdexcept, or
29   equal the macro FE_DFL_ENV or an implementation-defined environment
30   macro. Note that fesetenv merely installs the state of the exception
31   flags represented through its argument, and does not raise these
32   exceptions.
33 */
34
35extern void (* __MINGW_IMP_SYMBOL(_fpreset))(void);
36extern void _fpreset(void);
37
38int fesetenv(const fenv_t *env)
39{
40    unsigned int x87_cw, cw, x87_stat, stat;
41    unsigned int mask = ~0u;
42
43    if (!env->_Fe_ctl && !env->_Fe_stat) {
44        _fpreset();
45        return 0;
46    }
47
48    if (!fenv_decode(env->_Fe_ctl, &x87_cw, &cw))
49        return 1;
50    if (!fenv_decode(env->_Fe_stat, &x87_stat, &stat))
51        return 1;
52
53#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__))
54    __mingw_setfp(&x87_cw, mask, &x87_stat, ~0);
55    if (__mingw_has_sse())
56        __mingw_setfp_sse(&cw, mask, &stat, ~0);
57#else
58    __mingw_setfp(&cw, mask, &stat, ~0);
59#endif
60    return 0;
61}