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 * $FreeBSD$ 361fdcc5e5SRuslan Bukin */ 371fdcc5e5SRuslan Bukin 381fdcc5e5SRuslan Bukin #ifndef _FENV_H_ 391fdcc5e5SRuslan Bukin #define _FENV_H_ 401fdcc5e5SRuslan Bukin 411fdcc5e5SRuslan Bukin #include <sys/_types.h> 421fdcc5e5SRuslan Bukin 431fdcc5e5SRuslan Bukin #ifndef __fenv_static 441fdcc5e5SRuslan Bukin #define __fenv_static static 451fdcc5e5SRuslan Bukin #endif 461fdcc5e5SRuslan Bukin 471fdcc5e5SRuslan Bukin typedef __uint64_t fenv_t; 481fdcc5e5SRuslan Bukin typedef __uint64_t fexcept_t; 491fdcc5e5SRuslan Bukin 501fdcc5e5SRuslan Bukin /* Exception flags */ 511fdcc5e5SRuslan Bukin #define FE_INVALID 0x0010 521fdcc5e5SRuslan Bukin #define FE_DIVBYZERO 0x0008 531fdcc5e5SRuslan Bukin #define FE_OVERFLOW 0x0004 541fdcc5e5SRuslan Bukin #define FE_UNDERFLOW 0x0002 551fdcc5e5SRuslan Bukin #define FE_INEXACT 0x0001 561fdcc5e5SRuslan Bukin #define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ 571fdcc5e5SRuslan Bukin FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) 581fdcc5e5SRuslan Bukin 591fdcc5e5SRuslan Bukin /* 601fdcc5e5SRuslan Bukin * RISC-V Rounding modes 611fdcc5e5SRuslan Bukin */ 621fdcc5e5SRuslan Bukin #define _ROUND_SHIFT 5 637804dd52SRuslan Bukin #define FE_TONEAREST (0x00 << _ROUND_SHIFT) 647804dd52SRuslan Bukin #define FE_TOWARDZERO (0x01 << _ROUND_SHIFT) 657804dd52SRuslan Bukin #define FE_DOWNWARD (0x02 << _ROUND_SHIFT) 667804dd52SRuslan Bukin #define FE_UPWARD (0x03 << _ROUND_SHIFT) 671fdcc5e5SRuslan Bukin #define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ 681fdcc5e5SRuslan Bukin FE_UPWARD | FE_TOWARDZERO) 691fdcc5e5SRuslan Bukin 701fdcc5e5SRuslan Bukin __BEGIN_DECLS 711fdcc5e5SRuslan Bukin 721fdcc5e5SRuslan Bukin /* Default floating-point environment */ 731fdcc5e5SRuslan Bukin extern const fenv_t __fe_dfl_env; 741fdcc5e5SRuslan Bukin #define FE_DFL_ENV (&__fe_dfl_env) 751fdcc5e5SRuslan Bukin 763b05ffafSBrooks Davis #if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double) 773b05ffafSBrooks Davis #if defined(__riscv_float_abi_single) 783b05ffafSBrooks Davis #error single precision floating point ABI not supported 793b05ffafSBrooks Davis #else 803b05ffafSBrooks Davis #error compiler did not set soft/hard float macros 813b05ffafSBrooks Davis #endif 823b05ffafSBrooks Davis #endif 833b05ffafSBrooks Davis 843b05ffafSBrooks Davis #ifndef __riscv_float_abi_soft 857804dd52SRuslan Bukin #define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) 867804dd52SRuslan Bukin #define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) 877804dd52SRuslan Bukin #endif 881fdcc5e5SRuslan Bukin 893b05ffafSBrooks Davis #ifdef __riscv_float_abi_soft 907804dd52SRuslan Bukin int feclearexcept(int __excepts); 917804dd52SRuslan Bukin int fegetexceptflag(fexcept_t *__flagp, int __excepts); 927804dd52SRuslan Bukin int fesetexceptflag(const fexcept_t *__flagp, int __excepts); 937804dd52SRuslan Bukin int feraiseexcept(int __excepts); 947804dd52SRuslan Bukin int fetestexcept(int __excepts); 957804dd52SRuslan Bukin int fegetround(void); 967804dd52SRuslan Bukin int fesetround(int __round); 977804dd52SRuslan Bukin int fegetenv(fenv_t *__envp); 987804dd52SRuslan Bukin int feholdexcept(fenv_t *__envp); 997804dd52SRuslan Bukin int fesetenv(const fenv_t *__envp); 1007804dd52SRuslan Bukin int feupdateenv(const fenv_t *__envp); 1017804dd52SRuslan Bukin #else 1021fdcc5e5SRuslan Bukin __fenv_static inline int 1031fdcc5e5SRuslan Bukin feclearexcept(int __excepts) 1041fdcc5e5SRuslan Bukin { 1051fdcc5e5SRuslan Bukin 1067804dd52SRuslan Bukin __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 1077804dd52SRuslan Bukin 1081fdcc5e5SRuslan Bukin return (0); 1091fdcc5e5SRuslan Bukin } 1101fdcc5e5SRuslan Bukin 1111fdcc5e5SRuslan Bukin __fenv_static inline int 1121fdcc5e5SRuslan Bukin fegetexceptflag(fexcept_t *__flagp, int __excepts) 1131fdcc5e5SRuslan Bukin { 1147804dd52SRuslan Bukin fexcept_t __fcsr; 1151fdcc5e5SRuslan Bukin 1167804dd52SRuslan Bukin __rfs(__fcsr); 1177804dd52SRuslan Bukin *__flagp = __fcsr & __excepts; 1187804dd52SRuslan Bukin 1191fdcc5e5SRuslan Bukin return (0); 1201fdcc5e5SRuslan Bukin } 1211fdcc5e5SRuslan Bukin 1221fdcc5e5SRuslan Bukin __fenv_static inline int 1231fdcc5e5SRuslan Bukin fesetexceptflag(const fexcept_t *__flagp, int __excepts) 1241fdcc5e5SRuslan Bukin { 1257804dd52SRuslan Bukin fexcept_t __fcsr; 1261fdcc5e5SRuslan Bukin 1277804dd52SRuslan Bukin __fcsr = *__flagp; 1287804dd52SRuslan Bukin __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); 1297804dd52SRuslan Bukin __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); 1307804dd52SRuslan Bukin 1311fdcc5e5SRuslan Bukin return (0); 1321fdcc5e5SRuslan Bukin } 1331fdcc5e5SRuslan Bukin 1341fdcc5e5SRuslan Bukin __fenv_static inline int 1351fdcc5e5SRuslan Bukin feraiseexcept(int __excepts) 1361fdcc5e5SRuslan Bukin { 1371fdcc5e5SRuslan Bukin 1387804dd52SRuslan Bukin __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); 1397804dd52SRuslan Bukin 1401fdcc5e5SRuslan Bukin return (0); 1411fdcc5e5SRuslan Bukin } 1421fdcc5e5SRuslan Bukin 1431fdcc5e5SRuslan Bukin __fenv_static inline int 1441fdcc5e5SRuslan Bukin fetestexcept(int __excepts) 1451fdcc5e5SRuslan Bukin { 1467804dd52SRuslan Bukin fexcept_t __fcsr; 1471fdcc5e5SRuslan Bukin 1487804dd52SRuslan Bukin __rfs(__fcsr); 1497804dd52SRuslan Bukin 1507804dd52SRuslan Bukin return (__fcsr & __excepts); 1511fdcc5e5SRuslan Bukin } 1521fdcc5e5SRuslan Bukin 1531fdcc5e5SRuslan Bukin __fenv_static inline int 1541fdcc5e5SRuslan Bukin fegetround(void) 1551fdcc5e5SRuslan Bukin { 1567804dd52SRuslan Bukin fexcept_t __fcsr; 1571fdcc5e5SRuslan Bukin 1587804dd52SRuslan Bukin __rfs(__fcsr); 1597804dd52SRuslan Bukin 1607804dd52SRuslan Bukin return (__fcsr & _ROUND_MASK); 1611fdcc5e5SRuslan Bukin } 1621fdcc5e5SRuslan Bukin 1631fdcc5e5SRuslan Bukin __fenv_static inline int 1641fdcc5e5SRuslan Bukin fesetround(int __round) 1651fdcc5e5SRuslan Bukin { 1667804dd52SRuslan Bukin fexcept_t __fcsr; 1671fdcc5e5SRuslan Bukin 1687804dd52SRuslan Bukin if (__round & ~_ROUND_MASK) 1691fdcc5e5SRuslan Bukin return (-1); 1707804dd52SRuslan Bukin 1717804dd52SRuslan Bukin __rfs(__fcsr); 1727804dd52SRuslan Bukin __fcsr &= ~_ROUND_MASK; 1737804dd52SRuslan Bukin __fcsr |= __round; 1747804dd52SRuslan Bukin __wfs(__fcsr); 1757804dd52SRuslan Bukin 1767804dd52SRuslan Bukin return (0); 1771fdcc5e5SRuslan Bukin } 1781fdcc5e5SRuslan Bukin 1791fdcc5e5SRuslan Bukin __fenv_static inline int 1801fdcc5e5SRuslan Bukin fegetenv(fenv_t *__envp) 1811fdcc5e5SRuslan Bukin { 1821fdcc5e5SRuslan Bukin 1837804dd52SRuslan Bukin __rfs(*__envp); 1847804dd52SRuslan Bukin 1851fdcc5e5SRuslan Bukin return (0); 1861fdcc5e5SRuslan Bukin } 1871fdcc5e5SRuslan Bukin 1881fdcc5e5SRuslan Bukin __fenv_static inline int 18915211f19SAlex Richardson feholdexcept(fenv_t *__envp __unused) 1901fdcc5e5SRuslan Bukin { 1911fdcc5e5SRuslan Bukin 1927804dd52SRuslan Bukin /* No exception traps. */ 1937804dd52SRuslan Bukin 1947804dd52SRuslan Bukin return (-1); 1951fdcc5e5SRuslan Bukin } 1961fdcc5e5SRuslan Bukin 1971fdcc5e5SRuslan Bukin __fenv_static inline int 1981fdcc5e5SRuslan Bukin fesetenv(const fenv_t *__envp) 1991fdcc5e5SRuslan Bukin { 2001fdcc5e5SRuslan Bukin 2011fdcc5e5SRuslan Bukin __wfs(*__envp); 2027804dd52SRuslan Bukin 2031fdcc5e5SRuslan Bukin return (0); 2041fdcc5e5SRuslan Bukin } 2051fdcc5e5SRuslan Bukin 2061fdcc5e5SRuslan Bukin __fenv_static inline int 2071fdcc5e5SRuslan Bukin feupdateenv(const fenv_t *__envp) 2081fdcc5e5SRuslan Bukin { 2097804dd52SRuslan Bukin fexcept_t __fcsr; 2101fdcc5e5SRuslan Bukin 2117804dd52SRuslan Bukin __rfs(__fcsr); 2121fdcc5e5SRuslan Bukin __wfs(*__envp); 2137804dd52SRuslan Bukin feraiseexcept(__fcsr & FE_ALL_EXCEPT); 2147804dd52SRuslan Bukin 2151fdcc5e5SRuslan Bukin return (0); 2161fdcc5e5SRuslan Bukin } 2173b05ffafSBrooks Davis #endif /* !__riscv_float_abi_soft */ 2181fdcc5e5SRuslan Bukin 2191fdcc5e5SRuslan Bukin #if __BSD_VISIBLE 2201fdcc5e5SRuslan Bukin 2211fdcc5e5SRuslan Bukin /* We currently provide no external definitions of the functions below. */ 2221fdcc5e5SRuslan Bukin 2233b05ffafSBrooks Davis #ifdef __riscv_float_abi_soft 2247804dd52SRuslan Bukin int feenableexcept(int __mask); 2257804dd52SRuslan Bukin int fedisableexcept(int __mask); 2267804dd52SRuslan Bukin int fegetexcept(void); 2277804dd52SRuslan Bukin #else 2281fdcc5e5SRuslan Bukin static inline int 22915211f19SAlex Richardson feenableexcept(int __mask __unused) 2301fdcc5e5SRuslan Bukin { 2311fdcc5e5SRuslan Bukin 2327804dd52SRuslan Bukin /* No exception traps. */ 2337804dd52SRuslan Bukin 234*dd5ed53aSAlex Richardson return (0); 2351fdcc5e5SRuslan Bukin } 2361fdcc5e5SRuslan Bukin 2371fdcc5e5SRuslan Bukin static inline int 23815211f19SAlex Richardson fedisableexcept(int __mask __unused) 2391fdcc5e5SRuslan Bukin { 2401fdcc5e5SRuslan Bukin 2417804dd52SRuslan Bukin /* No exception traps. */ 2427804dd52SRuslan Bukin 2437804dd52SRuslan Bukin return (0); 2441fdcc5e5SRuslan Bukin } 2451fdcc5e5SRuslan Bukin 2461fdcc5e5SRuslan Bukin static inline int 2471fdcc5e5SRuslan Bukin fegetexcept(void) 2481fdcc5e5SRuslan Bukin { 2491fdcc5e5SRuslan Bukin 2507804dd52SRuslan Bukin /* No exception traps. */ 2517804dd52SRuslan Bukin 2527804dd52SRuslan Bukin return (0); 2531fdcc5e5SRuslan Bukin } 2543b05ffafSBrooks Davis #endif /* !__riscv_float_abi_soft */ 2551fdcc5e5SRuslan Bukin 2561fdcc5e5SRuslan Bukin #endif /* __BSD_VISIBLE */ 2571fdcc5e5SRuslan Bukin 2581fdcc5e5SRuslan Bukin __END_DECLS 2591fdcc5e5SRuslan Bukin 2601fdcc5e5SRuslan Bukin #endif /* !_FENV_H_ */ 261