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 __declare_fenv_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 __declare_fenv_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 __declare_fenv_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 __declare_fenv_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 __declare_fenv_inline(int)
fesetexcept(int excepts)83 fesetexcept(int excepts)
84 {
85 return feraiseexcept(excepts);
86 }
87
88 __declare_fenv_inline(int)
fetestexcept(int excepts)89 fetestexcept(int excepts)
90 {
91 union __fpscr __r;
92
93 __mffs(&__r);
94 return (__r.__bits.__reg & excepts);
95 }
96
97 __declare_fenv_inline(int)
fegetround(void)98 fegetround(void)
99 {
100 union __fpscr __r;
101
102 __mffs(&__r);
103 return (__r.__bits.__reg & _ROUND_MASK);
104 }
105
106 __declare_fenv_inline(int)
fesetround(int rounding_mode)107 fesetround(int rounding_mode)
108 {
109 union __fpscr __r;
110
111 if (rounding_mode & ~_ROUND_MASK)
112 return (-1);
113 __mffs(&__r);
114 __r.__bits.__reg &= ~_ROUND_MASK;
115 __r.__bits.__reg |= rounding_mode;
116 __mtfsf(__r);
117 return (0);
118 }
119
120 __declare_fenv_inline(int)
fegetenv(fenv_t * envp)121 fegetenv(fenv_t *envp)
122 {
123 union __fpscr __r;
124
125 __mffs(&__r);
126 *envp = __r.__bits.__reg;
127 return (0);
128 }
129
130 __declare_fenv_inline(int)
feholdexcept(fenv_t * envp)131 feholdexcept(fenv_t *envp)
132 {
133 union __fpscr __r;
134
135 __mffs(&__r);
136 *envp = __r.__bits.__reg;
137 __r.__bits.__reg &= ~(FE_ALL_EXCEPT | _ENABLE_MASK);
138 __mtfsf(__r);
139 return (0);
140 }
141
142 __declare_fenv_inline(int)
fesetenv(const fenv_t * envp)143 fesetenv(const fenv_t *envp)
144 {
145 union __fpscr __r;
146
147 __r.__bits.__reg = *envp;
148 __mtfsf(__r);
149 return (0);
150 }
151
152 __declare_fenv_inline(int)
feupdateenv(const fenv_t * envp)153 feupdateenv(const fenv_t *envp)
154 {
155 union __fpscr __r;
156
157 __mffs(&__r);
158 __r.__bits.__reg &= FE_ALL_EXCEPT;
159 __r.__bits.__reg |= *envp;
160 __mtfsf(__r);
161 return (0);
162 }
163
164 #if __BSD_VISIBLE
165
166 __declare_fenv_inline(int)
feenableexcept(int __mask)167 feenableexcept(int __mask)
168 {
169 union __fpscr __r;
170 fenv_t __oldmask;
171
172 __mffs(&__r);
173 __oldmask = __r.__bits.__reg;
174 __r.__bits.__reg |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT;
175 __mtfsf(__r);
176 return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
177 }
178
179 __declare_fenv_inline(int)
fedisableexcept(int __mask)180 fedisableexcept(int __mask)
181 {
182 union __fpscr __r;
183 fenv_t __oldmask;
184
185 __mffs(&__r);
186 __oldmask = __r.__bits.__reg;
187 __r.__bits.__reg &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT);
188 __mtfsf(__r);
189 return ((__oldmask & _ENABLE_MASK) << _FPUSW_SHIFT);
190 }
191
192 __declare_fenv_inline(int)
fegetexcept(void)193 fegetexcept(void)
194 {
195 union __fpscr __r;
196
197 __mffs(&__r);
198 return ((__r.__bits.__reg & _ENABLE_MASK) << _FPUSW_SHIFT);
199 }
200
201 #endif /* __BSD_VISIBLE */
202