1 /*
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2010-2019 Red Hat, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #ifndef _SYS_FENV_H
30 #define _SYS_FENV_H 1
31 
32 #include <sys/cdefs.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #ifdef _SOFT_FLOAT
39 typedef int fenv_t;
40 typedef int fexcept_t;
41 #else
42 
43 /* Primary sources:
44 
45      The Open Group Base Specifications Issue 6:
46    http://www.opengroup.org/onlinepubs/000095399/basedefs/fenv.h.html
47 
48      C99 Language spec (draft n1256):
49    <url unknown>
50 
51      Intel(R) 64 and IA-32 Architectures Software Developer's Manuals:
52    http://www.intel.com/products/processor/manuals/
53 
54      GNU C library manual pages:
55    http://www.gnu.org/software/libc/manual/html_node/Control-Functions.html
56    http://www.gnu.org/software/libc/manual/html_node/Rounding.html
57    http://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html
58    http://www.gnu.org/software/libc/manual/html_node/Status-bit-operations.html
59 
60      Linux online man page(s):
61    http://linux.die.net/man/3/fegetexcept
62 
63     The documentation quotes these sources for reference.  All definitions and
64    code have been developed solely based on the information from these specs.
65 
66 */
67 
68 /*  Represents the entire floating-point environment. The floating-point
69    environment refers collectively to any floating-point status flags and
70    control modes supported by the implementation.
71     In this implementation, the struct contains the state information from
72    the fstenv/fnstenv instructions and a copy of the SSE MXCSR, since GCC
73    uses SSE for a lot of floating-point operations.  (Cygwin assumes i686
74    or above these days, as does the compiler.)  */
75 
76 typedef struct _fenv_t
77 {
78   struct _fpu_env_info {
79     unsigned int _fpu_cw;	/* low 16 bits only. */
80     unsigned int _fpu_sw;	/* low 16 bits only. */
81     unsigned int _fpu_tagw;	/* low 16 bits only. */
82     unsigned int _fpu_ipoff;
83     unsigned int _fpu_ipsel;
84     unsigned int _fpu_opoff;
85     unsigned int _fpu_opsel;	/* low 16 bits only. */
86   } _fpu;
87   unsigned int _sse_mxcsr;
88 } fenv_t;
89 
90 /*  Represents the floating-point status flags collectively, including
91    any status the implementation associates with the flags. A floating-point
92    status flag is a system variable whose value is set (but never cleared)
93    when a floating-point exception is raised, which occurs as a side effect
94    of exceptional floating-point arithmetic to provide auxiliary information.
95     A floating-point control mode is a system variable whose value may be
96    set by the user to affect the subsequent behavior of floating-point
97    arithmetic. */
98 
99 typedef __uint32_t fexcept_t;
100 
101 /*  The <fenv.h> header shall define the following constants if and only
102    if the implementation supports the floating-point exception by means
103    of the floating-point functions feclearexcept(), fegetexceptflag(),
104    feraiseexcept(), fesetexceptflag(), and fetestexcept(). Each expands to
105    an integer constant expression with values such that bitwise-inclusive
106    ORs of all combinations of the constants result in distinct values.  */
107 
108 #define FE_DIVBYZERO	(1 << 2)
109 #define FE_INEXACT	(1 << 5)
110 #define FE_INVALID	(1 << 0)
111 #define FE_OVERFLOW	(1 << 3)
112 #define FE_UNDERFLOW	(1 << 4)
113 
114 /*  The <fenv.h> header shall define the following constant, which is
115    simply the bitwise-inclusive OR of all floating-point exception
116    constants defined above:  */
117 
118 /* in agreement w/ Linux the subnormal exception will always be masked */
119 #define FE_ALL_EXCEPT \
120   (FE_INEXACT | FE_UNDERFLOW | FE_OVERFLOW | FE_DIVBYZERO | FE_INVALID)
121 
122 /*  The <fenv.h> header shall define the following constants if and only
123    if the implementation supports getting and setting the represented
124    rounding direction by means of the fegetround() and fesetround()
125    functions. Each expands to an integer constant expression whose values
126    are distinct non-negative vales.  */
127 
128 #define FE_DOWNWARD	(1)
129 #define FE_TONEAREST	(0)
130 #define FE_TOWARDZERO	(3)
131 #define FE_UPWARD	(2)
132 
133 /* Only Solaris and QNX implement fegetprec/fesetprec.  As Solaris, use the
134    values defined by http://www.open-std.org/jtc1/sc22//WG14/www/docs/n752.htm
135    QNX defines different values. */
136 #if __MISC_VISIBLE
137 #define FE_FLTPREC	(0)
138 #define FE_DBLPREC	(2)
139 #define FE_LDBLPREC	(3)
140 #endif
141 /*  Additional implementation-defined environments, with macro
142    definitions beginning with FE_ and an uppercase letter,and having
143    type "pointer to const-qualified fenv_t",may also be specified by
144    the implementation.  */
145 
146 #if __GNU_VISIBLE
147 /*  If possible, the GNU C Library defines a macro FE_NOMASK_ENV which
148    represents an environment where every exception raised causes a trap
149    to occur. You can test for this macro using #ifdef. It is only defined
150    if _GNU_SOURCE is defined.  */
151 extern const fenv_t *_fe_nomask_env;
152 #define FE_NOMASK_ENV (_fe_nomask_env)
153 #endif
154 
155 #ifdef __CYGWIN__
156 
157 #if __MISC_VISIBLE
158 int fegetprec (void);
159 int fesetprec (int __prec);
160 #endif
161 
162 #endif /* __CYGWIN__ */
163 
164 #endif /* !_SOFT_FLOAT */
165 
166 #ifdef _SOFT_FLOAT
167 
168 #if !defined(__declare_fenv_inline) && defined(__declare_extern_inline)
169 #define	__declare_fenv_inline(type) __declare_extern_inline(type)
170 #endif
171 
172 #ifdef __declare_fenv_inline
173 #include <machine/fenv-softfloat.h>
174 #endif
175 
176 #endif
177 
178 #ifdef __cplusplus
179 }
180 #endif
181 
182 #endif /* _FENV_H */
183