xref: /illumos-gate/usr/src/head/fenv.h (revision 9938df9e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23  */
24 /*
25  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #ifndef _FENV_H
30 #define	_FENV_H
31 
32 #include <sys/feature_tests.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /*
39  * Rounding modes
40  */
41 #if defined(__sparc)
42 
43 #define	FE_TONEAREST	0
44 #define	FE_TOWARDZERO	1
45 #define	FE_UPWARD	2
46 #define	FE_DOWNWARD	3
47 
48 #elif defined(__i386) || defined(__amd64)
49 
50 #define	FE_TONEAREST	0
51 #define	FE_DOWNWARD	1
52 #define	FE_UPWARD	2
53 #define	FE_TOWARDZERO	3
54 
55 #endif
56 
57 extern int fegetround(void);
58 extern int fesetround(int);
59 
60 #if (defined(__i386) || defined(__amd64)) && \
61 	(!defined(_STRICT_STDC) || defined(__EXTENSIONS__))
62 
63 #define	FE_FLTPREC	0
64 #define	FE_DBLPREC	2
65 #define	FE_LDBLPREC	3
66 
67 extern int fegetprec(void);
68 extern int fesetprec(int);
69 
70 #endif
71 
72 /*
73  * Exception flags
74  */
75 #if defined(__sparc)
76 
77 #define	FE_INEXACT	0x01
78 #define	FE_DIVBYZERO	0x02
79 #define	FE_UNDERFLOW	0x04
80 #define	FE_OVERFLOW	0x08
81 #define	FE_INVALID	0x10
82 #define	FE_ALL_EXCEPT	0x1f
83 
84 #elif defined(__i386) || defined(__amd64)
85 
86 #define	FE_INVALID	0x01
87 #define	FE_DIVBYZERO	0x04
88 #define	FE_OVERFLOW	0x08
89 #define	FE_UNDERFLOW	0x10
90 #define	FE_INEXACT	0x20
91 #define	FE_ALL_EXCEPT	0x3d
92 
93 #endif
94 
95 typedef int fexcept_t;
96 
97 extern int feclearexcept(int);
98 extern int feraiseexcept(int);
99 extern int fetestexcept(int);
100 extern int fegetexceptflag(fexcept_t *, int);
101 extern int fesetexceptflag(const fexcept_t *, int);
102 
103 #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
104 
105 /*
106  * Exception handling extensions
107  */
108 #define	FEX_NOHANDLER	-1
109 #define	FEX_NONSTOP	0
110 #define	FEX_ABORT	1
111 #define	FEX_SIGNAL	2
112 #define	FEX_CUSTOM	3
113 
114 #define	FEX_INEXACT	0x001
115 #define	FEX_DIVBYZERO	0x002
116 #define	FEX_UNDERFLOW	0x004
117 #define	FEX_OVERFLOW	0x008
118 #define	FEX_INV_ZDZ	0x010
119 #define	FEX_INV_IDI	0x020
120 #define	FEX_INV_ISI	0x040
121 #define	FEX_INV_ZMI	0x080
122 #define	FEX_INV_SQRT	0x100
123 #define	FEX_INV_SNAN	0x200
124 #define	FEX_INV_INT	0x400
125 #define	FEX_INV_CMP	0x800
126 #define	FEX_INVALID	0xff0
127 #define	FEX_COMMON	(FEX_INVALID | FEX_DIVBYZERO | FEX_OVERFLOW)
128 #define	FEX_ALL		(FEX_COMMON | FEX_UNDERFLOW | FEX_INEXACT)
129 #define	FEX_NONE	0
130 
131 #define	FEX_NUM_EXC	12
132 
133 /* structure to hold a numeric value in any format used by the FPU */
134 typedef struct {
135 	enum fex_nt {
136 		fex_nodata	= 0,
137 		fex_int		= 1,
138 		fex_llong	= 2,
139 		fex_float	= 3,
140 		fex_double	= 4,
141 		fex_ldouble	= 5
142 	} type;
143 	union {
144 		int		i;
145 #if !defined(_STRICT_STDC) && !defined(_NO_LONGLONG) || defined(_STDC_C99) || \
146 	defined(__C99FEATURES__)
147 		long long	l;
148 #else
149 		struct {
150 			int	l[2];
151 		} l;
152 #endif
153 		float		f;
154 		double		d;
155 		long double	q;
156 	} val;
157 } fex_numeric_t;
158 
159 /* structure to supply information about an exception to a custom handler */
160 typedef struct {
161 	enum fex_op {
162 		fex_add		= 0,
163 		fex_sub		= 1,
164 		fex_mul		= 2,
165 		fex_div		= 3,
166 		fex_sqrt	= 4,
167 		fex_cnvt	= 5,
168 		fex_cmp		= 6,
169 		fex_other	= 7
170 	} op;			/* operation that caused the exception */
171 	int		flags;	/* flags to be set */
172 	fex_numeric_t	op1, op2, res;	/* operands and result */
173 } fex_info_t;
174 
175 typedef struct fex_handler_data {
176 	int	__mode;
177 	void	(*__handler)();
178 } fex_handler_t[FEX_NUM_EXC];
179 
180 extern int fex_get_handling(int);
181 extern int fex_set_handling(int, int, void (*)());
182 
183 extern void fex_getexcepthandler(fex_handler_t *, int);
184 extern void fex_setexcepthandler(const fex_handler_t *, int);
185 
186 #ifdef __STDC__
187 #include <stdio_tag.h>
188 #ifndef	_FILEDEFED
189 #define	_FILEDEFED
190 typedef	__FILE FILE;
191 #endif
192 #endif
193 extern FILE *fex_get_log(void);
194 extern int fex_set_log(FILE *);
195 extern int fex_get_log_depth(void);
196 extern int fex_set_log_depth(int);
197 extern void fex_log_entry(const char *);
198 
199 #define	__fex_handler_t	fex_handler_t
200 
201 #else
202 
203 typedef struct {
204 	int	__mode;
205 	void	(*__handler)();
206 } __fex_handler_t[12];
207 
208 #endif /* !defined(_STRICT_STDC) || defined(__EXTENSIONS__) */
209 
210 /*
211  * Environment as a whole
212  */
213 typedef struct {
214 	__fex_handler_t	__handlers;
215 	unsigned long	__fsr;
216 } fenv_t;
217 
218 #ifdef __STDC__
219 extern const fenv_t __fenv_dfl_env;
220 #else
221 extern fenv_t __fenv_dfl_env;
222 #endif
223 
224 #define	FE_DFL_ENV	(&__fenv_dfl_env)
225 
226 extern int fegetenv(fenv_t *);
227 extern int fesetenv(const fenv_t *);
228 extern int feholdexcept(fenv_t *);
229 extern int feupdateenv(const fenv_t *);
230 
231 #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
232 extern void fex_merge_flags(const fenv_t *);
233 #endif
234 
235 #ifdef __cplusplus
236 }
237 #endif
238 
239 #endif	/* _FENV_H */
240