1/*- 2 * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG> 3 * Copyright (c) 2015 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 FE_TONEAREST (0x00 << 5) 63#define FE_TOWARDZERO (0x01 << 5) 64#define FE_DOWNWARD (0x02 << 5) 65#define FE_UPWARD (0x03 << 5) 66#define _ROUND_SHIFT 5 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/* We need to be able to map status flag positions to mask flag positions */ 77#define _FPUSW_SHIFT 0 78#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) 79 80#define __rfs(__fpsr) __asm __volatile("csrr %0, fcsr" : "=r" (*(__fpsr))) 81#define __wfs(__fpsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fpsr)) 82 83__fenv_static inline int 84feclearexcept(int __excepts) 85{ 86 fexcept_t __fpsr; 87 88 __rfs(&__fpsr); 89 __fpsr &= ~__excepts; 90 __wfs(__fpsr); 91 return (0); 92} 93 94__fenv_static inline int 95fegetexceptflag(fexcept_t *__flagp, int __excepts) 96{ 97 fexcept_t __fpsr; 98 99 __rfs(&__fpsr); 100 *__flagp = __fpsr & __excepts; 101 return (0); 102} 103 104__fenv_static inline int 105fesetexceptflag(const fexcept_t *__flagp, int __excepts) 106{ 107 fexcept_t __fpsr; 108 109 __rfs(&__fpsr); 110 __fpsr &= ~__excepts; 111 __fpsr |= *__flagp & __excepts; 112 __wfs(__fpsr); 113 return (0); 114} 115 116__fenv_static inline int 117feraiseexcept(int __excepts) 118{ 119 fexcept_t __ex = __excepts; 120 121 fesetexceptflag(&__ex, __excepts); /* XXX */ 122 return (0); 123} 124 125__fenv_static inline int 126fetestexcept(int __excepts) 127{ 128 fexcept_t __fpsr; 129 130 __rfs(&__fpsr); 131 return (__fpsr & __excepts); 132} 133 134__fenv_static inline int 135fegetround(void) 136{ 137 138 return (-1); 139} 140 141__fenv_static inline int 142fesetround(int __round) 143{ 144 145 return (-1); 146} 147 148__fenv_static inline int 149fegetenv(fenv_t *__envp) 150{ 151 152 __rfs(__envp); 153 return (0); 154} 155 156__fenv_static inline int 157feholdexcept(fenv_t *__envp) 158{ 159 fenv_t __env; 160 161 __rfs(&__env); 162 *__envp = __env; 163 __env &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); 164 __wfs(__env); 165 return (0); 166} 167 168__fenv_static inline int 169fesetenv(const fenv_t *__envp) 170{ 171 172 __wfs(*__envp); 173 return (0); 174} 175 176__fenv_static inline int 177feupdateenv(const fenv_t *__envp) 178{ 179 fexcept_t __fpsr; 180 181 __rfs(&__fpsr); 182 __wfs(*__envp); 183 feraiseexcept(__fpsr & FE_ALL_EXCEPT); 184 return (0); 185} 186 187#if __BSD_VISIBLE 188 189/* We currently provide no external definitions of the functions below. */ 190 191static inline int 192feenableexcept(int __mask) 193{ 194 fenv_t __old_fpsr; 195 fenv_t __new_fpsr; 196 197 __rfs(&__old_fpsr); 198 __new_fpsr = __old_fpsr | (__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT; 199 __wfs(__new_fpsr); 200 return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); 201} 202 203static inline int 204fedisableexcept(int __mask) 205{ 206 fenv_t __old_fpsr; 207 fenv_t __new_fpsr; 208 209 __rfs(&__old_fpsr); 210 __new_fpsr = __old_fpsr & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); 211 __wfs(__new_fpsr); 212 return ((__old_fpsr >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); 213} 214 215static inline int 216fegetexcept(void) 217{ 218 fenv_t __fpsr; 219 220 __rfs(&__fpsr); 221 return ((__fpsr & _ENABLE_MASK) >> _FPUSW_SHIFT); 222} 223 224#endif /* __BSD_VISIBLE */ 225 226__END_DECLS 227 228#endif /* !_FENV_H_ */ 229