numpy 2.0.0
|
00001 /*- 00002 * Copyright (c) 2004 David Schultz <das@FreeBSD.ORG> 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 00015 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00016 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00017 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 00018 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00019 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00020 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00021 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00022 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00023 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00024 * SUCH DAMAGE. 00025 * 00026 * $FreeBSD$ 00027 */ 00028 00029 #ifndef _FENV_H_ 00030 #define _FENV_H_ 00031 00032 #include <sys/cdefs.h> 00033 #include <sys/types.h> 00034 00035 typedef struct { 00036 __uint32_t __control; 00037 __uint32_t __status; 00038 __uint32_t __tag; 00039 char __other[16]; 00040 } fenv_t; 00041 00042 typedef __uint16_t fexcept_t; 00043 00044 /* Exception flags */ 00045 #define FE_INVALID 0x01 00046 #define FE_DENORMAL 0x02 00047 #define FE_DIVBYZERO 0x04 00048 #define FE_OVERFLOW 0x08 00049 #define FE_UNDERFLOW 0x10 00050 #define FE_INEXACT 0x20 00051 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_DENORMAL | FE_INEXACT | \ 00052 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) 00053 00054 /* Rounding modes */ 00055 #define FE_TONEAREST 0x0000 00056 #define FE_DOWNWARD 0x0400 00057 #define FE_UPWARD 0x0800 00058 #define FE_TOWARDZERO 0x0c00 00059 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ 00060 FE_UPWARD | FE_TOWARDZERO) 00061 00062 __BEGIN_DECLS 00063 00064 /* Default floating-point environment */ 00065 extern const fenv_t npy__fe_dfl_env; 00066 #define FE_DFL_ENV (&npy__fe_dfl_env) 00067 00068 #define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) 00069 #define __fldenv(__env) __asm __volatile("fldenv %0" : : "m" (__env)) 00070 #define __fnclex() __asm __volatile("fnclex") 00071 #define __fnstenv(__env) __asm __volatile("fnstenv %0" : "=m" (*(__env))) 00072 #define __fnstcw(__cw) __asm __volatile("fnstcw %0" : "=m" (*(__cw))) 00073 #define __fnstsw(__sw) __asm __volatile("fnstsw %0" : "=am" (*(__sw))) 00074 #define __fwait() __asm __volatile("fwait") 00075 00076 static __inline int 00077 feclearexcept(int __excepts) 00078 { 00079 fenv_t __env; 00080 00081 if (__excepts == FE_ALL_EXCEPT) { 00082 __fnclex(); 00083 } else { 00084 __fnstenv(&__env); 00085 __env.__status &= ~__excepts; 00086 __fldenv(__env); 00087 } 00088 return (0); 00089 } 00090 00091 static __inline int 00092 fegetexceptflag(fexcept_t *__flagp, int __excepts) 00093 { 00094 __uint16_t __status; 00095 00096 __fnstsw(&__status); 00097 *__flagp = __status & __excepts; 00098 return (0); 00099 } 00100 00101 static __inline int 00102 fesetexceptflag(const fexcept_t *__flagp, int __excepts) 00103 { 00104 fenv_t __env; 00105 00106 __fnstenv(&__env); 00107 __env.__status &= ~__excepts; 00108 __env.__status |= *__flagp & __excepts; 00109 __fldenv(__env); 00110 return (0); 00111 } 00112 00113 static __inline int 00114 feraiseexcept(int __excepts) 00115 { 00116 fexcept_t __ex = __excepts; 00117 00118 fesetexceptflag(&__ex, __excepts); 00119 __fwait(); 00120 return (0); 00121 } 00122 00123 static __inline int 00124 fetestexcept(int __excepts) 00125 { 00126 __uint16_t __status; 00127 00128 __fnstsw(&__status); 00129 return (__status & __excepts); 00130 } 00131 00132 static __inline int 00133 fegetround(void) 00134 { 00135 int __control; 00136 00137 __fnstcw(&__control); 00138 return (__control & _ROUND_MASK); 00139 } 00140 00141 static __inline int 00142 fesetround(int __round) 00143 { 00144 int __control; 00145 00146 if (__round & ~_ROUND_MASK) 00147 return (-1); 00148 __fnstcw(&__control); 00149 __control &= ~_ROUND_MASK; 00150 __control |= __round; 00151 __fldcw(__control); 00152 return (0); 00153 } 00154 00155 static __inline int 00156 fegetenv(fenv_t *__envp) 00157 { 00158 int __control; 00159 00160 /* 00161 * fnstenv masks all exceptions, so we need to save and 00162 * restore the control word to avoid this side effect. 00163 */ 00164 __fnstcw(&__control); 00165 __fnstenv(__envp); 00166 __fldcw(__control); 00167 return (0); 00168 } 00169 00170 static __inline int 00171 feholdexcept(fenv_t *__envp) 00172 { 00173 00174 __fnstenv(__envp); 00175 __fnclex(); 00176 return (0); 00177 } 00178 00179 static __inline int 00180 fesetenv(const fenv_t *__envp) 00181 { 00182 00183 __fldenv(*__envp); 00184 return (0); 00185 } 00186 00187 static __inline int 00188 feupdateenv(const fenv_t *__envp) 00189 { 00190 __uint16_t __status; 00191 00192 __fnstsw(&__status); 00193 __fldenv(*__envp); 00194 feraiseexcept(__status & FE_ALL_EXCEPT); 00195 return (0); 00196 } 00197 00198 #if __BSD_VISIBLE 00199 00200 static __inline int 00201 fesetmask(int __mask) 00202 { 00203 int __control; 00204 00205 __fnstcw(&__control); 00206 __mask = (__control | FE_ALL_EXCEPT) & ~__mask; 00207 __fldcw(__mask); 00208 return (~__control & FE_ALL_EXCEPT); 00209 } 00210 00211 static __inline int 00212 fegetmask(void) 00213 { 00214 int __control; 00215 00216 __fnstcw(&__control); 00217 return (~__control & FE_ALL_EXCEPT); 00218 } 00219 00220 #endif /* __BSD_VISIBLE */ 00221 00222 __END_DECLS 00223 00224 #endif /* !_FENV_H_ */