fenv.h revision 1.2.2.3 1 1.2.2.3 skrll /* $NetBSD: fenv.h,v 1.2.2.3 2016/03/19 11:30:01 skrll Exp $ */
2 1.2.2.2 skrll
3 1.2.2.2 skrll /*-
4 1.2.2.2 skrll * Copyright (c) 2015 The NetBSD Foundation, Inc.
5 1.2.2.2 skrll * All rights reserved.
6 1.2.2.2 skrll *
7 1.2.2.2 skrll * This code is derived from software contributed to The NetBSD Foundation
8 1.2.2.2 skrll * by Christos Zoulas.
9 1.2.2.2 skrll *
10 1.2.2.2 skrll * Redistribution and use in source and binary forms, with or without
11 1.2.2.2 skrll * modification, are permitted provided that the following conditions
12 1.2.2.2 skrll * are met:
13 1.2.2.2 skrll * 1. Redistributions of source code must retain the above copyright
14 1.2.2.2 skrll * notice, this list of conditions and the following disclaimer.
15 1.2.2.2 skrll * 2. Redistributions in binary form must reproduce the above copyright
16 1.2.2.2 skrll * notice, this list of conditions and the following disclaimer in the
17 1.2.2.2 skrll * documentation and/or other materials provided with the distribution.
18 1.2.2.2 skrll *
19 1.2.2.2 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.2.2.2 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.2.2.2 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.2.2.2 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.2.2.2 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.2.2.2 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.2.2.2 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.2.2.2 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.2.2.2 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.2.2.2 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.2.2.2 skrll * POSSIBILITY OF SUCH DAMAGE.
30 1.2.2.2 skrll */
31 1.2.2.2 skrll
32 1.2.2.2 skrll #ifndef _M68K_FENV_H_
33 1.2.2.2 skrll #define _M68K_FENV_H_
34 1.2.2.2 skrll
35 1.2.2.2 skrll #include <sys/stdint.h>
36 1.2.2.2 skrll #include <m68k/float.h>
37 1.2.2.2 skrll #include <m68k/fpreg.h>
38 1.2.2.2 skrll
39 1.2.2.2 skrll #ifndef __fenv_static
40 1.2.2.2 skrll #define __fenv_static static
41 1.2.2.2 skrll #endif
42 1.2.2.2 skrll
43 1.2.2.2 skrll /* Exception bits, from FPSR */
44 1.2.2.2 skrll #define FE_INEXACT FPSR_AINEX
45 1.2.2.2 skrll #define FE_DIVBYZERO FPSR_ADZ
46 1.2.2.2 skrll #define FE_UNDERFLOW FPSR_AUNFL
47 1.2.2.2 skrll #define FE_OVERFLOW FPSR_AOVFL
48 1.2.2.2 skrll #define FE_INVALID FPSR_AIOP
49 1.2.2.2 skrll
50 1.2.2.2 skrll #define FE_ALL_EXCEPT \
51 1.2.2.2 skrll (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)
52 1.2.2.2 skrll
53 1.2.2.2 skrll /* Rounding modes, from FPSR */
54 1.2.2.2 skrll #define FE_TONEAREST FPCR_NEAR
55 1.2.2.2 skrll #define FE_TOWARDZERO FPCR_ZERO
56 1.2.2.2 skrll #define FE_DOWNWARD FPCR_MINF
57 1.2.2.2 skrll #define FE_UPWARD FPCR_PINF
58 1.2.2.2 skrll
59 1.2.2.2 skrll #define _ROUND_MASK \
60 1.2.2.2 skrll (FE_TONEAREST | FE_TOWARDZERO | FE_DOWNWARD | FE_UPWARD)
61 1.2.2.2 skrll
62 1.2.2.3 skrll #if !defined(__mc68010__) && !defined(__mcoldfire__)
63 1.2.2.3 skrll
64 1.2.2.2 skrll typedef uint32_t fexcept_t;
65 1.2.2.2 skrll
66 1.2.2.2 skrll /* same layout as fmovem */
67 1.2.2.2 skrll typedef struct {
68 1.2.2.2 skrll uint32_t fpcr;
69 1.2.2.2 skrll uint32_t fpsr;
70 1.2.2.2 skrll uint32_t fppc;
71 1.2.2.2 skrll } fenv_t;
72 1.2.2.2 skrll
73 1.2.2.2 skrll #define FE_DFL_ENV ((fenv_t *) -1)
74 1.2.2.2 skrll
75 1.2.2.2 skrll #define __get_fpcr(__fpcr) \
76 1.2.2.2 skrll __asm__ __volatile__ ("fmove%.l %!,%0" : "=dm" (__fpcr))
77 1.2.2.2 skrll #define __set_fpcr(__fpcr) \
78 1.2.2.2 skrll __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (__fpcr))
79 1.2.2.2 skrll
80 1.2.2.2 skrll #define __get_fpsr(__fpsr) \
81 1.2.2.2 skrll __asm__ __volatile__ ("fmove%.l %/fpsr,%0" : "=dm" (__fpsr))
82 1.2.2.2 skrll #define __set_fpsr(__fpsr) \
83 1.2.2.2 skrll __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (__fpsr))
84 1.2.2.2 skrll
85 1.2.2.2 skrll #define __fmul(__s, __t, __d) \
86 1.2.2.2 skrll do { \
87 1.2.2.2 skrll __t d = __d; \
88 1.2.2.2 skrll __asm__ __volatile__ ("fmul" __s "; fnop" : "=f" (d) : "0" (d)); \
89 1.2.2.2 skrll } while (/*CONSTCOND*/0)
90 1.2.2.2 skrll
91 1.2.2.2 skrll #define __fdiv(__s, __t, __d) \
92 1.2.2.2 skrll do { \
93 1.2.2.2 skrll __t d = __d; \
94 1.2.2.2 skrll __asm__ __volatile__ ("fdiv" __s "; fnop" : "=f" (d) : "0" (d)); \
95 1.2.2.2 skrll } while (/*CONSTCOND*/0)
96 1.2.2.2 skrll
97 1.2.2.2 skrll #define __fetox(__s, __t, __d) \
98 1.2.2.2 skrll do { \
99 1.2.2.2 skrll __t d = __d; \
100 1.2.2.2 skrll __asm__ __volatile__ ("fetox" __s "; fnop" : "=f" (d) : "0" (d)); \
101 1.2.2.2 skrll } while (/*CONSTCOND*/0)
102 1.2.2.2 skrll
103 1.2.2.2 skrll #define __fgetenv(__envp) \
104 1.2.2.2 skrll __asm__ __volatile__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (__envp))
105 1.2.2.2 skrll
106 1.2.2.2 skrll #define __fsetenv(__envp) \
107 1.2.2.2 skrll __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr/%/fpiar" : : "m" (__envp))
108 1.2.2.2 skrll
109 1.2.2.2 skrll __BEGIN_DECLS
110 1.2.2.2 skrll
111 1.2.2.2 skrll __fenv_static inline int
112 1.2.2.2 skrll feclearexcept(int __excepts)
113 1.2.2.2 skrll {
114 1.2.2.2 skrll fexcept_t __fpsr;
115 1.2.2.2 skrll
116 1.2.2.2 skrll __excepts &= FE_ALL_EXCEPT;
117 1.2.2.2 skrll
118 1.2.2.2 skrll __get_fpsr(__fpsr);
119 1.2.2.2 skrll __fpsr &= ~__excepts;
120 1.2.2.2 skrll __set_fpsr(__fpsr);
121 1.2.2.2 skrll
122 1.2.2.2 skrll return 0;
123 1.2.2.2 skrll }
124 1.2.2.2 skrll
125 1.2.2.2 skrll __fenv_static inline int
126 1.2.2.2 skrll fegetexceptflag(fexcept_t *__flagp, int __excepts)
127 1.2.2.2 skrll {
128 1.2.2.2 skrll fexcept_t __fpsr;
129 1.2.2.2 skrll
130 1.2.2.2 skrll __get_fpsr(__fpsr);
131 1.2.2.2 skrll
132 1.2.2.2 skrll *__flagp = __fpsr & __excepts & FE_ALL_EXCEPT;
133 1.2.2.2 skrll
134 1.2.2.2 skrll return 0;
135 1.2.2.2 skrll }
136 1.2.2.2 skrll
137 1.2.2.2 skrll __fenv_static inline int
138 1.2.2.2 skrll fesetexceptflag(const fexcept_t *__flagp, int __excepts)
139 1.2.2.2 skrll {
140 1.2.2.2 skrll fexcept_t __fpsr;
141 1.2.2.2 skrll
142 1.2.2.2 skrll __get_fpsr(__fpsr);
143 1.2.2.2 skrll
144 1.2.2.2 skrll __fpsr &= ~(__excepts & FE_ALL_EXCEPT);
145 1.2.2.2 skrll __fpsr |= *__flagp & __excepts & FE_ALL_EXCEPT;
146 1.2.2.2 skrll
147 1.2.2.2 skrll __set_fpsr(__fpsr);
148 1.2.2.2 skrll
149 1.2.2.2 skrll return 0;
150 1.2.2.2 skrll }
151 1.2.2.2 skrll
152 1.2.2.2 skrll __fenv_static inline int
153 1.2.2.2 skrll feraiseexcept(int __excepts)
154 1.2.2.2 skrll {
155 1.2.2.2 skrll if (__excepts & FE_INVALID) /* Inf * 0 */
156 1.2.2.2 skrll __fmul("%.s %#0r0,%0", double, __builtin_huge_val());
157 1.2.2.2 skrll
158 1.2.2.2 skrll if (__excepts & FE_DIVBYZERO) /* 1.0 / 0 */
159 1.2.2.2 skrll __fdiv("%.s %#0r0,%0", double, 1.0);
160 1.2.2.2 skrll
161 1.2.2.2 skrll if (__excepts & FE_OVERFLOW) /* MAX * MAX */
162 1.2.2.2 skrll __fmul("%.x %0,%0", long double, LDBL_MAX);
163 1.2.2.2 skrll
164 1.2.2.2 skrll if (__excepts & FE_UNDERFLOW) /* e ^ -MAX */
165 1.2.2.2 skrll __fetox("%.x %0", long double, -LDBL_MAX);
166 1.2.2.2 skrll
167 1.2.2.2 skrll if (__excepts & FE_INEXACT) /* 1 / 3 */
168 1.2.2.2 skrll __fdiv("%.s %#0r3,%0", long double, 1.0);
169 1.2.2.2 skrll
170 1.2.2.2 skrll return 0;
171 1.2.2.2 skrll }
172 1.2.2.2 skrll
173 1.2.2.2 skrll __fenv_static inline int
174 1.2.2.2 skrll fetestexcept(int __excepts)
175 1.2.2.2 skrll {
176 1.2.2.2 skrll fexcept_t __fpsr;
177 1.2.2.2 skrll
178 1.2.2.2 skrll __get_fpsr(__fpsr);
179 1.2.2.2 skrll
180 1.2.2.2 skrll return __fpsr & __excepts & FE_ALL_EXCEPT;
181 1.2.2.2 skrll }
182 1.2.2.2 skrll
183 1.2.2.2 skrll __fenv_static inline int
184 1.2.2.2 skrll fegetround(void)
185 1.2.2.2 skrll {
186 1.2.2.2 skrll fexcept_t __fpcr;
187 1.2.2.2 skrll
188 1.2.2.2 skrll __get_fpcr(__fpcr);
189 1.2.2.2 skrll return __fpcr & _ROUND_MASK;
190 1.2.2.2 skrll }
191 1.2.2.2 skrll
192 1.2.2.2 skrll __fenv_static inline int
193 1.2.2.2 skrll fesetround(int __round)
194 1.2.2.2 skrll {
195 1.2.2.2 skrll fexcept_t __fpcr;
196 1.2.2.2 skrll
197 1.2.2.2 skrll if (__round & ~_ROUND_MASK)
198 1.2.2.2 skrll return -1;
199 1.2.2.2 skrll
200 1.2.2.2 skrll __get_fpcr(__fpcr);
201 1.2.2.2 skrll
202 1.2.2.2 skrll __fpcr &= ~_ROUND_MASK;
203 1.2.2.2 skrll __fpcr |= __round;
204 1.2.2.2 skrll
205 1.2.2.2 skrll __set_fpcr(__fpcr);
206 1.2.2.2 skrll
207 1.2.2.2 skrll return 0;
208 1.2.2.2 skrll }
209 1.2.2.2 skrll
210 1.2.2.2 skrll __fenv_static inline int
211 1.2.2.2 skrll fegetenv(fenv_t *__envp)
212 1.2.2.2 skrll {
213 1.2.2.2 skrll __fgetenv(__envp);
214 1.2.2.2 skrll
215 1.2.2.2 skrll return 0;
216 1.2.2.2 skrll }
217 1.2.2.2 skrll
218 1.2.2.2 skrll __fenv_static inline int
219 1.2.2.2 skrll feholdexcept(fenv_t *__envp)
220 1.2.2.2 skrll {
221 1.2.2.2 skrll fexcept_t __fpcr, __fpsr;
222 1.2.2.2 skrll
223 1.2.2.2 skrll __fgetenv(__envp);
224 1.2.2.2 skrll __fpsr = __envp->fpsr & ~FE_ALL_EXCEPT;
225 1.2.2.2 skrll __set_fpsr(__fpsr); /* clear all */
226 1.2.2.2 skrll __fpcr = __envp->fpcr & ~(FE_ALL_EXCEPT << 6);
227 1.2.2.2 skrll __set_fpcr(__fpcr); /* set non/stop */
228 1.2.2.2 skrll
229 1.2.2.2 skrll return 0;
230 1.2.2.2 skrll }
231 1.2.2.2 skrll
232 1.2.2.2 skrll __fenv_static inline int
233 1.2.2.2 skrll fesetenv(const fenv_t *__envp)
234 1.2.2.2 skrll {
235 1.2.2.2 skrll fenv_t __tenv;
236 1.2.2.2 skrll
237 1.2.2.2 skrll __fgetenv(__tenv);
238 1.2.2.2 skrll
239 1.2.2.2 skrll if (__envp == FE_DFL_ENV) {
240 1.2.2.2 skrll __tenv.fpcr |=
241 1.2.2.2 skrll __envp->fpcr & ((FE_ALL_EXCEPT << 6) | FE_UPWARD);
242 1.2.2.2 skrll __tenv.fpsr |= __envp->fpsr & FE_ALL_EXCEPT;
243 1.2.2.2 skrll }
244 1.2.2.2 skrll
245 1.2.2.2 skrll __fsetenv(__tenv);
246 1.2.2.2 skrll
247 1.2.2.2 skrll return 0;
248 1.2.2.2 skrll }
249 1.2.2.2 skrll
250 1.2.2.2 skrll __fenv_static inline int
251 1.2.2.2 skrll feupdateenv(const fenv_t *__envp)
252 1.2.2.2 skrll {
253 1.2.2.2 skrll fexcept_t __fpsr;
254 1.2.2.2 skrll
255 1.2.2.2 skrll __get_fpsr(__fpsr);
256 1.2.2.2 skrll __fpsr &= FE_ALL_EXCEPT;
257 1.2.2.2 skrll fesetenv(__envp);
258 1.2.2.2 skrll feraiseexcept((int)__fpsr);
259 1.2.2.2 skrll return 0;
260 1.2.2.2 skrll }
261 1.2.2.2 skrll
262 1.2.2.2 skrll #if defined(_NETBSD_SOURCE) || defined(_GNU_SOURCE)
263 1.2.2.2 skrll
264 1.2.2.2 skrll /* We currently provide no external definitions of the functions below. */
265 1.2.2.2 skrll
266 1.2.2.2 skrll static inline int
267 1.2.2.2 skrll feenableexcept(int __mask)
268 1.2.2.2 skrll {
269 1.2.2.2 skrll fexcept_t __fpsr, __oldmask;
270 1.2.2.2 skrll
271 1.2.2.2 skrll __get_fpsr(__fpsr);
272 1.2.2.2 skrll __oldmask = __fpsr & FE_ALL_EXCEPT;
273 1.2.2.2 skrll __fpsr |= __mask & FE_ALL_EXCEPT;
274 1.2.2.2 skrll __set_fpsr(__fpsr);
275 1.2.2.2 skrll
276 1.2.2.2 skrll return __oldmask;
277 1.2.2.2 skrll }
278 1.2.2.2 skrll
279 1.2.2.2 skrll static inline int
280 1.2.2.2 skrll fedisableexcept(int __mask)
281 1.2.2.2 skrll {
282 1.2.2.2 skrll fexcept_t __fpsr, __oldmask;
283 1.2.2.2 skrll
284 1.2.2.2 skrll __get_fpsr(__fpsr);
285 1.2.2.2 skrll __oldmask = __fpsr & FE_ALL_EXCEPT;
286 1.2.2.2 skrll __fpsr &= ~(__mask & FE_ALL_EXCEPT);
287 1.2.2.2 skrll __set_fpsr(__fpsr);
288 1.2.2.2 skrll
289 1.2.2.2 skrll return __oldmask;
290 1.2.2.2 skrll }
291 1.2.2.2 skrll
292 1.2.2.2 skrll static inline int
293 1.2.2.2 skrll fegetexcept(void)
294 1.2.2.2 skrll {
295 1.2.2.2 skrll fexcept_t __fpsr;
296 1.2.2.2 skrll
297 1.2.2.2 skrll __get_fpsr(__fpsr);
298 1.2.2.2 skrll
299 1.2.2.2 skrll return __fpsr & FE_ALL_EXCEPT;
300 1.2.2.2 skrll }
301 1.2.2.2 skrll
302 1.2.2.2 skrll #endif /* _NETBSD_SOURCE || _GNU_SOURCE */
303 1.2.2.2 skrll
304 1.2.2.2 skrll __END_DECLS
305 1.2.2.2 skrll
306 1.2.2.3 skrll #endif /* !__m68010__ && !__mcoldfire__ */
307 1.2.2.3 skrll
308 1.2.2.2 skrll #endif /* _M68K_FENV_H_ */
309