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 /*
  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 
  57 extern int fegetround(void);
  58 extern 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 
  67 extern int fegetprec(void);
  68 extern 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 
  95 typedef int fexcept_t;
  96 
  97 extern int feclearexcept(int);
  98 extern int feraiseexcept(int);
  99 extern int fetestexcept(int);
 100 extern int fegetexceptflag(fexcept_t *, int);
 101 extern 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 */
 134 typedef 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 */
 160 typedef 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 
 175 typedef struct fex_handler_data {
 176         int     __mode;
 177         void    (*__handler)();
 178 } fex_handler_t[FEX_NUM_EXC];
 179 
 180 extern int fex_get_handling(int);
 181 extern int fex_set_handling(int, int, void (*)());
 182 
 183 extern void fex_getexcepthandler(fex_handler_t *, int);
 184 extern void fex_setexcepthandler(const fex_handler_t *, int);
 185 
 186 #ifdef __STDC__
 187 #include <stdio_tag.h>
 188 #ifndef _FILEDEFED
 189 #define _FILEDEFED
 190 typedef __FILE FILE;
 191 #endif
 192 #endif
 193 extern FILE *fex_get_log(void);
 194 extern int fex_set_log(FILE *);
 195 extern int fex_get_log_depth(void);
 196 extern int fex_set_log_depth(int);
 197 extern void fex_log_entry(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(fenv_t *);
 227 extern int fesetenv(const fenv_t *);
 228 extern int feholdexcept(fenv_t *);
 229 extern int feupdateenv(const fenv_t *);
 230 
 231 #if !defined(_STRICT_STDC) || defined(__EXTENSIONS__)
 232 extern void fex_merge_flags(const fenv_t *);
 233 #endif
 234 
 235 #ifdef __cplusplus
 236 }
 237 #endif
 238 
 239 #endif  /* _FENV_H */