xref: /illumos-gate/usr/src/head/fenv.h (revision 876de206688d9fe008ad80c116a23a56701579d1)
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 #ifndef __P
39 #ifdef __STDC__
40 #define	__P(p)	p
41 #else
42 #define	__P(p)	()
43 #endif
44 #endif	/* !defined(__P) */
45 
46 /*
47  * Rounding modes
48  */
49 #if defined(__sparc)
50 
51 #define	FE_TONEAREST	0
52 #define	FE_TOWARDZERO	1
53 #define	FE_UPWARD	2
54 #define	FE_DOWNWARD	3
55 
56 #elif defined(__i386) || defined(__amd64)
57 
58 #define	FE_TONEAREST	0
59 #define	FE_DOWNWARD	1
60 #define	FE_UPWARD	2
61 #define	FE_TOWARDZERO	3
62 
63 #endif
64 
65 extern int fegetround __P((void));
66 extern int fesetround __P((int));
67 
68 #if (defined(__i386) || defined(__amd64)) && \
69 	(!defined(_STRICT_STDC) || defined(__EXTENSIONS__))
70 
71 #define	FE_FLTPREC	0
72 #define	FE_DBLPREC	2
73 #define	FE_LDBLPREC	3
74 
75 extern int fegetprec __P((void));
76 extern int fesetprec __P((int));
77 
78 #endif
79 
80 /*
81  * Exception flags
82  */
83 #if defined(__sparc)
84 
85 #define	FE_INEXACT	0x01
86 #define	FE_DIVBYZERO	0x02
87 #define	FE_UNDERFLOW	0x04
88 #define	FE_OVERFLOW	0x08
89 #define	FE_INVALID	0x10
90 #define	FE_ALL_EXCEPT	0x1f
91 
92 #elif defined(__i386) || defined(__amd64)
93 
94 #define	FE_INVALID	0x01
95 #define	FE_DIVBYZERO	0x04
96 #define	FE_OVERFLOW	0x08
97 #define	FE_UNDERFLOW	0x10
98 #define	FE_INEXACT	0x20
99 #define	FE_ALL_EXCEPT	0x3d
100 
101 #endif
102 
103 typedef int fexcept_t;
104 
105 extern int feclearexcept __P((int));
106 extern int feraiseexcept __P((int));
107 extern int fetestexcept __P((int));
108 extern int fegetexceptflag __P((fexcept_t *, int));
109 extern int fesetexceptflag __P((const fexcept_t *, int));
110 
111 #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
112 
113 /*
114  * Exception handling extensions
115  */
116 #define	FEX_NOHANDLER	-1
117 #define	FEX_NONSTOP	0
118 #define	FEX_ABORT	1
119 #define	FEX_SIGNAL	2
120 #define	FEX_CUSTOM	3
121 
122 #define	FEX_INEXACT	0x001
123 #define	FEX_DIVBYZERO	0x002
124 #define	FEX_UNDERFLOW	0x004
125 #define	FEX_OVERFLOW	0x008
126 #define	FEX_INV_ZDZ	0x010
127 #define	FEX_INV_IDI	0x020
128 #define	FEX_INV_ISI	0x040
129 #define	FEX_INV_ZMI	0x080
130 #define	FEX_INV_SQRT	0x100
131 #define	FEX_INV_SNAN	0x200
132 #define	FEX_INV_INT	0x400
133 #define	FEX_INV_CMP	0x800
134 #define	FEX_INVALID	0xff0
135 #define	FEX_COMMON	(FEX_INVALID | FEX_DIVBYZERO | FEX_OVERFLOW)
136 #define	FEX_ALL		(FEX_COMMON | FEX_UNDERFLOW | FEX_INEXACT)
137 #define	FEX_NONE	0
138 
139 #define	FEX_NUM_EXC	12
140 
141 /* structure to hold a numeric value in any format used by the FPU */
142 typedef struct {
143 	enum fex_nt {
144 		fex_nodata	= 0,
145 		fex_int		= 1,
146 		fex_llong	= 2,
147 		fex_float	= 3,
148 		fex_double	= 4,
149 		fex_ldouble	= 5
150 	} type;
151 	union {
152 		int		i;
153 #if !defined(_STRICT_STDC) && !defined(_NO_LONGLONG) || defined(_STDC_C99) || \
154 	defined(__C99FEATURES__)
155 		long long	l;
156 #else
157 		struct {
158 			int	l[2];
159 		} l;
160 #endif
161 		float		f;
162 		double		d;
163 		long double	q;
164 	} val;
165 } fex_numeric_t;
166 
167 /* structure to supply information about an exception to a custom handler */
168 typedef struct {
169 	enum fex_op {
170 		fex_add		= 0,
171 		fex_sub		= 1,
172 		fex_mul		= 2,
173 		fex_div		= 3,
174 		fex_sqrt	= 4,
175 		fex_cnvt	= 5,
176 		fex_cmp		= 6,
177 		fex_other	= 7
178 	} op;			/* operation that caused the exception */
179 	int		flags;	/* flags to be set */
180 	fex_numeric_t	op1, op2, res;	/* operands and result */
181 } fex_info_t;
182 
183 typedef struct fex_handler_data {
184 	int	__mode;
185 	void	(*__handler)();
186 } fex_handler_t[FEX_NUM_EXC];
187 
188 extern int fex_get_handling __P((int));
189 extern int fex_set_handling __P((int, int, void (*)()));
190 
191 extern void fex_getexcepthandler __P((fex_handler_t *, int));
192 extern void fex_setexcepthandler __P((const fex_handler_t *, int));
193 
194 #ifdef __STDC__
195 #include <stdio_tag.h>
196 #ifndef	_FILEDEFED
197 #define	_FILEDEFED
198 typedef	__FILE FILE;
199 #endif
200 #endif
201 extern FILE *fex_get_log __P((void));
202 extern int fex_set_log __P((FILE *));
203 extern int fex_get_log_depth __P((void));
204 extern int fex_set_log_depth __P((int));
205 extern void fex_log_entry __P((const char *));
206 
207 #define	__fex_handler_t	fex_handler_t
208 
209 #else
210 
211 typedef struct {
212 	int	__mode;
213 	void	(*__handler)();
214 } __fex_handler_t[12];
215 
216 #endif /* !defined(_STRICT_STDC) || defined(__EXTENSIONS__) */
217 
218 /*
219  * Environment as a whole
220  */
221 typedef struct {
222 	__fex_handler_t	__handlers;
223 	unsigned long	__fsr;
224 } fenv_t;
225 
226 #ifdef __STDC__
227 extern const fenv_t __fenv_dfl_env;
228 #else
229 extern fenv_t __fenv_dfl_env;
230 #endif
231 
232 #define	FE_DFL_ENV	(&__fenv_dfl_env)
233 
234 extern int fegetenv __P((fenv_t *));
235 extern int fesetenv __P((const fenv_t *));
236 extern int feholdexcept __P((fenv_t *));
237 extern int feupdateenv __P((const fenv_t *));
238 
239 #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
240 extern void fex_merge_flags __P((const fenv_t *));
241 #endif
242 
243 #ifdef __cplusplus
244 }
245 #endif
246 
247 #endif	/* _FENV_H */
248