]> Git Repo - qemu.git/blob - target/loongarch/fpu_helper.c
81466678eb7a652ef8babe741540e59ba22fcb80
[qemu.git] / target / loongarch / fpu_helper.c
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
16 #define FLOAT_TO_INT32_OVERFLOW 0x7fffffff
17 #define FLOAT_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
18
19 static inline uint64_t nanbox_s(float32 fp)
20 {
21     return fp | MAKE_64BIT_MASK(32, 32);
22 }
23
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
30 };
31
32 void restore_fp_status(CPULoongArchState *env)
33 {
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);
37 }
38
39 static int ieee_ex_to_loongarch(int xcpt)
40 {
41     int ret = 0;
42     if (xcpt & float_flag_invalid) {
43         ret |= FP_INVALID;
44     }
45     if (xcpt & float_flag_overflow) {
46         ret |= FP_OVERFLOW;
47     }
48     if (xcpt & float_flag_underflow) {
49         ret |= FP_UNDERFLOW;
50     }
51     if (xcpt & float_flag_divbyzero) {
52         ret |= FP_DIV0;
53     }
54     if (xcpt & float_flag_inexact) {
55         ret |= FP_INEXACT;
56     }
57     return ret;
58 }
59
60 static void update_fcsr0_mask(CPULoongArchState *env, uintptr_t pc, int mask)
61 {
62     int flags = get_float_exception_flags(&env->fp_status);
63
64     set_float_exception_flags(0, &env->fp_status);
65
66     flags &= ~mask;
67
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);
74     }
75
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);
80     }
81 }
82
83 static void update_fcsr0(CPULoongArchState *env, uintptr_t pc)
84 {
85     update_fcsr0_mask(env, pc, 0);
86 }
87
88 uint64_t helper_fadd_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
89 {
90     uint64_t fd;
91
92     fd = nanbox_s(float32_add((uint32_t)fj, (uint32_t)fk, &env->fp_status));
93     update_fcsr0(env, GETPC());
94     return fd;
95 }
96
97 uint64_t helper_fadd_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
98 {
99     uint64_t fd;
100
101     fd = float64_add(fj, fk, &env->fp_status);
102     update_fcsr0(env, GETPC());
103     return fd;
104 }
105
106 uint64_t helper_fsub_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
107 {
108     uint64_t fd;
109
110     fd = nanbox_s(float32_sub((uint32_t)fj, (uint32_t)fk, &env->fp_status));
111     update_fcsr0(env, GETPC());
112     return fd;
113 }
114
115 uint64_t helper_fsub_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
116 {
117     uint64_t fd;
118
119     fd = float64_sub(fj, fk, &env->fp_status);
120     update_fcsr0(env, GETPC());
121     return fd;
122 }
123
124 uint64_t helper_fmul_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
125 {
126     uint64_t fd;
127
128     fd = nanbox_s(float32_mul((uint32_t)fj, (uint32_t)fk, &env->fp_status));
129     update_fcsr0(env, GETPC());
130     return fd;
131 }
132
133 uint64_t helper_fmul_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
134 {
135     uint64_t fd;
136
137     fd = float64_mul(fj, fk, &env->fp_status);
138     update_fcsr0(env, GETPC());
139     return fd;
140 }
141
142 uint64_t helper_fdiv_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
143 {
144     uint64_t fd;
145
146     fd = nanbox_s(float32_div((uint32_t)fj, (uint32_t)fk, &env->fp_status));
147     update_fcsr0(env, GETPC());
148     return fd;
149 }
150
151 uint64_t helper_fdiv_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
152 {
153     uint64_t fd;
154
155     fd = float64_div(fj, fk, &env->fp_status);
156     update_fcsr0(env, GETPC());
157     return fd;
158 }
159
160 uint64_t helper_fmax_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
161 {
162     uint64_t fd;
163
164     fd = nanbox_s(float32_maxnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
165     update_fcsr0(env, GETPC());
166     return fd;
167 }
168
169 uint64_t helper_fmax_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
170 {
171     uint64_t fd;
172
173     fd = float64_maxnum(fj, fk, &env->fp_status);
174     update_fcsr0(env, GETPC());
175     return fd;
176 }
177
178 uint64_t helper_fmin_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
179 {
180     uint64_t fd;
181
182     fd = nanbox_s(float32_minnum((uint32_t)fj, (uint32_t)fk, &env->fp_status));
183     update_fcsr0(env, GETPC());
184     return fd;
185 }
186
187 uint64_t helper_fmin_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
188 {
189     uint64_t fd;
190
191     fd = float64_minnum(fj, fk, &env->fp_status);
192     update_fcsr0(env, GETPC());
193     return fd;
194 }
195
196 uint64_t helper_fmaxa_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
197 {
198     uint64_t fd;
199
200     fd = nanbox_s(float32_maxnummag((uint32_t)fj,
201                                     (uint32_t)fk, &env->fp_status));
202     update_fcsr0(env, GETPC());
203     return fd;
204 }
205
206 uint64_t helper_fmaxa_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
207 {
208     uint64_t fd;
209
210     fd = float64_maxnummag(fj, fk, &env->fp_status);
211     update_fcsr0(env, GETPC());
212     return fd;
213 }
214
215 uint64_t helper_fmina_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
216 {
217     uint64_t fd;
218
219     fd = nanbox_s(float32_minnummag((uint32_t)fj,
220                                     (uint32_t)fk, &env->fp_status));
221     update_fcsr0(env, GETPC());
222     return fd;
223 }
224
225 uint64_t helper_fmina_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
226 {
227     uint64_t fd;
228
229     fd = float64_minnummag(fj, fk, &env->fp_status);
230     update_fcsr0(env, GETPC());
231     return fd;
232 }
233
234 uint64_t helper_fscaleb_s(CPULoongArchState *env, uint64_t fj, uint64_t fk)
235 {
236     uint64_t fd;
237     int32_t n = (int32_t)fk;
238
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;
245 }
246
247 uint64_t helper_fscaleb_d(CPULoongArchState *env, uint64_t fj, uint64_t fk)
248 {
249     uint64_t fd;
250     int64_t n = (int64_t)fk;
251
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;
258 }
259
260 uint64_t helper_fsqrt_s(CPULoongArchState *env, uint64_t fj)
261 {
262     uint64_t fd;
263
264     fd = nanbox_s(float32_sqrt((uint32_t)fj, &env->fp_status));
265     update_fcsr0(env, GETPC());
266     return fd;
267 }
268
269 uint64_t helper_fsqrt_d(CPULoongArchState *env, uint64_t fj)
270 {
271     uint64_t fd;
272
273     fd = float64_sqrt(fj, &env->fp_status);
274     update_fcsr0(env, GETPC());
275     return fd;
276 }
277
278 uint64_t helper_frecip_s(CPULoongArchState *env, uint64_t fj)
279 {
280     uint64_t fd;
281
282     fd = nanbox_s(float32_div(float32_one, (uint32_t)fj, &env->fp_status));
283     update_fcsr0(env, GETPC());
284     return fd;
285 }
286
287 uint64_t helper_frecip_d(CPULoongArchState *env, uint64_t fj)
288 {
289     uint64_t fd;
290
291     fd = float64_div(float64_one, fj, &env->fp_status);
292     update_fcsr0(env, GETPC());
293     return fd;
294 }
295
296 uint64_t helper_frsqrt_s(CPULoongArchState *env, uint64_t fj)
297 {
298     uint64_t fd;
299     uint32_t fp;
300
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;
305 }
306
307 uint64_t helper_frsqrt_d(CPULoongArchState *env, uint64_t fj)
308 {
309     uint64_t fp, fd;
310
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;
315 }
316
317 uint64_t helper_flogb_s(CPULoongArchState *env, uint64_t fj)
318 {
319     uint64_t fd;
320     uint32_t fp;
321     float_status *status = &env->fp_status;
322     FloatRoundMode old_mode = get_float_rounding_mode(status);
323
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;
330 }
331
332 uint64_t helper_flogb_d(CPULoongArchState *env, uint64_t fj)
333 {
334     uint64_t fd;
335     float_status *status = &env->fp_status;
336     FloatRoundMode old_mode = get_float_rounding_mode(status);
337
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;
344 }
345
346 uint64_t helper_fclass_s(CPULoongArchState *env, uint64_t fj)
347 {
348     float32 f = fj;
349     bool sign = float32_is_neg(f);
350
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;
362     }
363 }
364
365 uint64_t helper_fclass_d(CPULoongArchState *env, uint64_t fj)
366 {
367     float64 f = fj;
368     bool sign = float64_is_neg(f);
369
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;
381     }
382 }
383
384 uint64_t helper_fmuladd_s(CPULoongArchState *env, uint64_t fj,
385                           uint64_t fk, uint64_t fa, uint32_t flag)
386 {
387     uint64_t fd;
388
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;
393 }
394
395 uint64_t helper_fmuladd_d(CPULoongArchState *env, uint64_t fj,
396                           uint64_t fk, uint64_t fa, uint32_t flag)
397 {
398     uint64_t fd;
399
400     fd = float64_muladd(fj, fk, fa, flag, &env->fp_status);
401     update_fcsr0(env, GETPC());
402     return fd;
403 }
404
405 static uint64_t fcmp_common(CPULoongArchState *env, FloatRelation cmp,
406                             uint32_t flags)
407 {
408     bool ret;
409
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();
425     }
426     update_fcsr0(env, GETPC());
427
428     return ret;
429 }
430
431 /* fcmp_cXXX_s */
432 uint64_t helper_fcmp_c_s(CPULoongArchState *env, uint64_t fj,
433                          uint64_t fk, uint32_t flags)
434 {
435     FloatRelation cmp = float32_compare_quiet((uint32_t)fj,
436                                               (uint32_t)fk, &env->fp_status);
437     return fcmp_common(env, cmp, flags);
438 }
439
440 /* fcmp_sXXX_s */
441 uint64_t helper_fcmp_s_s(CPULoongArchState *env, uint64_t fj,
442                          uint64_t fk, uint32_t flags)
443 {
444     FloatRelation cmp = float32_compare((uint32_t)fj,
445                                         (uint32_t)fk, &env->fp_status);
446     return fcmp_common(env, cmp, flags);
447 }
448
449 /* fcmp_cXXX_d */
450 uint64_t helper_fcmp_c_d(CPULoongArchState *env, uint64_t fj,
451                          uint64_t fk, uint32_t flags)
452 {
453     FloatRelation cmp = float64_compare_quiet(fj, fk, &env->fp_status);
454     return fcmp_common(env, cmp, flags);
455 }
456
457 /* fcmp_sXXX_d */
458 uint64_t helper_fcmp_s_d(CPULoongArchState *env, uint64_t fj,
459                          uint64_t fk, uint32_t flags)
460 {
461     FloatRelation cmp = float64_compare(fj, fk, &env->fp_status);
462     return fcmp_common(env, cmp, flags);
463 }
464
465 /* floating point conversion */
466 uint64_t helper_fcvt_s_d(CPULoongArchState *env, uint64_t fj)
467 {
468     uint64_t fd;
469
470     fd = nanbox_s(float64_to_float32(fj, &env->fp_status));
471     update_fcsr0(env, GETPC());
472     return fd;
473 }
474
475 uint64_t helper_fcvt_d_s(CPULoongArchState *env, uint64_t fj)
476 {
477     uint64_t fd;
478
479     fd = float32_to_float64((uint32_t)fj, &env->fp_status);
480     update_fcsr0(env, GETPC());
481     return fd;
482 }
483
484 uint64_t helper_ffint_s_w(CPULoongArchState *env, uint64_t fj)
485 {
486     uint64_t fd;
487
488     fd = nanbox_s(int32_to_float32((int32_t)fj, &env->fp_status));
489     update_fcsr0(env, GETPC());
490     return fd;
491 }
492
493 uint64_t helper_ffint_s_l(CPULoongArchState *env, uint64_t fj)
494 {
495     uint64_t fd;
496
497     fd = nanbox_s(int64_to_float32(fj, &env->fp_status));
498     update_fcsr0(env, GETPC());
499     return fd;
500 }
501
502 uint64_t helper_ffint_d_w(CPULoongArchState *env, uint64_t fj)
503 {
504     uint64_t fd;
505
506     fd = int32_to_float64((int32_t)fj, &env->fp_status);
507     update_fcsr0(env, GETPC());
508     return fd;
509 }
510
511 uint64_t helper_ffint_d_l(CPULoongArchState *env, uint64_t fj)
512 {
513     uint64_t fd;
514
515     fd = int64_to_float64(fj, &env->fp_status);
516     update_fcsr0(env, GETPC());
517     return fd;
518 }
519
520 uint64_t helper_frint_s(CPULoongArchState *env, uint64_t fj)
521 {
522     uint64_t fd;
523
524     fd = (uint64_t)(float32_round_to_int((uint32_t)fj, &env->fp_status));
525     update_fcsr0(env, GETPC());
526     return fd;
527 }
528
529 uint64_t helper_frint_d(CPULoongArchState *env, uint64_t fj)
530 {
531     uint64_t fd;
532
533     fd = float64_round_to_int(fj, &env->fp_status);
534     update_fcsr0(env, GETPC());
535     return fd;
536 }
537
538 uint64_t helper_ftintrm_l_d(CPULoongArchState *env, uint64_t fj)
539 {
540     uint64_t fd;
541     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
542
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);
546
547     if (get_float_exception_flags(&env->fp_status) &
548         (float_flag_invalid | float_flag_overflow)) {
549         fd = FLOAT_TO_INT64_OVERFLOW;
550     }
551     update_fcsr0(env, GETPC());
552     return fd;
553 }
554
555 uint64_t helper_ftintrm_l_s(CPULoongArchState *env, uint64_t fj)
556 {
557     uint64_t fd;
558     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
559
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);
563
564     if (get_float_exception_flags(&env->fp_status) &
565         (float_flag_invalid | float_flag_overflow)) {
566         fd = FLOAT_TO_INT64_OVERFLOW;
567     }
568     update_fcsr0(env, GETPC());
569     return fd;
570 }
571
572 uint64_t helper_ftintrm_w_d(CPULoongArchState *env, uint64_t fj)
573 {
574     uint64_t fd;
575     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
576
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);
580
581     if (get_float_exception_flags(&env->fp_status) &
582         (float_flag_invalid | float_flag_overflow)) {
583         fd = FLOAT_TO_INT32_OVERFLOW;
584     }
585     update_fcsr0(env, GETPC());
586     return fd;
587 }
588
589 uint64_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
598     if (get_float_exception_flags(&env->fp_status) &
599         (float_flag_invalid | float_flag_overflow)) {
600         fd = FLOAT_TO_INT32_OVERFLOW;
601     }
602     update_fcsr0(env, GETPC());
603     return fd;
604 }
605
606 uint64_t helper_ftintrp_l_d(CPULoongArchState *env, uint64_t fj)
607 {
608     uint64_t fd;
609     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
610
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);
614
615     if (get_float_exception_flags(&env->fp_status) &
616         (float_flag_invalid | float_flag_overflow)) {
617         fd = FLOAT_TO_INT64_OVERFLOW;
618     }
619     update_fcsr0(env, GETPC());
620     return fd;
621 }
622
623 uint64_t helper_ftintrp_l_s(CPULoongArchState *env, uint64_t fj)
624 {
625     uint64_t fd;
626     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
627
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);
631
632     if (get_float_exception_flags(&env->fp_status) &
633         (float_flag_invalid | float_flag_overflow)) {
634         fd = FLOAT_TO_INT64_OVERFLOW;
635     }
636     update_fcsr0(env, GETPC());
637     return fd;
638 }
639
640 uint64_t helper_ftintrp_w_d(CPULoongArchState *env, uint64_t fj)
641 {
642     uint64_t fd;
643     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
644
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);
648
649     if (get_float_exception_flags(&env->fp_status) &
650         (float_flag_invalid | float_flag_overflow)) {
651         fd = FLOAT_TO_INT32_OVERFLOW;
652     }
653     update_fcsr0(env, GETPC());
654     return fd;
655 }
656
657 uint64_t helper_ftintrp_w_s(CPULoongArchState *env, uint64_t fj)
658 {
659     uint64_t fd;
660     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
661
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);
665
666     if (get_float_exception_flags(&env->fp_status) &
667         (float_flag_invalid | float_flag_overflow)) {
668         fd = FLOAT_TO_INT32_OVERFLOW;
669     }
670     update_fcsr0(env, GETPC());
671     return fd;
672 }
673
674 uint64_t helper_ftintrz_l_d(CPULoongArchState *env, uint64_t fj)
675 {
676     uint64_t fd;
677     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
678
679     fd = float64_to_int64_round_to_zero(fj, &env->fp_status);
680     set_float_rounding_mode(old_mode, &env->fp_status);
681
682     if (get_float_exception_flags(&env->fp_status) &
683         (float_flag_invalid | float_flag_overflow)) {
684         fd = FLOAT_TO_INT64_OVERFLOW;
685     }
686     update_fcsr0(env, GETPC());
687     return fd;
688 }
689
690 uint64_t helper_ftintrz_l_s(CPULoongArchState *env, uint64_t fj)
691 {
692     uint64_t fd;
693     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
694
695     fd = float32_to_int64_round_to_zero((uint32_t)fj, &env->fp_status);
696     set_float_rounding_mode(old_mode, &env->fp_status);
697
698     if (get_float_exception_flags(&env->fp_status) &
699         (float_flag_invalid | float_flag_overflow)) {
700         fd = FLOAT_TO_INT64_OVERFLOW;
701     }
702     update_fcsr0(env, GETPC());
703     return fd;
704 }
705
706 uint64_t helper_ftintrz_w_d(CPULoongArchState *env, uint64_t fj)
707 {
708     uint64_t fd;
709     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
710
711     fd = (uint64_t)float64_to_int32_round_to_zero(fj, &env->fp_status);
712     set_float_rounding_mode(old_mode, &env->fp_status);
713
714     if (get_float_exception_flags(&env->fp_status) &
715         (float_flag_invalid | float_flag_overflow)) {
716         fd = FLOAT_TO_INT32_OVERFLOW;
717     }
718     update_fcsr0(env, GETPC());
719     return fd;
720 }
721
722 uint64_t helper_ftintrz_w_s(CPULoongArchState *env, uint64_t fj)
723 {
724     uint32_t fd;
725     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
726
727     fd = float32_to_int32_round_to_zero((uint32_t)fj, &env->fp_status);
728     set_float_rounding_mode(old_mode, &env->fp_status);
729
730     if (get_float_exception_flags(&env->fp_status) &
731         (float_flag_invalid | float_flag_overflow)) {
732         fd = FLOAT_TO_INT32_OVERFLOW;
733     }
734     update_fcsr0(env, GETPC());
735     return (uint64_t)fd;
736 }
737
738 uint64_t helper_ftintrne_l_d(CPULoongArchState *env, uint64_t fj)
739 {
740     uint64_t fd;
741     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
742
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);
746
747     if (get_float_exception_flags(&env->fp_status) &
748         (float_flag_invalid | float_flag_overflow)) {
749         fd = FLOAT_TO_INT64_OVERFLOW;
750     }
751     update_fcsr0(env, GETPC());
752     return fd;
753 }
754
755 uint64_t helper_ftintrne_l_s(CPULoongArchState *env, uint64_t fj)
756 {
757     uint64_t fd;
758     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
759
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);
763
764     if (get_float_exception_flags(&env->fp_status) &
765         (float_flag_invalid | float_flag_overflow)) {
766         fd = FLOAT_TO_INT64_OVERFLOW;
767     }
768     update_fcsr0(env, GETPC());
769     return fd;
770 }
771
772 uint64_t helper_ftintrne_w_d(CPULoongArchState *env, uint64_t fj)
773 {
774     uint64_t fd;
775     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
776
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);
780
781     if (get_float_exception_flags(&env->fp_status) &
782         (float_flag_invalid | float_flag_overflow)) {
783         fd = FLOAT_TO_INT32_OVERFLOW;
784     }
785     update_fcsr0(env, GETPC());
786     return fd;
787 }
788
789 uint64_t helper_ftintrne_w_s(CPULoongArchState *env, uint64_t fj)
790 {
791     uint32_t fd;
792     FloatRoundMode old_mode = get_float_rounding_mode(&env->fp_status);
793
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);
797
798     if (get_float_exception_flags(&env->fp_status) &
799         (float_flag_invalid | float_flag_overflow)) {
800         fd = FLOAT_TO_INT32_OVERFLOW;
801     }
802     update_fcsr0(env, GETPC());
803     return (uint64_t)fd;
804 }
805
806 uint64_t helper_ftint_l_d(CPULoongArchState *env, uint64_t fj)
807 {
808     uint64_t fd;
809
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;
814     }
815     update_fcsr0(env, GETPC());
816     return fd;
817 }
818
819 uint64_t helper_ftint_l_s(CPULoongArchState *env, uint64_t fj)
820 {
821     uint64_t fd;
822
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;
827     }
828     update_fcsr0(env, GETPC());
829     return fd;
830 }
831
832 uint64_t helper_ftint_w_s(CPULoongArchState *env, uint64_t fj)
833 {
834     uint64_t fd;
835
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;
840     }
841     update_fcsr0(env, GETPC());
842     return fd;
843 }
844
845 uint64_t helper_ftint_w_d(CPULoongArchState *env, uint64_t fj)
846 {
847     uint64_t fd;
848
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;
853     }
854     update_fcsr0(env, GETPC());
855     return fd;
856 }
This page took 0.065383 seconds and 2 git commands to generate.