icount: Take iothread lock when running QEMU timers
[qemu/ar7.git] / target / loongarch / fpu_helper.c
blob4b9637210a9521d959b29c7f8158647f0d25cc61
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3 * LoongArch float point emulation helpers for QEMU
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
6 */
8 #include "qemu/osdep.h"
9 #include "cpu.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,
24 float_round_to_zero,
25 float_round_up,
26 float_round_down
29 void restore_fp_status(CPULoongArchState *env)
31 set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3],
32 &env->fp_status);
33 set_flush_to_zero(0, &env->fp_status);
36 static int ieee_ex_to_loongarch(int xcpt)
38 int ret = 0;
39 if (xcpt & float_flag_invalid) {
40 ret |= FP_INVALID;
42 if (xcpt & float_flag_overflow) {
43 ret |= FP_OVERFLOW;
45 if (xcpt & float_flag_underflow) {
46 ret |= FP_UNDERFLOW;
48 if (xcpt & float_flag_divbyzero) {
49 ret |= FP_DIV0;
51 if (xcpt & float_flag_inexact) {
52 ret |= FP_INEXACT;
54 return ret;
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);
63 flags &= ~mask;
65 if (!flags) {
66 SET_FP_CAUSE(env->fcsr0, flags);
67 return;
68 } else {
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);
75 } else {
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)
87 uint64_t fd;
89 fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, &env->fp_status));
90 update_fcsr0(env, GETPC());
91 return fd;
94 uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
96 uint64_t fd;
98 fd = float64_add(fj, fk, &env->fp_status);
99 update_fcsr0(env, GETPC());
100 return fd;
103 uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
105 uint64_t fd;
107 fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, &env->fp_status));
108 update_fcsr0(env, GETPC());
109 return fd;
112 uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
114 uint64_t fd;
116 fd = float64_sub(fj, fk, &env->fp_status);
117 update_fcsr0(env, GETPC());
118 return fd;
121 uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
123 uint64_t fd;
125 fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, &env->fp_status));
126 update_fcsr0(env, GETPC());
127 return fd;
130 uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
132 uint64_t fd;
134 fd = float64_mul(fj, fk, &env->fp_status);
135 update_fcsr0(env, GETPC());
136 return fd;
139 uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
141 uint64_t fd;
143 fd = nanbox_s(float32_div((uint32_t)fj, (uint32_t)fk, &env->fp_status));
144 update_fcsr0(env, GETPC());
145 return fd;
148 uint64_t helper_fdiv_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
150 uint64_t fd;
152 fd = float64_div(fj, fk, &env->fp_status);
153 update_fcsr0(env, GETPC());
154 return fd;
157 uint64_t helper_fmax_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
159 uint64_t fd;
161 fd = nanbox_s(float32_maxnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
162 update_fcsr0(env, GETPC());
163 return fd;
166 uint64_t helper_fmax_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
168 uint64_t fd;
170 fd = float64_maxnum(fj, fk, &env->fp_status);
171 update_fcsr0(env, GETPC());
172 return fd;
175 uint64_t helper_fmin_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
177 uint64_t fd;
179 fd = nanbox_s(float32_minnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
180 update_fcsr0(env, GETPC());
181 return fd;
184 uint64_t helper_fmin_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
186 uint64_t fd;
188 fd = float64_minnum(fj, fk, &env->fp_status);
189 update_fcsr0(env, GETPC());
190 return fd;
193 uint64_t helper_fmaxa_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
195 uint64_t fd;
197 fd = nanbox_s(float32_maxnummag((uint32_t)fj,
198 (uint32_t)fk, &env->fp_status));
199 update_fcsr0(env, GETPC());
200 return fd;
203 uint64_t helper_fmaxa_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
205 uint64_t fd;
207 fd = float64_maxnummag(fj, fk, &env->fp_status);
208 update_fcsr0(env, GETPC());
209 return fd;
212 uint64_t helper_fmina_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
214 uint64_t fd;
216 fd = nanbox_s(float32_minnummag((uint32_t)fj,
217 (uint32_t)fk, &env->fp_status));
218 update_fcsr0(env, GETPC());
219 return fd;
222 uint64_t helper_fmina_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
224 uint64_t fd;
226 fd = float64_minnummag(fj, fk, &env->fp_status);
227 update_fcsr0(env, GETPC());
228 return fd;
231 uint64_t helper_fscaleb_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
233 uint64_t fd;
234 int32_t n = (int32_t)fk;
236 fd = nanbox_s(float32_scalbn((uint32_t)fj,
237 n > 0x200 ? 0x200 :
238 n < -0x200 ? -0x200 : n,
239 &env->fp_status));
240 update_fcsr0(env, GETPC());
241 return fd;
244 uint64_t helper_fscaleb_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
246 uint64_t fd;
247 int64_t n = (int64_t)fk;
249 fd = float64_scalbn(fj,
250 n > 0x1000 ? 0x1000 :
251 n < -0x1000 ? -0x1000 : n,
252 &env->fp_status);
253 update_fcsr0(env, GETPC());
254 return fd;
257 uint64_t helper_fsqrt_s(CPULoongArchState *env, uint64_t fj)
259 uint64_t fd;
261 fd = nanbox_s(float32_sqrt((uint32_t)fj, &env->fp_status));
262 update_fcsr0(env, GETPC());
263 return fd;
266 uint64_t helper_fsqrt_d(CPULoongArchState *env, uint64_t fj)
268 uint64_t fd;
270 fd = float64_sqrt(fj, &env->fp_status);
271 update_fcsr0(env, GETPC());
272 return fd;
275 uint64_t helper_frecip_s(CPULoongArchState *env, uint64_t fj)
277 uint64_t fd;
279 fd = nanbox_s(float32_div(float32_one, (uint32_t)fj, &env->fp_status));
280 update_fcsr0(env, GETPC());
281 return fd;
284 uint64_t helper_frecip_d(CPULoongArchState *env, uint64_t fj)
286 uint64_t fd;
288 fd = float64_div(float64_one, fj, &env->fp_status);
289 update_fcsr0(env, GETPC());
290 return fd;
293 uint64_t helper_frsqrt_s(CPULoongArchState *env, uint64_t fj)
295 uint64_t fd;
296 uint32_t fp;
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());
301 return fd;
304 uint64_t helper_frsqrt_d(CPULoongArchState *env, uint64_t fj)
306 uint64_t fp, fd;
308 fp = float64_sqrt(fj, &env->fp_status);
309 fd = float64_div(float64_one, fp, &env->fp_status);
310 update_fcsr0(env, GETPC());
311 return fd;
314 uint64_t helper_flogb_s(CPULoongArchState *env, uint64_t fj)
316 uint64_t fd;
317 uint32_t fp;
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);
326 return fd;
329 uint64_t helper_flogb_d(CPULoongArchState *env, uint64_t fj)
331 uint64_t fd;
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);
340 return fd;
343 uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
345 float32 f = 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;
357 } else {
358 return sign ? 1 << 3 : 1 << 7;
362 uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
364 float64 f = 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;
376 } else {
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)
384 uint64_t fd;
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());
389 return fd;
392 uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t fj,
393 uint64_t fk, uint64_t fa, uint32_t flag)
395 uint64_t fd;
397 fd = float64_muladd(fj, fk, fa, flag, &env->fp_status);
398 update_fcsr0(env, GETPC());
399 return fd;
402 static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp,
403 uint32_t flags)
405 bool ret;
407 switch (cmp) {
408 case float_relation_less:
409 ret = (flags & FCMP_LT);
410 break;
411 case float_relation_equal:
412 ret = (flags & FCMP_EQ);
413 break;
414 case float_relation_greater:
415 ret = (flags & FCMP_GT);
416 break;
417 case float_relation_unordered:
418 ret = (flags & FCMP_UN);
419 break;
420 default:
421 g_assert_not_reached();
423 update_fcsr0(env, GETPC());
425 return ret;
428 /* fcmp_cXXX_s */
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);
437 /* fcmp_sXXX_s */
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);
446 /* fcmp_cXXX_d */
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);
454 /* fcmp_sXXX_d */
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)
465 uint64_t fd;
467 fd = nanbox_s(float64_to_float32(fj, &env->fp_status));
468 update_fcsr0(env, GETPC());
469 return fd;
472 uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj)
474 uint64_t fd;
476 fd = float32_to_float64((uint32_t)fj, &env->fp_status);
477 update_fcsr0(env, GETPC());
478 return fd;
481 uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj)
483 uint64_t fd;
485 fd = nanbox_s(int32_to_float32((int32_t)fj, &env->fp_status));
486 update_fcsr0(env, GETPC());
487 return fd;
490 uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj)
492 uint64_t fd;
494 fd = nanbox_s(int64_to_float32(fj, &env->fp_status));
495 update_fcsr0(env, GETPC());
496 return fd;
499 uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj)
501 uint64_t fd;
503 fd = int32_to_float64((int32_t)fj, &env->fp_status);
504 update_fcsr0(env, GETPC());
505 return fd;
508 uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj)
510 uint64_t fd;
512 fd = int64_to_float64(fj, &env->fp_status);
513 update_fcsr0(env, GETPC());
514 return fd;
517 uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj)
519 uint64_t fd;
521 fd = (uint64_t)(float32_round_to_int((uint32_t)fj, &env->fp_status));
522 update_fcsr0(env, GETPC());
523 return fd;
526 uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj)
528 uint64_t fd;
530 fd = float64_round_to_int(fj, &env->fp_status);
531 update_fcsr0(env, GETPC());
532 return fd;
535 uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
537 uint64_t fd;
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)) {
546 fd = 0;
549 update_fcsr0(env, GETPC());
550 return fd;
553 uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
555 uint64_t fd;
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)) {
564 fd = 0;
567 update_fcsr0(env, GETPC());
568 return fd;
571 uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
573 uint64_t fd;
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)) {
582 fd = 0;
585 update_fcsr0(env, GETPC());
586 return fd;
589 uint64_t helper_ftintrm_w_s(CPULoongArchState *env, uint64_t fj)
591 uint64_t fd;
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)) {
600 fd = 0;
603 update_fcsr0(env, GETPC());
604 return fd;
607 uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
609 uint64_t fd;
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)) {
618 fd = 0;
621 update_fcsr0(env, GETPC());
622 return fd;
625 uint64_t helper_ftintrp_l_s(CPULoongArchState *env, uint64_t fj)
627 uint64_t fd;
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)) {
636 fd = 0;
639 update_fcsr0(env, GETPC());
640 return fd;
643 uint64_t helper_ftintrp_w_d(CPULoongArchState *env, uint64_t fj)
645 uint64_t fd;
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)) {
654 fd = 0;
657 update_fcsr0(env, GETPC());
658 return fd;
661 uint64_t helper_ftintrp_w_s(CPULoongArchState *env, uint64_t fj)
663 uint64_t fd;
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)) {
672 fd = 0;
675 update_fcsr0(env, GETPC());
676 return fd;
679 uint64_t helper_ftintrz_l_d(CPULoongArchState *env, uint64_t fj)
681 uint64_t fd;
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)) {
689 fd = 0;
692 update_fcsr0(env, GETPC());
693 return fd;
696 uint64_t helper_ftintrz_l_s(CPULoongArchState *env, uint64_t fj)
698 uint64_t fd;
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)) {
706 fd = 0;
709 update_fcsr0(env, GETPC());
710 return fd;
713 uint64_t helper_ftintrz_w_d(CPULoongArchState *env, uint64_t fj)
715 uint64_t fd;
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)) {
723 fd = 0;
726 update_fcsr0(env, GETPC());
727 return fd;
730 uint64_t helper_ftintrz_w_s(CPULoongArchState *env, uint64_t fj)
732 uint32_t fd;
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)) {
740 fd = 0;
743 update_fcsr0(env, GETPC());
744 return (uint64_t)fd;
747 uint64_t helper_ftintrne_l_d(CPULoongArchState *env, uint64_t fj)
749 uint64_t fd;
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)) {
758 fd = 0;
761 update_fcsr0(env, GETPC());
762 return fd;
765 uint64_t helper_ftintrne_l_s(CPULoongArchState *env, uint64_t fj)
767 uint64_t fd;
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)) {
776 fd = 0;
779 update_fcsr0(env, GETPC());
780 return fd;
783 uint64_t helper_ftintrne_w_d(CPULoongArchState *env, uint64_t fj)
785 uint64_t fd;
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)) {
794 fd = 0;
797 update_fcsr0(env, GETPC());
798 return fd;
801 uint64_t helper_ftintrne_w_s(CPULoongArchState *env, uint64_t fj)
803 uint32_t fd;
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)) {
812 fd = 0;
815 update_fcsr0(env, GETPC());
816 return (uint64_t)fd;
819 uint64_t helper_ftint_l_d(CPULoongArchState *env, uint64_t fj)
821 uint64_t fd;
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)) {
826 fd = 0;
829 update_fcsr0(env, GETPC());
830 return fd;
833 uint64_t helper_ftint_l_s(CPULoongArchState *env, uint64_t fj)
835 uint64_t fd;
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)) {
840 fd = 0;
843 update_fcsr0(env, GETPC());
844 return fd;
847 uint64_t helper_ftint_w_s(CPULoongArchState *env, uint64_t fj)
849 uint64_t fd;
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)) {
854 fd = 0;
857 update_fcsr0(env, GETPC());
858 return fd;
861 uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj)
863 uint64_t fd;
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)) {
868 fd = 0;
871 update_fcsr0(env, GETPC());
872 return fd;
875 void helper_set_rounding_mode(CPULoongArchState *env)
877 set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3],
878 &env->fp_status);