xref: /freebsd/lib/msun/riscv/fenv.h (revision dd5ed53a2f93a5a54efe96bed6bbd0f18b6bdbe2)
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