1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * LoongArch float point emulation helpers for QEMU
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
8 #include "qemu/osdep.h"
10 #include "exec/helper-proto.h"
11 #include "exec/exec-all.h"
12 #include "exec/cpu_ldst.h"
13 #include "fpu/softfloat.h"
14 #include "internals.h"
16 #define FLOAT_TO_INT32_OVERFLOW 0x7fffffff
17 #define FLOAT_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
19 static inline uint64_t nanbox_s(float32 fp
)
21 return fp
| MAKE_64BIT_MASK(32, 32);
24 /* Convert loongarch rounding mode in fcsr0 to IEEE library */
25 static const FloatRoundMode ieee_rm
[4] = {
26 float_round_nearest_even
,
32 void restore_fp_status(CPULoongArchState
*env
)
34 set_float_rounding_mode(ieee_rm
[(env
->fcsr0
>> FCSR0_RM
) & 0x3],
36 set_flush_to_zero(0, &env
->fp_status
);
39 static int ieee_ex_to_loongarch(int xcpt
)
42 if (xcpt
& float_flag_invalid
) {
45 if (xcpt
& float_flag_overflow
) {
48 if (xcpt
& float_flag_underflow
) {
51 if (xcpt
& float_flag_divbyzero
) {
54 if (xcpt
& float_flag_inexact
) {
60 static void update_fcsr0_mask(CPULoongArchState
*env
, uintptr_t pc
, int mask
)
62 int flags
= get_float_exception_flags(&env
->fp_status
);
64 set_float_exception_flags(0, &env
->fp_status
);
69 SET_FP_CAUSE(env
->fcsr0
, flags
);
72 flags
= ieee_ex_to_loongarch(flags
);
73 SET_FP_CAUSE(env
->fcsr0
, flags
);
76 if (GET_FP_ENABLES(env
->fcsr0
) & flags
) {
77 do_raise_exception(env
, EXCCODE_FPE
, pc
);
79 UPDATE_FP_FLAGS(env
->fcsr0
, flags
);
83 static void update_fcsr0(CPULoongArchState
*env
, uintptr_t pc
)
85 update_fcsr0_mask(env
, pc
, 0);
88 uint64_t helper_fadd_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
92 fd
= nanbox_s(float32_add((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
93 update_fcsr0(env
, GETPC());
97 uint64_t helper_fadd_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
101 fd
= float64_add(fj
, fk
, &env
->fp_status
);
102 update_fcsr0(env
, GETPC());
106 uint64_t helper_fsub_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
110 fd
= nanbox_s(float32_sub((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
111 update_fcsr0(env
, GETPC());
115 uint64_t helper_fsub_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
119 fd
= float64_sub(fj
, fk
, &env
->fp_status
);
120 update_fcsr0(env
, GETPC());
124 uint64_t helper_fmul_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
128 fd
= nanbox_s(float32_mul((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
129 update_fcsr0(env
, GETPC());
133 uint64_t helper_fmul_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
137 fd
= float64_mul(fj
, fk
, &env
->fp_status
);
138 update_fcsr0(env
, GETPC());
142 uint64_t helper_fdiv_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
146 fd
= nanbox_s(float32_div((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
147 update_fcsr0(env
, GETPC());
151 uint64_t helper_fdiv_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
155 fd
= float64_div(fj
, fk
, &env
->fp_status
);
156 update_fcsr0(env
, GETPC());
160 uint64_t helper_fmax_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
164 fd
= nanbox_s(float32_maxnum((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
165 update_fcsr0(env
, GETPC());
169 uint64_t helper_fmax_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
173 fd
= float64_maxnum(fj
, fk
, &env
->fp_status
);
174 update_fcsr0(env
, GETPC());
178 uint64_t helper_fmin_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
182 fd
= nanbox_s(float32_minnum((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
183 update_fcsr0(env
, GETPC());
187 uint64_t helper_fmin_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
191 fd
= float64_minnum(fj
, fk
, &env
->fp_status
);
192 update_fcsr0(env
, GETPC());
196 uint64_t helper_fmaxa_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
200 fd
= nanbox_s(float32_maxnummag((uint32_t)fj
,
201 (uint32_t)fk
, &env
->fp_status
));
202 update_fcsr0(env
, GETPC());
206 uint64_t helper_fmaxa_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
210 fd
= float64_maxnummag(fj
, fk
, &env
->fp_status
);
211 update_fcsr0(env
, GETPC());
215 uint64_t helper_fmina_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
219 fd
= nanbox_s(float32_minnummag((uint32_t)fj
,
220 (uint32_t)fk
, &env
->fp_status
));
221 update_fcsr0(env
, GETPC());
225 uint64_t helper_fmina_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
229 fd
= float64_minnummag(fj
, fk
, &env
->fp_status
);
230 update_fcsr0(env
, GETPC());
234 uint64_t helper_fscaleb_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
237 int32_t n
= (int32_t)fk
;
239 fd
= nanbox_s(float32_scalbn((uint32_t)fj
,
241 n
< -0x200 ? -0x200 : n
,
243 update_fcsr0(env
, GETPC());
247 uint64_t helper_fscaleb_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
250 int64_t n
= (int64_t)fk
;
252 fd
= float64_scalbn(fj
,
253 n
> 0x1000 ? 0x1000 :
254 n
< -0x1000 ? -0x1000 : n
,
256 update_fcsr0(env
, GETPC());
260 uint64_t helper_fsqrt_s(CPULoongArchState
*env
, uint64_t fj
)
264 fd
= nanbox_s(float32_sqrt((uint32_t)fj
, &env
->fp_status
));
265 update_fcsr0(env
, GETPC());
269 uint64_t helper_fsqrt_d(CPULoongArchState
*env
, uint64_t fj
)
273 fd
= float64_sqrt(fj
, &env
->fp_status
);
274 update_fcsr0(env
, GETPC());
278 uint64_t helper_frecip_s(CPULoongArchState
*env
, uint64_t fj
)
282 fd
= nanbox_s(float32_div(float32_one
, (uint32_t)fj
, &env
->fp_status
));
283 update_fcsr0(env
, GETPC());
287 uint64_t helper_frecip_d(CPULoongArchState
*env
, uint64_t fj
)
291 fd
= float64_div(float64_one
, fj
, &env
->fp_status
);
292 update_fcsr0(env
, GETPC());
296 uint64_t helper_frsqrt_s(CPULoongArchState
*env
, uint64_t fj
)
301 fp
= float32_sqrt((uint32_t)fj
, &env
->fp_status
);
302 fd
= nanbox_s(float32_div(float32_one
, fp
, &env
->fp_status
));
303 update_fcsr0(env
, GETPC());
307 uint64_t helper_frsqrt_d(CPULoongArchState
*env
, uint64_t fj
)
311 fp
= float64_sqrt(fj
, &env
->fp_status
);
312 fd
= float64_div(float64_one
, fp
, &env
->fp_status
);
313 update_fcsr0(env
, GETPC());
317 uint64_t helper_flogb_s(CPULoongArchState
*env
, uint64_t fj
)
321 float_status
*status
= &env
->fp_status
;
322 FloatRoundMode old_mode
= get_float_rounding_mode(status
);
324 set_float_rounding_mode(float_round_down
, status
);
325 fp
= float32_log2((uint32_t)fj
, status
);
326 fd
= nanbox_s(float32_round_to_int(fp
, status
));
327 set_float_rounding_mode(old_mode
, status
);
328 update_fcsr0_mask(env
, GETPC(), float_flag_inexact
);
332 uint64_t helper_flogb_d(CPULoongArchState
*env
, uint64_t fj
)
335 float_status
*status
= &env
->fp_status
;
336 FloatRoundMode old_mode
= get_float_rounding_mode(status
);
338 set_float_rounding_mode(float_round_down
, status
);
339 fd
= float64_log2(fj
, status
);
340 fd
= float64_round_to_int(fd
, status
);
341 set_float_rounding_mode(old_mode
, status
);
342 update_fcsr0_mask(env
, GETPC(), float_flag_inexact
);
346 uint64_t helper_fclass_s(CPULoongArchState
*env
, uint64_t fj
)
349 bool sign
= float32_is_neg(f
);
351 if (float32_is_infinity(f
)) {
352 return sign
? 1 << 2 : 1 << 6;
353 } else if (float32_is_zero(f
)) {
354 return sign
? 1 << 5 : 1 << 9;
355 } else if (float32_is_zero_or_denormal(f
)) {
356 return sign
? 1 << 4 : 1 << 8;
357 } else if (float32_is_any_nan(f
)) {
358 float_status s
= { }; /* for snan_bit_is_one */
359 return float32_is_quiet_nan(f
, &s
) ? 1 << 1 : 1 << 0;
361 return sign
? 1 << 3 : 1 << 7;
365 uint64_t helper_fclass_d(CPULoongArchState
*env
, uint64_t fj
)
368 bool sign
= float64_is_neg(f
);
370 if (float64_is_infinity(f
)) {
371 return sign
? 1 << 2 : 1 << 6;
372 } else if (float64_is_zero(f
)) {
373 return sign
? 1 << 5 : 1 << 9;
374 } else if (float64_is_zero_or_denormal(f
)) {
375 return sign
? 1 << 4 : 1 << 8;
376 } else if (float64_is_any_nan(f
)) {
377 float_status s
= { }; /* for snan_bit_is_one */
378 return float64_is_quiet_nan(f
, &s
) ? 1 << 1 : 1 << 0;
380 return sign
? 1 << 3 : 1 << 7;
384 uint64_t helper_fmuladd_s(CPULoongArchState
*env
, uint64_t fj
,
385 uint64_t fk
, uint64_t fa
, uint32_t flag
)
389 fd
= nanbox_s(float32_muladd((uint32_t)fj
, (uint32_t)fk
,
390 (uint32_t)fa
, flag
, &env
->fp_status
));
391 update_fcsr0(env
, GETPC());
395 uint64_t helper_fmuladd_d(CPULoongArchState
*env
, uint64_t fj
,
396 uint64_t fk
, uint64_t fa
, uint32_t flag
)
400 fd
= float64_muladd(fj
, fk
, fa
, flag
, &env
->fp_status
);
401 update_fcsr0(env
, GETPC());
405 static uint64_t fcmp_common(CPULoongArchState
*env
, FloatRelation cmp
,
411 case float_relation_less
:
412 ret
= (flags
& FCMP_LT
);
414 case float_relation_equal
:
415 ret
= (flags
& FCMP_EQ
);
417 case float_relation_greater
:
418 ret
= (flags
& FCMP_GT
);
420 case float_relation_unordered
:
421 ret
= (flags
& FCMP_UN
);
424 g_assert_not_reached();
426 update_fcsr0(env
, GETPC());
432 uint64_t helper_fcmp_c_s(CPULoongArchState
*env
, uint64_t fj
,
433 uint64_t fk
, uint32_t flags
)
435 FloatRelation cmp
= float32_compare_quiet((uint32_t)fj
,
436 (uint32_t)fk
, &env
->fp_status
);
437 return fcmp_common(env
, cmp
, flags
);
441 uint64_t helper_fcmp_s_s(CPULoongArchState
*env
, uint64_t fj
,
442 uint64_t fk
, uint32_t flags
)
444 FloatRelation cmp
= float32_compare((uint32_t)fj
,
445 (uint32_t)fk
, &env
->fp_status
);
446 return fcmp_common(env
, cmp
, flags
);
450 uint64_t helper_fcmp_c_d(CPULoongArchState
*env
, uint64_t fj
,
451 uint64_t fk
, uint32_t flags
)
453 FloatRelation cmp
= float64_compare_quiet(fj
, fk
, &env
->fp_status
);
454 return fcmp_common(env
, cmp
, flags
);
458 uint64_t helper_fcmp_s_d(CPULoongArchState
*env
, uint64_t fj
,
459 uint64_t fk
, uint32_t flags
)
461 FloatRelation cmp
= float64_compare(fj
, fk
, &env
->fp_status
);
462 return fcmp_common(env
, cmp
, flags
);
465 /* floating point conversion */
466 uint64_t helper_fcvt_s_d(CPULoongArchState
*env
, uint64_t fj
)
470 fd
= nanbox_s(float64_to_float32(fj
, &env
->fp_status
));
471 update_fcsr0(env
, GETPC());
475 uint64_t helper_fcvt_d_s(CPULoongArchState
*env
, uint64_t fj
)
479 fd
= float32_to_float64((uint32_t)fj
, &env
->fp_status
);
480 update_fcsr0(env
, GETPC());
484 uint64_t helper_ffint_s_w(CPULoongArchState
*env
, uint64_t fj
)
488 fd
= nanbox_s(int32_to_float32((int32_t)fj
, &env
->fp_status
));
489 update_fcsr0(env
, GETPC());
493 uint64_t helper_ffint_s_l(CPULoongArchState
*env
, uint64_t fj
)
497 fd
= nanbox_s(int64_to_float32(fj
, &env
->fp_status
));
498 update_fcsr0(env
, GETPC());
502 uint64_t helper_ffint_d_w(CPULoongArchState
*env
, uint64_t fj
)
506 fd
= int32_to_float64((int32_t)fj
, &env
->fp_status
);
507 update_fcsr0(env
, GETPC());
511 uint64_t helper_ffint_d_l(CPULoongArchState
*env
, uint64_t fj
)
515 fd
= int64_to_float64(fj
, &env
->fp_status
);
516 update_fcsr0(env
, GETPC());
520 uint64_t helper_frint_s(CPULoongArchState
*env
, uint64_t fj
)
524 fd
= (uint64_t)(float32_round_to_int((uint32_t)fj
, &env
->fp_status
));
525 update_fcsr0(env
, GETPC());
529 uint64_t helper_frint_d(CPULoongArchState
*env
, uint64_t fj
)
533 fd
= float64_round_to_int(fj
, &env
->fp_status
);
534 update_fcsr0(env
, GETPC());
538 uint64_t helper_ftintrm_l_d(CPULoongArchState
*env
, uint64_t fj
)
541 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
543 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
544 fd
= float64_to_int64(fj
, &env
->fp_status
);
545 set_float_rounding_mode(old_mode
, &env
->fp_status
);
547 if (get_float_exception_flags(&env
->fp_status
) &
548 (float_flag_invalid
| float_flag_overflow
)) {
549 fd
= FLOAT_TO_INT64_OVERFLOW
;
551 update_fcsr0(env
, GETPC());
555 uint64_t helper_ftintrm_l_s(CPULoongArchState
*env
, uint64_t fj
)
558 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
560 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
561 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
562 set_float_rounding_mode(old_mode
, &env
->fp_status
);
564 if (get_float_exception_flags(&env
->fp_status
) &
565 (float_flag_invalid
| float_flag_overflow
)) {
566 fd
= FLOAT_TO_INT64_OVERFLOW
;
568 update_fcsr0(env
, GETPC());
572 uint64_t helper_ftintrm_w_d(CPULoongArchState
*env
, uint64_t fj
)
575 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
577 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
578 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
579 set_float_rounding_mode(old_mode
, &env
->fp_status
);
581 if (get_float_exception_flags(&env
->fp_status
) &
582 (float_flag_invalid
| float_flag_overflow
)) {
583 fd
= FLOAT_TO_INT32_OVERFLOW
;
585 update_fcsr0(env
, GETPC());
589 uint64_t helper_ftintrm_w_s(CPULoongArchState
*env
, uint64_t fj
)
592 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
594 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
595 fd
= (uint64_t)float32_to_int32((uint32_t)fj
, &env
->fp_status
);
596 set_float_rounding_mode(old_mode
, &env
->fp_status
);
598 if (get_float_exception_flags(&env
->fp_status
) &
599 (float_flag_invalid
| float_flag_overflow
)) {
600 fd
= FLOAT_TO_INT32_OVERFLOW
;
602 update_fcsr0(env
, GETPC());
606 uint64_t helper_ftintrp_l_d(CPULoongArchState
*env
, uint64_t fj
)
609 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
611 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
612 fd
= float64_to_int64(fj
, &env
->fp_status
);
613 set_float_rounding_mode(old_mode
, &env
->fp_status
);
615 if (get_float_exception_flags(&env
->fp_status
) &
616 (float_flag_invalid
| float_flag_overflow
)) {
617 fd
= FLOAT_TO_INT64_OVERFLOW
;
619 update_fcsr0(env
, GETPC());
623 uint64_t helper_ftintrp_l_s(CPULoongArchState
*env
, uint64_t fj
)
626 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
628 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
629 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
630 set_float_rounding_mode(old_mode
, &env
->fp_status
);
632 if (get_float_exception_flags(&env
->fp_status
) &
633 (float_flag_invalid
| float_flag_overflow
)) {
634 fd
= FLOAT_TO_INT64_OVERFLOW
;
636 update_fcsr0(env
, GETPC());
640 uint64_t helper_ftintrp_w_d(CPULoongArchState
*env
, uint64_t fj
)
643 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
645 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
646 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
647 set_float_rounding_mode(old_mode
, &env
->fp_status
);
649 if (get_float_exception_flags(&env
->fp_status
) &
650 (float_flag_invalid
| float_flag_overflow
)) {
651 fd
= FLOAT_TO_INT32_OVERFLOW
;
653 update_fcsr0(env
, GETPC());
657 uint64_t helper_ftintrp_w_s(CPULoongArchState
*env
, uint64_t fj
)
660 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
662 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
663 fd
= (uint64_t)float32_to_int32((uint32_t)fj
, &env
->fp_status
);
664 set_float_rounding_mode(old_mode
, &env
->fp_status
);
666 if (get_float_exception_flags(&env
->fp_status
) &
667 (float_flag_invalid
| float_flag_overflow
)) {
668 fd
= FLOAT_TO_INT32_OVERFLOW
;
670 update_fcsr0(env
, GETPC());
674 uint64_t helper_ftintrz_l_d(CPULoongArchState
*env
, uint64_t fj
)
677 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
679 fd
= float64_to_int64_round_to_zero(fj
, &env
->fp_status
);
680 set_float_rounding_mode(old_mode
, &env
->fp_status
);
682 if (get_float_exception_flags(&env
->fp_status
) &
683 (float_flag_invalid
| float_flag_overflow
)) {
684 fd
= FLOAT_TO_INT64_OVERFLOW
;
686 update_fcsr0(env
, GETPC());
690 uint64_t helper_ftintrz_l_s(CPULoongArchState
*env
, uint64_t fj
)
693 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
695 fd
= float32_to_int64_round_to_zero((uint32_t)fj
, &env
->fp_status
);
696 set_float_rounding_mode(old_mode
, &env
->fp_status
);
698 if (get_float_exception_flags(&env
->fp_status
) &
699 (float_flag_invalid
| float_flag_overflow
)) {
700 fd
= FLOAT_TO_INT64_OVERFLOW
;
702 update_fcsr0(env
, GETPC());
706 uint64_t helper_ftintrz_w_d(CPULoongArchState
*env
, uint64_t fj
)
709 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
711 fd
= (uint64_t)float64_to_int32_round_to_zero(fj
, &env
->fp_status
);
712 set_float_rounding_mode(old_mode
, &env
->fp_status
);
714 if (get_float_exception_flags(&env
->fp_status
) &
715 (float_flag_invalid
| float_flag_overflow
)) {
716 fd
= FLOAT_TO_INT32_OVERFLOW
;
718 update_fcsr0(env
, GETPC());
722 uint64_t helper_ftintrz_w_s(CPULoongArchState
*env
, uint64_t fj
)
725 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
727 fd
= float32_to_int32_round_to_zero((uint32_t)fj
, &env
->fp_status
);
728 set_float_rounding_mode(old_mode
, &env
->fp_status
);
730 if (get_float_exception_flags(&env
->fp_status
) &
731 (float_flag_invalid
| float_flag_overflow
)) {
732 fd
= FLOAT_TO_INT32_OVERFLOW
;
734 update_fcsr0(env
, GETPC());
738 uint64_t helper_ftintrne_l_d(CPULoongArchState
*env
, uint64_t fj
)
741 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
743 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
744 fd
= float64_to_int64(fj
, &env
->fp_status
);
745 set_float_rounding_mode(old_mode
, &env
->fp_status
);
747 if (get_float_exception_flags(&env
->fp_status
) &
748 (float_flag_invalid
| float_flag_overflow
)) {
749 fd
= FLOAT_TO_INT64_OVERFLOW
;
751 update_fcsr0(env
, GETPC());
755 uint64_t helper_ftintrne_l_s(CPULoongArchState
*env
, uint64_t fj
)
758 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
760 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
761 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
762 set_float_rounding_mode(old_mode
, &env
->fp_status
);
764 if (get_float_exception_flags(&env
->fp_status
) &
765 (float_flag_invalid
| float_flag_overflow
)) {
766 fd
= FLOAT_TO_INT64_OVERFLOW
;
768 update_fcsr0(env
, GETPC());
772 uint64_t helper_ftintrne_w_d(CPULoongArchState
*env
, uint64_t fj
)
775 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
777 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
778 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
779 set_float_rounding_mode(old_mode
, &env
->fp_status
);
781 if (get_float_exception_flags(&env
->fp_status
) &
782 (float_flag_invalid
| float_flag_overflow
)) {
783 fd
= FLOAT_TO_INT32_OVERFLOW
;
785 update_fcsr0(env
, GETPC());
789 uint64_t helper_ftintrne_w_s(CPULoongArchState
*env
, uint64_t fj
)
792 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
794 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
795 fd
= float32_to_int32((uint32_t)fj
, &env
->fp_status
);
796 set_float_rounding_mode(old_mode
, &env
->fp_status
);
798 if (get_float_exception_flags(&env
->fp_status
) &
799 (float_flag_invalid
| float_flag_overflow
)) {
800 fd
= FLOAT_TO_INT32_OVERFLOW
;
802 update_fcsr0(env
, GETPC());
806 uint64_t helper_ftint_l_d(CPULoongArchState
*env
, uint64_t fj
)
810 fd
= float64_to_int64(fj
, &env
->fp_status
);
811 if (get_float_exception_flags(&env
->fp_status
) &
812 (float_flag_invalid
| float_flag_overflow
)) {
813 fd
= FLOAT_TO_INT64_OVERFLOW
;
815 update_fcsr0(env
, GETPC());
819 uint64_t helper_ftint_l_s(CPULoongArchState
*env
, uint64_t fj
)
823 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
824 if (get_float_exception_flags(&env
->fp_status
) &
825 (float_flag_invalid
| float_flag_overflow
)) {
826 fd
= FLOAT_TO_INT64_OVERFLOW
;
828 update_fcsr0(env
, GETPC());
832 uint64_t helper_ftint_w_s(CPULoongArchState
*env
, uint64_t fj
)
836 fd
= (uint64_t)float32_to_int32((uint32_t)fj
, &env
->fp_status
);
837 if (get_float_exception_flags(&env
->fp_status
)
838 & (float_flag_invalid
| float_flag_overflow
)) {
839 fd
= FLOAT_TO_INT32_OVERFLOW
;
841 update_fcsr0(env
, GETPC());
845 uint64_t helper_ftint_w_d(CPULoongArchState
*env
, uint64_t fj
)
849 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
850 if (get_float_exception_flags(&env
->fp_status
)
851 & (float_flag_invalid
| float_flag_overflow
)) {
852 fd
= FLOAT_TO_INT32_OVERFLOW
;
854 update_fcsr0(env
, GETPC());
858 void helper_set_rounding_mode(CPULoongArchState
*env
, uint32_t fcsr0
)
860 set_float_rounding_mode(ieee_rm
[(fcsr0
>> FCSR0_RM
) & 0x3],