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