2 * Helpers for emulation of FPU-related MIPS instructions.
4 * Copyright (C) 2004-2005 Jocelyn Mayer
5 * Copyright (C) 2020 Wave Computing, Inc.
6 * Copyright (C) 2020 Aleksandar Markovic <amarkovic@wavecomp.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
23 #include "qemu/osdep.h"
24 #include "qemu/main-loop.h"
27 #include "qemu/host-utils.h"
28 #include "exec/helper-proto.h"
29 #include "exec/exec-all.h"
30 #include "exec/cpu_ldst.h"
31 #include "exec/memop.h"
32 #include "sysemu/kvm.h"
33 #include "fpu/softfloat.h"
36 /* Complex FPU operations which may need stack space. */
38 #define FLOAT_TWO32 make_float32(1 << 30)
39 #define FLOAT_TWO64 make_float64(1ULL << 62)
41 #define FP_TO_INT32_OVERFLOW 0x7fffffff
42 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
44 /* convert MIPS rounding mode in FCR31 to IEEE library */
45 unsigned int ieee_rm
[] = {
46 float_round_nearest_even
,
52 target_ulong
helper_cfc1(CPUMIPSState
*env
, uint32_t reg
)
54 target_ulong arg1
= 0;
58 arg1
= (int32_t)env
->active_fpu
.fcr0
;
61 /* UFR Support - Read Status FR */
62 if (env
->active_fpu
.fcr0
& (1 << FCR0_UFRP
)) {
63 if (env
->CP0_Config5
& (1 << CP0C5_UFR
)) {
65 ((env
->CP0_Status
& (1 << CP0St_FR
)) >> CP0St_FR
);
67 do_raise_exception(env
, EXCP_RI
, GETPC());
72 /* FRE Support - read Config5.FRE bit */
73 if (env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) {
74 if (env
->CP0_Config5
& (1 << CP0C5_UFE
)) {
75 arg1
= (env
->CP0_Config5
>> CP0C5_FRE
) & 1;
77 helper_raise_exception(env
, EXCP_RI
);
82 arg1
= ((env
->active_fpu
.fcr31
>> 24) & 0xfe) |
83 ((env
->active_fpu
.fcr31
>> 23) & 0x1);
86 arg1
= env
->active_fpu
.fcr31
& 0x0003f07c;
89 arg1
= (env
->active_fpu
.fcr31
& 0x00000f83) |
90 ((env
->active_fpu
.fcr31
>> 22) & 0x4);
93 arg1
= (int32_t)env
->active_fpu
.fcr31
;
100 void helper_ctc1(CPUMIPSState
*env
, target_ulong arg1
, uint32_t fs
, uint32_t rt
)
104 /* UFR Alias - Reset Status FR */
105 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_UFRP
)) && (rt
== 0))) {
108 if (env
->CP0_Config5
& (1 << CP0C5_UFR
)) {
109 env
->CP0_Status
&= ~(1 << CP0St_FR
);
112 do_raise_exception(env
, EXCP_RI
, GETPC());
116 /* UNFR Alias - Set Status FR */
117 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_UFRP
)) && (rt
== 0))) {
120 if (env
->CP0_Config5
& (1 << CP0C5_UFR
)) {
121 env
->CP0_Status
|= (1 << CP0St_FR
);
124 do_raise_exception(env
, EXCP_RI
, GETPC());
128 /* FRE Support - clear Config5.FRE bit */
129 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) && (rt
== 0))) {
132 if (env
->CP0_Config5
& (1 << CP0C5_UFE
)) {
133 env
->CP0_Config5
&= ~(1 << CP0C5_FRE
);
136 helper_raise_exception(env
, EXCP_RI
);
140 /* FRE Support - set Config5.FRE bit */
141 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) && (rt
== 0))) {
144 if (env
->CP0_Config5
& (1 << CP0C5_UFE
)) {
145 env
->CP0_Config5
|= (1 << CP0C5_FRE
);
148 helper_raise_exception(env
, EXCP_RI
);
152 if ((env
->insn_flags
& ISA_MIPS32R6
) || (arg1
& 0xffffff00)) {
155 env
->active_fpu
.fcr31
= (env
->active_fpu
.fcr31
& 0x017fffff) |
156 ((arg1
& 0xfe) << 24) |
157 ((arg1
& 0x1) << 23);
160 if (arg1
& 0x007c0000) {
163 env
->active_fpu
.fcr31
= (env
->active_fpu
.fcr31
& 0xfffc0f83) |
167 if (arg1
& 0x007c0000) {
170 env
->active_fpu
.fcr31
= (env
->active_fpu
.fcr31
& 0xfefff07c) |
171 (arg1
& 0x00000f83) |
172 ((arg1
& 0x4) << 22);
175 env
->active_fpu
.fcr31
= (arg1
& env
->active_fpu
.fcr31_rw_bitmask
) |
176 (env
->active_fpu
.fcr31
& ~(env
->active_fpu
.fcr31_rw_bitmask
));
179 if (env
->insn_flags
& ISA_MIPS32R6
) {
180 do_raise_exception(env
, EXCP_RI
, GETPC());
184 restore_fp_status(env
);
185 set_float_exception_flags(0, &env
->active_fpu
.fp_status
);
186 if ((GET_FP_ENABLE(env
->active_fpu
.fcr31
) | 0x20) &
187 GET_FP_CAUSE(env
->active_fpu
.fcr31
)) {
188 do_raise_exception(env
, EXCP_FPE
, GETPC());
192 static inline int ieee_to_mips_xcpt(int ieee_xcpt
)
196 if (ieee_xcpt
& float_flag_invalid
) {
197 mips_xcpt
|= FP_INVALID
;
199 if (ieee_xcpt
& float_flag_overflow
) {
200 mips_xcpt
|= FP_OVERFLOW
;
202 if (ieee_xcpt
& float_flag_underflow
) {
203 mips_xcpt
|= FP_UNDERFLOW
;
205 if (ieee_xcpt
& float_flag_divbyzero
) {
206 mips_xcpt
|= FP_DIV0
;
208 if (ieee_xcpt
& float_flag_inexact
) {
209 mips_xcpt
|= FP_INEXACT
;
215 static inline void update_fcr31(CPUMIPSState
*env
, uintptr_t pc
)
217 int ieee_exception_flags
= get_float_exception_flags(
218 &env
->active_fpu
.fp_status
);
219 int mips_exception_flags
= 0;
221 if (ieee_exception_flags
) {
222 mips_exception_flags
= ieee_to_mips_xcpt(ieee_exception_flags
);
225 SET_FP_CAUSE(env
->active_fpu
.fcr31
, mips_exception_flags
);
227 if (mips_exception_flags
) {
228 set_float_exception_flags(0, &env
->active_fpu
.fp_status
);
230 if (GET_FP_ENABLE(env
->active_fpu
.fcr31
) & mips_exception_flags
) {
231 do_raise_exception(env
, EXCP_FPE
, pc
);
233 UPDATE_FP_FLAGS(env
->active_fpu
.fcr31
, mips_exception_flags
);
240 * Single precition routines have a "s" suffix, double precision a
241 * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
242 * paired single lower "pl", paired single upper "pu".
245 /* unary operations, modifying fp status */
246 uint64_t helper_float_sqrt_d(CPUMIPSState
*env
, uint64_t fdt0
)
248 fdt0
= float64_sqrt(fdt0
, &env
->active_fpu
.fp_status
);
249 update_fcr31(env
, GETPC());
253 uint32_t helper_float_sqrt_s(CPUMIPSState
*env
, uint32_t fst0
)
255 fst0
= float32_sqrt(fst0
, &env
->active_fpu
.fp_status
);
256 update_fcr31(env
, GETPC());
260 uint64_t helper_float_cvtd_s(CPUMIPSState
*env
, uint32_t fst0
)
264 fdt2
= float32_to_float64(fst0
, &env
->active_fpu
.fp_status
);
265 update_fcr31(env
, GETPC());
269 uint64_t helper_float_cvtd_w(CPUMIPSState
*env
, uint32_t wt0
)
273 fdt2
= int32_to_float64(wt0
, &env
->active_fpu
.fp_status
);
274 update_fcr31(env
, GETPC());
278 uint64_t helper_float_cvtd_l(CPUMIPSState
*env
, uint64_t dt0
)
282 fdt2
= int64_to_float64(dt0
, &env
->active_fpu
.fp_status
);
283 update_fcr31(env
, GETPC());
287 uint64_t helper_float_cvt_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
291 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
292 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
293 & (float_flag_invalid
| float_flag_overflow
)) {
294 dt2
= FP_TO_INT64_OVERFLOW
;
296 update_fcr31(env
, GETPC());
300 uint64_t helper_float_cvt_l_s(CPUMIPSState
*env
, uint32_t fst0
)
304 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
305 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
306 & (float_flag_invalid
| float_flag_overflow
)) {
307 dt2
= FP_TO_INT64_OVERFLOW
;
309 update_fcr31(env
, GETPC());
313 uint64_t helper_float_cvtps_pw(CPUMIPSState
*env
, uint64_t dt0
)
318 fst2
= int32_to_float32(dt0
& 0XFFFFFFFF, &env
->active_fpu
.fp_status
);
319 fsth2
= int32_to_float32(dt0
>> 32, &env
->active_fpu
.fp_status
);
320 update_fcr31(env
, GETPC());
321 return ((uint64_t)fsth2
<< 32) | fst2
;
324 uint64_t helper_float_cvtpw_ps(CPUMIPSState
*env
, uint64_t fdt0
)
330 wt2
= float32_to_int32(fdt0
& 0XFFFFFFFF, &env
->active_fpu
.fp_status
);
331 excp
= get_float_exception_flags(&env
->active_fpu
.fp_status
);
332 if (excp
& (float_flag_overflow
| float_flag_invalid
)) {
333 wt2
= FP_TO_INT32_OVERFLOW
;
336 set_float_exception_flags(0, &env
->active_fpu
.fp_status
);
337 wth2
= float32_to_int32(fdt0
>> 32, &env
->active_fpu
.fp_status
);
338 excph
= get_float_exception_flags(&env
->active_fpu
.fp_status
);
339 if (excph
& (float_flag_overflow
| float_flag_invalid
)) {
340 wth2
= FP_TO_INT32_OVERFLOW
;
343 set_float_exception_flags(excp
| excph
, &env
->active_fpu
.fp_status
);
344 update_fcr31(env
, GETPC());
346 return ((uint64_t)wth2
<< 32) | wt2
;
349 uint32_t helper_float_cvts_d(CPUMIPSState
*env
, uint64_t fdt0
)
353 fst2
= float64_to_float32(fdt0
, &env
->active_fpu
.fp_status
);
354 update_fcr31(env
, GETPC());
358 uint32_t helper_float_cvts_w(CPUMIPSState
*env
, uint32_t wt0
)
362 fst2
= int32_to_float32(wt0
, &env
->active_fpu
.fp_status
);
363 update_fcr31(env
, GETPC());
367 uint32_t helper_float_cvts_l(CPUMIPSState
*env
, uint64_t dt0
)
371 fst2
= int64_to_float32(dt0
, &env
->active_fpu
.fp_status
);
372 update_fcr31(env
, GETPC());
376 uint32_t helper_float_cvts_pl(CPUMIPSState
*env
, uint32_t wt0
)
381 update_fcr31(env
, GETPC());
385 uint32_t helper_float_cvts_pu(CPUMIPSState
*env
, uint32_t wth0
)
390 update_fcr31(env
, GETPC());
394 uint32_t helper_float_cvt_w_s(CPUMIPSState
*env
, uint32_t fst0
)
398 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
399 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
400 & (float_flag_invalid
| float_flag_overflow
)) {
401 wt2
= FP_TO_INT32_OVERFLOW
;
403 update_fcr31(env
, GETPC());
407 uint32_t helper_float_cvt_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
411 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
412 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
413 & (float_flag_invalid
| float_flag_overflow
)) {
414 wt2
= FP_TO_INT32_OVERFLOW
;
416 update_fcr31(env
, GETPC());
420 uint64_t helper_float_round_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
424 set_float_rounding_mode(float_round_nearest_even
,
425 &env
->active_fpu
.fp_status
);
426 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
427 restore_rounding_mode(env
);
428 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
429 & (float_flag_invalid
| float_flag_overflow
)) {
430 dt2
= FP_TO_INT64_OVERFLOW
;
432 update_fcr31(env
, GETPC());
436 uint64_t helper_float_round_l_s(CPUMIPSState
*env
, uint32_t fst0
)
440 set_float_rounding_mode(float_round_nearest_even
,
441 &env
->active_fpu
.fp_status
);
442 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
443 restore_rounding_mode(env
);
444 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
445 & (float_flag_invalid
| float_flag_overflow
)) {
446 dt2
= FP_TO_INT64_OVERFLOW
;
448 update_fcr31(env
, GETPC());
452 uint32_t helper_float_round_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
456 set_float_rounding_mode(float_round_nearest_even
,
457 &env
->active_fpu
.fp_status
);
458 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
459 restore_rounding_mode(env
);
460 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
461 & (float_flag_invalid
| float_flag_overflow
)) {
462 wt2
= FP_TO_INT32_OVERFLOW
;
464 update_fcr31(env
, GETPC());
468 uint32_t helper_float_round_w_s(CPUMIPSState
*env
, uint32_t fst0
)
472 set_float_rounding_mode(float_round_nearest_even
,
473 &env
->active_fpu
.fp_status
);
474 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
475 restore_rounding_mode(env
);
476 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
477 & (float_flag_invalid
| float_flag_overflow
)) {
478 wt2
= FP_TO_INT32_OVERFLOW
;
480 update_fcr31(env
, GETPC());
484 uint64_t helper_float_trunc_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
488 dt2
= float64_to_int64_round_to_zero(fdt0
,
489 &env
->active_fpu
.fp_status
);
490 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
491 & (float_flag_invalid
| float_flag_overflow
)) {
492 dt2
= FP_TO_INT64_OVERFLOW
;
494 update_fcr31(env
, GETPC());
498 uint64_t helper_float_trunc_l_s(CPUMIPSState
*env
, uint32_t fst0
)
502 dt2
= float32_to_int64_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
503 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
504 & (float_flag_invalid
| float_flag_overflow
)) {
505 dt2
= FP_TO_INT64_OVERFLOW
;
507 update_fcr31(env
, GETPC());
511 uint32_t helper_float_trunc_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
515 wt2
= float64_to_int32_round_to_zero(fdt0
, &env
->active_fpu
.fp_status
);
516 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
517 & (float_flag_invalid
| float_flag_overflow
)) {
518 wt2
= FP_TO_INT32_OVERFLOW
;
520 update_fcr31(env
, GETPC());
524 uint32_t helper_float_trunc_w_s(CPUMIPSState
*env
, uint32_t fst0
)
528 wt2
= float32_to_int32_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
529 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
530 & (float_flag_invalid
| float_flag_overflow
)) {
531 wt2
= FP_TO_INT32_OVERFLOW
;
533 update_fcr31(env
, GETPC());
537 uint64_t helper_float_ceil_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
541 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
542 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
543 restore_rounding_mode(env
);
544 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
545 & (float_flag_invalid
| float_flag_overflow
)) {
546 dt2
= FP_TO_INT64_OVERFLOW
;
548 update_fcr31(env
, GETPC());
552 uint64_t helper_float_ceil_l_s(CPUMIPSState
*env
, uint32_t fst0
)
556 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
557 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
558 restore_rounding_mode(env
);
559 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
560 & (float_flag_invalid
| float_flag_overflow
)) {
561 dt2
= FP_TO_INT64_OVERFLOW
;
563 update_fcr31(env
, GETPC());
567 uint32_t helper_float_ceil_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
571 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
572 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
573 restore_rounding_mode(env
);
574 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
575 & (float_flag_invalid
| float_flag_overflow
)) {
576 wt2
= FP_TO_INT32_OVERFLOW
;
578 update_fcr31(env
, GETPC());
582 uint32_t helper_float_ceil_w_s(CPUMIPSState
*env
, uint32_t fst0
)
586 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
587 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
588 restore_rounding_mode(env
);
589 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
590 & (float_flag_invalid
| float_flag_overflow
)) {
591 wt2
= FP_TO_INT32_OVERFLOW
;
593 update_fcr31(env
, GETPC());
597 uint64_t helper_float_floor_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
601 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
602 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
603 restore_rounding_mode(env
);
604 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
605 & (float_flag_invalid
| float_flag_overflow
)) {
606 dt2
= FP_TO_INT64_OVERFLOW
;
608 update_fcr31(env
, GETPC());
612 uint64_t helper_float_floor_l_s(CPUMIPSState
*env
, uint32_t fst0
)
616 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
617 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
618 restore_rounding_mode(env
);
619 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
620 & (float_flag_invalid
| float_flag_overflow
)) {
621 dt2
= FP_TO_INT64_OVERFLOW
;
623 update_fcr31(env
, GETPC());
627 uint32_t helper_float_floor_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
631 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
632 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
633 restore_rounding_mode(env
);
634 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
635 & (float_flag_invalid
| float_flag_overflow
)) {
636 wt2
= FP_TO_INT32_OVERFLOW
;
638 update_fcr31(env
, GETPC());
642 uint32_t helper_float_floor_w_s(CPUMIPSState
*env
, uint32_t fst0
)
646 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
647 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
648 restore_rounding_mode(env
);
649 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
650 & (float_flag_invalid
| float_flag_overflow
)) {
651 wt2
= FP_TO_INT32_OVERFLOW
;
653 update_fcr31(env
, GETPC());
657 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
661 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
662 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
663 & float_flag_invalid
) {
664 if (float64_is_any_nan(fdt0
)) {
668 update_fcr31(env
, GETPC());
672 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
676 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
677 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
678 & float_flag_invalid
) {
679 if (float32_is_any_nan(fst0
)) {
683 update_fcr31(env
, GETPC());
687 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
691 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
692 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
693 & float_flag_invalid
) {
694 if (float64_is_any_nan(fdt0
)) {
698 update_fcr31(env
, GETPC());
702 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
706 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
707 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
708 & float_flag_invalid
) {
709 if (float32_is_any_nan(fst0
)) {
713 update_fcr31(env
, GETPC());
717 uint64_t helper_float_round_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
721 set_float_rounding_mode(float_round_nearest_even
,
722 &env
->active_fpu
.fp_status
);
723 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
724 restore_rounding_mode(env
);
725 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
726 & float_flag_invalid
) {
727 if (float64_is_any_nan(fdt0
)) {
731 update_fcr31(env
, GETPC());
735 uint64_t helper_float_round_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
739 set_float_rounding_mode(float_round_nearest_even
,
740 &env
->active_fpu
.fp_status
);
741 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
742 restore_rounding_mode(env
);
743 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
744 & float_flag_invalid
) {
745 if (float32_is_any_nan(fst0
)) {
749 update_fcr31(env
, GETPC());
753 uint32_t helper_float_round_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
757 set_float_rounding_mode(float_round_nearest_even
,
758 &env
->active_fpu
.fp_status
);
759 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
760 restore_rounding_mode(env
);
761 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
762 & float_flag_invalid
) {
763 if (float64_is_any_nan(fdt0
)) {
767 update_fcr31(env
, GETPC());
771 uint32_t helper_float_round_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
775 set_float_rounding_mode(float_round_nearest_even
,
776 &env
->active_fpu
.fp_status
);
777 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
778 restore_rounding_mode(env
);
779 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
780 & float_flag_invalid
) {
781 if (float32_is_any_nan(fst0
)) {
785 update_fcr31(env
, GETPC());
789 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
793 dt2
= float64_to_int64_round_to_zero(fdt0
, &env
->active_fpu
.fp_status
);
794 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
795 & float_flag_invalid
) {
796 if (float64_is_any_nan(fdt0
)) {
800 update_fcr31(env
, GETPC());
804 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
808 dt2
= float32_to_int64_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
809 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
810 & float_flag_invalid
) {
811 if (float32_is_any_nan(fst0
)) {
815 update_fcr31(env
, GETPC());
819 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
823 wt2
= float64_to_int32_round_to_zero(fdt0
, &env
->active_fpu
.fp_status
);
824 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
825 & float_flag_invalid
) {
826 if (float64_is_any_nan(fdt0
)) {
830 update_fcr31(env
, GETPC());
834 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
838 wt2
= float32_to_int32_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
839 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
840 & float_flag_invalid
) {
841 if (float32_is_any_nan(fst0
)) {
845 update_fcr31(env
, GETPC());
849 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
853 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
854 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
855 restore_rounding_mode(env
);
856 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
857 & float_flag_invalid
) {
858 if (float64_is_any_nan(fdt0
)) {
862 update_fcr31(env
, GETPC());
866 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
870 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
871 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
872 restore_rounding_mode(env
);
873 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
874 & float_flag_invalid
) {
875 if (float32_is_any_nan(fst0
)) {
879 update_fcr31(env
, GETPC());
883 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
887 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
888 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
889 restore_rounding_mode(env
);
890 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
891 & float_flag_invalid
) {
892 if (float64_is_any_nan(fdt0
)) {
896 update_fcr31(env
, GETPC());
900 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
904 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
905 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
906 restore_rounding_mode(env
);
907 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
908 & float_flag_invalid
) {
909 if (float32_is_any_nan(fst0
)) {
913 update_fcr31(env
, GETPC());
917 uint64_t helper_float_floor_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
921 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
922 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
923 restore_rounding_mode(env
);
924 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
925 & float_flag_invalid
) {
926 if (float64_is_any_nan(fdt0
)) {
930 update_fcr31(env
, GETPC());
934 uint64_t helper_float_floor_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
938 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
939 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
940 restore_rounding_mode(env
);
941 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
942 & float_flag_invalid
) {
943 if (float32_is_any_nan(fst0
)) {
947 update_fcr31(env
, GETPC());
951 uint32_t helper_float_floor_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
955 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
956 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
957 restore_rounding_mode(env
);
958 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
959 & float_flag_invalid
) {
960 if (float64_is_any_nan(fdt0
)) {
964 update_fcr31(env
, GETPC());
968 uint32_t helper_float_floor_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
972 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
973 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
974 restore_rounding_mode(env
);
975 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
976 & float_flag_invalid
) {
977 if (float32_is_any_nan(fst0
)) {
981 update_fcr31(env
, GETPC());
985 /* unary operations, not modifying fp status */
986 #define FLOAT_UNOP(name) \
987 uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \
989 return float64_ ## name(fdt0); \
991 uint32_t helper_float_ ## name ## _s(uint32_t fst0) \
993 return float32_ ## name(fst0); \
995 uint64_t helper_float_ ## name ## _ps(uint64_t fdt0) \
1000 wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF); \
1001 wth0 = float32_ ## name(fdt0 >> 32); \
1002 return ((uint64_t)wth0 << 32) | wt0; \
1008 /* MIPS specific unary operations */
1009 uint64_t helper_float_recip_d(CPUMIPSState
*env
, uint64_t fdt0
)
1013 fdt2
= float64_div(float64_one
, fdt0
, &env
->active_fpu
.fp_status
);
1014 update_fcr31(env
, GETPC());
1018 uint32_t helper_float_recip_s(CPUMIPSState
*env
, uint32_t fst0
)
1022 fst2
= float32_div(float32_one
, fst0
, &env
->active_fpu
.fp_status
);
1023 update_fcr31(env
, GETPC());
1027 uint64_t helper_float_rsqrt_d(CPUMIPSState
*env
, uint64_t fdt0
)
1031 fdt2
= float64_sqrt(fdt0
, &env
->active_fpu
.fp_status
);
1032 fdt2
= float64_div(float64_one
, fdt2
, &env
->active_fpu
.fp_status
);
1033 update_fcr31(env
, GETPC());
1037 uint32_t helper_float_rsqrt_s(CPUMIPSState
*env
, uint32_t fst0
)
1041 fst2
= float32_sqrt(fst0
, &env
->active_fpu
.fp_status
);
1042 fst2
= float32_div(float32_one
, fst2
, &env
->active_fpu
.fp_status
);
1043 update_fcr31(env
, GETPC());
1047 uint64_t helper_float_recip1_d(CPUMIPSState
*env
, uint64_t fdt0
)
1051 fdt2
= float64_div(float64_one
, fdt0
, &env
->active_fpu
.fp_status
);
1052 update_fcr31(env
, GETPC());
1056 uint32_t helper_float_recip1_s(CPUMIPSState
*env
, uint32_t fst0
)
1060 fst2
= float32_div(float32_one
, fst0
, &env
->active_fpu
.fp_status
);
1061 update_fcr31(env
, GETPC());
1065 uint64_t helper_float_recip1_ps(CPUMIPSState
*env
, uint64_t fdt0
)
1070 fstl2
= float32_div(float32_one
, fdt0
& 0XFFFFFFFF,
1071 &env
->active_fpu
.fp_status
);
1072 fsth2
= float32_div(float32_one
, fdt0
>> 32, &env
->active_fpu
.fp_status
);
1073 update_fcr31(env
, GETPC());
1074 return ((uint64_t)fsth2
<< 32) | fstl2
;
1077 uint64_t helper_float_rsqrt1_d(CPUMIPSState
*env
, uint64_t fdt0
)
1081 fdt2
= float64_sqrt(fdt0
, &env
->active_fpu
.fp_status
);
1082 fdt2
= float64_div(float64_one
, fdt2
, &env
->active_fpu
.fp_status
);
1083 update_fcr31(env
, GETPC());
1087 uint32_t helper_float_rsqrt1_s(CPUMIPSState
*env
, uint32_t fst0
)
1091 fst2
= float32_sqrt(fst0
, &env
->active_fpu
.fp_status
);
1092 fst2
= float32_div(float32_one
, fst2
, &env
->active_fpu
.fp_status
);
1093 update_fcr31(env
, GETPC());
1097 uint64_t helper_float_rsqrt1_ps(CPUMIPSState
*env
, uint64_t fdt0
)
1102 fstl2
= float32_sqrt(fdt0
& 0XFFFFFFFF, &env
->active_fpu
.fp_status
);
1103 fsth2
= float32_sqrt(fdt0
>> 32, &env
->active_fpu
.fp_status
);
1104 fstl2
= float32_div(float32_one
, fstl2
, &env
->active_fpu
.fp_status
);
1105 fsth2
= float32_div(float32_one
, fsth2
, &env
->active_fpu
.fp_status
);
1106 update_fcr31(env
, GETPC());
1107 return ((uint64_t)fsth2
<< 32) | fstl2
;
1110 uint64_t helper_float_rint_d(CPUMIPSState
*env
, uint64_t fs
)
1114 fdret
= float64_round_to_int(fs
, &env
->active_fpu
.fp_status
);
1115 update_fcr31(env
, GETPC());
1119 uint32_t helper_float_rint_s(CPUMIPSState
*env
, uint32_t fs
)
1123 fdret
= float32_round_to_int(fs
, &env
->active_fpu
.fp_status
);
1124 update_fcr31(env
, GETPC());
1128 #define FLOAT_CLASS_SIGNALING_NAN 0x001
1129 #define FLOAT_CLASS_QUIET_NAN 0x002
1130 #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
1131 #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
1132 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1133 #define FLOAT_CLASS_NEGATIVE_ZERO 0x020
1134 #define FLOAT_CLASS_POSITIVE_INFINITY 0x040
1135 #define FLOAT_CLASS_POSITIVE_NORMAL 0x080
1136 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1137 #define FLOAT_CLASS_POSITIVE_ZERO 0x200
1139 uint64_t float_class_d(uint64_t arg
, float_status
*status
)
1141 if (float64_is_signaling_nan(arg
, status
)) {
1142 return FLOAT_CLASS_SIGNALING_NAN
;
1143 } else if (float64_is_quiet_nan(arg
, status
)) {
1144 return FLOAT_CLASS_QUIET_NAN
;
1145 } else if (float64_is_neg(arg
)) {
1146 if (float64_is_infinity(arg
)) {
1147 return FLOAT_CLASS_NEGATIVE_INFINITY
;
1148 } else if (float64_is_zero(arg
)) {
1149 return FLOAT_CLASS_NEGATIVE_ZERO
;
1150 } else if (float64_is_zero_or_denormal(arg
)) {
1151 return FLOAT_CLASS_NEGATIVE_SUBNORMAL
;
1153 return FLOAT_CLASS_NEGATIVE_NORMAL
;
1156 if (float64_is_infinity(arg
)) {
1157 return FLOAT_CLASS_POSITIVE_INFINITY
;
1158 } else if (float64_is_zero(arg
)) {
1159 return FLOAT_CLASS_POSITIVE_ZERO
;
1160 } else if (float64_is_zero_or_denormal(arg
)) {
1161 return FLOAT_CLASS_POSITIVE_SUBNORMAL
;
1163 return FLOAT_CLASS_POSITIVE_NORMAL
;
1168 uint64_t helper_float_class_d(CPUMIPSState
*env
, uint64_t arg
)
1170 return float_class_d(arg
, &env
->active_fpu
.fp_status
);
1173 uint32_t float_class_s(uint32_t arg
, float_status
*status
)
1175 if (float32_is_signaling_nan(arg
, status
)) {
1176 return FLOAT_CLASS_SIGNALING_NAN
;
1177 } else if (float32_is_quiet_nan(arg
, status
)) {
1178 return FLOAT_CLASS_QUIET_NAN
;
1179 } else if (float32_is_neg(arg
)) {
1180 if (float32_is_infinity(arg
)) {
1181 return FLOAT_CLASS_NEGATIVE_INFINITY
;
1182 } else if (float32_is_zero(arg
)) {
1183 return FLOAT_CLASS_NEGATIVE_ZERO
;
1184 } else if (float32_is_zero_or_denormal(arg
)) {
1185 return FLOAT_CLASS_NEGATIVE_SUBNORMAL
;
1187 return FLOAT_CLASS_NEGATIVE_NORMAL
;
1190 if (float32_is_infinity(arg
)) {
1191 return FLOAT_CLASS_POSITIVE_INFINITY
;
1192 } else if (float32_is_zero(arg
)) {
1193 return FLOAT_CLASS_POSITIVE_ZERO
;
1194 } else if (float32_is_zero_or_denormal(arg
)) {
1195 return FLOAT_CLASS_POSITIVE_SUBNORMAL
;
1197 return FLOAT_CLASS_POSITIVE_NORMAL
;
1202 uint32_t helper_float_class_s(CPUMIPSState
*env
, uint32_t arg
)
1204 return float_class_s(arg
, &env
->active_fpu
.fp_status
);
1207 /* binary operations */
1209 uint64_t helper_float_add_d(CPUMIPSState
*env
,
1210 uint64_t fdt0
, uint64_t fdt1
)
1214 dt2
= float64_add(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1215 update_fcr31(env
, GETPC());
1219 uint32_t helper_float_add_s(CPUMIPSState
*env
,
1220 uint32_t fst0
, uint32_t fst1
)
1224 wt2
= float32_sub(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1225 update_fcr31(env
, GETPC());
1229 uint64_t helper_float_add_ps(CPUMIPSState
*env
,
1230 uint64_t fdt0
, uint64_t fdt1
)
1232 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1233 uint32_t fsth0
= fdt0
>> 32;
1234 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1235 uint32_t fsth1
= fdt1
>> 32;
1239 wtl2
= float32_add(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1240 wth2
= float32_add(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1241 update_fcr31(env
, GETPC());
1242 return ((uint64_t)wth2
<< 32) | wtl2
;
1245 uint64_t helper_float_sub_d(CPUMIPSState
*env
,
1246 uint64_t fdt0
, uint64_t fdt1
)
1250 dt2
= float64_sub(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1251 update_fcr31(env
, GETPC());
1255 uint32_t helper_float_sub_s(CPUMIPSState
*env
,
1256 uint32_t fst0
, uint32_t fst1
)
1260 wt2
= float32_sub(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1261 update_fcr31(env
, GETPC());
1265 uint64_t helper_float_sub_ps(CPUMIPSState
*env
,
1266 uint64_t fdt0
, uint64_t fdt1
)
1268 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1269 uint32_t fsth0
= fdt0
>> 32;
1270 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1271 uint32_t fsth1
= fdt1
>> 32;
1275 wtl2
= float32_sub(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1276 wth2
= float32_sub(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1277 update_fcr31(env
, GETPC());
1278 return ((uint64_t)wth2
<< 32) | wtl2
;
1281 uint64_t helper_float_mul_d(CPUMIPSState
*env
,
1282 uint64_t fdt0
, uint64_t fdt1
)
1286 dt2
= float64_mul(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1287 update_fcr31(env
, GETPC());
1291 uint32_t helper_float_mul_s(CPUMIPSState
*env
,
1292 uint32_t fst0
, uint32_t fst1
)
1296 wt2
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1297 update_fcr31(env
, GETPC());
1301 uint64_t helper_float_mul_ps(CPUMIPSState
*env
,
1302 uint64_t fdt0
, uint64_t fdt1
)
1304 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1305 uint32_t fsth0
= fdt0
>> 32;
1306 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1307 uint32_t fsth1
= fdt1
>> 32;
1311 wtl2
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1312 wth2
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1313 update_fcr31(env
, GETPC());
1314 return ((uint64_t)wth2
<< 32) | wtl2
;
1317 uint64_t helper_float_div_d(CPUMIPSState
*env
,
1318 uint64_t fdt0
, uint64_t fdt1
)
1322 dt2
= float64_div(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1323 update_fcr31(env
, GETPC());
1327 uint32_t helper_float_div_s(CPUMIPSState
*env
,
1328 uint32_t fst0
, uint32_t fst1
)
1332 wt2
= float32_div(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1333 update_fcr31(env
, GETPC());
1337 uint64_t helper_float_div_ps(CPUMIPSState
*env
,
1338 uint64_t fdt0
, uint64_t fdt1
)
1340 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1341 uint32_t fsth0
= fdt0
>> 32;
1342 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1343 uint32_t fsth1
= fdt1
>> 32;
1347 wtl2
= float32_div(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1348 wth2
= float32_div(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1349 update_fcr31(env
, GETPC());
1350 return ((uint64_t)wth2
<< 32) | wtl2
;
1354 /* MIPS specific binary operations */
1355 uint64_t helper_float_recip2_d(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1357 fdt2
= float64_mul(fdt0
, fdt2
, &env
->active_fpu
.fp_status
);
1358 fdt2
= float64_chs(float64_sub(fdt2
, float64_one
,
1359 &env
->active_fpu
.fp_status
));
1360 update_fcr31(env
, GETPC());
1364 uint32_t helper_float_recip2_s(CPUMIPSState
*env
, uint32_t fst0
, uint32_t fst2
)
1366 fst2
= float32_mul(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1367 fst2
= float32_chs(float32_sub(fst2
, float32_one
,
1368 &env
->active_fpu
.fp_status
));
1369 update_fcr31(env
, GETPC());
1373 uint64_t helper_float_recip2_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1375 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1376 uint32_t fsth0
= fdt0
>> 32;
1377 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1378 uint32_t fsth2
= fdt2
>> 32;
1380 fstl2
= float32_mul(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1381 fsth2
= float32_mul(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1382 fstl2
= float32_chs(float32_sub(fstl2
, float32_one
,
1383 &env
->active_fpu
.fp_status
));
1384 fsth2
= float32_chs(float32_sub(fsth2
, float32_one
,
1385 &env
->active_fpu
.fp_status
));
1386 update_fcr31(env
, GETPC());
1387 return ((uint64_t)fsth2
<< 32) | fstl2
;
1390 uint64_t helper_float_rsqrt2_d(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1392 fdt2
= float64_mul(fdt0
, fdt2
, &env
->active_fpu
.fp_status
);
1393 fdt2
= float64_sub(fdt2
, float64_one
, &env
->active_fpu
.fp_status
);
1394 fdt2
= float64_chs(float64_div(fdt2
, FLOAT_TWO64
,
1395 &env
->active_fpu
.fp_status
));
1396 update_fcr31(env
, GETPC());
1400 uint32_t helper_float_rsqrt2_s(CPUMIPSState
*env
, uint32_t fst0
, uint32_t fst2
)
1402 fst2
= float32_mul(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1403 fst2
= float32_sub(fst2
, float32_one
, &env
->active_fpu
.fp_status
);
1404 fst2
= float32_chs(float32_div(fst2
, FLOAT_TWO32
,
1405 &env
->active_fpu
.fp_status
));
1406 update_fcr31(env
, GETPC());
1410 uint64_t helper_float_rsqrt2_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1412 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1413 uint32_t fsth0
= fdt0
>> 32;
1414 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1415 uint32_t fsth2
= fdt2
>> 32;
1417 fstl2
= float32_mul(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1418 fsth2
= float32_mul(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1419 fstl2
= float32_sub(fstl2
, float32_one
, &env
->active_fpu
.fp_status
);
1420 fsth2
= float32_sub(fsth2
, float32_one
, &env
->active_fpu
.fp_status
);
1421 fstl2
= float32_chs(float32_div(fstl2
, FLOAT_TWO32
,
1422 &env
->active_fpu
.fp_status
));
1423 fsth2
= float32_chs(float32_div(fsth2
, FLOAT_TWO32
,
1424 &env
->active_fpu
.fp_status
));
1425 update_fcr31(env
, GETPC());
1426 return ((uint64_t)fsth2
<< 32) | fstl2
;
1429 uint64_t helper_float_addr_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt1
)
1431 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1432 uint32_t fsth0
= fdt0
>> 32;
1433 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1434 uint32_t fsth1
= fdt1
>> 32;
1438 fstl2
= float32_add(fstl0
, fsth0
, &env
->active_fpu
.fp_status
);
1439 fsth2
= float32_add(fstl1
, fsth1
, &env
->active_fpu
.fp_status
);
1440 update_fcr31(env
, GETPC());
1441 return ((uint64_t)fsth2
<< 32) | fstl2
;
1444 uint64_t helper_float_mulr_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt1
)
1446 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1447 uint32_t fsth0
= fdt0
>> 32;
1448 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1449 uint32_t fsth1
= fdt1
>> 32;
1453 fstl2
= float32_mul(fstl0
, fsth0
, &env
->active_fpu
.fp_status
);
1454 fsth2
= float32_mul(fstl1
, fsth1
, &env
->active_fpu
.fp_status
);
1455 update_fcr31(env
, GETPC());
1456 return ((uint64_t)fsth2
<< 32) | fstl2
;
1459 #define FLOAT_MINMAX(name, bits, minmaxfunc) \
1460 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
1461 uint ## bits ## _t fs, \
1462 uint ## bits ## _t ft) \
1464 uint ## bits ## _t fdret; \
1466 fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \
1467 &env->active_fpu.fp_status); \
1468 update_fcr31(env, GETPC()); \
1472 FLOAT_MINMAX(max_s
, 32, maxnum
)
1473 FLOAT_MINMAX(max_d
, 64, maxnum
)
1474 FLOAT_MINMAX(maxa_s
, 32, maxnummag
)
1475 FLOAT_MINMAX(maxa_d
, 64, maxnummag
)
1477 FLOAT_MINMAX(min_s
, 32, minnum
)
1478 FLOAT_MINMAX(min_d
, 64, minnum
)
1479 FLOAT_MINMAX(mina_s
, 32, minnummag
)
1480 FLOAT_MINMAX(mina_d
, 64, minnummag
)
1483 /* ternary operations */
1485 uint64_t helper_float_madd_d(CPUMIPSState
*env
, uint64_t fst0
,
1486 uint64_t fst1
, uint64_t fst2
)
1488 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1489 fst0
= float64_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1491 update_fcr31(env
, GETPC());
1495 uint32_t helper_float_madd_s(CPUMIPSState
*env
, uint32_t fst0
,
1496 uint32_t fst1
, uint32_t fst2
)
1498 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1499 fst0
= float32_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1501 update_fcr31(env
, GETPC());
1505 uint64_t helper_float_madd_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1506 uint64_t fdt1
, uint64_t fdt2
)
1508 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1509 uint32_t fsth0
= fdt0
>> 32;
1510 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1511 uint32_t fsth1
= fdt1
>> 32;
1512 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1513 uint32_t fsth2
= fdt2
>> 32;
1515 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1516 fstl0
= float32_add(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1517 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1518 fsth0
= float32_add(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1520 update_fcr31(env
, GETPC());
1521 return ((uint64_t)fsth0
<< 32) | fstl0
;
1524 uint64_t helper_float_msub_d(CPUMIPSState
*env
, uint64_t fst0
,
1525 uint64_t fst1
, uint64_t fst2
)
1527 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1528 fst0
= float64_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1530 update_fcr31(env
, GETPC());
1534 uint32_t helper_float_msub_s(CPUMIPSState
*env
, uint32_t fst0
,
1535 uint32_t fst1
, uint32_t fst2
)
1537 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1538 fst0
= float32_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1540 update_fcr31(env
, GETPC());
1544 uint64_t helper_float_msub_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1545 uint64_t fdt1
, uint64_t fdt2
)
1547 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1548 uint32_t fsth0
= fdt0
>> 32;
1549 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1550 uint32_t fsth1
= fdt1
>> 32;
1551 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1552 uint32_t fsth2
= fdt2
>> 32;
1554 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1555 fstl0
= float32_sub(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1556 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1557 fsth0
= float32_sub(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1559 update_fcr31(env
, GETPC());
1560 return ((uint64_t)fsth0
<< 32) | fstl0
;
1563 uint64_t helper_float_nmadd_d(CPUMIPSState
*env
, uint64_t fst0
,
1564 uint64_t fst1
, uint64_t fst2
)
1566 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1567 fst0
= float64_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1568 fst0
= float64_chs(fst0
);
1570 update_fcr31(env
, GETPC());
1574 uint32_t helper_float_nmadd_s(CPUMIPSState
*env
, uint32_t fst0
,
1575 uint32_t fst1
, uint32_t fst2
)
1577 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1578 fst0
= float32_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1579 fst0
= float32_chs(fst0
);
1581 update_fcr31(env
, GETPC());
1585 uint64_t helper_float_nmadd_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1586 uint64_t fdt1
, uint64_t fdt2
)
1588 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1589 uint32_t fsth0
= fdt0
>> 32;
1590 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1591 uint32_t fsth1
= fdt1
>> 32;
1592 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1593 uint32_t fsth2
= fdt2
>> 32;
1595 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1596 fstl0
= float32_add(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1597 fstl0
= float32_chs(fstl0
);
1598 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1599 fsth0
= float32_add(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1600 fsth0
= float32_chs(fsth0
);
1602 update_fcr31(env
, GETPC());
1603 return ((uint64_t)fsth0
<< 32) | fstl0
;
1606 uint64_t helper_float_nmsub_d(CPUMIPSState
*env
, uint64_t fst0
,
1607 uint64_t fst1
, uint64_t fst2
)
1609 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1610 fst0
= float64_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1611 fst0
= float64_chs(fst0
);
1613 update_fcr31(env
, GETPC());
1617 uint32_t helper_float_nmsub_s(CPUMIPSState
*env
, uint32_t fst0
,
1618 uint32_t fst1
, uint32_t fst2
)
1620 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1621 fst0
= float32_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1622 fst0
= float32_chs(fst0
);
1624 update_fcr31(env
, GETPC());
1628 uint64_t helper_float_nmsub_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1629 uint64_t fdt1
, uint64_t fdt2
)
1631 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1632 uint32_t fsth0
= fdt0
>> 32;
1633 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1634 uint32_t fsth1
= fdt1
>> 32;
1635 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1636 uint32_t fsth2
= fdt2
>> 32;
1638 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1639 fstl0
= float32_sub(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1640 fstl0
= float32_chs(fstl0
);
1641 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1642 fsth0
= float32_sub(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1643 fsth0
= float32_chs(fsth0
);
1645 update_fcr31(env
, GETPC());
1646 return ((uint64_t)fsth0
<< 32) | fstl0
;
1650 #define FLOAT_FMADDSUB(name, bits, muladd_arg) \
1651 uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \
1652 uint ## bits ## _t fs, \
1653 uint ## bits ## _t ft, \
1654 uint ## bits ## _t fd) \
1656 uint ## bits ## _t fdret; \
1658 fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \
1659 &env->active_fpu.fp_status); \
1660 update_fcr31(env, GETPC()); \
1664 FLOAT_FMADDSUB(maddf_s
, 32, 0)
1665 FLOAT_FMADDSUB(maddf_d
, 64, 0)
1666 FLOAT_FMADDSUB(msubf_s
, 32, float_muladd_negate_product
)
1667 FLOAT_FMADDSUB(msubf_d
, 64, float_muladd_negate_product
)
1668 #undef FLOAT_FMADDSUB
1670 /* compare operations */
1671 #define FOP_COND_D(op, cond) \
1672 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1673 uint64_t fdt1, int cc) \
1677 update_fcr31(env, GETPC()); \
1679 SET_FP_COND(cc, env->active_fpu); \
1681 CLEAR_FP_COND(cc, env->active_fpu); \
1683 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1684 uint64_t fdt1, int cc) \
1687 fdt0 = float64_abs(fdt0); \
1688 fdt1 = float64_abs(fdt1); \
1690 update_fcr31(env, GETPC()); \
1692 SET_FP_COND(cc, env->active_fpu); \
1694 CLEAR_FP_COND(cc, env->active_fpu); \
1698 * NOTE: the comma operator will make "cond" to eval to false,
1699 * but float64_unordered_quiet() is still called.
1701 FOP_COND_D(f
, (float64_unordered_quiet(fdt1
, fdt0
,
1702 &env
->active_fpu
.fp_status
), 0))
1703 FOP_COND_D(un
, float64_unordered_quiet(fdt1
, fdt0
,
1704 &env
->active_fpu
.fp_status
))
1705 FOP_COND_D(eq
, float64_eq_quiet(fdt0
, fdt1
,
1706 &env
->active_fpu
.fp_status
))
1707 FOP_COND_D(ueq
, float64_unordered_quiet(fdt1
, fdt0
,
1708 &env
->active_fpu
.fp_status
)
1709 || float64_eq_quiet(fdt0
, fdt1
,
1710 &env
->active_fpu
.fp_status
))
1711 FOP_COND_D(olt
, float64_lt_quiet(fdt0
, fdt1
,
1712 &env
->active_fpu
.fp_status
))
1713 FOP_COND_D(ult
, float64_unordered_quiet(fdt1
, fdt0
,
1714 &env
->active_fpu
.fp_status
)
1715 || float64_lt_quiet(fdt0
, fdt1
,
1716 &env
->active_fpu
.fp_status
))
1717 FOP_COND_D(ole
, float64_le_quiet(fdt0
, fdt1
,
1718 &env
->active_fpu
.fp_status
))
1719 FOP_COND_D(ule
, float64_unordered_quiet(fdt1
, fdt0
,
1720 &env
->active_fpu
.fp_status
)
1721 || float64_le_quiet(fdt0
, fdt1
,
1722 &env
->active_fpu
.fp_status
))
1724 * NOTE: the comma operator will make "cond" to eval to false,
1725 * but float64_unordered() is still called.
1727 FOP_COND_D(sf
, (float64_unordered(fdt1
, fdt0
,
1728 &env
->active_fpu
.fp_status
), 0))
1729 FOP_COND_D(ngle
, float64_unordered(fdt1
, fdt0
,
1730 &env
->active_fpu
.fp_status
))
1731 FOP_COND_D(seq
, float64_eq(fdt0
, fdt1
,
1732 &env
->active_fpu
.fp_status
))
1733 FOP_COND_D(ngl
, float64_unordered(fdt1
, fdt0
,
1734 &env
->active_fpu
.fp_status
)
1735 || float64_eq(fdt0
, fdt1
,
1736 &env
->active_fpu
.fp_status
))
1737 FOP_COND_D(lt
, float64_lt(fdt0
, fdt1
,
1738 &env
->active_fpu
.fp_status
))
1739 FOP_COND_D(nge
, float64_unordered(fdt1
, fdt0
,
1740 &env
->active_fpu
.fp_status
)
1741 || float64_lt(fdt0
, fdt1
,
1742 &env
->active_fpu
.fp_status
))
1743 FOP_COND_D(le
, float64_le(fdt0
, fdt1
,
1744 &env
->active_fpu
.fp_status
))
1745 FOP_COND_D(ngt
, float64_unordered(fdt1
, fdt0
,
1746 &env
->active_fpu
.fp_status
)
1747 || float64_le(fdt0
, fdt1
,
1748 &env
->active_fpu
.fp_status
))
1750 #define FOP_COND_S(op, cond) \
1751 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1752 uint32_t fst1, int cc) \
1756 update_fcr31(env, GETPC()); \
1758 SET_FP_COND(cc, env->active_fpu); \
1760 CLEAR_FP_COND(cc, env->active_fpu); \
1762 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1763 uint32_t fst1, int cc) \
1766 fst0 = float32_abs(fst0); \
1767 fst1 = float32_abs(fst1); \
1769 update_fcr31(env, GETPC()); \
1771 SET_FP_COND(cc, env->active_fpu); \
1773 CLEAR_FP_COND(cc, env->active_fpu); \
1777 * NOTE: the comma operator will make "cond" to eval to false,
1778 * but float32_unordered_quiet() is still called.
1780 FOP_COND_S(f
, (float32_unordered_quiet(fst1
, fst0
,
1781 &env
->active_fpu
.fp_status
), 0))
1782 FOP_COND_S(un
, float32_unordered_quiet(fst1
, fst0
,
1783 &env
->active_fpu
.fp_status
))
1784 FOP_COND_S(eq
, float32_eq_quiet(fst0
, fst1
,
1785 &env
->active_fpu
.fp_status
))
1786 FOP_COND_S(ueq
, float32_unordered_quiet(fst1
, fst0
,
1787 &env
->active_fpu
.fp_status
)
1788 || float32_eq_quiet(fst0
, fst1
,
1789 &env
->active_fpu
.fp_status
))
1790 FOP_COND_S(olt
, float32_lt_quiet(fst0
, fst1
,
1791 &env
->active_fpu
.fp_status
))
1792 FOP_COND_S(ult
, float32_unordered_quiet(fst1
, fst0
,
1793 &env
->active_fpu
.fp_status
)
1794 || float32_lt_quiet(fst0
, fst1
,
1795 &env
->active_fpu
.fp_status
))
1796 FOP_COND_S(ole
, float32_le_quiet(fst0
, fst1
,
1797 &env
->active_fpu
.fp_status
))
1798 FOP_COND_S(ule
, float32_unordered_quiet(fst1
, fst0
,
1799 &env
->active_fpu
.fp_status
)
1800 || float32_le_quiet(fst0
, fst1
,
1801 &env
->active_fpu
.fp_status
))
1803 * NOTE: the comma operator will make "cond" to eval to false,
1804 * but float32_unordered() is still called.
1806 FOP_COND_S(sf
, (float32_unordered(fst1
, fst0
,
1807 &env
->active_fpu
.fp_status
), 0))
1808 FOP_COND_S(ngle
, float32_unordered(fst1
, fst0
,
1809 &env
->active_fpu
.fp_status
))
1810 FOP_COND_S(seq
, float32_eq(fst0
, fst1
,
1811 &env
->active_fpu
.fp_status
))
1812 FOP_COND_S(ngl
, float32_unordered(fst1
, fst0
,
1813 &env
->active_fpu
.fp_status
)
1814 || float32_eq(fst0
, fst1
,
1815 &env
->active_fpu
.fp_status
))
1816 FOP_COND_S(lt
, float32_lt(fst0
, fst1
,
1817 &env
->active_fpu
.fp_status
))
1818 FOP_COND_S(nge
, float32_unordered(fst1
, fst0
,
1819 &env
->active_fpu
.fp_status
)
1820 || float32_lt(fst0
, fst1
,
1821 &env
->active_fpu
.fp_status
))
1822 FOP_COND_S(le
, float32_le(fst0
, fst1
,
1823 &env
->active_fpu
.fp_status
))
1824 FOP_COND_S(ngt
, float32_unordered(fst1
, fst0
,
1825 &env
->active_fpu
.fp_status
)
1826 || float32_le(fst0
, fst1
,
1827 &env
->active_fpu
.fp_status
))
1829 #define FOP_COND_PS(op, condl, condh) \
1830 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1831 uint64_t fdt1, int cc) \
1833 uint32_t fst0, fsth0, fst1, fsth1; \
1835 fst0 = fdt0 & 0XFFFFFFFF; \
1836 fsth0 = fdt0 >> 32; \
1837 fst1 = fdt1 & 0XFFFFFFFF; \
1838 fsth1 = fdt1 >> 32; \
1841 update_fcr31(env, GETPC()); \
1843 SET_FP_COND(cc, env->active_fpu); \
1845 CLEAR_FP_COND(cc, env->active_fpu); \
1847 SET_FP_COND(cc + 1, env->active_fpu); \
1849 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1851 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1852 uint64_t fdt1, int cc) \
1854 uint32_t fst0, fsth0, fst1, fsth1; \
1856 fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
1857 fsth0 = float32_abs(fdt0 >> 32); \
1858 fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
1859 fsth1 = float32_abs(fdt1 >> 32); \
1862 update_fcr31(env, GETPC()); \
1864 SET_FP_COND(cc, env->active_fpu); \
1866 CLEAR_FP_COND(cc, env->active_fpu); \
1868 SET_FP_COND(cc + 1, env->active_fpu); \
1870 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1874 * NOTE: the comma operator will make "cond" to eval to false,
1875 * but float32_unordered_quiet() is still called.
1877 FOP_COND_PS(f
, (float32_unordered_quiet(fst1
, fst0
,
1878 &env
->active_fpu
.fp_status
), 0),
1879 (float32_unordered_quiet(fsth1
, fsth0
,
1880 &env
->active_fpu
.fp_status
), 0))
1881 FOP_COND_PS(un
, float32_unordered_quiet(fst1
, fst0
,
1882 &env
->active_fpu
.fp_status
),
1883 float32_unordered_quiet(fsth1
, fsth0
,
1884 &env
->active_fpu
.fp_status
))
1885 FOP_COND_PS(eq
, float32_eq_quiet(fst0
, fst1
,
1886 &env
->active_fpu
.fp_status
),
1887 float32_eq_quiet(fsth0
, fsth1
,
1888 &env
->active_fpu
.fp_status
))
1889 FOP_COND_PS(ueq
, float32_unordered_quiet(fst1
, fst0
,
1890 &env
->active_fpu
.fp_status
)
1891 || float32_eq_quiet(fst0
, fst1
,
1892 &env
->active_fpu
.fp_status
),
1893 float32_unordered_quiet(fsth1
, fsth0
,
1894 &env
->active_fpu
.fp_status
)
1895 || float32_eq_quiet(fsth0
, fsth1
,
1896 &env
->active_fpu
.fp_status
))
1897 FOP_COND_PS(olt
, float32_lt_quiet(fst0
, fst1
,
1898 &env
->active_fpu
.fp_status
),
1899 float32_lt_quiet(fsth0
, fsth1
,
1900 &env
->active_fpu
.fp_status
))
1901 FOP_COND_PS(ult
, float32_unordered_quiet(fst1
, fst0
,
1902 &env
->active_fpu
.fp_status
)
1903 || float32_lt_quiet(fst0
, fst1
,
1904 &env
->active_fpu
.fp_status
),
1905 float32_unordered_quiet(fsth1
, fsth0
,
1906 &env
->active_fpu
.fp_status
)
1907 || float32_lt_quiet(fsth0
, fsth1
,
1908 &env
->active_fpu
.fp_status
))
1909 FOP_COND_PS(ole
, float32_le_quiet(fst0
, fst1
,
1910 &env
->active_fpu
.fp_status
),
1911 float32_le_quiet(fsth0
, fsth1
,
1912 &env
->active_fpu
.fp_status
))
1913 FOP_COND_PS(ule
, float32_unordered_quiet(fst1
, fst0
,
1914 &env
->active_fpu
.fp_status
)
1915 || float32_le_quiet(fst0
, fst1
,
1916 &env
->active_fpu
.fp_status
),
1917 float32_unordered_quiet(fsth1
, fsth0
,
1918 &env
->active_fpu
.fp_status
)
1919 || float32_le_quiet(fsth0
, fsth1
,
1920 &env
->active_fpu
.fp_status
))
1922 * NOTE: the comma operator will make "cond" to eval to false,
1923 * but float32_unordered() is still called.
1925 FOP_COND_PS(sf
, (float32_unordered(fst1
, fst0
,
1926 &env
->active_fpu
.fp_status
), 0),
1927 (float32_unordered(fsth1
, fsth0
,
1928 &env
->active_fpu
.fp_status
), 0))
1929 FOP_COND_PS(ngle
, float32_unordered(fst1
, fst0
,
1930 &env
->active_fpu
.fp_status
),
1931 float32_unordered(fsth1
, fsth0
,
1932 &env
->active_fpu
.fp_status
))
1933 FOP_COND_PS(seq
, float32_eq(fst0
, fst1
,
1934 &env
->active_fpu
.fp_status
),
1935 float32_eq(fsth0
, fsth1
,
1936 &env
->active_fpu
.fp_status
))
1937 FOP_COND_PS(ngl
, float32_unordered(fst1
, fst0
,
1938 &env
->active_fpu
.fp_status
)
1939 || float32_eq(fst0
, fst1
,
1940 &env
->active_fpu
.fp_status
),
1941 float32_unordered(fsth1
, fsth0
,
1942 &env
->active_fpu
.fp_status
)
1943 || float32_eq(fsth0
, fsth1
,
1944 &env
->active_fpu
.fp_status
))
1945 FOP_COND_PS(lt
, float32_lt(fst0
, fst1
,
1946 &env
->active_fpu
.fp_status
),
1947 float32_lt(fsth0
, fsth1
,
1948 &env
->active_fpu
.fp_status
))
1949 FOP_COND_PS(nge
, float32_unordered(fst1
, fst0
,
1950 &env
->active_fpu
.fp_status
)
1951 || float32_lt(fst0
, fst1
,
1952 &env
->active_fpu
.fp_status
),
1953 float32_unordered(fsth1
, fsth0
,
1954 &env
->active_fpu
.fp_status
)
1955 || float32_lt(fsth0
, fsth1
,
1956 &env
->active_fpu
.fp_status
))
1957 FOP_COND_PS(le
, float32_le(fst0
, fst1
,
1958 &env
->active_fpu
.fp_status
),
1959 float32_le(fsth0
, fsth1
,
1960 &env
->active_fpu
.fp_status
))
1961 FOP_COND_PS(ngt
, float32_unordered(fst1
, fst0
,
1962 &env
->active_fpu
.fp_status
)
1963 || float32_le(fst0
, fst1
,
1964 &env
->active_fpu
.fp_status
),
1965 float32_unordered(fsth1
, fsth0
,
1966 &env
->active_fpu
.fp_status
)
1967 || float32_le(fsth0
, fsth1
,
1968 &env
->active_fpu
.fp_status
))
1970 /* R6 compare operations */
1971 #define FOP_CONDN_D(op, cond) \
1972 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1977 update_fcr31(env, GETPC()); \
1986 * NOTE: the comma operator will make "cond" to eval to false,
1987 * but float64_unordered_quiet() is still called.
1989 FOP_CONDN_D(af
, (float64_unordered_quiet(fdt1
, fdt0
,
1990 &env
->active_fpu
.fp_status
), 0))
1991 FOP_CONDN_D(un
, (float64_unordered_quiet(fdt1
, fdt0
,
1992 &env
->active_fpu
.fp_status
)))
1993 FOP_CONDN_D(eq
, (float64_eq_quiet(fdt0
, fdt1
,
1994 &env
->active_fpu
.fp_status
)))
1995 FOP_CONDN_D(ueq
, (float64_unordered_quiet(fdt1
, fdt0
,
1996 &env
->active_fpu
.fp_status
)
1997 || float64_eq_quiet(fdt0
, fdt1
,
1998 &env
->active_fpu
.fp_status
)))
1999 FOP_CONDN_D(lt
, (float64_lt_quiet(fdt0
, fdt1
,
2000 &env
->active_fpu
.fp_status
)))
2001 FOP_CONDN_D(ult
, (float64_unordered_quiet(fdt1
, fdt0
,
2002 &env
->active_fpu
.fp_status
)
2003 || float64_lt_quiet(fdt0
, fdt1
,
2004 &env
->active_fpu
.fp_status
)))
2005 FOP_CONDN_D(le
, (float64_le_quiet(fdt0
, fdt1
,
2006 &env
->active_fpu
.fp_status
)))
2007 FOP_CONDN_D(ule
, (float64_unordered_quiet(fdt1
, fdt0
,
2008 &env
->active_fpu
.fp_status
)
2009 || float64_le_quiet(fdt0
, fdt1
,
2010 &env
->active_fpu
.fp_status
)))
2012 * NOTE: the comma operator will make "cond" to eval to false,
2013 * but float64_unordered() is still called.\
2015 FOP_CONDN_D(saf
, (float64_unordered(fdt1
, fdt0
,
2016 &env
->active_fpu
.fp_status
), 0))
2017 FOP_CONDN_D(sun
, (float64_unordered(fdt1
, fdt0
,
2018 &env
->active_fpu
.fp_status
)))
2019 FOP_CONDN_D(seq
, (float64_eq(fdt0
, fdt1
,
2020 &env
->active_fpu
.fp_status
)))
2021 FOP_CONDN_D(sueq
, (float64_unordered(fdt1
, fdt0
,
2022 &env
->active_fpu
.fp_status
)
2023 || float64_eq(fdt0
, fdt1
,
2024 &env
->active_fpu
.fp_status
)))
2025 FOP_CONDN_D(slt
, (float64_lt(fdt0
, fdt1
,
2026 &env
->active_fpu
.fp_status
)))
2027 FOP_CONDN_D(sult
, (float64_unordered(fdt1
, fdt0
,
2028 &env
->active_fpu
.fp_status
)
2029 || float64_lt(fdt0
, fdt1
,
2030 &env
->active_fpu
.fp_status
)))
2031 FOP_CONDN_D(sle
, (float64_le(fdt0
, fdt1
,
2032 &env
->active_fpu
.fp_status
)))
2033 FOP_CONDN_D(sule
, (float64_unordered(fdt1
, fdt0
,
2034 &env
->active_fpu
.fp_status
)
2035 || float64_le(fdt0
, fdt1
,
2036 &env
->active_fpu
.fp_status
)))
2037 FOP_CONDN_D(or, (float64_le_quiet(fdt1
, fdt0
,
2038 &env
->active_fpu
.fp_status
)
2039 || float64_le_quiet(fdt0
, fdt1
,
2040 &env
->active_fpu
.fp_status
)))
2041 FOP_CONDN_D(une
, (float64_unordered_quiet(fdt1
, fdt0
,
2042 &env
->active_fpu
.fp_status
)
2043 || float64_lt_quiet(fdt1
, fdt0
,
2044 &env
->active_fpu
.fp_status
)
2045 || float64_lt_quiet(fdt0
, fdt1
,
2046 &env
->active_fpu
.fp_status
)))
2047 FOP_CONDN_D(ne
, (float64_lt_quiet(fdt1
, fdt0
,
2048 &env
->active_fpu
.fp_status
)
2049 || float64_lt_quiet(fdt0
, fdt1
,
2050 &env
->active_fpu
.fp_status
)))
2051 FOP_CONDN_D(sor
, (float64_le(fdt1
, fdt0
,
2052 &env
->active_fpu
.fp_status
)
2053 || float64_le(fdt0
, fdt1
,
2054 &env
->active_fpu
.fp_status
)))
2055 FOP_CONDN_D(sune
, (float64_unordered(fdt1
, fdt0
,
2056 &env
->active_fpu
.fp_status
)
2057 || float64_lt(fdt1
, fdt0
,
2058 &env
->active_fpu
.fp_status
)
2059 || float64_lt(fdt0
, fdt1
,
2060 &env
->active_fpu
.fp_status
)))
2061 FOP_CONDN_D(sne
, (float64_lt(fdt1
, fdt0
,
2062 &env
->active_fpu
.fp_status
)
2063 || float64_lt(fdt0
, fdt1
,
2064 &env
->active_fpu
.fp_status
)))
2066 #define FOP_CONDN_S(op, cond) \
2067 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2072 update_fcr31(env, GETPC()); \
2081 * NOTE: the comma operator will make "cond" to eval to false,
2082 * but float32_unordered_quiet() is still called.
2084 FOP_CONDN_S(af
, (float32_unordered_quiet(fst1
, fst0
,
2085 &env
->active_fpu
.fp_status
), 0))
2086 FOP_CONDN_S(un
, (float32_unordered_quiet(fst1
, fst0
,
2087 &env
->active_fpu
.fp_status
)))
2088 FOP_CONDN_S(eq
, (float32_eq_quiet(fst0
, fst1
,
2089 &env
->active_fpu
.fp_status
)))
2090 FOP_CONDN_S(ueq
, (float32_unordered_quiet(fst1
, fst0
,
2091 &env
->active_fpu
.fp_status
)
2092 || float32_eq_quiet(fst0
, fst1
,
2093 &env
->active_fpu
.fp_status
)))
2094 FOP_CONDN_S(lt
, (float32_lt_quiet(fst0
, fst1
,
2095 &env
->active_fpu
.fp_status
)))
2096 FOP_CONDN_S(ult
, (float32_unordered_quiet(fst1
, fst0
,
2097 &env
->active_fpu
.fp_status
)
2098 || float32_lt_quiet(fst0
, fst1
,
2099 &env
->active_fpu
.fp_status
)))
2100 FOP_CONDN_S(le
, (float32_le_quiet(fst0
, fst1
,
2101 &env
->active_fpu
.fp_status
)))
2102 FOP_CONDN_S(ule
, (float32_unordered_quiet(fst1
, fst0
,
2103 &env
->active_fpu
.fp_status
)
2104 || float32_le_quiet(fst0
, fst1
,
2105 &env
->active_fpu
.fp_status
)))
2107 * NOTE: the comma operator will make "cond" to eval to false,
2108 * but float32_unordered() is still called.
2110 FOP_CONDN_S(saf
, (float32_unordered(fst1
, fst0
,
2111 &env
->active_fpu
.fp_status
), 0))
2112 FOP_CONDN_S(sun
, (float32_unordered(fst1
, fst0
,
2113 &env
->active_fpu
.fp_status
)))
2114 FOP_CONDN_S(seq
, (float32_eq(fst0
, fst1
,
2115 &env
->active_fpu
.fp_status
)))
2116 FOP_CONDN_S(sueq
, (float32_unordered(fst1
, fst0
,
2117 &env
->active_fpu
.fp_status
)
2118 || float32_eq(fst0
, fst1
,
2119 &env
->active_fpu
.fp_status
)))
2120 FOP_CONDN_S(slt
, (float32_lt(fst0
, fst1
,
2121 &env
->active_fpu
.fp_status
)))
2122 FOP_CONDN_S(sult
, (float32_unordered(fst1
, fst0
,
2123 &env
->active_fpu
.fp_status
)
2124 || float32_lt(fst0
, fst1
,
2125 &env
->active_fpu
.fp_status
)))
2126 FOP_CONDN_S(sle
, (float32_le(fst0
, fst1
,
2127 &env
->active_fpu
.fp_status
)))
2128 FOP_CONDN_S(sule
, (float32_unordered(fst1
, fst0
,
2129 &env
->active_fpu
.fp_status
)
2130 || float32_le(fst0
, fst1
,
2131 &env
->active_fpu
.fp_status
)))
2132 FOP_CONDN_S(or, (float32_le_quiet(fst1
, fst0
,
2133 &env
->active_fpu
.fp_status
)
2134 || float32_le_quiet(fst0
, fst1
,
2135 &env
->active_fpu
.fp_status
)))
2136 FOP_CONDN_S(une
, (float32_unordered_quiet(fst1
, fst0
,
2137 &env
->active_fpu
.fp_status
)
2138 || float32_lt_quiet(fst1
, fst0
,
2139 &env
->active_fpu
.fp_status
)
2140 || float32_lt_quiet(fst0
, fst1
,
2141 &env
->active_fpu
.fp_status
)))
2142 FOP_CONDN_S(ne
, (float32_lt_quiet(fst1
, fst0
,
2143 &env
->active_fpu
.fp_status
)
2144 || float32_lt_quiet(fst0
, fst1
,
2145 &env
->active_fpu
.fp_status
)))
2146 FOP_CONDN_S(sor
, (float32_le(fst1
, fst0
,
2147 &env
->active_fpu
.fp_status
)
2148 || float32_le(fst0
, fst1
,
2149 &env
->active_fpu
.fp_status
)))
2150 FOP_CONDN_S(sune
, (float32_unordered(fst1
, fst0
,
2151 &env
->active_fpu
.fp_status
)
2152 || float32_lt(fst1
, fst0
,
2153 &env
->active_fpu
.fp_status
)
2154 || float32_lt(fst0
, fst1
,
2155 &env
->active_fpu
.fp_status
)))
2156 FOP_CONDN_S(sne
, (float32_lt(fst1
, fst0
,
2157 &env
->active_fpu
.fp_status
)
2158 || float32_lt(fst0
, fst1
,
2159 &env
->active_fpu
.fp_status
)))