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 static inline uint64_t nanbox_s(float32 fp
)
18 return fp
| MAKE_64BIT_MASK(32, 32);
21 /* Convert loongarch rounding mode in fcsr0 to IEEE library */
22 static const FloatRoundMode ieee_rm
[4] = {
23 float_round_nearest_even
,
29 void restore_fp_status(CPULoongArchState
*env
)
31 set_float_rounding_mode(ieee_rm
[(env
->fcsr0
>> FCSR0_RM
) & 0x3],
33 set_flush_to_zero(0, &env
->fp_status
);
36 static int ieee_ex_to_loongarch(int xcpt
)
39 if (xcpt
& float_flag_invalid
) {
42 if (xcpt
& float_flag_overflow
) {
45 if (xcpt
& float_flag_underflow
) {
48 if (xcpt
& float_flag_divbyzero
) {
51 if (xcpt
& float_flag_inexact
) {
57 static void update_fcsr0_mask(CPULoongArchState
*env
, uintptr_t pc
, int mask
)
59 int flags
= get_float_exception_flags(&env
->fp_status
);
61 set_float_exception_flags(0, &env
->fp_status
);
66 SET_FP_CAUSE(env
->fcsr0
, flags
);
69 flags
= ieee_ex_to_loongarch(flags
);
70 SET_FP_CAUSE(env
->fcsr0
, flags
);
73 if (GET_FP_ENABLES(env
->fcsr0
) & flags
) {
74 do_raise_exception(env
, EXCCODE_FPE
, pc
);
76 UPDATE_FP_FLAGS(env
->fcsr0
, flags
);
80 static void update_fcsr0(CPULoongArchState
*env
, uintptr_t pc
)
82 update_fcsr0_mask(env
, pc
, 0);
85 uint64_t helper_fadd_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
89 fd
= nanbox_s(float32_add((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
90 update_fcsr0(env
, GETPC());
94 uint64_t helper_fadd_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
98 fd
= float64_add(fj
, fk
, &env
->fp_status
);
99 update_fcsr0(env
, GETPC());
103 uint64_t helper_fsub_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
107 fd
= nanbox_s(float32_sub((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
108 update_fcsr0(env
, GETPC());
112 uint64_t helper_fsub_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
116 fd
= float64_sub(fj
, fk
, &env
->fp_status
);
117 update_fcsr0(env
, GETPC());
121 uint64_t helper_fmul_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
125 fd
= nanbox_s(float32_mul((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
126 update_fcsr0(env
, GETPC());
130 uint64_t helper_fmul_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
134 fd
= float64_mul(fj
, fk
, &env
->fp_status
);
135 update_fcsr0(env
, GETPC());
139 uint64_t helper_fdiv_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
143 fd
= nanbox_s(float32_div((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
144 update_fcsr0(env
, GETPC());
148 uint64_t helper_fdiv_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
152 fd
= float64_div(fj
, fk
, &env
->fp_status
);
153 update_fcsr0(env
, GETPC());
157 uint64_t helper_fmax_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
161 fd
= nanbox_s(float32_maxnum((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
162 update_fcsr0(env
, GETPC());
166 uint64_t helper_fmax_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
170 fd
= float64_maxnum(fj
, fk
, &env
->fp_status
);
171 update_fcsr0(env
, GETPC());
175 uint64_t helper_fmin_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
179 fd
= nanbox_s(float32_minnum((uint32_t)fj
, (uint32_t)fk
, &env
->fp_status
));
180 update_fcsr0(env
, GETPC());
184 uint64_t helper_fmin_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
188 fd
= float64_minnum(fj
, fk
, &env
->fp_status
);
189 update_fcsr0(env
, GETPC());
193 uint64_t helper_fmaxa_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
197 fd
= nanbox_s(float32_maxnummag((uint32_t)fj
,
198 (uint32_t)fk
, &env
->fp_status
));
199 update_fcsr0(env
, GETPC());
203 uint64_t helper_fmaxa_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
207 fd
= float64_maxnummag(fj
, fk
, &env
->fp_status
);
208 update_fcsr0(env
, GETPC());
212 uint64_t helper_fmina_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
216 fd
= nanbox_s(float32_minnummag((uint32_t)fj
,
217 (uint32_t)fk
, &env
->fp_status
));
218 update_fcsr0(env
, GETPC());
222 uint64_t helper_fmina_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
226 fd
= float64_minnummag(fj
, fk
, &env
->fp_status
);
227 update_fcsr0(env
, GETPC());
231 uint64_t helper_fscaleb_s(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
234 int32_t n
= (int32_t)fk
;
236 fd
= nanbox_s(float32_scalbn((uint32_t)fj
,
238 n
< -0x200 ? -0x200 : n
,
240 update_fcsr0(env
, GETPC());
244 uint64_t helper_fscaleb_d(CPULoongArchState
*env
, uint64_t fj
, uint64_t fk
)
247 int64_t n
= (int64_t)fk
;
249 fd
= float64_scalbn(fj
,
250 n
> 0x1000 ? 0x1000 :
251 n
< -0x1000 ? -0x1000 : n
,
253 update_fcsr0(env
, GETPC());
257 uint64_t helper_fsqrt_s(CPULoongArchState
*env
, uint64_t fj
)
261 fd
= nanbox_s(float32_sqrt((uint32_t)fj
, &env
->fp_status
));
262 update_fcsr0(env
, GETPC());
266 uint64_t helper_fsqrt_d(CPULoongArchState
*env
, uint64_t fj
)
270 fd
= float64_sqrt(fj
, &env
->fp_status
);
271 update_fcsr0(env
, GETPC());
275 uint64_t helper_frecip_s(CPULoongArchState
*env
, uint64_t fj
)
279 fd
= nanbox_s(float32_div(float32_one
, (uint32_t)fj
, &env
->fp_status
));
280 update_fcsr0(env
, GETPC());
284 uint64_t helper_frecip_d(CPULoongArchState
*env
, uint64_t fj
)
288 fd
= float64_div(float64_one
, fj
, &env
->fp_status
);
289 update_fcsr0(env
, GETPC());
293 uint64_t helper_frsqrt_s(CPULoongArchState
*env
, uint64_t fj
)
298 fp
= float32_sqrt((uint32_t)fj
, &env
->fp_status
);
299 fd
= nanbox_s(float32_div(float32_one
, fp
, &env
->fp_status
));
300 update_fcsr0(env
, GETPC());
304 uint64_t helper_frsqrt_d(CPULoongArchState
*env
, uint64_t fj
)
308 fp
= float64_sqrt(fj
, &env
->fp_status
);
309 fd
= float64_div(float64_one
, fp
, &env
->fp_status
);
310 update_fcsr0(env
, GETPC());
314 uint64_t helper_flogb_s(CPULoongArchState
*env
, uint64_t fj
)
318 float_status
*status
= &env
->fp_status
;
319 FloatRoundMode old_mode
= get_float_rounding_mode(status
);
321 set_float_rounding_mode(float_round_down
, status
);
322 fp
= float32_log2((uint32_t)fj
, status
);
323 fd
= nanbox_s(float32_round_to_int(fp
, status
));
324 set_float_rounding_mode(old_mode
, status
);
325 update_fcsr0_mask(env
, GETPC(), float_flag_inexact
);
329 uint64_t helper_flogb_d(CPULoongArchState
*env
, uint64_t fj
)
332 float_status
*status
= &env
->fp_status
;
333 FloatRoundMode old_mode
= get_float_rounding_mode(status
);
335 set_float_rounding_mode(float_round_down
, status
);
336 fd
= float64_log2(fj
, status
);
337 fd
= float64_round_to_int(fd
, status
);
338 set_float_rounding_mode(old_mode
, status
);
339 update_fcsr0_mask(env
, GETPC(), float_flag_inexact
);
343 uint64_t helper_fclass_s(CPULoongArchState
*env
, uint64_t fj
)
346 bool sign
= float32_is_neg(f
);
348 if (float32_is_infinity(f
)) {
349 return sign
? 1 << 2 : 1 << 6;
350 } else if (float32_is_zero(f
)) {
351 return sign
? 1 << 5 : 1 << 9;
352 } else if (float32_is_zero_or_denormal(f
)) {
353 return sign
? 1 << 4 : 1 << 8;
354 } else if (float32_is_any_nan(f
)) {
355 float_status s
= { }; /* for snan_bit_is_one */
356 return float32_is_quiet_nan(f
, &s
) ? 1 << 1 : 1 << 0;
358 return sign
? 1 << 3 : 1 << 7;
362 uint64_t helper_fclass_d(CPULoongArchState
*env
, uint64_t fj
)
365 bool sign
= float64_is_neg(f
);
367 if (float64_is_infinity(f
)) {
368 return sign
? 1 << 2 : 1 << 6;
369 } else if (float64_is_zero(f
)) {
370 return sign
? 1 << 5 : 1 << 9;
371 } else if (float64_is_zero_or_denormal(f
)) {
372 return sign
? 1 << 4 : 1 << 8;
373 } else if (float64_is_any_nan(f
)) {
374 float_status s
= { }; /* for snan_bit_is_one */
375 return float64_is_quiet_nan(f
, &s
) ? 1 << 1 : 1 << 0;
377 return sign
? 1 << 3 : 1 << 7;
381 uint64_t helper_fmuladd_s(CPULoongArchState
*env
, uint64_t fj
,
382 uint64_t fk
, uint64_t fa
, uint32_t flag
)
386 fd
= nanbox_s(float32_muladd((uint32_t)fj
, (uint32_t)fk
,
387 (uint32_t)fa
, flag
, &env
->fp_status
));
388 update_fcsr0(env
, GETPC());
392 uint64_t helper_fmuladd_d(CPULoongArchState
*env
, uint64_t fj
,
393 uint64_t fk
, uint64_t fa
, uint32_t flag
)
397 fd
= float64_muladd(fj
, fk
, fa
, flag
, &env
->fp_status
);
398 update_fcsr0(env
, GETPC());
402 static uint64_t fcmp_common(CPULoongArchState
*env
, FloatRelation cmp
,
408 case float_relation_less
:
409 ret
= (flags
& FCMP_LT
);
411 case float_relation_equal
:
412 ret
= (flags
& FCMP_EQ
);
414 case float_relation_greater
:
415 ret
= (flags
& FCMP_GT
);
417 case float_relation_unordered
:
418 ret
= (flags
& FCMP_UN
);
421 g_assert_not_reached();
423 update_fcsr0(env
, GETPC());
429 uint64_t helper_fcmp_c_s(CPULoongArchState
*env
, uint64_t fj
,
430 uint64_t fk
, uint32_t flags
)
432 FloatRelation cmp
= float32_compare_quiet((uint32_t)fj
,
433 (uint32_t)fk
, &env
->fp_status
);
434 return fcmp_common(env
, cmp
, flags
);
438 uint64_t helper_fcmp_s_s(CPULoongArchState
*env
, uint64_t fj
,
439 uint64_t fk
, uint32_t flags
)
441 FloatRelation cmp
= float32_compare((uint32_t)fj
,
442 (uint32_t)fk
, &env
->fp_status
);
443 return fcmp_common(env
, cmp
, flags
);
447 uint64_t helper_fcmp_c_d(CPULoongArchState
*env
, uint64_t fj
,
448 uint64_t fk
, uint32_t flags
)
450 FloatRelation cmp
= float64_compare_quiet(fj
, fk
, &env
->fp_status
);
451 return fcmp_common(env
, cmp
, flags
);
455 uint64_t helper_fcmp_s_d(CPULoongArchState
*env
, uint64_t fj
,
456 uint64_t fk
, uint32_t flags
)
458 FloatRelation cmp
= float64_compare(fj
, fk
, &env
->fp_status
);
459 return fcmp_common(env
, cmp
, flags
);
462 /* floating point conversion */
463 uint64_t helper_fcvt_s_d(CPULoongArchState
*env
, uint64_t fj
)
467 fd
= nanbox_s(float64_to_float32(fj
, &env
->fp_status
));
468 update_fcsr0(env
, GETPC());
472 uint64_t helper_fcvt_d_s(CPULoongArchState
*env
, uint64_t fj
)
476 fd
= float32_to_float64((uint32_t)fj
, &env
->fp_status
);
477 update_fcsr0(env
, GETPC());
481 uint64_t helper_ffint_s_w(CPULoongArchState
*env
, uint64_t fj
)
485 fd
= nanbox_s(int32_to_float32((int32_t)fj
, &env
->fp_status
));
486 update_fcsr0(env
, GETPC());
490 uint64_t helper_ffint_s_l(CPULoongArchState
*env
, uint64_t fj
)
494 fd
= nanbox_s(int64_to_float32(fj
, &env
->fp_status
));
495 update_fcsr0(env
, GETPC());
499 uint64_t helper_ffint_d_w(CPULoongArchState
*env
, uint64_t fj
)
503 fd
= int32_to_float64((int32_t)fj
, &env
->fp_status
);
504 update_fcsr0(env
, GETPC());
508 uint64_t helper_ffint_d_l(CPULoongArchState
*env
, uint64_t fj
)
512 fd
= int64_to_float64(fj
, &env
->fp_status
);
513 update_fcsr0(env
, GETPC());
517 uint64_t helper_frint_s(CPULoongArchState
*env
, uint64_t fj
)
521 fd
= (uint64_t)(float32_round_to_int((uint32_t)fj
, &env
->fp_status
));
522 update_fcsr0(env
, GETPC());
526 uint64_t helper_frint_d(CPULoongArchState
*env
, uint64_t fj
)
530 fd
= float64_round_to_int(fj
, &env
->fp_status
);
531 update_fcsr0(env
, GETPC());
535 uint64_t helper_ftintrm_l_d(CPULoongArchState
*env
, uint64_t fj
)
538 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
540 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
541 fd
= float64_to_int64(fj
, &env
->fp_status
);
542 set_float_rounding_mode(old_mode
, &env
->fp_status
);
544 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
545 if (float64_is_any_nan(fj
)) {
549 update_fcsr0(env
, GETPC());
553 uint64_t helper_ftintrm_l_s(CPULoongArchState
*env
, uint64_t fj
)
556 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
558 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
559 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
560 set_float_rounding_mode(old_mode
, &env
->fp_status
);
562 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
563 if (float32_is_any_nan((uint32_t)fj
)) {
567 update_fcsr0(env
, GETPC());
571 uint64_t helper_ftintrm_w_d(CPULoongArchState
*env
, uint64_t fj
)
574 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
576 set_float_rounding_mode(float_round_down
, &env
->fp_status
);
577 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
578 set_float_rounding_mode(old_mode
, &env
->fp_status
);
580 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
581 if (float64_is_any_nan(fj
)) {
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
) & (float_flag_invalid
)) {
599 if (float32_is_any_nan((uint32_t)fj
)) {
603 update_fcsr0(env
, GETPC());
607 uint64_t helper_ftintrp_l_d(CPULoongArchState
*env
, uint64_t fj
)
610 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
612 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
613 fd
= float64_to_int64(fj
, &env
->fp_status
);
614 set_float_rounding_mode(old_mode
, &env
->fp_status
);
616 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
617 if (float64_is_any_nan(fj
)) {
621 update_fcsr0(env
, GETPC());
625 uint64_t helper_ftintrp_l_s(CPULoongArchState
*env
, uint64_t fj
)
628 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
630 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
631 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
632 set_float_rounding_mode(old_mode
, &env
->fp_status
);
634 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
635 if (float32_is_any_nan((uint32_t)fj
)) {
639 update_fcsr0(env
, GETPC());
643 uint64_t helper_ftintrp_w_d(CPULoongArchState
*env
, uint64_t fj
)
646 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
648 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
649 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
650 set_float_rounding_mode(old_mode
, &env
->fp_status
);
652 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
653 if (float64_is_any_nan(fj
)) {
657 update_fcsr0(env
, GETPC());
661 uint64_t helper_ftintrp_w_s(CPULoongArchState
*env
, uint64_t fj
)
664 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
666 set_float_rounding_mode(float_round_up
, &env
->fp_status
);
667 fd
= (uint64_t)float32_to_int32((uint32_t)fj
, &env
->fp_status
);
668 set_float_rounding_mode(old_mode
, &env
->fp_status
);
670 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
671 if (float32_is_any_nan((uint32_t)fj
)) {
675 update_fcsr0(env
, GETPC());
679 uint64_t helper_ftintrz_l_d(CPULoongArchState
*env
, uint64_t fj
)
682 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
684 fd
= float64_to_int64_round_to_zero(fj
, &env
->fp_status
);
685 set_float_rounding_mode(old_mode
, &env
->fp_status
);
687 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
688 if (float64_is_any_nan(fj
)) {
692 update_fcsr0(env
, GETPC());
696 uint64_t helper_ftintrz_l_s(CPULoongArchState
*env
, uint64_t fj
)
699 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
701 fd
= float32_to_int64_round_to_zero((uint32_t)fj
, &env
->fp_status
);
702 set_float_rounding_mode(old_mode
, &env
->fp_status
);
704 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
705 if (float32_is_any_nan((uint32_t)fj
)) {
709 update_fcsr0(env
, GETPC());
713 uint64_t helper_ftintrz_w_d(CPULoongArchState
*env
, uint64_t fj
)
716 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
718 fd
= (uint64_t)float64_to_int32_round_to_zero(fj
, &env
->fp_status
);
719 set_float_rounding_mode(old_mode
, &env
->fp_status
);
721 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
722 if (float64_is_any_nan(fj
)) {
726 update_fcsr0(env
, GETPC());
730 uint64_t helper_ftintrz_w_s(CPULoongArchState
*env
, uint64_t fj
)
733 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
735 fd
= float32_to_int32_round_to_zero((uint32_t)fj
, &env
->fp_status
);
736 set_float_rounding_mode(old_mode
, &env
->fp_status
);
738 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
739 if (float32_is_any_nan((uint32_t)fj
)) {
743 update_fcsr0(env
, GETPC());
747 uint64_t helper_ftintrne_l_d(CPULoongArchState
*env
, uint64_t fj
)
750 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
752 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
753 fd
= float64_to_int64(fj
, &env
->fp_status
);
754 set_float_rounding_mode(old_mode
, &env
->fp_status
);
756 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
757 if (float64_is_any_nan(fj
)) {
761 update_fcsr0(env
, GETPC());
765 uint64_t helper_ftintrne_l_s(CPULoongArchState
*env
, uint64_t fj
)
768 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
770 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
771 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
772 set_float_rounding_mode(old_mode
, &env
->fp_status
);
774 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
775 if (float32_is_any_nan((uint32_t)fj
)) {
779 update_fcsr0(env
, GETPC());
783 uint64_t helper_ftintrne_w_d(CPULoongArchState
*env
, uint64_t fj
)
786 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
788 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
789 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
790 set_float_rounding_mode(old_mode
, &env
->fp_status
);
792 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
793 if (float64_is_any_nan(fj
)) {
797 update_fcsr0(env
, GETPC());
801 uint64_t helper_ftintrne_w_s(CPULoongArchState
*env
, uint64_t fj
)
804 FloatRoundMode old_mode
= get_float_rounding_mode(&env
->fp_status
);
806 set_float_rounding_mode(float_round_nearest_even
, &env
->fp_status
);
807 fd
= float32_to_int32((uint32_t)fj
, &env
->fp_status
);
808 set_float_rounding_mode(old_mode
, &env
->fp_status
);
810 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
811 if (float32_is_any_nan((uint32_t)fj
)) {
815 update_fcsr0(env
, GETPC());
819 uint64_t helper_ftint_l_d(CPULoongArchState
*env
, uint64_t fj
)
823 fd
= float64_to_int64(fj
, &env
->fp_status
);
824 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
825 if (float64_is_any_nan(fj
)) {
829 update_fcsr0(env
, GETPC());
833 uint64_t helper_ftint_l_s(CPULoongArchState
*env
, uint64_t fj
)
837 fd
= float32_to_int64((uint32_t)fj
, &env
->fp_status
);
838 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
839 if (float32_is_any_nan((uint32_t)fj
)) {
843 update_fcsr0(env
, GETPC());
847 uint64_t helper_ftint_w_s(CPULoongArchState
*env
, uint64_t fj
)
851 fd
= (uint64_t)float32_to_int32((uint32_t)fj
, &env
->fp_status
);
852 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
853 if (float32_is_any_nan((uint32_t)fj
)) {
857 update_fcsr0(env
, GETPC());
861 uint64_t helper_ftint_w_d(CPULoongArchState
*env
, uint64_t fj
)
865 fd
= (uint64_t)float64_to_int32(fj
, &env
->fp_status
);
866 if (get_float_exception_flags(&env
->fp_status
) & (float_flag_invalid
)) {
867 if (float64_is_any_nan(fj
)) {
871 update_fcsr0(env
, GETPC());
875 void helper_set_rounding_mode(CPULoongArchState
*env
)
877 set_float_rounding_mode(ieee_rm
[(env
->fcsr0
>> FCSR0_RM
) & 0x3],