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