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 47typedef __uint64_t fenv_t; 48typedef __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 */ 73extern const fenv_t __fe_dfl_env; 74#define FE_DFL_ENV (&__fe_dfl_env) 75 76#if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double) 77#if defined(__riscv_float_abi_single) 78#error single precision floating point ABI not supported 79#else 80#error compiler did not set soft/hard float macros 81#endif 82#endif 83 84#ifndef __riscv_float_abi_soft 85#define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) 86#define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) 87#endif 88 89#ifdef __riscv_float_abi_soft 90int feclearexcept(int __excepts); 91int fegetexceptflag(fexcept_t *__flagp, int __excepts); 92int fesetexceptflag(const fexcept_t *__flagp, int __excepts); 93int feraiseexcept(int __excepts); 94int fetestexcept(int __excepts); 95int fegetround(void); 96int fesetround(int __round); 97int fegetenv(fenv_t *__envp); 98int feholdexcept(fenv_t *__envp); 99int fesetenv(const fenv_t *__envp); 100int feupdateenv(const fenv_t *__envp); 101#else 102__fenv_static inline int 103feclearexcept(int __excepts) 104{ 105 106 __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 107 108 return (0); 109} 110 111__fenv_static inline int 112fegetexceptflag(fexcept_t *__flagp, int __excepts) 113{ 114 fexcept_t __fcsr; 115 116 __rfs(__fcsr); 117 *__flagp = __fcsr & __excepts; 118 119 return (0); 120} 121 122__fenv_static inline int 123fesetexceptflag(const fexcept_t *__flagp, int __excepts) 124{ 125 fexcept_t __fcsr; 126 127 __fcsr = *__flagp; 128 __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 129 __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); 130 131 return (0); 132} 133 134__fenv_static inline int 135feraiseexcept(int __excepts) 136{ 137 138 __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); 139 140 return (0); 141} 142 143__fenv_static inline int 144fetestexcept(int __excepts) 145{ 146 fexcept_t __fcsr; 147 148 __rfs(__fcsr); 149 150 return (__fcsr & __excepts); 151} 152 153__fenv_static inline int 154fegetround(void) 155{ 156 fexcept_t __fcsr; 157 158 __rfs(__fcsr); 159 160 return (__fcsr & _ROUND_MASK); 161} 162 163__fenv_static inline int 164fesetround(int __round) 165{ 166 fexcept_t __fcsr; 167 168 if (__round & ~_ROUND_MASK) 169 return (-1); 170 171 __rfs(__fcsr); 172 __fcsr &= ~_ROUND_MASK; 173 __fcsr |= __round; 174 __wfs(__fcsr); 175 176 return (0); 177} 178 179__fenv_static inline int 180fegetenv(fenv_t *__envp) 181{ 182 183 __rfs(*__envp); 184 185 return (0); 186} 187 188__fenv_static inline int 189feholdexcept(fenv_t *__envp) 190{ 191 192 /* No exception traps. */ 193 194 return (-1); 195} 196 197__fenv_static inline int 198fesetenv(const fenv_t *__envp) 199{ 200 201 __wfs(*__envp); 202 203 return (0); 204} 205 206__fenv_static inline int 207feupdateenv(const fenv_t *__envp) 208{ 209 fexcept_t __fcsr; 210 211 __rfs(__fcsr); 212 __wfs(*__envp); 213 feraiseexcept(__fcsr & FE_ALL_EXCEPT); 214 215 return (0); 216} 217#endif /* !__riscv_float_abi_soft */ 218 219#if __BSD_VISIBLE 220 221/* We currently provide no external definitions of the functions below. */ 222 223#ifdef __riscv_float_abi_soft 224int feenableexcept(int __mask); 225int fedisableexcept(int __mask); 226int fegetexcept(void); 227#else 228static inline int 229feenableexcept(int __mask) 230{ 231 232 /* No exception traps. */ 233 234 return (-1); 235} 236 237static inline int 238fedisableexcept(int __mask) 239{ 240 241 /* No exception traps. */ 242 243 return (0); 244} 245 246static inline int 247fegetexcept(void) 248{ 249 250 /* No exception traps. */ 251 252 return (0); 253} 254#endif /* !__riscv_float_abi_soft */ 255 256#endif /* __BSD_VISIBLE */ 257 258__END_DECLS 259 260#endif /* !_FENV_H_ */ 261