]> git.proxmox.com Git - mirror_qemu.git/blame - target/loongarch/fpu_helper.c
target/xtensa: Split constant in bit shift
[mirror_qemu.git] / target / loongarch / fpu_helper.c
CommitLineData
d578ca6c
SG
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/*
3 * LoongArch float point emulation helpers for QEMU
4 *
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
6 */
7
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"
15
d578ca6c
SG
16static inline uint64_t nanbox_s(float32 fp)
17{
18 return fp | MAKE_64BIT_MASK(32, 32);
19}
20
21/* Convert loongarch rounding mode in fcsr0 to IEEE library */
22static const FloatRoundMode ieee_rm[4] = {
23 float_round_nearest_even,
24 float_round_to_zero,
25 float_round_up,
26 float_round_down
27};
28
29void restore_fp_status(CPULoongArchState *env)
30{
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);
34}
35
36static int ieee_ex_to_loongarch(int xcpt)
37{
38 int ret = 0;
39 if (xcpt & float_flag_invalid) {
40 ret |= FP_INVALID;
41 }
42 if (xcpt & float_flag_overflow) {
43 ret |= FP_OVERFLOW;
44 }
45 if (xcpt & float_flag_underflow) {
46 ret |= FP_UNDERFLOW;
47 }
48 if (xcpt & float_flag_divbyzero) {
49 ret |= FP_DIV0;
50 }
51 if (xcpt & float_flag_inexact) {
52 ret |= FP_INEXACT;
53 }
54 return ret;
55}
56
57static void update_fcsr0_mask(CPULoongArchState *env, uintptr_t pc, int mask)
58{
59 int flags = get_float_exception_flags(&env->fp_status);
60
61 set_float_exception_flags(0, &env->fp_status);
62
63 flags &= ~mask;
64
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);
71 }
72
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);
77 }
78}
79
80static void update_fcsr0(CPULoongArchState *env, uintptr_t pc)
81{
82 update_fcsr0_mask(env, pc, 0);
83}
84
85uint64_t helper_fadd_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
86{
87 uint64_t fd;
88
89 fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, &env->fp_status));
90 update_fcsr0(env, GETPC());
91 return fd;
92}
93
94uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
95{
96 uint64_t fd;
97
98 fd = float64_add(fj, fk, &env->fp_status);
99 update_fcsr0(env, GETPC());
100 return fd;
101}
102
103uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
104{
105 uint64_t fd;
106
107 fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, &env->fp_status));
108 update_fcsr0(env, GETPC());
109 return fd;
110}
111
112uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
113{
114 uint64_t fd;
115
116 fd = float64_sub(fj, fk, &env->fp_status);
117 update_fcsr0(env, GETPC());
118 return fd;
119}
120
121uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
122{
123 uint64_t fd;
124
125 fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, &env->fp_status));
126 update_fcsr0(env, GETPC());
127 return fd;
128}
129
130uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
131{
132 uint64_t fd;
133
134 fd = float64_mul(fj, fk, &env->fp_status);
135 update_fcsr0(env, GETPC());
136 return fd;
137}
138
139uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
140{
141 uint64_t fd;
142
143 fd = nanbox_s(float32_div((uint32_t)fj, (uint32_t)fk, &env->fp_status));
144 update_fcsr0(env, GETPC());
145 return fd;
146}
147
148uint64_t helper_fdiv_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
149{
150 uint64_t fd;
151
152 fd = float64_div(fj, fk, &env->fp_status);
153 update_fcsr0(env, GETPC());
154 return fd;
155}
156
157uint64_t helper_fmax_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
158{
159 uint64_t fd;
160
161 fd = nanbox_s(float32_maxnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
162 update_fcsr0(env, GETPC());
163 return fd;
164}
165
166uint64_t helper_fmax_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
167{
168 uint64_t fd;
169
170 fd = float64_maxnum(fj, fk, &env->fp_status);
171 update_fcsr0(env, GETPC());
172 return fd;
173}
174
175uint64_t helper_fmin_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
176{
177 uint64_t fd;
178
179 fd = nanbox_s(float32_minnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
180 update_fcsr0(env, GETPC());
181 return fd;
182}
183
184uint64_t helper_fmin_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
185{
186 uint64_t fd;
187
188 fd = float64_minnum(fj, fk, &env->fp_status);
189 update_fcsr0(env, GETPC());
190 return fd;
191}
192
193uint64_t helper_fmaxa_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
194{
195 uint64_t fd;
196
197 fd = nanbox_s(float32_maxnummag((uint32_t)fj,
198 (uint32_t)fk, &env->fp_status));
199 update_fcsr0(env, GETPC());
200 return fd;
201}
202
203uint64_t helper_fmaxa_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
204{
205 uint64_t fd;
206
207 fd = float64_maxnummag(fj, fk, &env->fp_status);
208 update_fcsr0(env, GETPC());
209 return fd;
210}
211
212uint64_t helper_fmina_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
213{
214 uint64_t fd;
215
216 fd = nanbox_s(float32_minnummag((uint32_t)fj,
217 (uint32_t)fk, &env->fp_status));
218 update_fcsr0(env, GETPC());
219 return fd;
220}
221
222uint64_t helper_fmina_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
223{
224 uint64_t fd;
225
226 fd = float64_minnummag(fj, fk, &env->fp_status);
227 update_fcsr0(env, GETPC());
228 return fd;
229}
230
231uint64_t helper_fscaleb_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
232{
233 uint64_t fd;
234 int32_t n = (int32_t)fk;
235
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;
242}
243
244uint64_t helper_fscaleb_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
245{
246 uint64_t fd;
247 int64_t n = (int64_t)fk;
248
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;
255}
256
257uint64_t helper_fsqrt_s(CPULoongArchState *env, uint64_t fj)
258{
259 uint64_t fd;
260
261 fd = nanbox_s(float32_sqrt((uint32_t)fj, &env->fp_status));
262 update_fcsr0(env, GETPC());
263 return fd;
264}
265
266uint64_t helper_fsqrt_d(CPULoongArchState *env, uint64_t fj)
267{
268 uint64_t fd;
269
270 fd = float64_sqrt(fj, &env->fp_status);
271 update_fcsr0(env, GETPC());
272 return fd;
273}
274
275uint64_t helper_frecip_s(CPULoongArchState *env, uint64_t fj)
276{
277 uint64_t fd;
278
279 fd = nanbox_s(float32_div(float32_one, (uint32_t)fj, &env->fp_status));
280 update_fcsr0(env, GETPC());
281 return fd;
282}
283
284uint64_t helper_frecip_d(CPULoongArchState *env, uint64_t fj)
285{
286 uint64_t fd;
287
288 fd = float64_div(float64_one, fj, &env->fp_status);
289 update_fcsr0(env, GETPC());
290 return fd;
291}
292
293uint64_t helper_frsqrt_s(CPULoongArchState *env, uint64_t fj)
294{
295 uint64_t fd;
296 uint32_t fp;
297
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;
302}
303
304uint64_t helper_frsqrt_d(CPULoongArchState *env, uint64_t fj)
305{
306 uint64_t fp, fd;
307
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;
312}
313
314uint64_t helper_flogb_s(CPULoongArchState *env, uint64_t fj)
315{
316 uint64_t fd;
317 uint32_t fp;
318 float_status *status = &env->fp_status;
319 FloatRoundMode old_mode = get_float_rounding_mode(status);
320
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;
327}
328
329uint64_t helper_flogb_d(CPULoongArchState *env, uint64_t fj)
330{
331 uint64_t fd;
332 float_status *status = &env->fp_status;
333 FloatRoundMode old_mode = get_float_rounding_mode(status);
334
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;
341}
342
343uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
344{
345 float32 f = fj;
346 bool sign = float32_is_neg(f);
347
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;
359 }
360}
361
362uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
363{
364 float64 f = fj;
365 bool sign = float64_is_neg(f);
366
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;
378 }
379}
380
381uint64_t helper_fmuladd_s(CPULoongArchState *env, uint64_t fj,
382 uint64_t fk, uint64_t fa, uint32_t flag)
383{
384 uint64_t fd;
385
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;
390}
391
392uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t fj,
393 uint64_t fk, uint64_t fa, uint32_t flag)
394{
395 uint64_t fd;
396
397 fd = float64_muladd(fj, fk, fa, flag, &env->fp_status);
398 update_fcsr0(env, GETPC());
399 return fd;
400}
9b741076
SG
401
402static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp,
403 uint32_t flags)
404{
405 bool ret;
406
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();
422 }
423 update_fcsr0(env, GETPC());
424
425 return ret;
426}
427
428/* fcmp_cXXX_s */
429uint64_t helper_fcmp_c_s(CPULoongArchState *env, uint64_t fj,
430 uint64_t fk, uint32_t flags)
431{
432 FloatRelation cmp = float32_compare_quiet((uint32_t)fj,
433 (uint32_t)fk, &env->fp_status);
434 return fcmp_common(env, cmp, flags);
435}
436
437/* fcmp_sXXX_s */
438uint64_t helper_fcmp_s_s(CPULoongArchState *env, uint64_t fj,
439 uint64_t fk, uint32_t flags)
440{
441 FloatRelation cmp = float32_compare((uint32_t)fj,
442 (uint32_t)fk, &env->fp_status);
443 return fcmp_common(env, cmp, flags);
444}
445
446/* fcmp_cXXX_d */
447uint64_t helper_fcmp_c_d(CPULoongArchState *env, uint64_t fj,
448 uint64_t fk, uint32_t flags)
449{
450 FloatRelation cmp = float64_compare_quiet(fj, fk, &env->fp_status);
451 return fcmp_common(env, cmp, flags);
452}
453
454/* fcmp_sXXX_d */
455uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t fj,
456 uint64_t fk, uint32_t flags)
457{
458 FloatRelation cmp = float64_compare(fj, fk, &env->fp_status);
459 return fcmp_common(env, cmp, flags);
460}
7c1f8870
SG
461
462/* floating point conversion */
463uint64_t helper_fcvt_s_d(CPULoongArchState *env, uint64_t fj)
464{
465 uint64_t fd;
466
467 fd = nanbox_s(float64_to_float32(fj, &env->fp_status));
468 update_fcsr0(env, GETPC());
469 return fd;
470}
471
472uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj)
473{
474 uint64_t fd;
475
476 fd = float32_to_float64((uint32_t)fj, &env->fp_status);
477 update_fcsr0(env, GETPC());
478 return fd;
479}
480
481uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj)
482{
483 uint64_t fd;
484
485 fd = nanbox_s(int32_to_float32((int32_t)fj, &env->fp_status));
486 update_fcsr0(env, GETPC());
487 return fd;
488}
489
490uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj)
491{
492 uint64_t fd;
493
494 fd = nanbox_s(int64_to_float32(fj, &env->fp_status));
495 update_fcsr0(env, GETPC());
496 return fd;
497}
498
499uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj)
500{
501 uint64_t fd;
502
503 fd = int32_to_float64((int32_t)fj, &env->fp_status);
504 update_fcsr0(env, GETPC());
505 return fd;
506}
507
508uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj)
509{
510 uint64_t fd;
511
512 fd = int64_to_float64(fj, &env->fp_status);
513 update_fcsr0(env, GETPC());
514 return fd;
515}
516
517uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj)
518{
519 uint64_t fd;
520
521 fd = (uint64_t)(float32_round_to_int((uint32_t)fj, &env->fp_status));
522 update_fcsr0(env, GETPC());
523 return fd;
524}
525
526uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj)
527{
528 uint64_t fd;
529
530 fd = float64_round_to_int(fj, &env->fp_status);
531 update_fcsr0(env, GETPC());
532 return fd;
533}
534
535uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
536{
537 uint64_t fd;
538 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
539
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);
543
9fad2071
SG
544 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
545 if (float64_is_any_nan(fj)) {
546 fd = 0;
547 }
7c1f8870
SG
548 }
549 update_fcsr0(env, GETPC());
550 return fd;
551}
552
553uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
554{
555 uint64_t fd;
556 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
557
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);
561
9fad2071
SG
562 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
563 if (float32_is_any_nan((uint32_t)fj)) {
564 fd = 0;
565 }
7c1f8870
SG
566 }
567 update_fcsr0(env, GETPC());
568 return fd;
569}
570
571uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
572{
573 uint64_t fd;
574 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
575
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);
579
9fad2071
SG
580 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
581 if (float64_is_any_nan(fj)) {
582 fd = 0;
583 }
7c1f8870
SG
584 }
585 update_fcsr0(env, GETPC());
586 return fd;
587}
588
589uint64_t helper_ftintrm_w_s(CPULoongArchState *env, uint64_t fj)
590{
591 uint64_t fd;
592 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
593
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);
597
9fad2071
SG
598 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
599 if (float32_is_any_nan((uint32_t)fj)) {
600 fd = 0;
601 }
7c1f8870
SG
602 }
603 update_fcsr0(env, GETPC());
604 return fd;
605}
606
607uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
608{
609 uint64_t fd;
610 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
611
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);
615
9fad2071
SG
616 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
617 if (float64_is_any_nan(fj)) {
618 fd = 0;
619 }
7c1f8870
SG
620 }
621 update_fcsr0(env, GETPC());
622 return fd;
623}
624
625uint64_t helper_ftintrp_l_s(CPULoongArchState *env, uint64_t fj)
626{
627 uint64_t fd;
628 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
629
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);
633
9fad2071
SG
634 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
635 if (float32_is_any_nan((uint32_t)fj)) {
636 fd = 0;
637 }
7c1f8870
SG
638 }
639 update_fcsr0(env, GETPC());
640 return fd;
641}
642
643uint64_t helper_ftintrp_w_d(CPULoongArchState *env, uint64_t fj)
644{
645 uint64_t fd;
646 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
647
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);
651
9fad2071
SG
652 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
653 if (float64_is_any_nan(fj)) {
654 fd = 0;
655 }
7c1f8870
SG
656 }
657 update_fcsr0(env, GETPC());
658 return fd;
659}
660
661uint64_t helper_ftintrp_w_s(CPULoongArchState *env, uint64_t fj)
662{
663 uint64_t fd;
664 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
665
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);
669
9fad2071
SG
670 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
671 if (float32_is_any_nan((uint32_t)fj)) {
672 fd = 0;
673 }
7c1f8870
SG
674 }
675 update_fcsr0(env, GETPC());
676 return fd;
677}
678
679uint64_t helper_ftintrz_l_d(CPULoongArchState *env, uint64_t fj)
680{
681 uint64_t fd;
682 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
683
684 fd = float64_to_int64_round_to_zero(fj, &env->fp_status);
685 set_float_rounding_mode(old_mode, &env->fp_status);
686
9fad2071
SG
687 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
688 if (float64_is_any_nan(fj)) {
689 fd = 0;
690 }
7c1f8870
SG
691 }
692 update_fcsr0(env, GETPC());
693 return fd;
694}
695
696uint64_t helper_ftintrz_l_s(CPULoongArchState *env, uint64_t fj)
697{
698 uint64_t fd;
699 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
700
701 fd = float32_to_int64_round_to_zero((uint32_t)fj, &env->fp_status);
702 set_float_rounding_mode(old_mode, &env->fp_status);
703
9fad2071
SG
704 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
705 if (float32_is_any_nan((uint32_t)fj)) {
706 fd = 0;
707 }
7c1f8870
SG
708 }
709 update_fcsr0(env, GETPC());
710 return fd;
711}
712
713uint64_t helper_ftintrz_w_d(CPULoongArchState *env, uint64_t fj)
714{
715 uint64_t fd;
716 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
717
718 fd = (uint64_t)float64_to_int32_round_to_zero(fj, &env->fp_status);
719 set_float_rounding_mode(old_mode, &env->fp_status);
720
9fad2071
SG
721 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
722 if (float64_is_any_nan(fj)) {
723 fd = 0;
724 }
7c1f8870
SG
725 }
726 update_fcsr0(env, GETPC());
727 return fd;
728}
729
730uint64_t helper_ftintrz_w_s(CPULoongArchState *env, uint64_t fj)
731{
732 uint32_t fd;
733 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
734
735 fd = float32_to_int32_round_to_zero((uint32_t)fj, &env->fp_status);
736 set_float_rounding_mode(old_mode, &env->fp_status);
737
9fad2071
SG
738 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
739 if (float32_is_any_nan((uint32_t)fj)) {
740 fd = 0;
741 }
7c1f8870
SG
742 }
743 update_fcsr0(env, GETPC());
744 return (uint64_t)fd;
745}
746
747uint64_t helper_ftintrne_l_d(CPULoongArchState *env, uint64_t fj)
748{
749 uint64_t fd;
750 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
751
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);
755
9fad2071
SG
756 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
757 if (float64_is_any_nan(fj)) {
758 fd = 0;
759 }
7c1f8870
SG
760 }
761 update_fcsr0(env, GETPC());
762 return fd;
763}
764
765uint64_t helper_ftintrne_l_s(CPULoongArchState *env, uint64_t fj)
766{
767 uint64_t fd;
768 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
769
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);
773
9fad2071
SG
774 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
775 if (float32_is_any_nan((uint32_t)fj)) {
776 fd = 0;
777 }
7c1f8870
SG
778 }
779 update_fcsr0(env, GETPC());
780 return fd;
781}
782
783uint64_t helper_ftintrne_w_d(CPULoongArchState *env, uint64_t fj)
784{
785 uint64_t fd;
786 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
787
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);
791
9fad2071
SG
792 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
793 if (float64_is_any_nan(fj)) {
794 fd = 0;
795 }
7c1f8870
SG
796 }
797 update_fcsr0(env, GETPC());
798 return fd;
799}
800
801uint64_t helper_ftintrne_w_s(CPULoongArchState *env, uint64_t fj)
802{
803 uint32_t fd;
804 FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
805
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);
809
9fad2071
SG
810 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
811 if (float32_is_any_nan((uint32_t)fj)) {
812 fd = 0;
813 }
7c1f8870
SG
814 }
815 update_fcsr0(env, GETPC());
816 return (uint64_t)fd;
817}
818
819uint64_t helper_ftint_l_d(CPULoongArchState *env, uint64_t fj)
820{
821 uint64_t fd;
822
823 fd = float64_to_int64(fj, &env->fp_status);
9fad2071
SG
824 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
825 if (float64_is_any_nan(fj)) {
826 fd = 0;
827 }
7c1f8870
SG
828 }
829 update_fcsr0(env, GETPC());
830 return fd;
831}
832
833uint64_t helper_ftint_l_s(CPULoongArchState *env, uint64_t fj)
834{
835 uint64_t fd;
836
837 fd = float32_to_int64((uint32_t)fj, &env->fp_status);
9fad2071
SG
838 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
839 if (float32_is_any_nan((uint32_t)fj)) {
840 fd = 0;
841 }
7c1f8870
SG
842 }
843 update_fcsr0(env, GETPC());
844 return fd;
845}
846
847uint64_t helper_ftint_w_s(CPULoongArchState *env, uint64_t fj)
848{
849 uint64_t fd;
850
851 fd = (uint64_t)float32_to_int32((uint32_t)fj, &env->fp_status);
9fad2071
SG
852 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
853 if (float32_is_any_nan((uint32_t)fj)) {
854 fd = 0;
855 }
7c1f8870
SG
856 }
857 update_fcsr0(env, GETPC());
858 return fd;
859}
860
861uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj)
862{
863 uint64_t fd;
864
865 fd = (uint64_t)float64_to_int32(fj, &env->fp_status);
9fad2071
SG
866 if (get_float_exception_flags(&env->fp_status) & (float_flag_invalid)) {
867 if (float64_is_any_nan(fj)) {
868 fd = 0;
869 }
7c1f8870
SG
870 }
871 update_fcsr0(env, GETPC());
872 return fd;
873}
b7dabd56 874
10dcb08b 875void helper_set_rounding_mode(CPULoongArchState *env)
b7dabd56 876{
10dcb08b 877 set_float_rounding_mode(ieee_rm[(env->fcsr0 >> FCSR0_RM) & 0x3],
b7dabd56
SG
878 &env->fp_status);
879}