1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2004-2005 David Schultz <das@FreeBSD.ORG>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31 __fenv_static inline int
feclearexcept(int excepts)32 feclearexcept(int excepts)
33 {
34 union __fpscr __r;
35
36 if (excepts & FE_INVALID)
37 excepts |= FE_ALL_INVALID;
38 __mffs(&__r);
39 __r.__bits.__reg &= ~excepts;
40 __mtfsf(__r);
41 return (0);
42 }
43
44
45 __fenv_static inline int
fegetexceptflag(fexcept_t * flagp,int excepts)46 fegetexceptflag(fexcept_t *flagp, int excepts)
47 {
48 union __fpscr __r;
49
50 __mffs(&__r);
51 *flagp = __r.__bits.__reg & excepts;
52 return (0);
53 }
54
55 __fenv_static inline int
fesetexceptflag(const fexcept_t * flagp,int excepts)56 fesetexceptflag(const fexcept_t *flagp, int excepts)
57 {
58 union __fpscr __r;
59
60 if (excepts & FE_INVALID)
61 excepts |= FE_ALL_EXCEPT;
62 __mffs(&__r);
63 __r.__bits.__reg &= ~excepts;
64 __r.__bits.__reg |= *flagp & excepts;
65 __mtfsf(__r);
66 return (0);
67 }
68
69 __fenv_static inline int
feraiseexcept(int excepts)70 feraiseexcept(int excepts)
71 {
72 union __fpscr __r;
73
74 if (excepts & FE_INVALID)
75 excepts |= FE_VXSOFT;
76 __mffs(&__r);
77 __r.__bits.__reg |= excepts;
78 __mtfsf(__r);
79 return (0);
80 }
81
82 __fenv_static inline int
fetestexcept(int excepts)83 fetestexcept(int excepts)
84 {
85 union __fpscr __r;
86
87 __mffs(&__r);
88 return (__r.__bits.__reg & excepts);
89 }
90
91 __fenv_static inline int
fegetround(void)92 fegetround(void)
93 {
94 union __fpscr __r;
95
96 __mffs(&__r);
97 return (__r.__bits.__reg & _ROUND_MASK);
98 }
99
100 __fenv_static inline int
fesetround(int rounding_mode)101 fesetround(int rounding_mode)
102 {
103 union __fpscr __r;
104
105 if (rounding_mode & ~_ROUND_MASK)
106 return (-1);
107 __mffs(&__r);
108 __r.__bits.__reg &= ~_ROUND_MASK;
109 __r.__bits.__reg |= rounding_mode;
110 __mtfsf(__r);
111 return (0);
112 }
113
114 __fenv_static inline int
fegetenv(fenv_t * envp)115 fegetenv(fenv_t *envp)
116 {
117 union __fpscr __r;
118
119 __mffs(&__r);
120 *envp = __r.__bits.__reg;
121 return (0);
122 }
123
124 __fenv_static inline int
feholdexcept(fenv_t * envp)125 feholdexcept(fenv_t *envp)
126 {
127 union __fpscr __r;
128
129 __mffs(&__r);
130 *envp = __r.__bits.__reg;
131 __r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
132 __mtfsf(__r);
133 return (0);
134 }
135
136 __fenv_static inline int
fesetenv(const fenv_t * envp)137 fesetenv(const fenv_t *envp)
138 {
139 union __fpscr __r;
140
141 __r.__bits.__reg = *envp;
142 __mtfsf(__r);
143 return (0);
144 }
145
146 __fenv_static inline int
feupdateenv(const fenv_t * envp)147 feupdateenv(const fenv_t *envp)
148 {
149 union __fpscr __r;
150
151 __mffs(&__r);
152 __r.__bits.__reg &= FE_ALL_EXCEPT;
153 __r.__bits.__reg |= *envp;
154 __mtfsf(__r);
155 return (0);
156 }
157
158 #if __BSD_VISIBLE
159
160 /* We currently provide no external definitions of the functions below. */
161
162 static inline int
feenableexcept(int __mask)163 feenableexcept(int __mask)
164 {
165 union __fpscr __r;
166 fenv_t __oldmask;
167
168 __mffs(&__r);
169 __oldmask = __r.__bits.__reg;
170 __r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
171 __mtfsf(__r);
172 return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
173 }
174
175 static inline int
fedisableexcept(int __mask)176 fedisableexcept(int __mask)
177 {
178 union __fpscr __r;
179 fenv_t __oldmask;
180
181 __mffs(&__r);
182 __oldmask = __r.__bits.__reg;
183 __r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
184 __mtfsf(__r);
185 return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
186 }
187
188 static inline int
fegetexcept(void)189 fegetexcept(void)
190 {
191 union __fpscr __r;
192
193 __mffs(&__r);
194 return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
195 }
196
197 #endif /* __BSD_VISIBLE */
198
199