xref: /qemu/target/sparc/fop_helper.c (revision f88934b61ee0dc1d583f0a576ce87ed2ff9c116b)
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