gitlab: tweak comments in edk2/opensbi jobs
[qemu.git] / target / loongarch / fpu_helper.c
blob3d0cb8dd0d2b67623af2f2e6b9b24f9467b05fa4
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 #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,
27 float_round_to_zero,
28 float_round_up,
29 float_round_down
32 void restore_fp_status(CPULoongArchState *env)
34 set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3],
35 &env->fp_status);
36 set_flush_to_zero(0, &env->fp_status);
39 static int ieee_ex_to_loongarch(int xcpt)
41 int ret = 0;
42 if (xcpt & float_flag_invalid) {
43 ret |= FP_INVALID;
45 if (xcpt & float_flag_overflow) {
46 ret |= FP_OVERFLOW;
48 if (xcpt & float_flag_underflow) {
49 ret |= FP_UNDERFLOW;
51 if (xcpt & float_flag_divbyzero) {
52 ret |= FP_DIV0;
54 if (xcpt & float_flag_inexact) {
55 ret |= FP_INEXACT;
57 return ret;
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);
66 flags &= ~mask;
68 if (!flags) {
69 SET_FP_CAUSE(env->fcsr0, flags);
70 return;
71 } else {
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);
78 } else {
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)
90 uint64_t fd;
92 fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, &env->fp_status));
93 update_fcsr0(env, GETPC());
94 return fd;
97 uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
99 uint64_t fd;
101 fd = float64_add(fj, fk, &env->fp_status);
102 update_fcsr0(env, GETPC());
103 return fd;
106 uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
108 uint64_t fd;
110 fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, &env->fp_status));
111 update_fcsr0(env, GETPC());
112 return fd;
115 uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
117 uint64_t fd;
119 fd = float64_sub(fj, fk, &env->fp_status);
120 update_fcsr0(env, GETPC());
121 return fd;
124 uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
126 uint64_t fd;
128 fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, &env->fp_status));
129 update_fcsr0(env, GETPC());
130 return fd;
133 uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
135 uint64_t fd;
137 fd = float64_mul(fj, fk, &env->fp_status);
138 update_fcsr0(env, GETPC());
139 return fd;
142 uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
144 uint64_t fd;
146 fd = nanbox_s(float32_div((uint32_t)fj, (uint32_t)fk, &env->fp_status));
147 update_fcsr0(env, GETPC());
148 return fd;
151 uint64_t helper_fdiv_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
153 uint64_t fd;
155 fd = float64_div(fj, fk, &env->fp_status);
156 update_fcsr0(env, GETPC());
157 return fd;
160 uint64_t helper_fmax_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
162 uint64_t fd;
164 fd = nanbox_s(float32_maxnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
165 update_fcsr0(env, GETPC());
166 return fd;
169 uint64_t helper_fmax_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
171 uint64_t fd;
173 fd = float64_maxnum(fj, fk, &env->fp_status);
174 update_fcsr0(env, GETPC());
175 return fd;
178 uint64_t helper_fmin_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
180 uint64_t fd;
182 fd = nanbox_s(float32_minnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
183 update_fcsr0(env, GETPC());
184 return fd;
187 uint64_t helper_fmin_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
189 uint64_t fd;
191 fd = float64_minnum(fj, fk, &env->fp_status);
192 update_fcsr0(env, GETPC());
193 return fd;
196 uint64_t helper_fmaxa_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
198 uint64_t fd;
200 fd = nanbox_s(float32_maxnummag((uint32_t)fj,
201 (uint32_t)fk, &env->fp_status));
202 update_fcsr0(env, GETPC());
203 return fd;
206 uint64_t helper_fmaxa_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
208 uint64_t fd;
210 fd = float64_maxnummag(fj, fk, &env->fp_status);
211 update_fcsr0(env, GETPC());
212 return fd;
215 uint64_t helper_fmina_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
217 uint64_t fd;
219 fd = nanbox_s(float32_minnummag((uint32_t)fj,
220 (uint32_t)fk, &env->fp_status));
221 update_fcsr0(env, GETPC());
222 return fd;
225 uint64_t helper_fmina_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
227 uint64_t fd;
229 fd = float64_minnummag(fj, fk, &env->fp_status);
230 update_fcsr0(env, GETPC());
231 return fd;
234 uint64_t helper_fscaleb_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
236 uint64_t fd;
237 int32_t n = (int32_t)fk;
239 fd = nanbox_s(float32_scalbn((uint32_t)fj,
240 n > 0x200 ? 0x200 :
241 n < -0x200 ? -0x200 : n,
242 &env->fp_status));
243 update_fcsr0(env, GETPC());
244 return fd;
247 uint64_t helper_fscaleb_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
249 uint64_t fd;
250 int64_t n = (int64_t)fk;
252 fd = float64_scalbn(fj,
253 n > 0x1000 ? 0x1000 :
254 n < -0x1000 ? -0x1000 : n,
255 &env->fp_status);
256 update_fcsr0(env, GETPC());
257 return fd;
260 uint64_t helper_fsqrt_s(CPULoongArchState *env, uint64_t fj)
262 uint64_t fd;
264 fd = nanbox_s(float32_sqrt((uint32_t)fj, &env->fp_status));
265 update_fcsr0(env, GETPC());
266 return fd;
269 uint64_t helper_fsqrt_d(CPULoongArchState *env, uint64_t fj)
271 uint64_t fd;
273 fd = float64_sqrt(fj, &env->fp_status);
274 update_fcsr0(env, GETPC());
275 return fd;
278 uint64_t helper_frecip_s(CPULoongArchState *env, uint64_t fj)
280 uint64_t fd;
282 fd = nanbox_s(float32_div(float32_one, (uint32_t)fj, &env->fp_status));
283 update_fcsr0(env, GETPC());
284 return fd;
287 uint64_t helper_frecip_d(CPULoongArchState *env, uint64_t fj)
289 uint64_t fd;
291 fd = float64_div(float64_one, fj, &env->fp_status);
292 update_fcsr0(env, GETPC());
293 return fd;
296 uint64_t helper_frsqrt_s(CPULoongArchState *env, uint64_t fj)
298 uint64_t fd;
299 uint32_t fp;
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());
304 return fd;
307 uint64_t helper_frsqrt_d(CPULoongArchState *env, uint64_t fj)
309 uint64_t fp, fd;
311 fp = float64_sqrt(fj, &env->fp_status);
312 fd = float64_div(float64_one, fp, &env->fp_status);
313 update_fcsr0(env, GETPC());
314 return fd;
317 uint64_t helper_flogb_s(CPULoongArchState *env, uint64_t fj)
319 uint64_t fd;
320 uint32_t fp;
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);
329 return fd;
332 uint64_t helper_flogb_d(CPULoongArchState *env, uint64_t fj)
334 uint64_t fd;
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);
343 return fd;
346 uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
348 float32 f = 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;
360 } else {
361 return sign ? 1 << 3 : 1 << 7;
365 uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
367 float64 f = 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;
379 } else {
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)
387 uint64_t fd;
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());
392 return fd;
395 uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t fj,
396 uint64_t fk, uint64_t fa, uint32_t flag)
398 uint64_t fd;
400 fd = float64_muladd(fj, fk, fa, flag, &env->fp_status);
401 update_fcsr0(env, GETPC());
402 return fd;
405 static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp,
406 uint32_t flags)
408 bool ret;
410 switch (cmp) {
411 case float_relation_less:
412 ret = (flags & FCMP_LT);
413 break;
414 case float_relation_equal:
415 ret = (flags & FCMP_EQ);
416 break;
417 case float_relation_greater:
418 ret = (flags & FCMP_GT);
419 break;
420 case float_relation_unordered:
421 ret = (flags & FCMP_UN);
422 break;
423 default:
424 g_assert_not_reached();
426 update_fcsr0(env, GETPC());
428 return ret;
431 /* fcmp_cXXX_s */
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);
440 /* fcmp_sXXX_s */
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);
449 /* fcmp_cXXX_d */
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);
457 /* fcmp_sXXX_d */
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)
468 uint64_t fd;
470 fd = nanbox_s(float64_to_float32(fj, &env->fp_status));
471 update_fcsr0(env, GETPC());
472 return fd;
475 uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj)
477 uint64_t fd;
479 fd = float32_to_float64((uint32_t)fj, &env->fp_status);
480 update_fcsr0(env, GETPC());
481 return fd;
484 uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj)
486 uint64_t fd;
488 fd = nanbox_s(int32_to_float32((int32_t)fj, &env->fp_status));
489 update_fcsr0(env, GETPC());
490 return fd;
493 uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj)
495 uint64_t fd;
497 fd = nanbox_s(int64_to_float32(fj, &env->fp_status));
498 update_fcsr0(env, GETPC());
499 return fd;
502 uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj)
504 uint64_t fd;
506 fd = int32_to_float64((int32_t)fj, &env->fp_status);
507 update_fcsr0(env, GETPC());
508 return fd;
511 uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj)
513 uint64_t fd;
515 fd = int64_to_float64(fj, &env->fp_status);
516 update_fcsr0(env, GETPC());
517 return fd;
520 uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj)
522 uint64_t fd;
524 fd = (uint64_t)(float32_round_to_int((uint32_t)fj, &env->fp_status));
525 update_fcsr0(env, GETPC());
526 return fd;
529 uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj)
531 uint64_t fd;
533 fd = float64_round_to_int(fj, &env->fp_status);
534 update_fcsr0(env, GETPC());
535 return fd;
538 uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
540 uint64_t fd;
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());
552 return fd;
555 uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
557 uint64_t fd;
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());
569 return fd;
572 uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
574 uint64_t fd;
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());
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) &
599 (float_flag_invalid | float_flag_overflow)) {
600 fd = FLOAT_TO_INT32_OVERFLOW;
602 update_fcsr0(env, GETPC());
603 return fd;
606 uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
608 uint64_t fd;
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());
620 return fd;
623 uint64_t helper_ftintrp_l_s(CPULoongArchState *env, uint64_t fj)
625 uint64_t fd;
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());
637 return fd;
640 uint64_t helper_ftintrp_w_d(CPULoongArchState *env, uint64_t fj)
642 uint64_t fd;
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());
654 return fd;
657 uint64_t helper_ftintrp_w_s(CPULoongArchState *env, uint64_t fj)
659 uint64_t fd;
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());
671 return fd;
674 uint64_t helper_ftintrz_l_d(CPULoongArchState *env, uint64_t fj)
676 uint64_t fd;
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());
687 return fd;
690 uint64_t helper_ftintrz_l_s(CPULoongArchState *env, uint64_t fj)
692 uint64_t fd;
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());
703 return fd;
706 uint64_t helper_ftintrz_w_d(CPULoongArchState *env, uint64_t fj)
708 uint64_t fd;
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());
719 return fd;
722 uint64_t helper_ftintrz_w_s(CPULoongArchState *env, uint64_t fj)
724 uint32_t fd;
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());
735 return (uint64_t)fd;
738 uint64_t helper_ftintrne_l_d(CPULoongArchState *env, uint64_t fj)
740 uint64_t fd;
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());
752 return fd;
755 uint64_t helper_ftintrne_l_s(CPULoongArchState *env, uint64_t fj)
757 uint64_t fd;
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());
769 return fd;
772 uint64_t helper_ftintrne_w_d(CPULoongArchState *env, uint64_t fj)
774 uint64_t fd;
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());
786 return fd;
789 uint64_t helper_ftintrne_w_s(CPULoongArchState *env, uint64_t fj)
791 uint32_t fd;
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());
803 return (uint64_t)fd;
806 uint64_t helper_ftint_l_d(CPULoongArchState *env, uint64_t fj)
808 uint64_t fd;
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());
816 return fd;
819 uint64_t helper_ftint_l_s(CPULoongArchState *env, uint64_t fj)
821 uint64_t fd;
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());
829 return fd;
832 uint64_t helper_ftint_w_s(CPULoongArchState *env, uint64_t fj)
834 uint64_t fd;
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());
842 return fd;
845 uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj)
847 uint64_t fd;
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());
855 return fd;
858 void helper_set_rounding_mode(CPULoongArchState *env, uint32_t fcsr0)
860 set_float_rounding_mode(ieee_rm[(fcsr0 >> FCSR0_RM) & 0x3],
861 &env->fp_status);