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
35extern "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
57extern int fegetround(void);
58extern 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
67extern int fegetprec(void);
68extern 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
95typedef int fexcept_t;
96
97extern int feclearexcept(int);
98extern int feraiseexcept(int);
99extern int fetestexcept(int);
100extern int fegetexceptflag(fexcept_t *, int);
101extern 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 */
134typedef 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 */
160typedef 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
175typedef struct fex_handler_data {
176	int	__mode;
177	void	(*__handler)();
178} fex_handler_t[FEX_NUM_EXC];
179
180extern int fex_get_handling(int);
181extern int fex_set_handling(int, int, void (*)());
182
183extern void fex_getexcepthandler(fex_handler_t *, int);
184extern void fex_setexcepthandler(const fex_handler_t *, int);
185
186#ifdef __STDC__
187#include <stdio_tag.h>
188#ifndef	_FILEDEFED
189#define	_FILEDEFED
190typedef	__FILE FILE;
191#endif
192#endif
193extern FILE *fex_get_log(void);
194extern int fex_set_log(FILE *);
195extern int fex_get_log_depth(void);
196extern int fex_set_log_depth(int);
197extern void fex_log_entry(const char *);
198
199#define	__fex_handler_t	fex_handler_t
200
201#else
202
203typedef 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 */
213typedef struct {
214	__fex_handler_t	__handlers;
215	unsigned long	__fsr;
216} fenv_t;
217
218#ifdef __STDC__
219extern const fenv_t __fenv_dfl_env;
220#else
221extern fenv_t __fenv_dfl_env;
222#endif
223
224#define	FE_DFL_ENV	(&__fenv_dfl_env)
225
226extern int fegetenv(fenv_t *);
227extern int fesetenv(const fenv_t *);
228extern int feholdexcept(fenv_t *);
229extern int feupdateenv(const fenv_t *);
230
231#if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
232extern void fex_merge_flags(const fenv_t *);
233#endif
234
235#ifdef __cplusplus
236}
237#endif
238
239#endif	/* _FENV_H */
240