xref: /illumos-gate/usr/src/head/fenv.h (revision 9938df9e)
125c28e83SPiotr Jasiukajtis /*
225c28e83SPiotr Jasiukajtis  * CDDL HEADER START
325c28e83SPiotr Jasiukajtis  *
425c28e83SPiotr Jasiukajtis  * The contents of this file are subject to the terms of the
525c28e83SPiotr Jasiukajtis  * Common Development and Distribution License (the "License").
625c28e83SPiotr Jasiukajtis  * You may not use this file except in compliance with the License.
725c28e83SPiotr Jasiukajtis  *
825c28e83SPiotr Jasiukajtis  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
925c28e83SPiotr Jasiukajtis  * or http://www.opensolaris.org/os/licensing.
1025c28e83SPiotr Jasiukajtis  * See the License for the specific language governing permissions
1125c28e83SPiotr Jasiukajtis  * and limitations under the License.
1225c28e83SPiotr Jasiukajtis  *
1325c28e83SPiotr Jasiukajtis  * When distributing Covered Code, include this CDDL HEADER in each
1425c28e83SPiotr Jasiukajtis  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1525c28e83SPiotr Jasiukajtis  * If applicable, add the following below this CDDL HEADER, with the
1625c28e83SPiotr Jasiukajtis  * fields enclosed by brackets "[]" replaced with your own identifying
1725c28e83SPiotr Jasiukajtis  * information: Portions Copyright [yyyy] [name of copyright owner]
1825c28e83SPiotr Jasiukajtis  *
1925c28e83SPiotr Jasiukajtis  * CDDL HEADER END
2025c28e83SPiotr Jasiukajtis  */
2125c28e83SPiotr Jasiukajtis /*
2225c28e83SPiotr Jasiukajtis  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
2325c28e83SPiotr Jasiukajtis  */
2425c28e83SPiotr Jasiukajtis /*
2525c28e83SPiotr Jasiukajtis  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
2625c28e83SPiotr Jasiukajtis  * Use is subject to license terms.
2725c28e83SPiotr Jasiukajtis  */
2825c28e83SPiotr Jasiukajtis 
2925c28e83SPiotr Jasiukajtis #ifndef _FENV_H
3025c28e83SPiotr Jasiukajtis #define	_FENV_H
3125c28e83SPiotr Jasiukajtis 
3225c28e83SPiotr Jasiukajtis #include <sys/feature_tests.h>
3325c28e83SPiotr Jasiukajtis 
3425c28e83SPiotr Jasiukajtis #ifdef __cplusplus
3525c28e83SPiotr Jasiukajtis extern "C" {
3625c28e83SPiotr Jasiukajtis #endif
3725c28e83SPiotr Jasiukajtis 
3825c28e83SPiotr Jasiukajtis /*
3925c28e83SPiotr Jasiukajtis  * Rounding modes
4025c28e83SPiotr Jasiukajtis  */
4125c28e83SPiotr Jasiukajtis #if defined(__sparc)
4225c28e83SPiotr Jasiukajtis 
4325c28e83SPiotr Jasiukajtis #define	FE_TONEAREST	0
4425c28e83SPiotr Jasiukajtis #define	FE_TOWARDZERO	1
4525c28e83SPiotr Jasiukajtis #define	FE_UPWARD	2
4625c28e83SPiotr Jasiukajtis #define	FE_DOWNWARD	3
4725c28e83SPiotr Jasiukajtis 
4825c28e83SPiotr Jasiukajtis #elif defined(__i386) || defined(__amd64)
4925c28e83SPiotr Jasiukajtis 
5025c28e83SPiotr Jasiukajtis #define	FE_TONEAREST	0
5125c28e83SPiotr Jasiukajtis #define	FE_DOWNWARD	1
5225c28e83SPiotr Jasiukajtis #define	FE_UPWARD	2
5325c28e83SPiotr Jasiukajtis #define	FE_TOWARDZERO	3
5425c28e83SPiotr Jasiukajtis 
5525c28e83SPiotr Jasiukajtis #endif
5625c28e83SPiotr Jasiukajtis 
57*9938df9eSRichard Lowe extern int fegetround(void);
58*9938df9eSRichard Lowe extern int fesetround(int);
5925c28e83SPiotr Jasiukajtis 
6025c28e83SPiotr Jasiukajtis #if (defined(__i386) || defined(__amd64)) && \
6125c28e83SPiotr Jasiukajtis 	(!defined(_STRICT_STDC) || defined(__EXTENSIONS__))
6225c28e83SPiotr Jasiukajtis 
6325c28e83SPiotr Jasiukajtis #define	FE_FLTPREC	0
6425c28e83SPiotr Jasiukajtis #define	FE_DBLPREC	2
6525c28e83SPiotr Jasiukajtis #define	FE_LDBLPREC	3
6625c28e83SPiotr Jasiukajtis 
67*9938df9eSRichard Lowe extern int fegetprec(void);
68*9938df9eSRichard Lowe extern int fesetprec(int);
6925c28e83SPiotr Jasiukajtis 
7025c28e83SPiotr Jasiukajtis #endif
7125c28e83SPiotr Jasiukajtis 
7225c28e83SPiotr Jasiukajtis /*
7325c28e83SPiotr Jasiukajtis  * Exception flags
7425c28e83SPiotr Jasiukajtis  */
7525c28e83SPiotr Jasiukajtis #if defined(__sparc)
7625c28e83SPiotr Jasiukajtis 
7725c28e83SPiotr Jasiukajtis #define	FE_INEXACT	0x01
7825c28e83SPiotr Jasiukajtis #define	FE_DIVBYZERO	0x02
7925c28e83SPiotr Jasiukajtis #define	FE_UNDERFLOW	0x04
8025c28e83SPiotr Jasiukajtis #define	FE_OVERFLOW	0x08
8125c28e83SPiotr Jasiukajtis #define	FE_INVALID	0x10
8225c28e83SPiotr Jasiukajtis #define	FE_ALL_EXCEPT	0x1f
8325c28e83SPiotr Jasiukajtis 
8425c28e83SPiotr Jasiukajtis #elif defined(__i386) || defined(__amd64)
8525c28e83SPiotr Jasiukajtis 
8625c28e83SPiotr Jasiukajtis #define	FE_INVALID	0x01
8725c28e83SPiotr Jasiukajtis #define	FE_DIVBYZERO	0x04
8825c28e83SPiotr Jasiukajtis #define	FE_OVERFLOW	0x08
8925c28e83SPiotr Jasiukajtis #define	FE_UNDERFLOW	0x10
9025c28e83SPiotr Jasiukajtis #define	FE_INEXACT	0x20
9125c28e83SPiotr Jasiukajtis #define	FE_ALL_EXCEPT	0x3d
9225c28e83SPiotr Jasiukajtis 
9325c28e83SPiotr Jasiukajtis #endif
9425c28e83SPiotr Jasiukajtis 
9525c28e83SPiotr Jasiukajtis typedef int fexcept_t;
9625c28e83SPiotr Jasiukajtis 
97*9938df9eSRichard Lowe extern int feclearexcept(int);
98*9938df9eSRichard Lowe extern int feraiseexcept(int);
99*9938df9eSRichard Lowe extern int fetestexcept(int);
100*9938df9eSRichard Lowe extern int fegetexceptflag(fexcept_t *, int);
101*9938df9eSRichard Lowe extern int fesetexceptflag(const fexcept_t *, int);
10225c28e83SPiotr Jasiukajtis 
10325c28e83SPiotr Jasiukajtis #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
10425c28e83SPiotr Jasiukajtis 
10525c28e83SPiotr Jasiukajtis /*
10625c28e83SPiotr Jasiukajtis  * Exception handling extensions
10725c28e83SPiotr Jasiukajtis  */
10825c28e83SPiotr Jasiukajtis #define	FEX_NOHANDLER	-1
10925c28e83SPiotr Jasiukajtis #define	FEX_NONSTOP	0
11025c28e83SPiotr Jasiukajtis #define	FEX_ABORT	1
11125c28e83SPiotr Jasiukajtis #define	FEX_SIGNAL	2
11225c28e83SPiotr Jasiukajtis #define	FEX_CUSTOM	3
11325c28e83SPiotr Jasiukajtis 
11425c28e83SPiotr Jasiukajtis #define	FEX_INEXACT	0x001
11525c28e83SPiotr Jasiukajtis #define	FEX_DIVBYZERO	0x002
11625c28e83SPiotr Jasiukajtis #define	FEX_UNDERFLOW	0x004
11725c28e83SPiotr Jasiukajtis #define	FEX_OVERFLOW	0x008
11825c28e83SPiotr Jasiukajtis #define	FEX_INV_ZDZ	0x010
11925c28e83SPiotr Jasiukajtis #define	FEX_INV_IDI	0x020
12025c28e83SPiotr Jasiukajtis #define	FEX_INV_ISI	0x040
12125c28e83SPiotr Jasiukajtis #define	FEX_INV_ZMI	0x080
12225c28e83SPiotr Jasiukajtis #define	FEX_INV_SQRT	0x100
12325c28e83SPiotr Jasiukajtis #define	FEX_INV_SNAN	0x200
12425c28e83SPiotr Jasiukajtis #define	FEX_INV_INT	0x400
12525c28e83SPiotr Jasiukajtis #define	FEX_INV_CMP	0x800
12625c28e83SPiotr Jasiukajtis #define	FEX_INVALID	0xff0
12725c28e83SPiotr Jasiukajtis #define	FEX_COMMON	(FEX_INVALID | FEX_DIVBYZERO | FEX_OVERFLOW)
12825c28e83SPiotr Jasiukajtis #define	FEX_ALL		(FEX_COMMON | FEX_UNDERFLOW | FEX_INEXACT)
12925c28e83SPiotr Jasiukajtis #define	FEX_NONE	0
13025c28e83SPiotr Jasiukajtis 
13125c28e83SPiotr Jasiukajtis #define	FEX_NUM_EXC	12
13225c28e83SPiotr Jasiukajtis 
13325c28e83SPiotr Jasiukajtis /* structure to hold a numeric value in any format used by the FPU */
13425c28e83SPiotr Jasiukajtis typedef struct {
13525c28e83SPiotr Jasiukajtis 	enum fex_nt {
13625c28e83SPiotr Jasiukajtis 		fex_nodata	= 0,
13725c28e83SPiotr Jasiukajtis 		fex_int		= 1,
13825c28e83SPiotr Jasiukajtis 		fex_llong	= 2,
13925c28e83SPiotr Jasiukajtis 		fex_float	= 3,
14025c28e83SPiotr Jasiukajtis 		fex_double	= 4,
14125c28e83SPiotr Jasiukajtis 		fex_ldouble	= 5
14225c28e83SPiotr Jasiukajtis 	} type;
14325c28e83SPiotr Jasiukajtis 	union {
14425c28e83SPiotr Jasiukajtis 		int		i;
14525c28e83SPiotr Jasiukajtis #if !defined(_STRICT_STDC) && !defined(_NO_LONGLONG) || defined(_STDC_C99) || \
14625c28e83SPiotr Jasiukajtis 	defined(__C99FEATURES__)
14725c28e83SPiotr Jasiukajtis 		long long	l;
14825c28e83SPiotr Jasiukajtis #else
14925c28e83SPiotr Jasiukajtis 		struct {
15025c28e83SPiotr Jasiukajtis 			int	l[2];
15125c28e83SPiotr Jasiukajtis 		} l;
15225c28e83SPiotr Jasiukajtis #endif
15325c28e83SPiotr Jasiukajtis 		float		f;
15425c28e83SPiotr Jasiukajtis 		double		d;
15525c28e83SPiotr Jasiukajtis 		long double	q;
15625c28e83SPiotr Jasiukajtis 	} val;
15725c28e83SPiotr Jasiukajtis } fex_numeric_t;
15825c28e83SPiotr Jasiukajtis 
15925c28e83SPiotr Jasiukajtis /* structure to supply information about an exception to a custom handler */
16025c28e83SPiotr Jasiukajtis typedef struct {
16125c28e83SPiotr Jasiukajtis 	enum fex_op {
16225c28e83SPiotr Jasiukajtis 		fex_add		= 0,
16325c28e83SPiotr Jasiukajtis 		fex_sub		= 1,
16425c28e83SPiotr Jasiukajtis 		fex_mul		= 2,
16525c28e83SPiotr Jasiukajtis 		fex_div		= 3,
16625c28e83SPiotr Jasiukajtis 		fex_sqrt	= 4,
16725c28e83SPiotr Jasiukajtis 		fex_cnvt	= 5,
16825c28e83SPiotr Jasiukajtis 		fex_cmp		= 6,
16925c28e83SPiotr Jasiukajtis 		fex_other	= 7
17025c28e83SPiotr Jasiukajtis 	} op;			/* operation that caused the exception */
17125c28e83SPiotr Jasiukajtis 	int		flags;	/* flags to be set */
17225c28e83SPiotr Jasiukajtis 	fex_numeric_t	op1, op2, res;	/* operands and result */
17325c28e83SPiotr Jasiukajtis } fex_info_t;
17425c28e83SPiotr Jasiukajtis 
17525c28e83SPiotr Jasiukajtis typedef struct fex_handler_data {
17625c28e83SPiotr Jasiukajtis 	int	__mode;
17725c28e83SPiotr Jasiukajtis 	void	(*__handler)();
17825c28e83SPiotr Jasiukajtis } fex_handler_t[FEX_NUM_EXC];
17925c28e83SPiotr Jasiukajtis 
180*9938df9eSRichard Lowe extern int fex_get_handling(int);
181*9938df9eSRichard Lowe extern int fex_set_handling(int, int, void (*)());
18225c28e83SPiotr Jasiukajtis 
183*9938df9eSRichard Lowe extern void fex_getexcepthandler(fex_handler_t *, int);
184*9938df9eSRichard Lowe extern void fex_setexcepthandler(const fex_handler_t *, int);
18525c28e83SPiotr Jasiukajtis 
18625c28e83SPiotr Jasiukajtis #ifdef __STDC__
18725c28e83SPiotr Jasiukajtis #include <stdio_tag.h>
18825c28e83SPiotr Jasiukajtis #ifndef	_FILEDEFED
18925c28e83SPiotr Jasiukajtis #define	_FILEDEFED
19025c28e83SPiotr Jasiukajtis typedef	__FILE FILE;
19125c28e83SPiotr Jasiukajtis #endif
19225c28e83SPiotr Jasiukajtis #endif
193*9938df9eSRichard Lowe extern FILE *fex_get_log(void);
194*9938df9eSRichard Lowe extern int fex_set_log(FILE *);
195*9938df9eSRichard Lowe extern int fex_get_log_depth(void);
196*9938df9eSRichard Lowe extern int fex_set_log_depth(int);
197*9938df9eSRichard Lowe extern void fex_log_entry(const char *);
19825c28e83SPiotr Jasiukajtis 
19925c28e83SPiotr Jasiukajtis #define	__fex_handler_t	fex_handler_t
20025c28e83SPiotr Jasiukajtis 
20125c28e83SPiotr Jasiukajtis #else
20225c28e83SPiotr Jasiukajtis 
20325c28e83SPiotr Jasiukajtis typedef struct {
20425c28e83SPiotr Jasiukajtis 	int	__mode;
20525c28e83SPiotr Jasiukajtis 	void	(*__handler)();
20625c28e83SPiotr Jasiukajtis } __fex_handler_t[12];
20725c28e83SPiotr Jasiukajtis 
20825c28e83SPiotr Jasiukajtis #endif /* !defined(_STRICT_STDC) || defined(__EXTENSIONS__) */
20925c28e83SPiotr Jasiukajtis 
21025c28e83SPiotr Jasiukajtis /*
21125c28e83SPiotr Jasiukajtis  * Environment as a whole
21225c28e83SPiotr Jasiukajtis  */
21325c28e83SPiotr Jasiukajtis typedef struct {
21425c28e83SPiotr Jasiukajtis 	__fex_handler_t	__handlers;
21525c28e83SPiotr Jasiukajtis 	unsigned long	__fsr;
21625c28e83SPiotr Jasiukajtis } fenv_t;
21725c28e83SPiotr Jasiukajtis 
21825c28e83SPiotr Jasiukajtis #ifdef __STDC__
21925c28e83SPiotr Jasiukajtis extern const fenv_t __fenv_dfl_env;
22025c28e83SPiotr Jasiukajtis #else
22125c28e83SPiotr Jasiukajtis extern fenv_t __fenv_dfl_env;
22225c28e83SPiotr Jasiukajtis #endif
22325c28e83SPiotr Jasiukajtis 
22425c28e83SPiotr Jasiukajtis #define	FE_DFL_ENV	(&__fenv_dfl_env)
22525c28e83SPiotr Jasiukajtis 
226*9938df9eSRichard Lowe extern int fegetenv(fenv_t *);
227*9938df9eSRichard Lowe extern int fesetenv(const fenv_t *);
228*9938df9eSRichard Lowe extern int feholdexcept(fenv_t *);
229*9938df9eSRichard Lowe extern int feupdateenv(const fenv_t *);
23025c28e83SPiotr Jasiukajtis 
23125c28e83SPiotr Jasiukajtis #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
232*9938df9eSRichard Lowe extern void fex_merge_flags(const fenv_t *);
23325c28e83SPiotr Jasiukajtis #endif
23425c28e83SPiotr Jasiukajtis 
23525c28e83SPiotr Jasiukajtis #ifdef __cplusplus
23625c28e83SPiotr Jasiukajtis }
23725c28e83SPiotr Jasiukajtis #endif
23825c28e83SPiotr Jasiukajtis 
23925c28e83SPiotr Jasiukajtis #endif	/* _FENV_H */
240