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
feclearexcept(int __excepts)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
fegetexceptflag(fexcept_t * __flagp,int __excepts)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
fesetexceptflag(const fexcept_t * __flagp,int __excepts)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
feraiseexcept(int __excepts)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
fetestexcept(int __excepts)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
fegetround(void)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
fesetround(int __round)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
fegetenv(fenv_t * __envp)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
feholdexcept(fenv_t * __envp __unused)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
fesetenv(const fenv_t * __envp)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
feupdateenv(const fenv_t * __envp)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
feenableexcept(int __mask __unused)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
fedisableexcept(int __mask __unused)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
fegetexcept(void)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