ReactOS 0.4.16-dev-1059-gb1cf981
fenv.h
Go to the documentation of this file.
1//
2// fenv.h
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Floating point environment library.
7//
8#pragma once
9#ifndef _FENV // include guard for 3rd party interop
10#define _FENV
11
12#include <corecrt.h>
13#include <float.h>
14
15#pragma warning(push)
16#pragma warning(disable: _UCRT_DISABLED_WARNINGS)
18
20
21
22
23#define FE_TONEAREST _RC_NEAR
24#define FE_UPWARD _RC_UP
25#define FE_DOWNWARD _RC_DOWN
26#define FE_TOWARDZERO _RC_CHOP
27
28#define FE_ROUND_MASK _MCW_RC
29
32
33
34
35#if !defined _M_CEE
36
37 typedef unsigned long fexcept_t;
38
39 typedef struct fenv_t
40 {
41 unsigned long _Fe_ctl, _Fe_stat;
43
44
45
46 #define FE_INEXACT _SW_INEXACT // _EM_INEXACT 0x00000001 inexact (precision)
47 #define FE_UNDERFLOW _SW_UNDERFLOW // _EM_UNDERFLOW 0x00000002 underflow
48 #define FE_OVERFLOW _SW_OVERFLOW // _EM_OVERFLOW 0x00000004 overflow
49 #define FE_DIVBYZERO _SW_ZERODIVIDE // _EM_ZERODIVIDE 0x00000008 zero divide
50 #define FE_INVALID _SW_INVALID // _EM_INVALID 0x00000010 invalid
51
52 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
53
59 _ACRTIMP int __cdecl fegetexceptflag(_Out_ fexcept_t* _Except, _In_ int _TestFlags);
60 _ACRTIMP int __cdecl fesetexceptflag(_In_ fexcept_t const* _Except, _In_ int _SetFlags);
61
62 #if !defined __midl // MIDL does not support compound initializers
63 // In the original implementation (_Fenv0), the global variable was zero
64 // initialized, indicating no exceptions are masked. In the current
65 // implementation (_Fenv1), the global variable is initialized with all
66 // exceptions masked, which is the actual initial environment.
67 #ifdef __cplusplus
68 #define CPP_EXTERN extern
69 #else
70 #define CPP_EXTERN
71 #endif
72 #if defined _M_IX86
73 CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x3f3f103f, 0 };
74 #elif defined _M_X64
75 CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x3f00003f, 0 };
76 #else
77 CPP_EXTERN __declspec(selectany) const fenv_t _Fenv1 = { 0x0000003f, 0 };
78 #endif
79 #endif
80
81 #define FE_DFL_ENV (&_Fenv1)
82
83
84
85 // feraiseexcept is defined inline in this header so that it is compiled
86 // with the same /arch setting as is specified in the consuming application,
87 // rather than the /arch:IA32 setting with which the CRT sources are built.
88 // optimizer has to be turned off to avoid optimizing out since the function
89 // doesn't have side effects.
90 //
91 // feupdateenv is inline because it calls feraiseexcept.
92 #if _CRT_FUNCTIONS_REQUIRED
93 #if !defined(_BEGIN_PRAGMA_OPTIMIZE_DISABLE)
94 #define _BEGIN_PRAGMA_OPTIMIZE_DISABLE(flags, bug, reason) \
95 __pragma(optimize(flags, off))
96 #define _BEGIN_PRAGMA_OPTIMIZE_ENABLE(flags, bug, reason) \
97 __pragma(optimize(flags, on))
98 #define _END_PRAGMA_OPTIMIZE() \
99 __pragma(optimize("", on))
100 #endif
101 _BEGIN_PRAGMA_OPTIMIZE_DISABLE("", MSFT:4499495, "If optimizations are on, the floating-point exception might not get triggered (because the compiler optimizes it out), breaking the function.")
102 __inline int __CRTDECL feraiseexcept(_In_ int _Except)
103 {
104 static struct
105 {
106 int _Except_Val;
107 double _Num;
108 double _Denom;
109 } const _Table[] =
110 { // Raise exception by evaluating num / denom:
111 {FE_INVALID, 0.0, 0.0 },
112 {FE_DIVBYZERO, 1.0, 0.0 },
113 {FE_OVERFLOW, 1e+300, 1e-300 },
114 {FE_UNDERFLOW, 1e-300, 1e+300 },
115 {FE_INEXACT, 2.0, 3.0 }
116 };
117
118 double _Ans = 0.0;
119 (void) _Ans; // Suppress set-but-not-used warnings. _Ans is not "used" in the traditional static-analysis sense, but it is needed to trigger a floating point exception below.
120 size_t _Index;
121
122 if ((_Except &= FE_ALL_EXCEPT) == 0)
123 {
124 return 0;
125 }
126
127 // Raise the exceptions not masked:
128 for (_Index = 0; _Index < sizeof(_Table) / sizeof(_Table[0]); ++_Index)
129 {
130 if ((_Except & _Table[_Index]._Except_Val) != 0)
131 {
132 _Ans = _Table[_Index]._Num / _Table[_Index]._Denom;
133
134 // x87 exceptions are raised immediately before execution of the
135 // next floating point instruction. If we're using /arch:IA32,
136 // force the exception to be raised immediately:
137 #if defined _M_IX86 && _M_IX86_FP == 0 && !defined _M_HYBRID_X86_ARM64
138 #ifdef _MSC_VER
139 __asm fwait;
140 #else
141 __asm__ __volatile__("fwait");
142 #endif
143 #endif
144 }
145 }
146
147 return 0;
148 }
150
152 {
153 int _Except = fetestexcept(FE_ALL_EXCEPT);
154
155 if (fesetenv(_Penv) != 0 || feraiseexcept(_Except) != 0)
156 {
157 return 1;
158 }
159
160 return 0;
161 }
162 #endif // _CRT_FUNCTIONS_REQUIRED
163
164#endif // !defined _M_CEE && !defined _CORECRT_BUILD
165
168#pragma warning(pop) // _UCRT_DISABLED_WARNINGS
169#endif // _FENV
#define __inline
Definition: _wctype.cpp:15
#define __cdecl
Definition: accygwin.h:79
#define _END_PRAGMA_OPTIMIZE()
#define _BEGIN_PRAGMA_OPTIMIZE_DISABLE(flags, bug, reason)
unsigned short fexcept_t
Definition: fenv.h:39
int __cdecl fesetexceptflag(const fexcept_t *, int)
int __cdecl fesetenv(const fenv_t *)
int __cdecl fetestexcept(int excepts)
int __cdecl fegetround(void)
int __cdecl fegetexceptflag(fexcept_t *flagp, int excepts)
int __cdecl feholdexcept(fenv_t *)
int __cdecl feclearexcept(int)
int __cdecl feraiseexcept(int excepts)
int __cdecl fegetenv(fenv_t *envp)
int __cdecl fesetround(int mode)
int __cdecl feupdateenv(const fenv_t *)
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
void __declspec(noinline) __cdecl _free_base(void *const block)
Definition: free_base.cpp:98
#define e
Definition: ke_i.h:82
#define _Success_(c)
Definition: no_sal2.h:84
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tsub $32, %rsp\n" "\t.seh_stackalloc 32\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $32, %rsp\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
_In_ size_t _In_ int _Index
Definition: time.h:111
Definition: fenv.h:46
unsigned long _Fe_ctl
Definition: fenv.h:41
unsigned long _Fe_stat
Definition: fenv.h:41
#define _ACRTIMP
Definition: corecrt.h:138
#define _UCRT_DISABLE_CLANG_WARNINGS
Definition: corecrt.h:109
#define _UCRT_RESTORE_CLANG_WARNINGS
Definition: corecrt.h:117
#define FE_ALL_EXCEPT
Definition: fenv.h:52
#define FE_UNDERFLOW
Definition: fenv.h:47
#define FE_INVALID
Definition: fenv.h:50
#define FE_INEXACT
Definition: fenv.h:46
#define CPP_EXTERN
Definition: fenv.h:70
#define FE_DIVBYZERO
Definition: fenv.h:49
#define FE_OVERFLOW
Definition: fenv.h:48
#define _CRT_END_C_HEADER
Definition: vcruntime.h:42
#define _CRT_BEGIN_C_HEADER
Definition: vcruntime.h:40
#define __CRTDECL
Definition: yvals.h:17
#define const
Definition: zconf.h:233