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