root / target-sparc / fop_helper.c @ a8a00822
History | View | Annotate | Download (15.8 kB)
1 | 1bccec25 | Blue Swirl | /*
|
---|---|---|---|
2 | 1bccec25 | Blue Swirl | * FPU op helpers
|
3 | 1bccec25 | Blue Swirl | *
|
4 | 1bccec25 | Blue Swirl | * Copyright (c) 2003-2005 Fabrice Bellard
|
5 | 1bccec25 | Blue Swirl | *
|
6 | 1bccec25 | Blue Swirl | * This library is free software; you can redistribute it and/or
|
7 | 1bccec25 | Blue Swirl | * modify it under the terms of the GNU Lesser General Public
|
8 | 1bccec25 | Blue Swirl | * License as published by the Free Software Foundation; either
|
9 | 1bccec25 | Blue Swirl | * version 2 of the License, or (at your option) any later version.
|
10 | 1bccec25 | Blue Swirl | *
|
11 | 1bccec25 | Blue Swirl | * This library is distributed in the hope that it will be useful,
|
12 | 1bccec25 | Blue Swirl | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13 | 1bccec25 | Blue Swirl | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
14 | 1bccec25 | Blue Swirl | * Lesser General Public License for more details.
|
15 | 1bccec25 | Blue Swirl | *
|
16 | 1bccec25 | Blue Swirl | * You should have received a copy of the GNU Lesser General Public
|
17 | 1bccec25 | Blue Swirl | * License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
18 | 1bccec25 | Blue Swirl | */
|
19 | 1bccec25 | Blue Swirl | |
20 | 1bccec25 | Blue Swirl | #include "cpu.h" |
21 | 1bccec25 | Blue Swirl | #include "helper.h" |
22 | 1bccec25 | Blue Swirl | |
23 | 1bccec25 | Blue Swirl | #define QT0 (env->qt0)
|
24 | 1bccec25 | Blue Swirl | #define QT1 (env->qt1)
|
25 | 1bccec25 | Blue Swirl | |
26 | 44516772 | Richard Henderson | static void check_ieee_exceptions(CPUState *env) |
27 | 44516772 | Richard Henderson | { |
28 | 44516772 | Richard Henderson | target_ulong status; |
29 | 44516772 | Richard Henderson | |
30 | 44516772 | Richard Henderson | status = get_float_exception_flags(&env->fp_status); |
31 | 44516772 | Richard Henderson | if (status) {
|
32 | 44516772 | Richard Henderson | /* Copy IEEE 754 flags into FSR */
|
33 | 44516772 | Richard Henderson | if (status & float_flag_invalid) {
|
34 | 44516772 | Richard Henderson | env->fsr |= FSR_NVC; |
35 | 44516772 | Richard Henderson | } |
36 | 44516772 | Richard Henderson | if (status & float_flag_overflow) {
|
37 | 44516772 | Richard Henderson | env->fsr |= FSR_OFC; |
38 | 44516772 | Richard Henderson | } |
39 | 44516772 | Richard Henderson | if (status & float_flag_underflow) {
|
40 | 44516772 | Richard Henderson | env->fsr |= FSR_UFC; |
41 | 44516772 | Richard Henderson | } |
42 | 44516772 | Richard Henderson | if (status & float_flag_divbyzero) {
|
43 | 44516772 | Richard Henderson | env->fsr |= FSR_DZC; |
44 | 44516772 | Richard Henderson | } |
45 | 44516772 | Richard Henderson | if (status & float_flag_inexact) {
|
46 | 44516772 | Richard Henderson | env->fsr |= FSR_NXC; |
47 | 44516772 | Richard Henderson | } |
48 | 44516772 | Richard Henderson | |
49 | 44516772 | Richard Henderson | if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23)) { |
50 | 44516772 | Richard Henderson | /* Unmasked exception, generate a trap */
|
51 | 44516772 | Richard Henderson | env->fsr |= FSR_FTT_IEEE_EXCP; |
52 | 44516772 | Richard Henderson | helper_raise_exception(env, TT_FP_EXCP); |
53 | 44516772 | Richard Henderson | } else {
|
54 | 44516772 | Richard Henderson | /* Accumulate exceptions */
|
55 | 44516772 | Richard Henderson | env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
|
56 | 44516772 | Richard Henderson | } |
57 | 44516772 | Richard Henderson | } |
58 | 44516772 | Richard Henderson | } |
59 | 44516772 | Richard Henderson | |
60 | 44516772 | Richard Henderson | static inline void clear_float_exceptions(CPUState *env) |
61 | 44516772 | Richard Henderson | { |
62 | 44516772 | Richard Henderson | set_float_exception_flags(0, &env->fp_status);
|
63 | 44516772 | Richard Henderson | } |
64 | 44516772 | Richard Henderson | |
65 | 2e2f4ade | Blue Swirl | #define F_HELPER(name, p) void helper_f##name##p(CPUState *env) |
66 | 1bccec25 | Blue Swirl | |
67 | 1bccec25 | Blue Swirl | #define F_BINOP(name) \
|
68 | 44516772 | Richard Henderson | float32 helper_f ## name ## s (CPUState *env, float32 src1, \ |
69 | 2e2f4ade | Blue Swirl | float32 src2) \ |
70 | 1bccec25 | Blue Swirl | { \ |
71 | 44516772 | Richard Henderson | float32 ret; \ |
72 | 44516772 | Richard Henderson | clear_float_exceptions(env); \ |
73 | 44516772 | Richard Henderson | ret = float32_ ## name (src1, src2, &env->fp_status); \ |
74 | 44516772 | Richard Henderson | check_ieee_exceptions(env); \ |
75 | 44516772 | Richard Henderson | return ret; \
|
76 | 1bccec25 | Blue Swirl | } \ |
77 | 03fb8cfc | Richard Henderson | float64 helper_f ## name ## d (CPUState * env, float64 src1,\ |
78 | 03fb8cfc | Richard Henderson | float64 src2) \ |
79 | 1bccec25 | Blue Swirl | { \ |
80 | 44516772 | Richard Henderson | float64 ret; \ |
81 | 44516772 | Richard Henderson | clear_float_exceptions(env); \ |
82 | 44516772 | Richard Henderson | ret = float64_ ## name (src1, src2, &env->fp_status); \ |
83 | 44516772 | Richard Henderson | check_ieee_exceptions(env); \ |
84 | 44516772 | Richard Henderson | return ret; \
|
85 | 1bccec25 | Blue Swirl | } \ |
86 | 1bccec25 | Blue Swirl | F_HELPER(name, q) \ |
87 | 1bccec25 | Blue Swirl | { \ |
88 | 44516772 | Richard Henderson | clear_float_exceptions(env); \ |
89 | 1bccec25 | Blue Swirl | QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \ |
90 | 44516772 | Richard Henderson | check_ieee_exceptions(env); \ |
91 | 1bccec25 | Blue Swirl | } |
92 | 1bccec25 | Blue Swirl | |
93 | 1bccec25 | Blue Swirl | F_BINOP(add); |
94 | 1bccec25 | Blue Swirl | F_BINOP(sub); |
95 | 1bccec25 | Blue Swirl | F_BINOP(mul); |
96 | 1bccec25 | Blue Swirl | F_BINOP(div); |
97 | 1bccec25 | Blue Swirl | #undef F_BINOP
|
98 | 1bccec25 | Blue Swirl | |
99 | 03fb8cfc | Richard Henderson | float64 helper_fsmuld(CPUState *env, float32 src1, float32 src2) |
100 | 1bccec25 | Blue Swirl | { |
101 | 44516772 | Richard Henderson | float64 ret; |
102 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
103 | 44516772 | Richard Henderson | ret = float64_mul(float32_to_float64(src1, &env->fp_status), |
104 | 44516772 | Richard Henderson | float32_to_float64(src2, &env->fp_status), |
105 | 44516772 | Richard Henderson | &env->fp_status); |
106 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
107 | 44516772 | Richard Henderson | return ret;
|
108 | 1bccec25 | Blue Swirl | } |
109 | 1bccec25 | Blue Swirl | |
110 | 03fb8cfc | Richard Henderson | void helper_fdmulq(CPUState *env, float64 src1, float64 src2)
|
111 | 1bccec25 | Blue Swirl | { |
112 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
113 | 03fb8cfc | Richard Henderson | QT0 = float128_mul(float64_to_float128(src1, &env->fp_status), |
114 | 03fb8cfc | Richard Henderson | float64_to_float128(src2, &env->fp_status), |
115 | 1bccec25 | Blue Swirl | &env->fp_status); |
116 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
117 | 1bccec25 | Blue Swirl | } |
118 | 1bccec25 | Blue Swirl | |
119 | 1bccec25 | Blue Swirl | float32 helper_fnegs(float32 src) |
120 | 1bccec25 | Blue Swirl | { |
121 | 1bccec25 | Blue Swirl | return float32_chs(src);
|
122 | 1bccec25 | Blue Swirl | } |
123 | 1bccec25 | Blue Swirl | |
124 | 1bccec25 | Blue Swirl | #ifdef TARGET_SPARC64
|
125 | 03fb8cfc | Richard Henderson | float64 helper_fnegd(float64 src) |
126 | 1bccec25 | Blue Swirl | { |
127 | 03fb8cfc | Richard Henderson | return float64_chs(src);
|
128 | 1bccec25 | Blue Swirl | } |
129 | 1bccec25 | Blue Swirl | |
130 | 1bccec25 | Blue Swirl | F_HELPER(neg, q) |
131 | 1bccec25 | Blue Swirl | { |
132 | 1bccec25 | Blue Swirl | QT0 = float128_chs(QT1); |
133 | 1bccec25 | Blue Swirl | } |
134 | 1bccec25 | Blue Swirl | #endif
|
135 | 1bccec25 | Blue Swirl | |
136 | 1bccec25 | Blue Swirl | /* Integer to float conversion. */
|
137 | 2e2f4ade | Blue Swirl | float32 helper_fitos(CPUState *env, int32_t src) |
138 | 1bccec25 | Blue Swirl | { |
139 | 44516772 | Richard Henderson | /* Inexact error possible converting int to float. */
|
140 | 44516772 | Richard Henderson | float32 ret; |
141 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
142 | 44516772 | Richard Henderson | ret = int32_to_float32(src, &env->fp_status); |
143 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
144 | 44516772 | Richard Henderson | return ret;
|
145 | 1bccec25 | Blue Swirl | } |
146 | 1bccec25 | Blue Swirl | |
147 | 03fb8cfc | Richard Henderson | float64 helper_fitod(CPUState *env, int32_t src) |
148 | 1bccec25 | Blue Swirl | { |
149 | 44516772 | Richard Henderson | /* No possible exceptions converting int to double. */
|
150 | 03fb8cfc | Richard Henderson | return int32_to_float64(src, &env->fp_status);
|
151 | 1bccec25 | Blue Swirl | } |
152 | 1bccec25 | Blue Swirl | |
153 | 2e2f4ade | Blue Swirl | void helper_fitoq(CPUState *env, int32_t src)
|
154 | 1bccec25 | Blue Swirl | { |
155 | 44516772 | Richard Henderson | /* No possible exceptions converting int to long double. */
|
156 | 1bccec25 | Blue Swirl | QT0 = int32_to_float128(src, &env->fp_status); |
157 | 1bccec25 | Blue Swirl | } |
158 | 1bccec25 | Blue Swirl | |
159 | 1bccec25 | Blue Swirl | #ifdef TARGET_SPARC64
|
160 | 03fb8cfc | Richard Henderson | float32 helper_fxtos(CPUState *env, int64_t src) |
161 | 1bccec25 | Blue Swirl | { |
162 | 44516772 | Richard Henderson | float32 ret; |
163 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
164 | 44516772 | Richard Henderson | ret = int64_to_float32(src, &env->fp_status); |
165 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
166 | 44516772 | Richard Henderson | return ret;
|
167 | 1bccec25 | Blue Swirl | } |
168 | 1bccec25 | Blue Swirl | |
169 | 03fb8cfc | Richard Henderson | float64 helper_fxtod(CPUState *env, int64_t src) |
170 | 1bccec25 | Blue Swirl | { |
171 | 44516772 | Richard Henderson | float64 ret; |
172 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
173 | 44516772 | Richard Henderson | ret = int64_to_float64(src, &env->fp_status); |
174 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
175 | 44516772 | Richard Henderson | return ret;
|
176 | 1bccec25 | Blue Swirl | } |
177 | 1bccec25 | Blue Swirl | |
178 | 03fb8cfc | Richard Henderson | void helper_fxtoq(CPUState *env, int64_t src)
|
179 | 1bccec25 | Blue Swirl | { |
180 | 44516772 | Richard Henderson | /* No possible exceptions converting long long to long double. */
|
181 | 03fb8cfc | Richard Henderson | QT0 = int64_to_float128(src, &env->fp_status); |
182 | 1bccec25 | Blue Swirl | } |
183 | 1bccec25 | Blue Swirl | #endif
|
184 | 1bccec25 | Blue Swirl | #undef F_HELPER
|
185 | 1bccec25 | Blue Swirl | |
186 | 1bccec25 | Blue Swirl | /* floating point conversion */
|
187 | 03fb8cfc | Richard Henderson | float32 helper_fdtos(CPUState *env, float64 src) |
188 | 1bccec25 | Blue Swirl | { |
189 | 44516772 | Richard Henderson | float32 ret; |
190 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
191 | 44516772 | Richard Henderson | ret = float64_to_float32(src, &env->fp_status); |
192 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
193 | 44516772 | Richard Henderson | return ret;
|
194 | 1bccec25 | Blue Swirl | } |
195 | 1bccec25 | Blue Swirl | |
196 | 03fb8cfc | Richard Henderson | float64 helper_fstod(CPUState *env, float32 src) |
197 | 1bccec25 | Blue Swirl | { |
198 | 44516772 | Richard Henderson | float64 ret; |
199 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
200 | 44516772 | Richard Henderson | ret = float32_to_float64(src, &env->fp_status); |
201 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
202 | 44516772 | Richard Henderson | return ret;
|
203 | 1bccec25 | Blue Swirl | } |
204 | 1bccec25 | Blue Swirl | |
205 | 2e2f4ade | Blue Swirl | float32 helper_fqtos(CPUState *env) |
206 | 1bccec25 | Blue Swirl | { |
207 | 44516772 | Richard Henderson | float32 ret; |
208 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
209 | 44516772 | Richard Henderson | ret = float128_to_float32(QT1, &env->fp_status); |
210 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
211 | 44516772 | Richard Henderson | return ret;
|
212 | 1bccec25 | Blue Swirl | } |
213 | 1bccec25 | Blue Swirl | |
214 | 2e2f4ade | Blue Swirl | void helper_fstoq(CPUState *env, float32 src)
|
215 | 1bccec25 | Blue Swirl | { |
216 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
217 | 1bccec25 | Blue Swirl | QT0 = float32_to_float128(src, &env->fp_status); |
218 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
219 | 1bccec25 | Blue Swirl | } |
220 | 1bccec25 | Blue Swirl | |
221 | 03fb8cfc | Richard Henderson | float64 helper_fqtod(CPUState *env) |
222 | 1bccec25 | Blue Swirl | { |
223 | 44516772 | Richard Henderson | float64 ret; |
224 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
225 | 44516772 | Richard Henderson | ret = float128_to_float64(QT1, &env->fp_status); |
226 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
227 | 44516772 | Richard Henderson | return ret;
|
228 | 1bccec25 | Blue Swirl | } |
229 | 1bccec25 | Blue Swirl | |
230 | 03fb8cfc | Richard Henderson | void helper_fdtoq(CPUState *env, float64 src)
|
231 | 1bccec25 | Blue Swirl | { |
232 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
233 | 03fb8cfc | Richard Henderson | QT0 = float64_to_float128(src, &env->fp_status); |
234 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
235 | 1bccec25 | Blue Swirl | } |
236 | 1bccec25 | Blue Swirl | |
237 | 1bccec25 | Blue Swirl | /* Float to integer conversion. */
|
238 | 2e2f4ade | Blue Swirl | int32_t helper_fstoi(CPUState *env, float32 src) |
239 | 1bccec25 | Blue Swirl | { |
240 | 44516772 | Richard Henderson | int32_t ret; |
241 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
242 | 44516772 | Richard Henderson | ret = float32_to_int32_round_to_zero(src, &env->fp_status); |
243 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
244 | 44516772 | Richard Henderson | return ret;
|
245 | 1bccec25 | Blue Swirl | } |
246 | 1bccec25 | Blue Swirl | |
247 | 03fb8cfc | Richard Henderson | int32_t helper_fdtoi(CPUState *env, float64 src) |
248 | 1bccec25 | Blue Swirl | { |
249 | 44516772 | Richard Henderson | int32_t ret; |
250 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
251 | 44516772 | Richard Henderson | ret = float64_to_int32_round_to_zero(src, &env->fp_status); |
252 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
253 | 44516772 | Richard Henderson | return ret;
|
254 | 1bccec25 | Blue Swirl | } |
255 | 1bccec25 | Blue Swirl | |
256 | 2e2f4ade | Blue Swirl | int32_t helper_fqtoi(CPUState *env) |
257 | 1bccec25 | Blue Swirl | { |
258 | 44516772 | Richard Henderson | int32_t ret; |
259 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
260 | 44516772 | Richard Henderson | ret = float128_to_int32_round_to_zero(QT1, &env->fp_status); |
261 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
262 | 44516772 | Richard Henderson | return ret;
|
263 | 1bccec25 | Blue Swirl | } |
264 | 1bccec25 | Blue Swirl | |
265 | 1bccec25 | Blue Swirl | #ifdef TARGET_SPARC64
|
266 | 03fb8cfc | Richard Henderson | int64_t helper_fstox(CPUState *env, float32 src) |
267 | 1bccec25 | Blue Swirl | { |
268 | 44516772 | Richard Henderson | int64_t ret; |
269 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
270 | 44516772 | Richard Henderson | ret = float32_to_int64_round_to_zero(src, &env->fp_status); |
271 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
272 | 44516772 | Richard Henderson | return ret;
|
273 | 1bccec25 | Blue Swirl | } |
274 | 1bccec25 | Blue Swirl | |
275 | 03fb8cfc | Richard Henderson | int64_t helper_fdtox(CPUState *env, float64 src) |
276 | 1bccec25 | Blue Swirl | { |
277 | 44516772 | Richard Henderson | int64_t ret; |
278 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
279 | 44516772 | Richard Henderson | ret = float64_to_int64_round_to_zero(src, &env->fp_status); |
280 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
281 | 44516772 | Richard Henderson | return ret;
|
282 | 1bccec25 | Blue Swirl | } |
283 | 1bccec25 | Blue Swirl | |
284 | 03fb8cfc | Richard Henderson | int64_t helper_fqtox(CPUState *env) |
285 | 1bccec25 | Blue Swirl | { |
286 | 44516772 | Richard Henderson | int64_t ret; |
287 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
288 | 44516772 | Richard Henderson | ret = float128_to_int64_round_to_zero(QT1, &env->fp_status); |
289 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
290 | 44516772 | Richard Henderson | return ret;
|
291 | 1bccec25 | Blue Swirl | } |
292 | 1bccec25 | Blue Swirl | #endif
|
293 | 1bccec25 | Blue Swirl | |
294 | 1bccec25 | Blue Swirl | float32 helper_fabss(float32 src) |
295 | 1bccec25 | Blue Swirl | { |
296 | 1bccec25 | Blue Swirl | return float32_abs(src);
|
297 | 1bccec25 | Blue Swirl | } |
298 | 1bccec25 | Blue Swirl | |
299 | 1bccec25 | Blue Swirl | #ifdef TARGET_SPARC64
|
300 | f027c3b1 | Richard Henderson | float64 helper_fabsd(float64 src) |
301 | 1bccec25 | Blue Swirl | { |
302 | 03fb8cfc | Richard Henderson | return float64_abs(src);
|
303 | 1bccec25 | Blue Swirl | } |
304 | 1bccec25 | Blue Swirl | |
305 | 2e2f4ade | Blue Swirl | void helper_fabsq(CPUState *env)
|
306 | 1bccec25 | Blue Swirl | { |
307 | 1bccec25 | Blue Swirl | QT0 = float128_abs(QT1); |
308 | 1bccec25 | Blue Swirl | } |
309 | 1bccec25 | Blue Swirl | #endif
|
310 | 1bccec25 | Blue Swirl | |
311 | 2e2f4ade | Blue Swirl | float32 helper_fsqrts(CPUState *env, float32 src) |
312 | 1bccec25 | Blue Swirl | { |
313 | 44516772 | Richard Henderson | float32 ret; |
314 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
315 | 44516772 | Richard Henderson | ret = float32_sqrt(src, &env->fp_status); |
316 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
317 | 44516772 | Richard Henderson | return ret;
|
318 | 1bccec25 | Blue Swirl | } |
319 | 1bccec25 | Blue Swirl | |
320 | 03fb8cfc | Richard Henderson | float64 helper_fsqrtd(CPUState *env, float64 src) |
321 | 1bccec25 | Blue Swirl | { |
322 | 44516772 | Richard Henderson | float64 ret; |
323 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
324 | 44516772 | Richard Henderson | ret = float64_sqrt(src, &env->fp_status); |
325 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
326 | 44516772 | Richard Henderson | return ret;
|
327 | 1bccec25 | Blue Swirl | } |
328 | 1bccec25 | Blue Swirl | |
329 | 2e2f4ade | Blue Swirl | void helper_fsqrtq(CPUState *env)
|
330 | 1bccec25 | Blue Swirl | { |
331 | 44516772 | Richard Henderson | clear_float_exceptions(env); |
332 | 1bccec25 | Blue Swirl | QT0 = float128_sqrt(QT1, &env->fp_status); |
333 | 44516772 | Richard Henderson | check_ieee_exceptions(env); |
334 | 1bccec25 | Blue Swirl | } |
335 | 1bccec25 | Blue Swirl | |
336 | 1bccec25 | Blue Swirl | #define GEN_FCMP(name, size, reg1, reg2, FS, E) \
|
337 | 2e2f4ade | Blue Swirl | void glue(helper_, name) (CPUState *env) \
|
338 | 1bccec25 | Blue Swirl | { \ |
339 | 1bccec25 | Blue Swirl | env->fsr &= FSR_FTT_NMASK; \ |
340 | 1bccec25 | Blue Swirl | if (E && (glue(size, _is_any_nan)(reg1) || \
|
341 | 1bccec25 | Blue Swirl | glue(size, _is_any_nan)(reg2)) && \ |
342 | 1bccec25 | Blue Swirl | (env->fsr & FSR_NVM)) { \ |
343 | 1bccec25 | Blue Swirl | env->fsr |= FSR_NVC; \ |
344 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FTT_IEEE_EXCP; \ |
345 | 1bccec25 | Blue Swirl | helper_raise_exception(env, TT_FP_EXCP); \ |
346 | 1bccec25 | Blue Swirl | } \ |
347 | 1bccec25 | Blue Swirl | switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) { \
|
348 | 1bccec25 | Blue Swirl | case float_relation_unordered: \
|
349 | 1bccec25 | Blue Swirl | if ((env->fsr & FSR_NVM)) { \
|
350 | 1bccec25 | Blue Swirl | env->fsr |= FSR_NVC; \ |
351 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FTT_IEEE_EXCP; \ |
352 | 1bccec25 | Blue Swirl | helper_raise_exception(env, TT_FP_EXCP); \ |
353 | 1bccec25 | Blue Swirl | } else { \
|
354 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
355 | 1bccec25 | Blue Swirl | env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ |
356 | 1bccec25 | Blue Swirl | env->fsr |= FSR_NVA; \ |
357 | 1bccec25 | Blue Swirl | } \ |
358 | 1bccec25 | Blue Swirl | break; \
|
359 | 1bccec25 | Blue Swirl | case float_relation_less: \
|
360 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
361 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FCC0 << FS; \ |
362 | 1bccec25 | Blue Swirl | break; \
|
363 | 1bccec25 | Blue Swirl | case float_relation_greater: \
|
364 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
365 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FCC1 << FS; \ |
366 | 1bccec25 | Blue Swirl | break; \
|
367 | 1bccec25 | Blue Swirl | default: \
|
368 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
369 | 1bccec25 | Blue Swirl | break; \
|
370 | 1bccec25 | Blue Swirl | } \ |
371 | 1bccec25 | Blue Swirl | } |
372 | 03fb8cfc | Richard Henderson | #define GEN_FCMP_T(name, size, FS, E) \
|
373 | 03fb8cfc | Richard Henderson | void glue(helper_, name)(CPUState *env, size src1, size src2) \
|
374 | 1bccec25 | Blue Swirl | { \ |
375 | 1bccec25 | Blue Swirl | env->fsr &= FSR_FTT_NMASK; \ |
376 | 1bccec25 | Blue Swirl | if (E && (glue(size, _is_any_nan)(src1) || \
|
377 | 1bccec25 | Blue Swirl | glue(size, _is_any_nan)(src2)) && \ |
378 | 1bccec25 | Blue Swirl | (env->fsr & FSR_NVM)) { \ |
379 | 1bccec25 | Blue Swirl | env->fsr |= FSR_NVC; \ |
380 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FTT_IEEE_EXCP; \ |
381 | 1bccec25 | Blue Swirl | helper_raise_exception(env, TT_FP_EXCP); \ |
382 | 1bccec25 | Blue Swirl | } \ |
383 | 1bccec25 | Blue Swirl | switch (glue(size, _compare) (src1, src2, &env->fp_status)) { \
|
384 | 1bccec25 | Blue Swirl | case float_relation_unordered: \
|
385 | 1bccec25 | Blue Swirl | if ((env->fsr & FSR_NVM)) { \
|
386 | 1bccec25 | Blue Swirl | env->fsr |= FSR_NVC; \ |
387 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FTT_IEEE_EXCP; \ |
388 | 1bccec25 | Blue Swirl | helper_raise_exception(env, TT_FP_EXCP); \ |
389 | 1bccec25 | Blue Swirl | } else { \
|
390 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
391 | 1bccec25 | Blue Swirl | env->fsr |= (FSR_FCC1 | FSR_FCC0) << FS; \ |
392 | 1bccec25 | Blue Swirl | env->fsr |= FSR_NVA; \ |
393 | 1bccec25 | Blue Swirl | } \ |
394 | 1bccec25 | Blue Swirl | break; \
|
395 | 1bccec25 | Blue Swirl | case float_relation_less: \
|
396 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
397 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FCC0 << FS; \ |
398 | 1bccec25 | Blue Swirl | break; \
|
399 | 1bccec25 | Blue Swirl | case float_relation_greater: \
|
400 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
401 | 1bccec25 | Blue Swirl | env->fsr |= FSR_FCC1 << FS; \ |
402 | 1bccec25 | Blue Swirl | break; \
|
403 | 1bccec25 | Blue Swirl | default: \
|
404 | 1bccec25 | Blue Swirl | env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ |
405 | 1bccec25 | Blue Swirl | break; \
|
406 | 1bccec25 | Blue Swirl | } \ |
407 | 1bccec25 | Blue Swirl | } |
408 | 1bccec25 | Blue Swirl | |
409 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmps, float32, 0, 0); |
410 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpd, float64, 0, 0); |
411 | 1bccec25 | Blue Swirl | |
412 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpes, float32, 0, 1); |
413 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmped, float64, 0, 1); |
414 | 1bccec25 | Blue Swirl | |
415 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0); |
416 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1); |
417 | 1bccec25 | Blue Swirl | |
418 | 1bccec25 | Blue Swirl | #ifdef TARGET_SPARC64
|
419 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmps_fcc1, float32, 22, 0); |
420 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpd_fcc1, float64, 22, 0); |
421 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0); |
422 | 1bccec25 | Blue Swirl | |
423 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmps_fcc2, float32, 24, 0); |
424 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpd_fcc2, float64, 24, 0); |
425 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0); |
426 | 1bccec25 | Blue Swirl | |
427 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmps_fcc3, float32, 26, 0); |
428 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpd_fcc3, float64, 26, 0); |
429 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0); |
430 | 1bccec25 | Blue Swirl | |
431 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpes_fcc1, float32, 22, 1); |
432 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmped_fcc1, float64, 22, 1); |
433 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1); |
434 | 1bccec25 | Blue Swirl | |
435 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpes_fcc2, float32, 24, 1); |
436 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmped_fcc2, float64, 24, 1); |
437 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1); |
438 | 1bccec25 | Blue Swirl | |
439 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmpes_fcc3, float32, 26, 1); |
440 | 03fb8cfc | Richard Henderson | GEN_FCMP_T(fcmped_fcc3, float64, 26, 1); |
441 | 1bccec25 | Blue Swirl | GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1); |
442 | 1bccec25 | Blue Swirl | #endif
|
443 | 03fb8cfc | Richard Henderson | #undef GEN_FCMP_T
|
444 | 03fb8cfc | Richard Henderson | #undef GEN_FCMP
|
445 | 1bccec25 | Blue Swirl | |
446 | 2e2f4ade | Blue Swirl | static inline void set_fsr(CPUState *env) |
447 | 1bccec25 | Blue Swirl | { |
448 | 1bccec25 | Blue Swirl | int rnd_mode;
|
449 | 1bccec25 | Blue Swirl | |
450 | 1bccec25 | Blue Swirl | switch (env->fsr & FSR_RD_MASK) {
|
451 | 1bccec25 | Blue Swirl | case FSR_RD_NEAREST:
|
452 | 1bccec25 | Blue Swirl | rnd_mode = float_round_nearest_even; |
453 | 1bccec25 | Blue Swirl | break;
|
454 | 1bccec25 | Blue Swirl | default:
|
455 | 1bccec25 | Blue Swirl | case FSR_RD_ZERO:
|
456 | 1bccec25 | Blue Swirl | rnd_mode = float_round_to_zero; |
457 | 1bccec25 | Blue Swirl | break;
|
458 | 1bccec25 | Blue Swirl | case FSR_RD_POS:
|
459 | 1bccec25 | Blue Swirl | rnd_mode = float_round_up; |
460 | 1bccec25 | Blue Swirl | break;
|
461 | 1bccec25 | Blue Swirl | case FSR_RD_NEG:
|
462 | 1bccec25 | Blue Swirl | rnd_mode = float_round_down; |
463 | 1bccec25 | Blue Swirl | break;
|
464 | 1bccec25 | Blue Swirl | } |
465 | 1bccec25 | Blue Swirl | set_float_rounding_mode(rnd_mode, &env->fp_status); |
466 | 1bccec25 | Blue Swirl | } |
467 | 1bccec25 | Blue Swirl | |
468 | 2e2f4ade | Blue Swirl | void helper_ldfsr(CPUState *env, uint32_t new_fsr)
|
469 | 1bccec25 | Blue Swirl | { |
470 | 1bccec25 | Blue Swirl | env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK); |
471 | 2e2f4ade | Blue Swirl | set_fsr(env); |
472 | 1bccec25 | Blue Swirl | } |
473 | 1bccec25 | Blue Swirl | |
474 | 1bccec25 | Blue Swirl | #ifdef TARGET_SPARC64
|
475 | 2e2f4ade | Blue Swirl | void helper_ldxfsr(CPUState *env, uint64_t new_fsr)
|
476 | 1bccec25 | Blue Swirl | { |
477 | 1bccec25 | Blue Swirl | env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK); |
478 | 2e2f4ade | Blue Swirl | set_fsr(env); |
479 | 1bccec25 | Blue Swirl | } |
480 | 1bccec25 | Blue Swirl | #endif |