1 /*- 2 * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG> 3 * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> 4 * All rights reserved. 5 * 6 * Portions of this software were developed by SRI International and the 7 * University of Cambridge Computer Laboratory under DARPA/AFRL contract 8 * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. 9 * 10 * Portions of this software were developed by the University of Cambridge 11 * Computer Laboratory as part of the CTSRD Project, with support from the 12 * UK Higher Education Innovation Fund (HEIF). 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 1. Redistributions of source code must retain the above copyright 18 * notice, this list of conditions and the following disclaimer. 19 * 2. Redistributions in binary form must reproduce the above copyright 20 * notice, this list of conditions and the following disclaimer in the 21 * documentation and/or other materials provided with the distribution. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * $FreeBSD$ 36 */ 37 38 #ifndef _FENV_H_ 39 #define _FENV_H_ 40 41 #include <sys/_types.h> 42 43 #ifndef __fenv_static 44 #define __fenv_static static 45 #endif 46 47 typedef __uint64_t fenv_t; 48 typedef __uint64_t fexcept_t; 49 50 /* Exception flags */ 51 #define FE_INVALID 0x0010 52 #define FE_DIVBYZERO 0x0008 53 #define FE_OVERFLOW 0x0004 54 #define FE_UNDERFLOW 0x0002 55 #define FE_INEXACT 0x0001 56 #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ 57 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) 58 59 /* 60 * RISC-V Rounding modes 61 */ 62 #define _ROUND_SHIFT 5 63 #define FE_TONEAREST (0x00 << _ROUND_SHIFT) 64 #define FE_TOWARDZERO (0x01 << _ROUND_SHIFT) 65 #define FE_DOWNWARD (0x02 << _ROUND_SHIFT) 66 #define FE_UPWARD (0x03 << _ROUND_SHIFT) 67 #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ 68 FE_UPWARD | FE_TOWARDZERO) 69 70 __BEGIN_DECLS 71 72 /* Default floating-point environment */ 73 extern const fenv_t __fe_dfl_env; 74 #define FE_DFL_ENV (&__fe_dfl_env) 75 76 #ifndef SOFTFLOAT 77 #define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) 78 #define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) 79 #endif 80 81 #ifdef SOFTFLOAT 82 int feclearexcept(int __excepts); 83 int fegetexceptflag(fexcept_t *__flagp, int __excepts); 84 int fesetexceptflag(const fexcept_t *__flagp, int __excepts); 85 int feraiseexcept(int __excepts); 86 int fetestexcept(int __excepts); 87 int fegetround(void); 88 int fesetround(int __round); 89 int fegetenv(fenv_t *__envp); 90 int feholdexcept(fenv_t *__envp); 91 int fesetenv(const fenv_t *__envp); 92 int feupdateenv(const fenv_t *__envp); 93 #else 94 __fenv_static inline int 95 feclearexcept(int __excepts) 96 { 97 98 __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 99 100 return (0); 101 } 102 103 __fenv_static inline int 104 fegetexceptflag(fexcept_t *__flagp, int __excepts) 105 { 106 fexcept_t __fcsr; 107 108 __rfs(__fcsr); 109 *__flagp = __fcsr & __excepts; 110 111 return (0); 112 } 113 114 __fenv_static inline int 115 fesetexceptflag(const fexcept_t *__flagp, int __excepts) 116 { 117 fexcept_t __fcsr; 118 119 __fcsr = *__flagp; 120 __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 121 __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); 122 123 return (0); 124 } 125 126 __fenv_static inline int 127 feraiseexcept(int __excepts) 128 { 129 130 __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); 131 132 return (0); 133 } 134 135 __fenv_static inline int 136 fetestexcept(int __excepts) 137 { 138 fexcept_t __fcsr; 139 140 __rfs(__fcsr); 141 142 return (__fcsr & __excepts); 143 } 144 145 __fenv_static inline int 146 fegetround(void) 147 { 148 fexcept_t __fcsr; 149 150 __rfs(__fcsr); 151 152 return (__fcsr & _ROUND_MASK); 153 } 154 155 __fenv_static inline int 156 fesetround(int __round) 157 { 158 fexcept_t __fcsr; 159 160 if (__round & ~_ROUND_MASK) 161 return (-1); 162 163 __rfs(__fcsr); 164 __fcsr &= ~_ROUND_MASK; 165 __fcsr |= __round; 166 __wfs(__fcsr); 167 168 return (0); 169 } 170 171 __fenv_static inline int 172 fegetenv(fenv_t *__envp) 173 { 174 175 __rfs(*__envp); 176 177 return (0); 178 } 179 180 __fenv_static inline int 181 feholdexcept(fenv_t *__envp) 182 { 183 184 /* No exception traps. */ 185 186 return (-1); 187 } 188 189 __fenv_static inline int 190 fesetenv(const fenv_t *__envp) 191 { 192 193 __wfs(*__envp); 194 195 return (0); 196 } 197 198 __fenv_static inline int 199 feupdateenv(const fenv_t *__envp) 200 { 201 fexcept_t __fcsr; 202 203 __rfs(__fcsr); 204 __wfs(*__envp); 205 feraiseexcept(__fcsr & FE_ALL_EXCEPT); 206 207 return (0); 208 } 209 #endif /* !SOFTFLOAT */ 210 211 #if __BSD_VISIBLE 212 213 /* We currently provide no external definitions of the functions below. */ 214 215 #ifdef SOFTFLOAT 216 int feenableexcept(int __mask); 217 int fedisableexcept(int __mask); 218 int fegetexcept(void); 219 #else 220 static inline int 221 feenableexcept(int __mask) 222 { 223 224 /* No exception traps. */ 225 226 return (-1); 227 } 228 229 static inline int 230 fedisableexcept(int __mask) 231 { 232 233 /* No exception traps. */ 234 235 return (0); 236 } 237 238 static inline int 239 fegetexcept(void) 240 { 241 242 /* No exception traps. */ 243 244 return (0); 245 } 246 #endif /* !SOFTFLOAT */ 247 248 #endif /* __BSD_VISIBLE */ 249 250 __END_DECLS 251 252 #endif /* !_FENV_H_ */ 253