master
1/*-
2 * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
3 * Copyright (c) 2015-2016 Ruslan Bukin <br@bsdpad.com>
4 * All rights reserved.
5 *
6 * Portions of this software were developed by SRI International and the
7 * University of Cambridge Computer Laboratory under DARPA/AFRL contract
8 * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
9 *
10 * Portions of this software were developed by the University of Cambridge
11 * Computer Laboratory as part of the CTSRD Project, with support from the
12 * UK Higher Education Innovation Fund (HEIF).
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35
36#ifndef _FENV_H_
37#define _FENV_H_
38
39#include <sys/_types.h>
40
41#ifndef __fenv_static
42#define __fenv_static static
43#endif
44
45typedef __uint64_t fenv_t;
46typedef __uint64_t fexcept_t;
47
48/* Exception flags */
49#define FE_INVALID 0x0010
50#define FE_DIVBYZERO 0x0008
51#define FE_OVERFLOW 0x0004
52#define FE_UNDERFLOW 0x0002
53#define FE_INEXACT 0x0001
54#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \
55 FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW)
56
57/*
58 * RISC-V Rounding modes
59 */
60#define _ROUND_SHIFT 5
61#define FE_TONEAREST (0x00 << _ROUND_SHIFT)
62#define FE_TOWARDZERO (0x01 << _ROUND_SHIFT)
63#define FE_DOWNWARD (0x02 << _ROUND_SHIFT)
64#define FE_UPWARD (0x03 << _ROUND_SHIFT)
65#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \
66 FE_UPWARD | FE_TOWARDZERO)
67
68__BEGIN_DECLS
69
70/* Default floating-point environment */
71extern const fenv_t __fe_dfl_env;
72#define FE_DFL_ENV (&__fe_dfl_env)
73
74#if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double)
75#if defined(__riscv_float_abi_single)
76#error single precision floating point ABI not supported
77#else
78#error compiler did not set soft/hard float macros
79#endif
80#endif
81
82#ifndef __riscv_float_abi_soft
83#define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr))
84#define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr))
85#endif
86
87#ifdef __riscv_float_abi_soft
88int feclearexcept(int __excepts);
89int fegetexceptflag(fexcept_t *__flagp, int __excepts);
90int fesetexceptflag(const fexcept_t *__flagp, int __excepts);
91int feraiseexcept(int __excepts);
92int fetestexcept(int __excepts);
93int fegetround(void);
94int fesetround(int __round);
95int fegetenv(fenv_t *__envp);
96int feholdexcept(fenv_t *__envp);
97int fesetenv(const fenv_t *__envp);
98int feupdateenv(const fenv_t *__envp);
99#else
100__fenv_static inline int
101feclearexcept(int __excepts)
102{
103
104 __asm __volatile("csrc fflags, %0" :: "r"(__excepts));
105
106 return (0);
107}
108
109__fenv_static inline int
110fegetexceptflag(fexcept_t *__flagp, int __excepts)
111{
112 fexcept_t __fcsr;
113
114 __rfs(__fcsr);
115 *__flagp = __fcsr & __excepts;
116
117 return (0);
118}
119
120__fenv_static inline int
121fesetexceptflag(const fexcept_t *__flagp, int __excepts)
122{
123 fexcept_t __fcsr;
124
125 __fcsr = *__flagp;
126 __asm __volatile("csrc fflags, %0" :: "r"(__excepts));
127 __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts));
128
129 return (0);
130}
131
132__fenv_static inline int
133feraiseexcept(int __excepts)
134{
135
136 __asm __volatile("csrs fflags, %0" :: "r"(__excepts));
137
138 return (0);
139}
140
141__fenv_static inline int
142fetestexcept(int __excepts)
143{
144 fexcept_t __fcsr;
145
146 __rfs(__fcsr);
147
148 return (__fcsr & __excepts);
149}
150
151__fenv_static inline int
152fegetround(void)
153{
154 fexcept_t __fcsr;
155
156 __rfs(__fcsr);
157
158 return (__fcsr & _ROUND_MASK);
159}
160
161__fenv_static inline int
162fesetround(int __round)
163{
164 fexcept_t __fcsr;
165
166 if (__round & ~_ROUND_MASK)
167 return (-1);
168
169 __rfs(__fcsr);
170 __fcsr &= ~_ROUND_MASK;
171 __fcsr |= __round;
172 __wfs(__fcsr);
173
174 return (0);
175}
176
177__fenv_static inline int
178fegetenv(fenv_t *__envp)
179{
180
181 __rfs(*__envp);
182
183 return (0);
184}
185
186__fenv_static inline int
187feholdexcept(fenv_t *__envp __unused)
188{
189
190 /* No exception traps. */
191
192 return (-1);
193}
194
195__fenv_static inline int
196fesetenv(const fenv_t *__envp)
197{
198
199 __wfs(*__envp);
200
201 return (0);
202}
203
204__fenv_static inline int
205feupdateenv(const fenv_t *__envp)
206{
207 fexcept_t __fcsr;
208
209 __rfs(__fcsr);
210 __wfs(*__envp);
211 feraiseexcept(__fcsr & FE_ALL_EXCEPT);
212
213 return (0);
214}
215#endif /* !__riscv_float_abi_soft */
216
217#if __BSD_VISIBLE
218
219#ifdef __riscv_float_abi_soft
220int feenableexcept(int __mask);
221int fedisableexcept(int __mask);
222int fegetexcept(void);
223#else
224__fenv_static inline int
225feenableexcept(int __mask __unused)
226{
227
228 /* No exception traps. */
229
230 return (0);
231}
232
233__fenv_static inline int
234fedisableexcept(int __mask __unused)
235{
236
237 /* No exception traps. */
238
239 return (0);
240}
241
242/* We currently provide no external definition of fegetexcept(). */
243static inline int
244fegetexcept(void)
245{
246
247 /* No exception traps. */
248
249 return (0);
250}
251#endif /* !__riscv_float_abi_soft */
252
253#endif /* __BSD_VISIBLE */
254
255__END_DECLS
256
257#endif /* !_FENV_H_ */