1 /*
2 * FPU op helpers
3 *
4 * Copyright (c) 2003-2005 Fabrice Bellard
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "qemu/osdep.h"
21 #include "cpu.h"
22 #include "exec/helper-proto.h"
23 #include "fpu/softfloat.h"
24
f128_in(Int128 i)25 static inline float128 f128_in(Int128 i)
26 {
27 union {
28 Int128 i;
29 float128 f;
30 } u;
31
32 u.i = i;
33 return u.f;
34 }
35
f128_ret(float128 f)36 static inline Int128 f128_ret(float128 f)
37 {
38 union {
39 Int128 i;
40 float128 f;
41 } u;
42
43 u.f = f;
44 return u.i;
45 }
46
check_ieee_exceptions(CPUSPARCState * env,uintptr_t ra)47 static void check_ieee_exceptions(CPUSPARCState *env, uintptr_t ra)
48 {
49 target_ulong status = get_float_exception_flags(&env->fp_status);
50 uint32_t cexc = 0;
51
52 if (unlikely(status)) {
53 /* Keep exception flags clear for next time. */
54 set_float_exception_flags(0, &env->fp_status);
55
56 /* Copy IEEE 754 flags into FSR */
57 if (status & float_flag_invalid) {
58 cexc |= FSR_NVC;
59 }
60 if (status & float_flag_overflow) {
61 cexc |= FSR_OFC;
62 }
63 if (status & float_flag_underflow) {
64 cexc |= FSR_UFC;
65 }
66 if (status & float_flag_divbyzero) {
67 cexc |= FSR_DZC;
68 }
69 if (status & float_flag_inexact) {
70 cexc |= FSR_NXC;
71 }
72
73 if (cexc & (env->fsr >> FSR_TEM_SHIFT)) {
74 /* Unmasked exception, generate an IEEE trap. */
75 env->fsr_cexc_ftt = cexc | FSR_FTT_IEEE_EXCP;
76 cpu_raise_exception_ra(env, TT_FP_EXCP, ra);
77 }
78
79 /* Accumulate exceptions */
80 env->fsr |= cexc << FSR_AEXC_SHIFT;
81 }
82
83 /* No trap, so FTT is cleared. */
84 env->fsr_cexc_ftt = cexc;
85 }
86
helper_fadds(CPUSPARCState * env,float32 src1,float32 src2)87 float32 helper_fadds(CPUSPARCState *env, float32 src1, float32 src2)
88 {
89 float32 ret = float32_add(src1, src2, &env->fp_status);
90 check_ieee_exceptions(env, GETPC());
91 return ret;
92 }
93
helper_fsubs(CPUSPARCState * env,float32 src1,float32 src2)94 float32 helper_fsubs(CPUSPARCState *env, float32 src1, float32 src2)
95 {
96 float32 ret = float32_sub(src1, src2, &env->fp_status);
97 check_ieee_exceptions(env, GETPC());
98 return ret;
99 }
100
helper_fmuls(CPUSPARCState * env,float32 src1,float32 src2)101 float32 helper_fmuls(CPUSPARCState *env, float32 src1, float32 src2)
102 {
103 float32 ret = float32_mul(src1, src2, &env->fp_status);
104 check_ieee_exceptions(env, GETPC());
105 return ret;
106 }
107
helper_fdivs(CPUSPARCState * env,float32 src1,float32 src2)108 float32 helper_fdivs(CPUSPARCState *env, float32 src1, float32 src2)
109 {
110 float32 ret = float32_div(src1, src2, &env->fp_status);
111 check_ieee_exceptions(env, GETPC());
112 return ret;
113 }
114
helper_faddd(CPUSPARCState * env,float64 src1,float64 src2)115 float64 helper_faddd(CPUSPARCState *env, float64 src1, float64 src2)
116 {
117 float64 ret = float64_add(src1, src2, &env->fp_status);
118 check_ieee_exceptions(env, GETPC());
119 return ret;
120 }
121
helper_fsubd(CPUSPARCState * env,float64 src1,float64 src2)122 float64 helper_fsubd(CPUSPARCState *env, float64 src1, float64 src2)
123 {
124 float64 ret = float64_sub(src1, src2, &env->fp_status);
125 check_ieee_exceptions(env, GETPC());
126 return ret;
127 }
128
helper_fmuld(CPUSPARCState * env,float64 src1,float64 src2)129 float64 helper_fmuld(CPUSPARCState *env, float64 src1, float64 src2)
130 {
131 float64 ret = float64_mul(src1, src2, &env->fp_status);
132 check_ieee_exceptions(env, GETPC());
133 return ret;
134 }
135
helper_fdivd(CPUSPARCState * env,float64 src1,float64 src2)136 float64 helper_fdivd(CPUSPARCState *env, float64 src1, float64 src2)
137 {
138 float64 ret = float64_div(src1, src2, &env->fp_status);
139 check_ieee_exceptions(env, GETPC());
140 return ret;
141 }
142
helper_faddq(CPUSPARCState * env,Int128 src1,Int128 src2)143 Int128 helper_faddq(CPUSPARCState *env, Int128 src1, Int128 src2)
144 {
145 float128 ret = float128_add(f128_in(src1), f128_in(src2), &env->fp_status);
146 check_ieee_exceptions(env, GETPC());
147 return f128_ret(ret);
148 }
149
helper_fsubq(CPUSPARCState * env,Int128 src1,Int128 src2)150 Int128 helper_fsubq(CPUSPARCState *env, Int128 src1, Int128 src2)
151 {
152 float128 ret = float128_sub(f128_in(src1), f128_in(src2), &env->fp_status);
153 check_ieee_exceptions(env, GETPC());
154 return f128_ret(ret);
155 }
156
helper_fmulq(CPUSPARCState * env,Int128 src1,Int128 src2)157 Int128 helper_fmulq(CPUSPARCState *env, Int128 src1, Int128 src2)
158 {
159 float128 ret = float128_mul(f128_in(src1), f128_in(src2), &env->fp_status);
160 check_ieee_exceptions(env, GETPC());
161 return f128_ret(ret);
162 }
163
helper_fdivq(CPUSPARCState * env,Int128 src1,Int128 src2)164 Int128 helper_fdivq(CPUSPARCState *env, Int128 src1, Int128 src2)
165 {
166 float128 ret = float128_div(f128_in(src1), f128_in(src2), &env->fp_status);
167 check_ieee_exceptions(env, GETPC());
168 return f128_ret(ret);
169 }
170
helper_fsmuld(CPUSPARCState * env,float32 src1,float32 src2)171 float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)
172 {
173 float64 ret = float64_mul(float32_to_float64(src1, &env->fp_status),
174 float32_to_float64(src2, &env->fp_status),
175 &env->fp_status);
176 check_ieee_exceptions(env, GETPC());
177 return ret;
178 }
179
helper_fdmulq(CPUSPARCState * env,float64 src1,float64 src2)180 Int128 helper_fdmulq(CPUSPARCState *env, float64 src1, float64 src2)
181 {
182 float128 ret = float128_mul(float64_to_float128(src1, &env->fp_status),
183 float64_to_float128(src2, &env->fp_status),
184 &env->fp_status);
185 check_ieee_exceptions(env, GETPC());
186 return f128_ret(ret);
187 }
188
189 /* Integer to float conversion. */
helper_fitos(CPUSPARCState * env,int32_t src)190 float32 helper_fitos(CPUSPARCState *env, int32_t src)
191 {
192 float32 ret = int32_to_float32(src, &env->fp_status);
193 check_ieee_exceptions(env, GETPC());
194 return ret;
195 }
196
helper_fitod(CPUSPARCState * env,int32_t src)197 float64 helper_fitod(CPUSPARCState *env, int32_t src)
198 {
199 float64 ret = int32_to_float64(src, &env->fp_status);
200 check_ieee_exceptions(env, GETPC());
201 return ret;
202 }
203
helper_fitoq(CPUSPARCState * env,int32_t src)204 Int128 helper_fitoq(CPUSPARCState *env, int32_t src)
205 {
206 float128 ret = int32_to_float128(src, &env->fp_status);
207 check_ieee_exceptions(env, GETPC());
208 return f128_ret(ret);
209 }
210
211 #ifdef TARGET_SPARC64
helper_fxtos(CPUSPARCState * env,int64_t src)212 float32 helper_fxtos(CPUSPARCState *env, int64_t src)
213 {
214 float32 ret = int64_to_float32(src, &env->fp_status);
215 check_ieee_exceptions(env, GETPC());
216 return ret;
217 }
218
helper_fxtod(CPUSPARCState * env,int64_t src)219 float64 helper_fxtod(CPUSPARCState *env, int64_t src)
220 {
221 float64 ret = int64_to_float64(src, &env->fp_status);
222 check_ieee_exceptions(env, GETPC());
223 return ret;
224 }
225
helper_fxtoq(CPUSPARCState * env,int64_t src)226 Int128 helper_fxtoq(CPUSPARCState *env, int64_t src)
227 {
228 float128 ret = int64_to_float128(src, &env->fp_status);
229 check_ieee_exceptions(env, GETPC());
230 return f128_ret(ret);
231 }
232 #endif
233
234 /* floating point conversion */
helper_fdtos(CPUSPARCState * env,float64 src)235 float32 helper_fdtos(CPUSPARCState *env, float64 src)
236 {
237 float32 ret = float64_to_float32(src, &env->fp_status);
238 check_ieee_exceptions(env, GETPC());
239 return ret;
240 }
241
helper_fstod(CPUSPARCState * env,float32 src)242 float64 helper_fstod(CPUSPARCState *env, float32 src)
243 {
244 float64 ret = float32_to_float64(src, &env->fp_status);
245 check_ieee_exceptions(env, GETPC());
246 return ret;
247 }
248
helper_fqtos(CPUSPARCState * env,Int128 src)249 float32 helper_fqtos(CPUSPARCState *env, Int128 src)
250 {
251 float32 ret = float128_to_float32(f128_in(src), &env->fp_status);
252 check_ieee_exceptions(env, GETPC());
253 return ret;
254 }
255
helper_fstoq(CPUSPARCState * env,float32 src)256 Int128 helper_fstoq(CPUSPARCState *env, float32 src)
257 {
258 float128 ret = float32_to_float128(src, &env->fp_status);
259 check_ieee_exceptions(env, GETPC());
260 return f128_ret(ret);
261 }
262
helper_fqtod(CPUSPARCState * env,Int128 src)263 float64 helper_fqtod(CPUSPARCState *env, Int128 src)
264 {
265 float64 ret = float128_to_float64(f128_in(src), &env->fp_status);
266 check_ieee_exceptions(env, GETPC());
267 return ret;
268 }
269
helper_fdtoq(CPUSPARCState * env,float64 src)270 Int128 helper_fdtoq(CPUSPARCState *env, float64 src)
271 {
272 float128 ret = float64_to_float128(src, &env->fp_status);
273 check_ieee_exceptions(env, GETPC());
274 return f128_ret(ret);
275 }
276
277 /* Float to integer conversion. */
helper_fstoi(CPUSPARCState * env,float32 src)278 int32_t helper_fstoi(CPUSPARCState *env, float32 src)
279 {
280 int32_t ret = float32_to_int32_round_to_zero(src, &env->fp_status);
281 check_ieee_exceptions(env, GETPC());
282 return ret;
283 }
284
helper_fdtoi(CPUSPARCState * env,float64 src)285 int32_t helper_fdtoi(CPUSPARCState *env, float64 src)
286 {
287 int32_t ret = float64_to_int32_round_to_zero(src, &env->fp_status);
288 check_ieee_exceptions(env, GETPC());
289 return ret;
290 }
291
helper_fqtoi(CPUSPARCState * env,Int128 src)292 int32_t helper_fqtoi(CPUSPARCState *env, Int128 src)
293 {
294 int32_t ret = float128_to_int32_round_to_zero(f128_in(src),
295 &env->fp_status);
296 check_ieee_exceptions(env, GETPC());
297 return ret;
298 }
299
300 #ifdef TARGET_SPARC64
helper_fstox(CPUSPARCState * env,float32 src)301 int64_t helper_fstox(CPUSPARCState *env, float32 src)
302 {
303 int64_t ret = float32_to_int64_round_to_zero(src, &env->fp_status);
304 check_ieee_exceptions(env, GETPC());
305 return ret;
306 }
307
helper_fdtox(CPUSPARCState * env,float64 src)308 int64_t helper_fdtox(CPUSPARCState *env, float64 src)
309 {
310 int64_t ret = float64_to_int64_round_to_zero(src, &env->fp_status);
311 check_ieee_exceptions(env, GETPC());
312 return ret;
313 }
314
helper_fqtox(CPUSPARCState * env,Int128 src)315 int64_t helper_fqtox(CPUSPARCState *env, Int128 src)
316 {
317 int64_t ret = float128_to_int64_round_to_zero(f128_in(src),
318 &env->fp_status);
319 check_ieee_exceptions(env, GETPC());
320 return ret;
321 }
322 #endif
323
helper_fsqrts(CPUSPARCState * env,float32 src)324 float32 helper_fsqrts(CPUSPARCState *env, float32 src)
325 {
326 float32 ret = float32_sqrt(src, &env->fp_status);
327 check_ieee_exceptions(env, GETPC());
328 return ret;
329 }
330
helper_fsqrtd(CPUSPARCState * env,float64 src)331 float64 helper_fsqrtd(CPUSPARCState *env, float64 src)
332 {
333 float64 ret = float64_sqrt(src, &env->fp_status);
334 check_ieee_exceptions(env, GETPC());
335 return ret;
336 }
337
helper_fsqrtq(CPUSPARCState * env,Int128 src)338 Int128 helper_fsqrtq(CPUSPARCState *env, Int128 src)
339 {
340 float128 ret = float128_sqrt(f128_in(src), &env->fp_status);
341 check_ieee_exceptions(env, GETPC());
342 return f128_ret(ret);
343 }
344
helper_fmadds(CPUSPARCState * env,float32 s1,float32 s2,float32 s3,int32_t sc,uint32_t op)345 float32 helper_fmadds(CPUSPARCState *env, float32 s1,
346 float32 s2, float32 s3, int32_t sc, uint32_t op)
347 {
348 float32 ret = float32_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
349 check_ieee_exceptions(env, GETPC());
350 return ret;
351 }
352
helper_fmaddd(CPUSPARCState * env,float64 s1,float64 s2,float64 s3,int32_t sc,uint32_t op)353 float64 helper_fmaddd(CPUSPARCState *env, float64 s1,
354 float64 s2, float64 s3, int32_t sc, uint32_t op)
355 {
356 float64 ret = float64_muladd_scalbn(s1, s2, s3, sc, op, &env->fp_status);
357 check_ieee_exceptions(env, GETPC());
358 return ret;
359 }
360
helper_fnadds(CPUSPARCState * env,float32 src1,float32 src2)361 float32 helper_fnadds(CPUSPARCState *env, float32 src1, float32 src2)
362 {
363 float32 ret = float32_add(src1, src2, &env->fp_status);
364
365 /*
366 * NaN inputs or result do not get a sign change.
367 * Nor, apparently, does zero: on hardware, -(x + -x) yields +0.
368 */
369 if (!float32_is_any_nan(ret) && !float32_is_zero(ret)) {
370 ret = float32_chs(ret);
371 }
372 check_ieee_exceptions(env, GETPC());
373 return ret;
374 }
375
helper_fnmuls(CPUSPARCState * env,float32 src1,float32 src2)376 float32 helper_fnmuls(CPUSPARCState *env, float32 src1, float32 src2)
377 {
378 float32 ret = float32_mul(src1, src2, &env->fp_status);
379
380 /* NaN inputs or result do not get a sign change. */
381 if (!float32_is_any_nan(ret)) {
382 ret = float32_chs(ret);
383 }
384 check_ieee_exceptions(env, GETPC());
385 return ret;
386 }
387
helper_fnaddd(CPUSPARCState * env,float64 src1,float64 src2)388 float64 helper_fnaddd(CPUSPARCState *env, float64 src1, float64 src2)
389 {
390 float64 ret = float64_add(src1, src2, &env->fp_status);
391
392 /*
393 * NaN inputs or result do not get a sign change.
394 * Nor, apparently, does zero: on hardware, -(x + -x) yields +0.
395 */
396 if (!float64_is_any_nan(ret) && !float64_is_zero(ret)) {
397 ret = float64_chs(ret);
398 }
399 check_ieee_exceptions(env, GETPC());
400 return ret;
401 }
402
helper_fnmuld(CPUSPARCState * env,float64 src1,float64 src2)403 float64 helper_fnmuld(CPUSPARCState *env, float64 src1, float64 src2)
404 {
405 float64 ret = float64_mul(src1, src2, &env->fp_status);
406
407 /* NaN inputs or result do not get a sign change. */
408 if (!float64_is_any_nan(ret)) {
409 ret = float64_chs(ret);
410 }
411 check_ieee_exceptions(env, GETPC());
412 return ret;
413 }
414
helper_fnsmuld(CPUSPARCState * env,float32 src1,float32 src2)415 float64 helper_fnsmuld(CPUSPARCState *env, float32 src1, float32 src2)
416 {
417 float64 ret = float64_mul(float32_to_float64(src1, &env->fp_status),
418 float32_to_float64(src2, &env->fp_status),
419 &env->fp_status);
420
421 /* NaN inputs or result do not get a sign change. */
422 if (!float64_is_any_nan(ret)) {
423 ret = float64_chs(ret);
424 }
425 check_ieee_exceptions(env, GETPC());
426 return ret;
427 }
428
finish_fcmp(CPUSPARCState * env,FloatRelation r,uintptr_t ra)429 static uint32_t finish_fcmp(CPUSPARCState *env, FloatRelation r, uintptr_t ra)
430 {
431 check_ieee_exceptions(env, ra);
432
433 /*
434 * FCC values:
435 * 0 =
436 * 1 <
437 * 2 >
438 * 3 unordered
439 */
440 switch (r) {
441 case float_relation_equal:
442 return 0;
443 case float_relation_less:
444 return 1;
445 case float_relation_greater:
446 return 2;
447 case float_relation_unordered:
448 return 3;
449 }
450 g_assert_not_reached();
451 }
452
helper_fcmps(CPUSPARCState * env,float32 src1,float32 src2)453 uint32_t helper_fcmps(CPUSPARCState *env, float32 src1, float32 src2)
454 {
455 FloatRelation r = float32_compare_quiet(src1, src2, &env->fp_status);
456 return finish_fcmp(env, r, GETPC());
457 }
458
helper_fcmpes(CPUSPARCState * env,float32 src1,float32 src2)459 uint32_t helper_fcmpes(CPUSPARCState *env, float32 src1, float32 src2)
460 {
461 FloatRelation r = float32_compare(src1, src2, &env->fp_status);
462 return finish_fcmp(env, r, GETPC());
463 }
464
helper_fcmpd(CPUSPARCState * env,float64 src1,float64 src2)465 uint32_t helper_fcmpd(CPUSPARCState *env, float64 src1, float64 src2)
466 {
467 FloatRelation r = float64_compare_quiet(src1, src2, &env->fp_status);
468 return finish_fcmp(env, r, GETPC());
469 }
470
helper_fcmped(CPUSPARCState * env,float64 src1,float64 src2)471 uint32_t helper_fcmped(CPUSPARCState *env, float64 src1, float64 src2)
472 {
473 FloatRelation r = float64_compare(src1, src2, &env->fp_status);
474 return finish_fcmp(env, r, GETPC());
475 }
476
helper_fcmpq(CPUSPARCState * env,Int128 src1,Int128 src2)477 uint32_t helper_fcmpq(CPUSPARCState *env, Int128 src1, Int128 src2)
478 {
479 FloatRelation r = float128_compare_quiet(f128_in(src1), f128_in(src2),
480 &env->fp_status);
481 return finish_fcmp(env, r, GETPC());
482 }
483
helper_fcmpeq(CPUSPARCState * env,Int128 src1,Int128 src2)484 uint32_t helper_fcmpeq(CPUSPARCState *env, Int128 src1, Int128 src2)
485 {
486 FloatRelation r = float128_compare(f128_in(src1), f128_in(src2),
487 &env->fp_status);
488 return finish_fcmp(env, r, GETPC());
489 }
490
helper_flcmps(CPUSPARCState * env,float32 src1,float32 src2)491 uint32_t helper_flcmps(CPUSPARCState *env, float32 src1, float32 src2)
492 {
493 /*
494 * FLCMP never raises an exception nor modifies any FSR fields.
495 * Perform the comparison with a dummy fp environment.
496 */
497 float_status discard = env->fp_status;
498 FloatRelation r;
499
500 set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
501 r = float32_compare_quiet(src1, src2, &discard);
502
503 switch (r) {
504 case float_relation_equal:
505 if (src2 == float32_zero && src1 != float32_zero) {
506 return 1; /* -0.0 < +0.0 */
507 }
508 return 0;
509 case float_relation_less:
510 return 1;
511 case float_relation_greater:
512 return 0;
513 case float_relation_unordered:
514 return float32_is_any_nan(src2) ? 3 : 2;
515 }
516 g_assert_not_reached();
517 }
518
helper_flcmpd(CPUSPARCState * env,float64 src1,float64 src2)519 uint32_t helper_flcmpd(CPUSPARCState *env, float64 src1, float64 src2)
520 {
521 float_status discard = env->fp_status;
522 FloatRelation r;
523
524 set_float_2nan_prop_rule(float_2nan_prop_s_ba, &discard);
525 r = float64_compare_quiet(src1, src2, &discard);
526
527 switch (r) {
528 case float_relation_equal:
529 if (src2 == float64_zero && src1 != float64_zero) {
530 return 1; /* -0.0 < +0.0 */
531 }
532 return 0;
533 case float_relation_less:
534 return 1;
535 case float_relation_greater:
536 return 0;
537 case float_relation_unordered:
538 return float64_is_any_nan(src2) ? 3 : 2;
539 }
540 g_assert_not_reached();
541 }
542
cpu_get_fsr(CPUSPARCState * env)543 target_ulong cpu_get_fsr(CPUSPARCState *env)
544 {
545 target_ulong fsr = env->fsr | env->fsr_cexc_ftt;
546
547 fsr |= env->fcc[0] << FSR_FCC0_SHIFT;
548 #ifdef TARGET_SPARC64
549 fsr |= (uint64_t)env->fcc[1] << FSR_FCC1_SHIFT;
550 fsr |= (uint64_t)env->fcc[2] << FSR_FCC2_SHIFT;
551 fsr |= (uint64_t)env->fcc[3] << FSR_FCC3_SHIFT;
552 #elif !defined(CONFIG_USER_ONLY)
553 fsr |= env->fsr_qne;
554 #endif
555
556 /* VER is kept completely separate until re-assembly. */
557 fsr |= env->def.fpu_version;
558
559 return fsr;
560 }
561
helper_get_fsr(CPUSPARCState * env)562 target_ulong helper_get_fsr(CPUSPARCState *env)
563 {
564 return cpu_get_fsr(env);
565 }
566
set_fsr_nonsplit(CPUSPARCState * env,target_ulong fsr)567 static void set_fsr_nonsplit(CPUSPARCState *env, target_ulong fsr)
568 {
569 int rnd_mode;
570
571 env->fsr = fsr & (FSR_RD_MASK | FSR_TEM_MASK | FSR_AEXC_MASK);
572
573 switch (fsr & FSR_RD_MASK) {
574 case FSR_RD_NEAREST:
575 rnd_mode = float_round_nearest_even;
576 break;
577 default:
578 case FSR_RD_ZERO:
579 rnd_mode = float_round_to_zero;
580 break;
581 case FSR_RD_POS:
582 rnd_mode = float_round_up;
583 break;
584 case FSR_RD_NEG:
585 rnd_mode = float_round_down;
586 break;
587 }
588 set_float_rounding_mode(rnd_mode, &env->fp_status);
589 }
590
cpu_put_fsr(CPUSPARCState * env,target_ulong fsr)591 void cpu_put_fsr(CPUSPARCState *env, target_ulong fsr)
592 {
593 env->fsr_cexc_ftt = fsr & (FSR_CEXC_MASK | FSR_FTT_MASK);
594
595 env->fcc[0] = extract32(fsr, FSR_FCC0_SHIFT, 2);
596 #ifdef TARGET_SPARC64
597 env->fcc[1] = extract64(fsr, FSR_FCC1_SHIFT, 2);
598 env->fcc[2] = extract64(fsr, FSR_FCC2_SHIFT, 2);
599 env->fcc[3] = extract64(fsr, FSR_FCC3_SHIFT, 2);
600 #elif !defined(CONFIG_USER_ONLY)
601 env->fsr_qne = fsr & FSR_QNE;
602 #endif
603
604 set_fsr_nonsplit(env, fsr);
605 }
606
helper_set_fsr_nofcc_noftt(CPUSPARCState * env,uint32_t fsr)607 void helper_set_fsr_nofcc_noftt(CPUSPARCState *env, uint32_t fsr)
608 {
609 env->fsr_cexc_ftt &= FSR_FTT_MASK;
610 env->fsr_cexc_ftt |= fsr & FSR_CEXC_MASK;
611 set_fsr_nonsplit(env, fsr);
612 }
613
helper_set_fsr_nofcc(CPUSPARCState * env,uint32_t fsr)614 void helper_set_fsr_nofcc(CPUSPARCState *env, uint32_t fsr)
615 {
616 env->fsr_cexc_ftt = fsr & (FSR_CEXC_MASK | FSR_FTT_MASK);
617 set_fsr_nonsplit(env, fsr);
618 }
619