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