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