4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 /* Copyright (c) 1988 AT&T */
30 /* All Rights Reserved */
41 * Floating point enviornment for machines that support
42 * the IEEE 754 floating-point standard. This file currently
43 * supports the 80*87, and SPARC families.
45 * This header defines the following interfaces:
46 * 1) Classes of floating point numbers
48 * 3) Exception Control
49 * 4) Exception Handling
51 * 6) Full Exception Environment Control
55 * CLASSES of floating point numbers *************************
56 * IEEE floating point values fall into 1 of the following 10
59 typedef enum fpclass_t
{
60 FP_SNAN
= 0, /* signaling NaN */
61 FP_QNAN
= 1, /* quiet NaN */
62 FP_NINF
= 2, /* negative infinity */
63 FP_PINF
= 3, /* positive infinity */
64 FP_NDENORM
= 4, /* negative denormalized non-zero */
65 FP_PDENORM
= 5, /* positive denormalized non-zero */
66 FP_NZERO
= 6, /* -0.0 */
67 FP_PZERO
= 7, /* +0.0 */
68 FP_NNORM
= 8, /* negative normalized non-zero */
69 FP_PNORM
= 9 /* positive normalized non-zero */
72 extern fpclass_t
fpclass(double); /* get class of double value */
73 extern int finite(double);
74 extern int unordered(double, double);
77 * ROUNDING CONTROL ******************************************
79 * At all times, floating-point math is done using one of four
80 * mutually-exclusive rounding modes.
83 #if defined(__i386) || defined(__amd64)
86 * NOTE: the values given are chosen to match those used by the
87 * 80*87 rounding mode field in the control word.
90 FP_RN
= 0, /* round to nearest representable number, tie -> even */
91 FP_RM
= 1, /* round toward minus infinity */
92 FP_RP
= 2, /* round toward plus infinity */
93 FP_RZ
= 3 /* round toward zero (truncate) */
101 * NOTE: the values given are chosen to match those used by the
102 * RD (Round Direction) field of the FSR (Floating Point State Register).
104 typedef enum fp_rnd
{
105 FP_RN
= 0, /* round to nearest representable number, tie -> even */
106 FP_RZ
= 1, /* round toward zero (truncate) */
107 FP_RP
= 2, /* round toward plus infinity */
108 FP_RM
= 3 /* round toward minus infinity */
113 extern fp_rnd
fpsetround(fp_rnd
); /* set rounding mode, return previous */
114 extern fp_rnd
fpgetround(void); /* return current rounding mode */
117 * EXCEPTION CONTROL *****************************************
121 #define fp_except int
123 #define FP_DISABLE 0 /* exception will be ignored */
124 #define FP_ENABLE 1 /* exception will cause SIGFPE */
125 #define FP_CLEAR 0 /* exception has not occurred */
126 #define FP_SET 1 /* exception has occurred */
128 #if defined(__i386) || defined(__amd64)
131 * There are six floating point exceptions, which can be individually
132 * ENABLED (== 1) or DISABLED (== 0). When an exception occurs
133 * (ENABLED or not), the fact is noted by changing an associated
134 * "sticky bit" from CLEAR (==0) to SET (==1).
136 * NOTE: the bit positions in fp_except are chosen to match those of
137 * the 80*87 control word mask bits. Although the 87 chips actually
138 * ENABLE exceptions with a mask value of 0 (not 1, as on the 3b), it
139 * is felt that switching these values may create more problems than
143 /* an fp_except can have the following (not exclusive) values: */
144 #define FP_X_INV 0x01 /* invalid operation exception */
145 #define FP_X_DNML 0x02 /* denormalization exception */
146 #define FP_X_DZ 0x04 /* divide-by-zero exception */
147 #define FP_X_OFL 0x08 /* overflow exception */
148 #define FP_X_UFL 0x10 /* underflow exception */
149 #define FP_X_IMP 0x20 /* imprecise (loss of precision) */
156 * There are five floating-point exceptions, which can be individually
157 * ENABLED (== 1) or DISABLED (== 0). When an exception occurs
158 * (ENABLED or not), the fact is noted by changing an associated
159 * "sticky bit" from CLEAR (==0) to SET (==1).
161 * NOTE: the bit positions in an fp_except are chosen to match that in
162 * the Trap Enable Mask of the FSR (Floating Point State Register).
165 /* an fp_except can have the following (not exclusive) values: */
166 #define FP_X_INV 0x10 /* invalid operation exception */
167 #define FP_X_OFL 0x08 /* overflow exception */
168 #define FP_X_UFL 0x04 /* underflow exception */
169 #define FP_X_DZ 0x02 /* divide-by-zero exception */
170 #define FP_X_IMP 0x01 /* imprecise (loss of precision) */
174 extern fp_except
fpgetmask(void); /* current exception mask */
175 extern fp_except
fpsetmask(fp_except
); /* set mask, return previous */
176 extern fp_except
fpgetsticky(void); /* return logged exceptions */
177 extern fp_except
fpsetsticky(fp_except
); /* change logged exceptions */
180 * UTILITY MACROS ********************************************
183 extern int isnanf(float);
184 extern int isnand(double);
186 #if defined(__i386) || defined(__amd64)
189 * EXCEPTION HANDLING ****************************************
191 * When a signal handler catches an FPE, it will have a freshly initialized
192 * coprocessor. This allows signal handling routines to make use of
193 * floating point arithmetic, if need be. The previous state of the 87
194 * chip is available, however. There are two ways to get at this information,
195 * depending on how the signal handler was set up.
197 * If the handler was set via signal() or sigset(), the old, SVR3, method
198 * should be used: the signal handler assumes that it has a single parameter,
199 * which is of type struct _fpstackframe, defined below. By investigating
200 * this parameter, the cause of the FPE may be determined. By modifying it,
201 * the state of the coprocessor can be changed upon return to the main task.
202 * THIS METHOD IS OBSOLETE, AND MAY NOT BE SUPPORTED IN FUTURE RELEASES.
204 * If the handler was set via sigaction(), the new, SVR4, method should be
205 * used: the third argument to the handler will be a pointer to a ucontext
206 * structure (see sys/ucontext.h). The uc_mcontext.fpregs member of the
207 * ucontext structure holds the saved floating-point registers. This can be
208 * examined and/or modified. By modifying it, the state of the coprocessor
209 * can be changed upon return to the main task.
212 struct _fpreg
{ /* structure of a temp real fp register */
213 unsigned short significand
[4]; /* 64 bit mantissa value */
214 unsigned short exponent
; /* 15 bit exponent and sign bit */
220 * AMD64 users should use sigaction() as described above.
223 struct _fpstackframe
{ /* signal handler's argument */
224 long signo
; /* signal number arg */
225 long regs
[19]; /* all registers */
226 struct _fpstate
*fpsp
; /* address of saved 387 state */
227 char *wsp
; /* address of saved Weitek state */
232 #if defined(__i386) || defined(__amd64)
235 #define _fpstate _fpstate32
238 struct _fpstate
{ /* saved state info from an exception */
239 unsigned int cw
, /* control word */
240 sw
, /* status word after fnclex-not useful */
242 ipoff
, /* %eip register */
243 cssel
, /* code segment selector */
244 dataoff
, /* data operand address */
245 datasel
; /* data operand selector */
246 struct _fpreg _st
[8]; /* saved register stack */
247 unsigned int status
; /* status word saved at exception */
249 unsigned int xstatus
; /* status word saved at exception */
250 unsigned int __pad
[2];
251 unsigned int xmm
[8][4];
258 #endif /* __i386 || __amd64 */
261 * The structure of the 80*87 status and control words, and the mxcsr
262 * register are given by the following structures.
266 mask
: 6, /* exception masks */
267 res1
: 2, /* not used */
268 prec
: 2, /* precision control field */
269 rnd
: 2, /* rounding control field */
270 inf
: 1, /* infinity control (not on 387) */
271 res2
: 3; /* not used */
276 excp
: 6, /* exception sticky bits */
277 res1
: 1, /* not used */
278 errs
: 1, /* error summary-set if unmasked excp */
279 c012
: 3, /* condition code bits 0..2 */
280 stkt
: 3, /* stack top pointer */
281 c3
: 1, /* condition code bit 3 */
282 busy
: 1; /* coprocessor busy */
287 excp
: 6, /* exception sticky bits */
288 daz
: 1, /* denormals are zeroes */
289 mask
: 6, /* exception masks */
290 rnd
: 2, /* rounding control */
291 fzero
: 1; /* flush to zero */
300 #endif /* _IEEEFP_H */