xref: /freebsd/lib/msun/riscv/fenv.h (revision 312a05c3)
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 
74312a05c3SBrooks Davis #ifndef __riscv_float_abi_double
75312a05c3SBrooks 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