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 74*312a05c3SBrooks Davis #ifndef __riscv_float_abi_double 75*312a05c3SBrooks Davis #error only double hard float ABI supported 763b05ffafSBrooks Davis #endif 773b05ffafSBrooks Davis 787804dd52SRuslan Bukin #define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) 797804dd52SRuslan Bukin #define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) 801fdcc5e5SRuslan Bukin 811fdcc5e5SRuslan Bukin __fenv_static inline int 821fdcc5e5SRuslan Bukin feclearexcept(int __excepts) 831fdcc5e5SRuslan Bukin { 841fdcc5e5SRuslan Bukin 857804dd52SRuslan Bukin __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 867804dd52SRuslan Bukin 871fdcc5e5SRuslan Bukin return (0); 881fdcc5e5SRuslan Bukin } 891fdcc5e5SRuslan Bukin 901fdcc5e5SRuslan Bukin __fenv_static inline int 911fdcc5e5SRuslan Bukin fegetexceptflag(fexcept_t *__flagp, int __excepts) 921fdcc5e5SRuslan Bukin { 937804dd52SRuslan Bukin fexcept_t __fcsr; 941fdcc5e5SRuslan Bukin 957804dd52SRuslan Bukin __rfs(__fcsr); 967804dd52SRuslan Bukin *__flagp = __fcsr & __excepts; 977804dd52SRuslan Bukin 981fdcc5e5SRuslan Bukin return (0); 991fdcc5e5SRuslan Bukin } 1001fdcc5e5SRuslan Bukin 1011fdcc5e5SRuslan Bukin __fenv_static inline int 1021fdcc5e5SRuslan Bukin fesetexceptflag(const fexcept_t *__flagp, int __excepts) 1031fdcc5e5SRuslan Bukin { 1047804dd52SRuslan Bukin fexcept_t __fcsr; 1051fdcc5e5SRuslan Bukin 1067804dd52SRuslan Bukin __fcsr = *__flagp; 1077804dd52SRuslan Bukin __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 1087804dd52SRuslan Bukin __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); 1097804dd52SRuslan Bukin 1101fdcc5e5SRuslan Bukin return (0); 1111fdcc5e5SRuslan Bukin } 1121fdcc5e5SRuslan Bukin 1131fdcc5e5SRuslan Bukin __fenv_static inline int 1141fdcc5e5SRuslan Bukin feraiseexcept(int __excepts) 1151fdcc5e5SRuslan Bukin { 1161fdcc5e5SRuslan Bukin 1177804dd52SRuslan Bukin __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); 1187804dd52SRuslan Bukin 1191fdcc5e5SRuslan Bukin return (0); 1201fdcc5e5SRuslan Bukin } 1211fdcc5e5SRuslan Bukin 1221fdcc5e5SRuslan Bukin __fenv_static inline int 1231fdcc5e5SRuslan Bukin fetestexcept(int __excepts) 1241fdcc5e5SRuslan Bukin { 1257804dd52SRuslan Bukin fexcept_t __fcsr; 1261fdcc5e5SRuslan Bukin 1277804dd52SRuslan Bukin __rfs(__fcsr); 1287804dd52SRuslan Bukin 1297804dd52SRuslan Bukin return (__fcsr & __excepts); 1301fdcc5e5SRuslan Bukin } 1311fdcc5e5SRuslan Bukin 1321fdcc5e5SRuslan Bukin __fenv_static inline int 1331fdcc5e5SRuslan Bukin fegetround(void) 1341fdcc5e5SRuslan Bukin { 1357804dd52SRuslan Bukin fexcept_t __fcsr; 1361fdcc5e5SRuslan Bukin 1377804dd52SRuslan Bukin __rfs(__fcsr); 1387804dd52SRuslan Bukin 1397804dd52SRuslan Bukin return (__fcsr & _ROUND_MASK); 1401fdcc5e5SRuslan Bukin } 1411fdcc5e5SRuslan Bukin 1421fdcc5e5SRuslan Bukin __fenv_static inline int 1431fdcc5e5SRuslan Bukin fesetround(int __round) 1441fdcc5e5SRuslan Bukin { 1457804dd52SRuslan Bukin fexcept_t __fcsr; 1461fdcc5e5SRuslan Bukin 1477804dd52SRuslan Bukin if (__round & ~_ROUND_MASK) 1481fdcc5e5SRuslan Bukin return (-1); 1497804dd52SRuslan Bukin 1507804dd52SRuslan Bukin __rfs(__fcsr); 1517804dd52SRuslan Bukin __fcsr &= ~_ROUND_MASK; 1527804dd52SRuslan Bukin __fcsr |= __round; 1537804dd52SRuslan Bukin __wfs(__fcsr); 1547804dd52SRuslan Bukin 1557804dd52SRuslan Bukin return (0); 1561fdcc5e5SRuslan Bukin } 1571fdcc5e5SRuslan Bukin 1581fdcc5e5SRuslan Bukin __fenv_static inline int 1591fdcc5e5SRuslan Bukin fegetenv(fenv_t *__envp) 1601fdcc5e5SRuslan Bukin { 1611fdcc5e5SRuslan Bukin 1627804dd52SRuslan Bukin __rfs(*__envp); 1637804dd52SRuslan Bukin 1641fdcc5e5SRuslan Bukin return (0); 1651fdcc5e5SRuslan Bukin } 1661fdcc5e5SRuslan Bukin 1671fdcc5e5SRuslan Bukin __fenv_static inline int 16815211f19SAlex Richardson feholdexcept(fenv_t *__envp __unused) 1691fdcc5e5SRuslan Bukin { 1701fdcc5e5SRuslan Bukin 1717804dd52SRuslan Bukin /* No exception traps. */ 1727804dd52SRuslan Bukin 1737804dd52SRuslan Bukin return (-1); 1741fdcc5e5SRuslan Bukin } 1751fdcc5e5SRuslan Bukin 1761fdcc5e5SRuslan Bukin __fenv_static inline int 1771fdcc5e5SRuslan Bukin fesetenv(const fenv_t *__envp) 1781fdcc5e5SRuslan Bukin { 1791fdcc5e5SRuslan Bukin 1801fdcc5e5SRuslan Bukin __wfs(*__envp); 1817804dd52SRuslan Bukin 1821fdcc5e5SRuslan Bukin return (0); 1831fdcc5e5SRuslan Bukin } 1841fdcc5e5SRuslan Bukin 1851fdcc5e5SRuslan Bukin __fenv_static inline int 1861fdcc5e5SRuslan Bukin feupdateenv(const fenv_t *__envp) 1871fdcc5e5SRuslan Bukin { 1887804dd52SRuslan Bukin fexcept_t __fcsr; 1891fdcc5e5SRuslan Bukin 1907804dd52SRuslan Bukin __rfs(__fcsr); 1911fdcc5e5SRuslan Bukin __wfs(*__envp); 1927804dd52SRuslan Bukin feraiseexcept(__fcsr & FE_ALL_EXCEPT); 1937804dd52SRuslan Bukin 1941fdcc5e5SRuslan Bukin return (0); 1951fdcc5e5SRuslan Bukin } 1961fdcc5e5SRuslan Bukin 1971fdcc5e5SRuslan Bukin #if __BSD_VISIBLE 1981fdcc5e5SRuslan Bukin 1991947a938SBrooks Davis __fenv_static inline int 20015211f19SAlex Richardson feenableexcept(int __mask __unused) 2011fdcc5e5SRuslan Bukin { 2021fdcc5e5SRuslan Bukin 2037804dd52SRuslan Bukin /* No exception traps. */ 2047804dd52SRuslan Bukin 205dd5ed53aSAlex Richardson return (0); 2061fdcc5e5SRuslan Bukin } 2071fdcc5e5SRuslan Bukin 2081947a938SBrooks Davis __fenv_static inline int 20915211f19SAlex Richardson fedisableexcept(int __mask __unused) 2101fdcc5e5SRuslan Bukin { 2111fdcc5e5SRuslan Bukin 2127804dd52SRuslan Bukin /* No exception traps. */ 2137804dd52SRuslan Bukin 2147804dd52SRuslan Bukin return (0); 2151fdcc5e5SRuslan Bukin } 2161fdcc5e5SRuslan Bukin 2171947a938SBrooks Davis /* We currently provide no external definition of fegetexcept(). */ 2181fdcc5e5SRuslan Bukin static inline int 2191fdcc5e5SRuslan Bukin fegetexcept(void) 2201fdcc5e5SRuslan Bukin { 2211fdcc5e5SRuslan Bukin 2227804dd52SRuslan Bukin /* No exception traps. */ 2237804dd52SRuslan Bukin 2247804dd52SRuslan Bukin return (0); 2251fdcc5e5SRuslan Bukin } 2261fdcc5e5SRuslan Bukin 2271fdcc5e5SRuslan Bukin #endif /* __BSD_VISIBLE */ 2281fdcc5e5SRuslan Bukin 2291fdcc5e5SRuslan Bukin __END_DECLS 2301fdcc5e5SRuslan Bukin 2311fdcc5e5SRuslan Bukin #endif /* !_FENV_H_ */ 232