11fdcc5e5SRuslan Bukin /*- 21fdcc5e5SRuslan Bukin * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG> 37804dd52SRuslan Bukin * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com> 41fdcc5e5SRuslan Bukin * All rights reserved. 51fdcc5e5SRuslan Bukin * 61fdcc5e5SRuslan Bukin * Portions of this software were developed by SRI International and the 71fdcc5e5SRuslan Bukin * University of Cambridge Computer Laboratory under DARPA/AFRL contract 81fdcc5e5SRuslan Bukin * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. 91fdcc5e5SRuslan Bukin * 101fdcc5e5SRuslan Bukin * Portions of this software were developed by the University of Cambridge 111fdcc5e5SRuslan Bukin * Computer Laboratory as part of the CTSRD Project, with support from the 121fdcc5e5SRuslan Bukin * UK Higher Education Innovation Fund (HEIF). 131fdcc5e5SRuslan Bukin * 141fdcc5e5SRuslan Bukin * Redistribution and use in source and binary forms, with or without 151fdcc5e5SRuslan Bukin * modification, are permitted provided that the following conditions 161fdcc5e5SRuslan Bukin * are met: 171fdcc5e5SRuslan Bukin * 1. Redistributions of source code must retain the above copyright 181fdcc5e5SRuslan Bukin * notice, this list of conditions and the following disclaimer. 191fdcc5e5SRuslan Bukin * 2. Redistributions in binary form must reproduce the above copyright 201fdcc5e5SRuslan Bukin * notice, this list of conditions and the following disclaimer in the 211fdcc5e5SRuslan Bukin * documentation and/or other materials provided with the distribution. 221fdcc5e5SRuslan Bukin * 231fdcc5e5SRuslan Bukin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 241fdcc5e5SRuslan Bukin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 251fdcc5e5SRuslan Bukin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 261fdcc5e5SRuslan Bukin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 271fdcc5e5SRuslan Bukin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 281fdcc5e5SRuslan Bukin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 291fdcc5e5SRuslan Bukin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 301fdcc5e5SRuslan Bukin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 311fdcc5e5SRuslan Bukin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 321fdcc5e5SRuslan Bukin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 331fdcc5e5SRuslan Bukin * SUCH DAMAGE. 341fdcc5e5SRuslan Bukin */ 351fdcc5e5SRuslan Bukin 361fdcc5e5SRuslan Bukin #ifndef _FENV_H_ 371fdcc5e5SRuslan Bukin #define _FENV_H_ 381fdcc5e5SRuslan Bukin 391fdcc5e5SRuslan Bukin #include <sys/_types.h> 401fdcc5e5SRuslan Bukin 411fdcc5e5SRuslan Bukin #ifndef __fenv_static 421fdcc5e5SRuslan Bukin #define __fenv_static static 431fdcc5e5SRuslan Bukin #endif 441fdcc5e5SRuslan Bukin 451fdcc5e5SRuslan Bukin typedef __uint64_t fenv_t; 461fdcc5e5SRuslan Bukin typedef __uint64_t fexcept_t; 471fdcc5e5SRuslan Bukin 481fdcc5e5SRuslan Bukin /* Exception flags */ 491fdcc5e5SRuslan Bukin #define FE_INVALID 0x0010 501fdcc5e5SRuslan Bukin #define FE_DIVBYZERO 0x0008 511fdcc5e5SRuslan Bukin #define FE_OVERFLOW 0x0004 521fdcc5e5SRuslan Bukin #define FE_UNDERFLOW 0x0002 531fdcc5e5SRuslan Bukin #define FE_INEXACT 0x0001 541fdcc5e5SRuslan Bukin #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ 551fdcc5e5SRuslan Bukin FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) 561fdcc5e5SRuslan Bukin 571fdcc5e5SRuslan Bukin /* 581fdcc5e5SRuslan Bukin * RISC-V Rounding modes 591fdcc5e5SRuslan Bukin */ 601fdcc5e5SRuslan Bukin #define _ROUND_SHIFT 5 617804dd52SRuslan Bukin #define FE_TONEAREST (0x00 << _ROUND_SHIFT) 627804dd52SRuslan Bukin #define FE_TOWARDZERO (0x01 << _ROUND_SHIFT) 637804dd52SRuslan Bukin #define FE_DOWNWARD (0x02 << _ROUND_SHIFT) 647804dd52SRuslan Bukin #define FE_UPWARD (0x03 << _ROUND_SHIFT) 651fdcc5e5SRuslan Bukin #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ 661fdcc5e5SRuslan Bukin FE_UPWARD | FE_TOWARDZERO) 671fdcc5e5SRuslan Bukin 681fdcc5e5SRuslan Bukin __BEGIN_DECLS 691fdcc5e5SRuslan Bukin 701fdcc5e5SRuslan Bukin /* Default floating-point environment */ 711fdcc5e5SRuslan Bukin extern const fenv_t __fe_dfl_env; 721fdcc5e5SRuslan Bukin #define FE_DFL_ENV (&__fe_dfl_env) 731fdcc5e5SRuslan Bukin 743b05ffafSBrooks Davis #if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double) 753b05ffafSBrooks Davis #if defined(__riscv_float_abi_single) 763b05ffafSBrooks Davis #error single precision floating point ABI not supported 773b05ffafSBrooks Davis #else 783b05ffafSBrooks Davis #error compiler did not set soft/hard float macros 793b05ffafSBrooks Davis #endif 803b05ffafSBrooks Davis #endif 813b05ffafSBrooks Davis 823b05ffafSBrooks Davis #ifndef __riscv_float_abi_soft 837804dd52SRuslan Bukin #define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) 847804dd52SRuslan Bukin #define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) 857804dd52SRuslan Bukin #endif 861fdcc5e5SRuslan Bukin 873b05ffafSBrooks Davis #ifdef __riscv_float_abi_soft 887804dd52SRuslan Bukin int feclearexcept(int __excepts); 897804dd52SRuslan Bukin int fegetexceptflag(fexcept_t *__flagp, int __excepts); 907804dd52SRuslan Bukin int fesetexceptflag(const fexcept_t *__flagp, int __excepts); 917804dd52SRuslan Bukin int feraiseexcept(int __excepts); 927804dd52SRuslan Bukin int fetestexcept(int __excepts); 937804dd52SRuslan Bukin int fegetround(void); 947804dd52SRuslan Bukin int fesetround(int __round); 957804dd52SRuslan Bukin int fegetenv(fenv_t *__envp); 967804dd52SRuslan Bukin int feholdexcept(fenv_t *__envp); 977804dd52SRuslan Bukin int fesetenv(const fenv_t *__envp); 987804dd52SRuslan Bukin int feupdateenv(const fenv_t *__envp); 997804dd52SRuslan Bukin #else 1001fdcc5e5SRuslan Bukin __fenv_static inline int 1011fdcc5e5SRuslan Bukin feclearexcept(int __excepts) 1021fdcc5e5SRuslan Bukin { 1031fdcc5e5SRuslan Bukin 1047804dd52SRuslan Bukin __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 1057804dd52SRuslan Bukin 1061fdcc5e5SRuslan Bukin return (0); 1071fdcc5e5SRuslan Bukin } 1081fdcc5e5SRuslan Bukin 1091fdcc5e5SRuslan Bukin __fenv_static inline int 1101fdcc5e5SRuslan Bukin fegetexceptflag(fexcept_t *__flagp, int __excepts) 1111fdcc5e5SRuslan Bukin { 1127804dd52SRuslan Bukin fexcept_t __fcsr; 1131fdcc5e5SRuslan Bukin 1147804dd52SRuslan Bukin __rfs(__fcsr); 1157804dd52SRuslan Bukin *__flagp = __fcsr & __excepts; 1167804dd52SRuslan Bukin 1171fdcc5e5SRuslan Bukin return (0); 1181fdcc5e5SRuslan Bukin } 1191fdcc5e5SRuslan Bukin 1201fdcc5e5SRuslan Bukin __fenv_static inline int 1211fdcc5e5SRuslan Bukin fesetexceptflag(const fexcept_t *__flagp, int __excepts) 1221fdcc5e5SRuslan Bukin { 1237804dd52SRuslan Bukin fexcept_t __fcsr; 1241fdcc5e5SRuslan Bukin 1257804dd52SRuslan Bukin __fcsr = *__flagp; 1267804dd52SRuslan Bukin __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 1277804dd52SRuslan Bukin __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); 1287804dd52SRuslan Bukin 1291fdcc5e5SRuslan Bukin return (0); 1301fdcc5e5SRuslan Bukin } 1311fdcc5e5SRuslan Bukin 1321fdcc5e5SRuslan Bukin __fenv_static inline int 1331fdcc5e5SRuslan Bukin feraiseexcept(int __excepts) 1341fdcc5e5SRuslan Bukin { 1351fdcc5e5SRuslan Bukin 1367804dd52SRuslan Bukin __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); 1377804dd52SRuslan Bukin 1381fdcc5e5SRuslan Bukin return (0); 1391fdcc5e5SRuslan Bukin } 1401fdcc5e5SRuslan Bukin 1411fdcc5e5SRuslan Bukin __fenv_static inline int 1421fdcc5e5SRuslan Bukin fetestexcept(int __excepts) 1431fdcc5e5SRuslan Bukin { 1447804dd52SRuslan Bukin fexcept_t __fcsr; 1451fdcc5e5SRuslan Bukin 1467804dd52SRuslan Bukin __rfs(__fcsr); 1477804dd52SRuslan Bukin 1487804dd52SRuslan Bukin return (__fcsr & __excepts); 1491fdcc5e5SRuslan Bukin } 1501fdcc5e5SRuslan Bukin 1511fdcc5e5SRuslan Bukin __fenv_static inline int 1521fdcc5e5SRuslan Bukin fegetround(void) 1531fdcc5e5SRuslan Bukin { 1547804dd52SRuslan Bukin fexcept_t __fcsr; 1551fdcc5e5SRuslan Bukin 1567804dd52SRuslan Bukin __rfs(__fcsr); 1577804dd52SRuslan Bukin 1587804dd52SRuslan Bukin return (__fcsr & _ROUND_MASK); 1591fdcc5e5SRuslan Bukin } 1601fdcc5e5SRuslan Bukin 1611fdcc5e5SRuslan Bukin __fenv_static inline int 1621fdcc5e5SRuslan Bukin fesetround(int __round) 1631fdcc5e5SRuslan Bukin { 1647804dd52SRuslan Bukin fexcept_t __fcsr; 1651fdcc5e5SRuslan Bukin 1667804dd52SRuslan Bukin if (__round & ~_ROUND_MASK) 1671fdcc5e5SRuslan Bukin return (-1); 1687804dd52SRuslan Bukin 1697804dd52SRuslan Bukin __rfs(__fcsr); 1707804dd52SRuslan Bukin __fcsr &= ~_ROUND_MASK; 1717804dd52SRuslan Bukin __fcsr |= __round; 1727804dd52SRuslan Bukin __wfs(__fcsr); 1737804dd52SRuslan Bukin 1747804dd52SRuslan Bukin return (0); 1751fdcc5e5SRuslan Bukin } 1761fdcc5e5SRuslan Bukin 1771fdcc5e5SRuslan Bukin __fenv_static inline int 1781fdcc5e5SRuslan Bukin fegetenv(fenv_t *__envp) 1791fdcc5e5SRuslan Bukin { 1801fdcc5e5SRuslan Bukin 1817804dd52SRuslan Bukin __rfs(*__envp); 1827804dd52SRuslan Bukin 1831fdcc5e5SRuslan Bukin return (0); 1841fdcc5e5SRuslan Bukin } 1851fdcc5e5SRuslan Bukin 1861fdcc5e5SRuslan Bukin __fenv_static inline int 18715211f19SAlex Richardson feholdexcept(fenv_t *__envp __unused) 1881fdcc5e5SRuslan Bukin { 1891fdcc5e5SRuslan Bukin 1907804dd52SRuslan Bukin /* No exception traps. */ 1917804dd52SRuslan Bukin 1927804dd52SRuslan Bukin return (-1); 1931fdcc5e5SRuslan Bukin } 1941fdcc5e5SRuslan Bukin 1951fdcc5e5SRuslan Bukin __fenv_static inline int 1961fdcc5e5SRuslan Bukin fesetenv(const fenv_t *__envp) 1971fdcc5e5SRuslan Bukin { 1981fdcc5e5SRuslan Bukin 1991fdcc5e5SRuslan Bukin __wfs(*__envp); 2007804dd52SRuslan Bukin 2011fdcc5e5SRuslan Bukin return (0); 2021fdcc5e5SRuslan Bukin } 2031fdcc5e5SRuslan Bukin 2041fdcc5e5SRuslan Bukin __fenv_static inline int 2051fdcc5e5SRuslan Bukin feupdateenv(const fenv_t *__envp) 2061fdcc5e5SRuslan Bukin { 2077804dd52SRuslan Bukin fexcept_t __fcsr; 2081fdcc5e5SRuslan Bukin 2097804dd52SRuslan Bukin __rfs(__fcsr); 2101fdcc5e5SRuslan Bukin __wfs(*__envp); 2117804dd52SRuslan Bukin feraiseexcept(__fcsr & FE_ALL_EXCEPT); 2127804dd52SRuslan Bukin 2131fdcc5e5SRuslan Bukin return (0); 2141fdcc5e5SRuslan Bukin } 2153b05ffafSBrooks Davis #endif /* !__riscv_float_abi_soft */ 2161fdcc5e5SRuslan Bukin 2171fdcc5e5SRuslan Bukin #if __BSD_VISIBLE 2181fdcc5e5SRuslan Bukin 2193b05ffafSBrooks Davis #ifdef __riscv_float_abi_soft 2207804dd52SRuslan Bukin int feenableexcept(int __mask); 2217804dd52SRuslan Bukin int fedisableexcept(int __mask); 2227804dd52SRuslan Bukin int fegetexcept(void); 2237804dd52SRuslan Bukin #else 224*1947a938SBrooks Davis __fenv_static inline int 22515211f19SAlex Richardson feenableexcept(int __mask __unused) 2261fdcc5e5SRuslan Bukin { 2271fdcc5e5SRuslan Bukin 2287804dd52SRuslan Bukin /* No exception traps. */ 2297804dd52SRuslan Bukin 230dd5ed53aSAlex Richardson return (0); 2311fdcc5e5SRuslan Bukin } 2321fdcc5e5SRuslan Bukin 233*1947a938SBrooks Davis __fenv_static inline int 23415211f19SAlex Richardson fedisableexcept(int __mask __unused) 2351fdcc5e5SRuslan Bukin { 2361fdcc5e5SRuslan Bukin 2377804dd52SRuslan Bukin /* No exception traps. */ 2387804dd52SRuslan Bukin 2397804dd52SRuslan Bukin return (0); 2401fdcc5e5SRuslan Bukin } 2411fdcc5e5SRuslan Bukin 242*1947a938SBrooks Davis /* We currently provide no external definition of fegetexcept(). */ 2431fdcc5e5SRuslan Bukin static inline int 2441fdcc5e5SRuslan Bukin fegetexcept(void) 2451fdcc5e5SRuslan Bukin { 2461fdcc5e5SRuslan Bukin 2477804dd52SRuslan Bukin /* No exception traps. */ 2487804dd52SRuslan Bukin 2497804dd52SRuslan Bukin return (0); 2501fdcc5e5SRuslan Bukin } 2513b05ffafSBrooks Davis #endif /* !__riscv_float_abi_soft */ 2521fdcc5e5SRuslan Bukin 2531fdcc5e5SRuslan Bukin #endif /* __BSD_VISIBLE */ 2541fdcc5e5SRuslan Bukin 2551fdcc5e5SRuslan Bukin __END_DECLS 2561fdcc5e5SRuslan Bukin 2571fdcc5e5SRuslan Bukin #endif /* !_FENV_H_ */ 258