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.1 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"
26 #include "exec/helper-proto.h"
27 #include "exec/exec-all.h"
28 #include "exec/cpu_ldst.h"
29 #include "fpu/softfloat.h"
30 #include "fpu_helper.h"
33 /* Complex FPU operations which may need stack space. */
35 #define FLOAT_TWO32 make_float32(1 << 30)
36 #define FLOAT_TWO64 make_float64(1ULL << 62)
38 #define FP_TO_INT32_OVERFLOW 0x7fffffff
39 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
41 /* convert MIPS rounding mode in FCR31 to IEEE library */
42 const FloatRoundMode ieee_rm
[4] = {
43 float_round_nearest_even
,
49 target_ulong
helper_cfc1(CPUMIPSState
*env
, uint32_t reg
)
51 target_ulong arg1
= 0;
55 arg1
= (int32_t)env
->active_fpu
.fcr0
;
58 /* UFR Support - Read Status FR */
59 if (env
->active_fpu
.fcr0
& (1 << FCR0_UFRP
)) {
60 if (env
->CP0_Config5
& (1 << CP0C5_UFR
)) {
62 ((env
->CP0_Status
& (1 << CP0St_FR
)) >> CP0St_FR
);
64 do_raise_exception(env
, EXCP_RI
, GETPC());
69 /* FRE Support - read Config5.FRE bit */
70 if (env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) {
71 if (env
->CP0_Config5
& (1 << CP0C5_UFE
)) {
72 arg1
= (env
->CP0_Config5
>> CP0C5_FRE
) & 1;
74 helper_raise_exception(env
, EXCP_RI
);
79 arg1
= ((env
->active_fpu
.fcr31
>> 24) & 0xfe) |
80 ((env
->active_fpu
.fcr31
>> 23) & 0x1);
83 arg1
= env
->active_fpu
.fcr31
& 0x0003f07c;
86 arg1
= (env
->active_fpu
.fcr31
& 0x00000f83) |
87 ((env
->active_fpu
.fcr31
>> 22) & 0x4);
90 arg1
= (int32_t)env
->active_fpu
.fcr31
;
97 void helper_ctc1(CPUMIPSState
*env
, target_ulong arg1
, uint32_t fs
, uint32_t rt
)
101 /* UFR Alias - Reset Status FR */
102 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_UFRP
)) && (rt
== 0))) {
105 if (env
->CP0_Config5
& (1 << CP0C5_UFR
)) {
106 env
->CP0_Status
&= ~(1 << CP0St_FR
);
109 do_raise_exception(env
, EXCP_RI
, GETPC());
113 /* UNFR Alias - Set Status FR */
114 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_UFRP
)) && (rt
== 0))) {
117 if (env
->CP0_Config5
& (1 << CP0C5_UFR
)) {
118 env
->CP0_Status
|= (1 << CP0St_FR
);
121 do_raise_exception(env
, EXCP_RI
, GETPC());
125 /* FRE Support - clear Config5.FRE bit */
126 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) && (rt
== 0))) {
129 if (env
->CP0_Config5
& (1 << CP0C5_UFE
)) {
130 env
->CP0_Config5
&= ~(1 << CP0C5_FRE
);
133 helper_raise_exception(env
, EXCP_RI
);
137 /* FRE Support - set Config5.FRE bit */
138 if (!((env
->active_fpu
.fcr0
& (1 << FCR0_FREP
)) && (rt
== 0))) {
141 if (env
->CP0_Config5
& (1 << CP0C5_UFE
)) {
142 env
->CP0_Config5
|= (1 << CP0C5_FRE
);
145 helper_raise_exception(env
, EXCP_RI
);
149 if ((env
->insn_flags
& ISA_MIPS_R6
) || (arg1
& 0xffffff00)) {
152 env
->active_fpu
.fcr31
= (env
->active_fpu
.fcr31
& 0x017fffff) |
153 ((arg1
& 0xfe) << 24) |
154 ((arg1
& 0x1) << 23);
157 if (arg1
& 0x007c0000) {
160 env
->active_fpu
.fcr31
= (env
->active_fpu
.fcr31
& 0xfffc0f83) |
164 if (arg1
& 0x007c0000) {
167 env
->active_fpu
.fcr31
= (env
->active_fpu
.fcr31
& 0xfefff07c) |
168 (arg1
& 0x00000f83) |
169 ((arg1
& 0x4) << 22);
172 env
->active_fpu
.fcr31
= (arg1
& env
->active_fpu
.fcr31_rw_bitmask
) |
173 (env
->active_fpu
.fcr31
& ~(env
->active_fpu
.fcr31_rw_bitmask
));
176 if (env
->insn_flags
& ISA_MIPS_R6
) {
177 do_raise_exception(env
, EXCP_RI
, GETPC());
181 restore_fp_status(env
);
182 set_float_exception_flags(0, &env
->active_fpu
.fp_status
);
183 if ((GET_FP_ENABLE(env
->active_fpu
.fcr31
) | 0x20) &
184 GET_FP_CAUSE(env
->active_fpu
.fcr31
)) {
185 do_raise_exception(env
, EXCP_FPE
, GETPC());
189 static inline int ieee_to_mips_xcpt(int ieee_xcpt
)
193 if (ieee_xcpt
& float_flag_invalid
) {
194 mips_xcpt
|= FP_INVALID
;
196 if (ieee_xcpt
& float_flag_overflow
) {
197 mips_xcpt
|= FP_OVERFLOW
;
199 if (ieee_xcpt
& float_flag_underflow
) {
200 mips_xcpt
|= FP_UNDERFLOW
;
202 if (ieee_xcpt
& float_flag_divbyzero
) {
203 mips_xcpt
|= FP_DIV0
;
205 if (ieee_xcpt
& float_flag_inexact
) {
206 mips_xcpt
|= FP_INEXACT
;
212 static inline void update_fcr31(CPUMIPSState
*env
, uintptr_t pc
)
214 int ieee_exception_flags
= get_float_exception_flags(
215 &env
->active_fpu
.fp_status
);
216 int mips_exception_flags
= 0;
218 if (ieee_exception_flags
) {
219 mips_exception_flags
= ieee_to_mips_xcpt(ieee_exception_flags
);
222 SET_FP_CAUSE(env
->active_fpu
.fcr31
, mips_exception_flags
);
224 if (mips_exception_flags
) {
225 set_float_exception_flags(0, &env
->active_fpu
.fp_status
);
227 if (GET_FP_ENABLE(env
->active_fpu
.fcr31
) & mips_exception_flags
) {
228 do_raise_exception(env
, EXCP_FPE
, pc
);
230 UPDATE_FP_FLAGS(env
->active_fpu
.fcr31
, mips_exception_flags
);
237 * Single precition routines have a "s" suffix, double precision a
238 * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
239 * paired single lower "pl", paired single upper "pu".
242 /* unary operations, modifying fp status */
243 uint64_t helper_float_sqrt_d(CPUMIPSState
*env
, uint64_t fdt0
)
245 fdt0
= float64_sqrt(fdt0
, &env
->active_fpu
.fp_status
);
246 update_fcr31(env
, GETPC());
250 uint32_t helper_float_sqrt_s(CPUMIPSState
*env
, uint32_t fst0
)
252 fst0
= float32_sqrt(fst0
, &env
->active_fpu
.fp_status
);
253 update_fcr31(env
, GETPC());
257 uint64_t helper_float_cvtd_s(CPUMIPSState
*env
, uint32_t fst0
)
261 fdt2
= float32_to_float64(fst0
, &env
->active_fpu
.fp_status
);
262 update_fcr31(env
, GETPC());
266 uint64_t helper_float_cvtd_w(CPUMIPSState
*env
, uint32_t wt0
)
270 fdt2
= int32_to_float64(wt0
, &env
->active_fpu
.fp_status
);
271 update_fcr31(env
, GETPC());
275 uint64_t helper_float_cvtd_l(CPUMIPSState
*env
, uint64_t dt0
)
279 fdt2
= int64_to_float64(dt0
, &env
->active_fpu
.fp_status
);
280 update_fcr31(env
, GETPC());
284 uint64_t helper_float_cvt_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
288 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
289 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
290 & (float_flag_invalid
| float_flag_overflow
)) {
291 dt2
= FP_TO_INT64_OVERFLOW
;
293 update_fcr31(env
, GETPC());
297 uint64_t helper_float_cvt_l_s(CPUMIPSState
*env
, uint32_t fst0
)
301 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
302 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
303 & (float_flag_invalid
| float_flag_overflow
)) {
304 dt2
= FP_TO_INT64_OVERFLOW
;
306 update_fcr31(env
, GETPC());
310 uint64_t helper_float_cvtps_pw(CPUMIPSState
*env
, uint64_t dt0
)
315 fst2
= int32_to_float32(dt0
& 0XFFFFFFFF, &env
->active_fpu
.fp_status
);
316 fsth2
= int32_to_float32(dt0
>> 32, &env
->active_fpu
.fp_status
);
317 update_fcr31(env
, GETPC());
318 return ((uint64_t)fsth2
<< 32) | fst2
;
321 uint64_t helper_float_cvtpw_ps(CPUMIPSState
*env
, uint64_t fdt0
)
327 wt2
= float32_to_int32(fdt0
& 0XFFFFFFFF, &env
->active_fpu
.fp_status
);
328 excp
= get_float_exception_flags(&env
->active_fpu
.fp_status
);
329 if (excp
& (float_flag_overflow
| float_flag_invalid
)) {
330 wt2
= FP_TO_INT32_OVERFLOW
;
333 set_float_exception_flags(0, &env
->active_fpu
.fp_status
);
334 wth2
= float32_to_int32(fdt0
>> 32, &env
->active_fpu
.fp_status
);
335 excph
= get_float_exception_flags(&env
->active_fpu
.fp_status
);
336 if (excph
& (float_flag_overflow
| float_flag_invalid
)) {
337 wth2
= FP_TO_INT32_OVERFLOW
;
340 set_float_exception_flags(excp
| excph
, &env
->active_fpu
.fp_status
);
341 update_fcr31(env
, GETPC());
343 return ((uint64_t)wth2
<< 32) | wt2
;
346 uint32_t helper_float_cvts_d(CPUMIPSState
*env
, uint64_t fdt0
)
350 fst2
= float64_to_float32(fdt0
, &env
->active_fpu
.fp_status
);
351 update_fcr31(env
, GETPC());
355 uint32_t helper_float_cvts_w(CPUMIPSState
*env
, uint32_t wt0
)
359 fst2
= int32_to_float32(wt0
, &env
->active_fpu
.fp_status
);
360 update_fcr31(env
, GETPC());
364 uint32_t helper_float_cvts_l(CPUMIPSState
*env
, uint64_t dt0
)
368 fst2
= int64_to_float32(dt0
, &env
->active_fpu
.fp_status
);
369 update_fcr31(env
, GETPC());
373 uint32_t helper_float_cvts_pl(CPUMIPSState
*env
, uint32_t wt0
)
378 update_fcr31(env
, GETPC());
382 uint32_t helper_float_cvts_pu(CPUMIPSState
*env
, uint32_t wth0
)
387 update_fcr31(env
, GETPC());
391 uint32_t helper_float_cvt_w_s(CPUMIPSState
*env
, uint32_t fst0
)
395 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
396 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
397 & (float_flag_invalid
| float_flag_overflow
)) {
398 wt2
= FP_TO_INT32_OVERFLOW
;
400 update_fcr31(env
, GETPC());
404 uint32_t helper_float_cvt_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
408 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
409 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
410 & (float_flag_invalid
| float_flag_overflow
)) {
411 wt2
= FP_TO_INT32_OVERFLOW
;
413 update_fcr31(env
, GETPC());
417 uint64_t helper_float_round_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
421 set_float_rounding_mode(float_round_nearest_even
,
422 &env
->active_fpu
.fp_status
);
423 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
424 restore_rounding_mode(env
);
425 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
426 & (float_flag_invalid
| float_flag_overflow
)) {
427 dt2
= FP_TO_INT64_OVERFLOW
;
429 update_fcr31(env
, GETPC());
433 uint64_t helper_float_round_l_s(CPUMIPSState
*env
, uint32_t fst0
)
437 set_float_rounding_mode(float_round_nearest_even
,
438 &env
->active_fpu
.fp_status
);
439 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
440 restore_rounding_mode(env
);
441 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
442 & (float_flag_invalid
| float_flag_overflow
)) {
443 dt2
= FP_TO_INT64_OVERFLOW
;
445 update_fcr31(env
, GETPC());
449 uint32_t helper_float_round_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
453 set_float_rounding_mode(float_round_nearest_even
,
454 &env
->active_fpu
.fp_status
);
455 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
456 restore_rounding_mode(env
);
457 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
458 & (float_flag_invalid
| float_flag_overflow
)) {
459 wt2
= FP_TO_INT32_OVERFLOW
;
461 update_fcr31(env
, GETPC());
465 uint32_t helper_float_round_w_s(CPUMIPSState
*env
, uint32_t fst0
)
469 set_float_rounding_mode(float_round_nearest_even
,
470 &env
->active_fpu
.fp_status
);
471 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
472 restore_rounding_mode(env
);
473 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
474 & (float_flag_invalid
| float_flag_overflow
)) {
475 wt2
= FP_TO_INT32_OVERFLOW
;
477 update_fcr31(env
, GETPC());
481 uint64_t helper_float_trunc_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
485 dt2
= float64_to_int64_round_to_zero(fdt0
,
486 &env
->active_fpu
.fp_status
);
487 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
488 & (float_flag_invalid
| float_flag_overflow
)) {
489 dt2
= FP_TO_INT64_OVERFLOW
;
491 update_fcr31(env
, GETPC());
495 uint64_t helper_float_trunc_l_s(CPUMIPSState
*env
, uint32_t fst0
)
499 dt2
= float32_to_int64_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
500 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
501 & (float_flag_invalid
| float_flag_overflow
)) {
502 dt2
= FP_TO_INT64_OVERFLOW
;
504 update_fcr31(env
, GETPC());
508 uint32_t helper_float_trunc_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
512 wt2
= float64_to_int32_round_to_zero(fdt0
, &env
->active_fpu
.fp_status
);
513 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
514 & (float_flag_invalid
| float_flag_overflow
)) {
515 wt2
= FP_TO_INT32_OVERFLOW
;
517 update_fcr31(env
, GETPC());
521 uint32_t helper_float_trunc_w_s(CPUMIPSState
*env
, uint32_t fst0
)
525 wt2
= float32_to_int32_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
526 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
527 & (float_flag_invalid
| float_flag_overflow
)) {
528 wt2
= FP_TO_INT32_OVERFLOW
;
530 update_fcr31(env
, GETPC());
534 uint64_t helper_float_ceil_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
538 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
539 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
540 restore_rounding_mode(env
);
541 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
542 & (float_flag_invalid
| float_flag_overflow
)) {
543 dt2
= FP_TO_INT64_OVERFLOW
;
545 update_fcr31(env
, GETPC());
549 uint64_t helper_float_ceil_l_s(CPUMIPSState
*env
, uint32_t fst0
)
553 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
554 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
555 restore_rounding_mode(env
);
556 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
557 & (float_flag_invalid
| float_flag_overflow
)) {
558 dt2
= FP_TO_INT64_OVERFLOW
;
560 update_fcr31(env
, GETPC());
564 uint32_t helper_float_ceil_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
568 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
569 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
570 restore_rounding_mode(env
);
571 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
572 & (float_flag_invalid
| float_flag_overflow
)) {
573 wt2
= FP_TO_INT32_OVERFLOW
;
575 update_fcr31(env
, GETPC());
579 uint32_t helper_float_ceil_w_s(CPUMIPSState
*env
, uint32_t fst0
)
583 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
584 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
585 restore_rounding_mode(env
);
586 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
587 & (float_flag_invalid
| float_flag_overflow
)) {
588 wt2
= FP_TO_INT32_OVERFLOW
;
590 update_fcr31(env
, GETPC());
594 uint64_t helper_float_floor_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
598 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
599 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
600 restore_rounding_mode(env
);
601 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
602 & (float_flag_invalid
| float_flag_overflow
)) {
603 dt2
= FP_TO_INT64_OVERFLOW
;
605 update_fcr31(env
, GETPC());
609 uint64_t helper_float_floor_l_s(CPUMIPSState
*env
, uint32_t fst0
)
613 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
614 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
615 restore_rounding_mode(env
);
616 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
617 & (float_flag_invalid
| float_flag_overflow
)) {
618 dt2
= FP_TO_INT64_OVERFLOW
;
620 update_fcr31(env
, GETPC());
624 uint32_t helper_float_floor_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
628 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
629 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
630 restore_rounding_mode(env
);
631 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
632 & (float_flag_invalid
| float_flag_overflow
)) {
633 wt2
= FP_TO_INT32_OVERFLOW
;
635 update_fcr31(env
, GETPC());
639 uint32_t helper_float_floor_w_s(CPUMIPSState
*env
, uint32_t fst0
)
643 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
644 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
645 restore_rounding_mode(env
);
646 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
647 & (float_flag_invalid
| float_flag_overflow
)) {
648 wt2
= FP_TO_INT32_OVERFLOW
;
650 update_fcr31(env
, GETPC());
654 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
658 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
659 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
660 & float_flag_invalid
) {
661 if (float64_is_any_nan(fdt0
)) {
665 update_fcr31(env
, GETPC());
669 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
673 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
674 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
675 & float_flag_invalid
) {
676 if (float32_is_any_nan(fst0
)) {
680 update_fcr31(env
, GETPC());
684 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
688 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
689 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
690 & float_flag_invalid
) {
691 if (float64_is_any_nan(fdt0
)) {
695 update_fcr31(env
, GETPC());
699 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
703 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
704 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
705 & float_flag_invalid
) {
706 if (float32_is_any_nan(fst0
)) {
710 update_fcr31(env
, GETPC());
714 uint64_t helper_float_round_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
718 set_float_rounding_mode(float_round_nearest_even
,
719 &env
->active_fpu
.fp_status
);
720 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
721 restore_rounding_mode(env
);
722 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
723 & float_flag_invalid
) {
724 if (float64_is_any_nan(fdt0
)) {
728 update_fcr31(env
, GETPC());
732 uint64_t helper_float_round_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
736 set_float_rounding_mode(float_round_nearest_even
,
737 &env
->active_fpu
.fp_status
);
738 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
739 restore_rounding_mode(env
);
740 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
741 & float_flag_invalid
) {
742 if (float32_is_any_nan(fst0
)) {
746 update_fcr31(env
, GETPC());
750 uint32_t helper_float_round_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
754 set_float_rounding_mode(float_round_nearest_even
,
755 &env
->active_fpu
.fp_status
);
756 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
757 restore_rounding_mode(env
);
758 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
759 & float_flag_invalid
) {
760 if (float64_is_any_nan(fdt0
)) {
764 update_fcr31(env
, GETPC());
768 uint32_t helper_float_round_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
772 set_float_rounding_mode(float_round_nearest_even
,
773 &env
->active_fpu
.fp_status
);
774 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
775 restore_rounding_mode(env
);
776 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
777 & float_flag_invalid
) {
778 if (float32_is_any_nan(fst0
)) {
782 update_fcr31(env
, GETPC());
786 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
790 dt2
= float64_to_int64_round_to_zero(fdt0
, &env
->active_fpu
.fp_status
);
791 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
792 & float_flag_invalid
) {
793 if (float64_is_any_nan(fdt0
)) {
797 update_fcr31(env
, GETPC());
801 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
805 dt2
= float32_to_int64_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
806 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
807 & float_flag_invalid
) {
808 if (float32_is_any_nan(fst0
)) {
812 update_fcr31(env
, GETPC());
816 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
820 wt2
= float64_to_int32_round_to_zero(fdt0
, &env
->active_fpu
.fp_status
);
821 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
822 & float_flag_invalid
) {
823 if (float64_is_any_nan(fdt0
)) {
827 update_fcr31(env
, GETPC());
831 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
835 wt2
= float32_to_int32_round_to_zero(fst0
, &env
->active_fpu
.fp_status
);
836 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
837 & float_flag_invalid
) {
838 if (float32_is_any_nan(fst0
)) {
842 update_fcr31(env
, GETPC());
846 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
850 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
851 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
852 restore_rounding_mode(env
);
853 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
854 & float_flag_invalid
) {
855 if (float64_is_any_nan(fdt0
)) {
859 update_fcr31(env
, GETPC());
863 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
867 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
868 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
869 restore_rounding_mode(env
);
870 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
871 & float_flag_invalid
) {
872 if (float32_is_any_nan(fst0
)) {
876 update_fcr31(env
, GETPC());
880 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
884 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
885 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
886 restore_rounding_mode(env
);
887 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
888 & float_flag_invalid
) {
889 if (float64_is_any_nan(fdt0
)) {
893 update_fcr31(env
, GETPC());
897 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
901 set_float_rounding_mode(float_round_up
, &env
->active_fpu
.fp_status
);
902 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
903 restore_rounding_mode(env
);
904 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
905 & float_flag_invalid
) {
906 if (float32_is_any_nan(fst0
)) {
910 update_fcr31(env
, GETPC());
914 uint64_t helper_float_floor_2008_l_d(CPUMIPSState
*env
, uint64_t fdt0
)
918 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
919 dt2
= float64_to_int64(fdt0
, &env
->active_fpu
.fp_status
);
920 restore_rounding_mode(env
);
921 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
922 & float_flag_invalid
) {
923 if (float64_is_any_nan(fdt0
)) {
927 update_fcr31(env
, GETPC());
931 uint64_t helper_float_floor_2008_l_s(CPUMIPSState
*env
, uint32_t fst0
)
935 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
936 dt2
= float32_to_int64(fst0
, &env
->active_fpu
.fp_status
);
937 restore_rounding_mode(env
);
938 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
939 & float_flag_invalid
) {
940 if (float32_is_any_nan(fst0
)) {
944 update_fcr31(env
, GETPC());
948 uint32_t helper_float_floor_2008_w_d(CPUMIPSState
*env
, uint64_t fdt0
)
952 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
953 wt2
= float64_to_int32(fdt0
, &env
->active_fpu
.fp_status
);
954 restore_rounding_mode(env
);
955 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
956 & float_flag_invalid
) {
957 if (float64_is_any_nan(fdt0
)) {
961 update_fcr31(env
, GETPC());
965 uint32_t helper_float_floor_2008_w_s(CPUMIPSState
*env
, uint32_t fst0
)
969 set_float_rounding_mode(float_round_down
, &env
->active_fpu
.fp_status
);
970 wt2
= float32_to_int32(fst0
, &env
->active_fpu
.fp_status
);
971 restore_rounding_mode(env
);
972 if (get_float_exception_flags(&env
->active_fpu
.fp_status
)
973 & float_flag_invalid
) {
974 if (float32_is_any_nan(fst0
)) {
978 update_fcr31(env
, GETPC());
982 /* unary operations, not modifying fp status */
984 uint64_t helper_float_abs_d(uint64_t fdt0
)
986 return float64_abs(fdt0
);
989 uint32_t helper_float_abs_s(uint32_t fst0
)
991 return float32_abs(fst0
);
994 uint64_t helper_float_abs_ps(uint64_t fdt0
)
999 wt0
= float32_abs(fdt0
& 0XFFFFFFFF);
1000 wth0
= float32_abs(fdt0
>> 32);
1001 return ((uint64_t)wth0
<< 32) | wt0
;
1004 uint64_t helper_float_chs_d(uint64_t fdt0
)
1006 return float64_chs(fdt0
);
1009 uint32_t helper_float_chs_s(uint32_t fst0
)
1011 return float32_chs(fst0
);
1014 uint64_t helper_float_chs_ps(uint64_t fdt0
)
1019 wt0
= float32_chs(fdt0
& 0XFFFFFFFF);
1020 wth0
= float32_chs(fdt0
>> 32);
1021 return ((uint64_t)wth0
<< 32) | wt0
;
1024 /* MIPS specific unary operations */
1025 uint64_t helper_float_recip_d(CPUMIPSState
*env
, uint64_t fdt0
)
1029 fdt2
= float64_div(float64_one
, fdt0
, &env
->active_fpu
.fp_status
);
1030 update_fcr31(env
, GETPC());
1034 uint32_t helper_float_recip_s(CPUMIPSState
*env
, uint32_t fst0
)
1038 fst2
= float32_div(float32_one
, fst0
, &env
->active_fpu
.fp_status
);
1039 update_fcr31(env
, GETPC());
1043 uint64_t helper_float_rsqrt_d(CPUMIPSState
*env
, uint64_t fdt0
)
1047 fdt2
= float64_sqrt(fdt0
, &env
->active_fpu
.fp_status
);
1048 fdt2
= float64_div(float64_one
, fdt2
, &env
->active_fpu
.fp_status
);
1049 update_fcr31(env
, GETPC());
1053 uint32_t helper_float_rsqrt_s(CPUMIPSState
*env
, uint32_t fst0
)
1057 fst2
= float32_sqrt(fst0
, &env
->active_fpu
.fp_status
);
1058 fst2
= float32_div(float32_one
, fst2
, &env
->active_fpu
.fp_status
);
1059 update_fcr31(env
, GETPC());
1063 uint64_t helper_float_recip1_d(CPUMIPSState
*env
, uint64_t fdt0
)
1067 fdt2
= float64_div(float64_one
, fdt0
, &env
->active_fpu
.fp_status
);
1068 update_fcr31(env
, GETPC());
1072 uint32_t helper_float_recip1_s(CPUMIPSState
*env
, uint32_t fst0
)
1076 fst2
= float32_div(float32_one
, fst0
, &env
->active_fpu
.fp_status
);
1077 update_fcr31(env
, GETPC());
1081 uint64_t helper_float_recip1_ps(CPUMIPSState
*env
, uint64_t fdt0
)
1086 fstl2
= float32_div(float32_one
, fdt0
& 0XFFFFFFFF,
1087 &env
->active_fpu
.fp_status
);
1088 fsth2
= float32_div(float32_one
, fdt0
>> 32, &env
->active_fpu
.fp_status
);
1089 update_fcr31(env
, GETPC());
1090 return ((uint64_t)fsth2
<< 32) | fstl2
;
1093 uint64_t helper_float_rsqrt1_d(CPUMIPSState
*env
, uint64_t fdt0
)
1097 fdt2
= float64_sqrt(fdt0
, &env
->active_fpu
.fp_status
);
1098 fdt2
= float64_div(float64_one
, fdt2
, &env
->active_fpu
.fp_status
);
1099 update_fcr31(env
, GETPC());
1103 uint32_t helper_float_rsqrt1_s(CPUMIPSState
*env
, uint32_t fst0
)
1107 fst2
= float32_sqrt(fst0
, &env
->active_fpu
.fp_status
);
1108 fst2
= float32_div(float32_one
, fst2
, &env
->active_fpu
.fp_status
);
1109 update_fcr31(env
, GETPC());
1113 uint64_t helper_float_rsqrt1_ps(CPUMIPSState
*env
, uint64_t fdt0
)
1118 fstl2
= float32_sqrt(fdt0
& 0XFFFFFFFF, &env
->active_fpu
.fp_status
);
1119 fsth2
= float32_sqrt(fdt0
>> 32, &env
->active_fpu
.fp_status
);
1120 fstl2
= float32_div(float32_one
, fstl2
, &env
->active_fpu
.fp_status
);
1121 fsth2
= float32_div(float32_one
, fsth2
, &env
->active_fpu
.fp_status
);
1122 update_fcr31(env
, GETPC());
1123 return ((uint64_t)fsth2
<< 32) | fstl2
;
1126 uint64_t helper_float_rint_d(CPUMIPSState
*env
, uint64_t fs
)
1130 fdret
= float64_round_to_int(fs
, &env
->active_fpu
.fp_status
);
1131 update_fcr31(env
, GETPC());
1135 uint32_t helper_float_rint_s(CPUMIPSState
*env
, uint32_t fs
)
1139 fdret
= float32_round_to_int(fs
, &env
->active_fpu
.fp_status
);
1140 update_fcr31(env
, GETPC());
1144 #define FLOAT_CLASS_SIGNALING_NAN 0x001
1145 #define FLOAT_CLASS_QUIET_NAN 0x002
1146 #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004
1147 #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008
1148 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
1149 #define FLOAT_CLASS_NEGATIVE_ZERO 0x020
1150 #define FLOAT_CLASS_POSITIVE_INFINITY 0x040
1151 #define FLOAT_CLASS_POSITIVE_NORMAL 0x080
1152 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
1153 #define FLOAT_CLASS_POSITIVE_ZERO 0x200
1155 uint64_t float_class_d(uint64_t arg
, float_status
*status
)
1157 if (float64_is_signaling_nan(arg
, status
)) {
1158 return FLOAT_CLASS_SIGNALING_NAN
;
1159 } else if (float64_is_quiet_nan(arg
, status
)) {
1160 return FLOAT_CLASS_QUIET_NAN
;
1161 } else if (float64_is_neg(arg
)) {
1162 if (float64_is_infinity(arg
)) {
1163 return FLOAT_CLASS_NEGATIVE_INFINITY
;
1164 } else if (float64_is_zero(arg
)) {
1165 return FLOAT_CLASS_NEGATIVE_ZERO
;
1166 } else if (float64_is_zero_or_denormal(arg
)) {
1167 return FLOAT_CLASS_NEGATIVE_SUBNORMAL
;
1169 return FLOAT_CLASS_NEGATIVE_NORMAL
;
1172 if (float64_is_infinity(arg
)) {
1173 return FLOAT_CLASS_POSITIVE_INFINITY
;
1174 } else if (float64_is_zero(arg
)) {
1175 return FLOAT_CLASS_POSITIVE_ZERO
;
1176 } else if (float64_is_zero_or_denormal(arg
)) {
1177 return FLOAT_CLASS_POSITIVE_SUBNORMAL
;
1179 return FLOAT_CLASS_POSITIVE_NORMAL
;
1184 uint64_t helper_float_class_d(CPUMIPSState
*env
, uint64_t arg
)
1186 return float_class_d(arg
, &env
->active_fpu
.fp_status
);
1189 uint32_t float_class_s(uint32_t arg
, float_status
*status
)
1191 if (float32_is_signaling_nan(arg
, status
)) {
1192 return FLOAT_CLASS_SIGNALING_NAN
;
1193 } else if (float32_is_quiet_nan(arg
, status
)) {
1194 return FLOAT_CLASS_QUIET_NAN
;
1195 } else if (float32_is_neg(arg
)) {
1196 if (float32_is_infinity(arg
)) {
1197 return FLOAT_CLASS_NEGATIVE_INFINITY
;
1198 } else if (float32_is_zero(arg
)) {
1199 return FLOAT_CLASS_NEGATIVE_ZERO
;
1200 } else if (float32_is_zero_or_denormal(arg
)) {
1201 return FLOAT_CLASS_NEGATIVE_SUBNORMAL
;
1203 return FLOAT_CLASS_NEGATIVE_NORMAL
;
1206 if (float32_is_infinity(arg
)) {
1207 return FLOAT_CLASS_POSITIVE_INFINITY
;
1208 } else if (float32_is_zero(arg
)) {
1209 return FLOAT_CLASS_POSITIVE_ZERO
;
1210 } else if (float32_is_zero_or_denormal(arg
)) {
1211 return FLOAT_CLASS_POSITIVE_SUBNORMAL
;
1213 return FLOAT_CLASS_POSITIVE_NORMAL
;
1218 uint32_t helper_float_class_s(CPUMIPSState
*env
, uint32_t arg
)
1220 return float_class_s(arg
, &env
->active_fpu
.fp_status
);
1223 /* binary operations */
1225 uint64_t helper_float_add_d(CPUMIPSState
*env
,
1226 uint64_t fdt0
, uint64_t fdt1
)
1230 dt2
= float64_add(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1231 update_fcr31(env
, GETPC());
1235 uint32_t helper_float_add_s(CPUMIPSState
*env
,
1236 uint32_t fst0
, uint32_t fst1
)
1240 wt2
= float32_add(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1241 update_fcr31(env
, GETPC());
1245 uint64_t helper_float_add_ps(CPUMIPSState
*env
,
1246 uint64_t fdt0
, uint64_t fdt1
)
1248 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1249 uint32_t fsth0
= fdt0
>> 32;
1250 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1251 uint32_t fsth1
= fdt1
>> 32;
1255 wtl2
= float32_add(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1256 wth2
= float32_add(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1257 update_fcr31(env
, GETPC());
1258 return ((uint64_t)wth2
<< 32) | wtl2
;
1261 uint64_t helper_float_sub_d(CPUMIPSState
*env
,
1262 uint64_t fdt0
, uint64_t fdt1
)
1266 dt2
= float64_sub(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1267 update_fcr31(env
, GETPC());
1271 uint32_t helper_float_sub_s(CPUMIPSState
*env
,
1272 uint32_t fst0
, uint32_t fst1
)
1276 wt2
= float32_sub(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1277 update_fcr31(env
, GETPC());
1281 uint64_t helper_float_sub_ps(CPUMIPSState
*env
,
1282 uint64_t fdt0
, uint64_t fdt1
)
1284 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1285 uint32_t fsth0
= fdt0
>> 32;
1286 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1287 uint32_t fsth1
= fdt1
>> 32;
1291 wtl2
= float32_sub(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1292 wth2
= float32_sub(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1293 update_fcr31(env
, GETPC());
1294 return ((uint64_t)wth2
<< 32) | wtl2
;
1297 uint64_t helper_float_mul_d(CPUMIPSState
*env
,
1298 uint64_t fdt0
, uint64_t fdt1
)
1302 dt2
= float64_mul(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1303 update_fcr31(env
, GETPC());
1307 uint32_t helper_float_mul_s(CPUMIPSState
*env
,
1308 uint32_t fst0
, uint32_t fst1
)
1312 wt2
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1313 update_fcr31(env
, GETPC());
1317 uint64_t helper_float_mul_ps(CPUMIPSState
*env
,
1318 uint64_t fdt0
, uint64_t fdt1
)
1320 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1321 uint32_t fsth0
= fdt0
>> 32;
1322 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1323 uint32_t fsth1
= fdt1
>> 32;
1327 wtl2
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1328 wth2
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1329 update_fcr31(env
, GETPC());
1330 return ((uint64_t)wth2
<< 32) | wtl2
;
1333 uint64_t helper_float_div_d(CPUMIPSState
*env
,
1334 uint64_t fdt0
, uint64_t fdt1
)
1338 dt2
= float64_div(fdt0
, fdt1
, &env
->active_fpu
.fp_status
);
1339 update_fcr31(env
, GETPC());
1343 uint32_t helper_float_div_s(CPUMIPSState
*env
,
1344 uint32_t fst0
, uint32_t fst1
)
1348 wt2
= float32_div(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1349 update_fcr31(env
, GETPC());
1353 uint64_t helper_float_div_ps(CPUMIPSState
*env
,
1354 uint64_t fdt0
, uint64_t fdt1
)
1356 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1357 uint32_t fsth0
= fdt0
>> 32;
1358 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1359 uint32_t fsth1
= fdt1
>> 32;
1363 wtl2
= float32_div(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1364 wth2
= float32_div(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1365 update_fcr31(env
, GETPC());
1366 return ((uint64_t)wth2
<< 32) | wtl2
;
1370 /* MIPS specific binary operations */
1371 uint64_t helper_float_recip2_d(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1373 fdt2
= float64_mul(fdt0
, fdt2
, &env
->active_fpu
.fp_status
);
1374 fdt2
= float64_chs(float64_sub(fdt2
, float64_one
,
1375 &env
->active_fpu
.fp_status
));
1376 update_fcr31(env
, GETPC());
1380 uint32_t helper_float_recip2_s(CPUMIPSState
*env
, uint32_t fst0
, uint32_t fst2
)
1382 fst2
= float32_mul(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1383 fst2
= float32_chs(float32_sub(fst2
, float32_one
,
1384 &env
->active_fpu
.fp_status
));
1385 update_fcr31(env
, GETPC());
1389 uint64_t helper_float_recip2_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1391 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1392 uint32_t fsth0
= fdt0
>> 32;
1393 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1394 uint32_t fsth2
= fdt2
>> 32;
1396 fstl2
= float32_mul(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1397 fsth2
= float32_mul(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1398 fstl2
= float32_chs(float32_sub(fstl2
, float32_one
,
1399 &env
->active_fpu
.fp_status
));
1400 fsth2
= float32_chs(float32_sub(fsth2
, float32_one
,
1401 &env
->active_fpu
.fp_status
));
1402 update_fcr31(env
, GETPC());
1403 return ((uint64_t)fsth2
<< 32) | fstl2
;
1406 uint64_t helper_float_rsqrt2_d(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1408 fdt2
= float64_mul(fdt0
, fdt2
, &env
->active_fpu
.fp_status
);
1409 fdt2
= float64_sub(fdt2
, float64_one
, &env
->active_fpu
.fp_status
);
1410 fdt2
= float64_chs(float64_div(fdt2
, FLOAT_TWO64
,
1411 &env
->active_fpu
.fp_status
));
1412 update_fcr31(env
, GETPC());
1416 uint32_t helper_float_rsqrt2_s(CPUMIPSState
*env
, uint32_t fst0
, uint32_t fst2
)
1418 fst2
= float32_mul(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1419 fst2
= float32_sub(fst2
, float32_one
, &env
->active_fpu
.fp_status
);
1420 fst2
= float32_chs(float32_div(fst2
, FLOAT_TWO32
,
1421 &env
->active_fpu
.fp_status
));
1422 update_fcr31(env
, GETPC());
1426 uint64_t helper_float_rsqrt2_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt2
)
1428 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1429 uint32_t fsth0
= fdt0
>> 32;
1430 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1431 uint32_t fsth2
= fdt2
>> 32;
1433 fstl2
= float32_mul(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1434 fsth2
= float32_mul(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1435 fstl2
= float32_sub(fstl2
, float32_one
, &env
->active_fpu
.fp_status
);
1436 fsth2
= float32_sub(fsth2
, float32_one
, &env
->active_fpu
.fp_status
);
1437 fstl2
= float32_chs(float32_div(fstl2
, FLOAT_TWO32
,
1438 &env
->active_fpu
.fp_status
));
1439 fsth2
= float32_chs(float32_div(fsth2
, FLOAT_TWO32
,
1440 &env
->active_fpu
.fp_status
));
1441 update_fcr31(env
, GETPC());
1442 return ((uint64_t)fsth2
<< 32) | fstl2
;
1445 uint64_t helper_float_addr_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt1
)
1447 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1448 uint32_t fsth0
= fdt0
>> 32;
1449 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1450 uint32_t fsth1
= fdt1
>> 32;
1454 fstl2
= float32_add(fstl0
, fsth0
, &env
->active_fpu
.fp_status
);
1455 fsth2
= float32_add(fstl1
, fsth1
, &env
->active_fpu
.fp_status
);
1456 update_fcr31(env
, GETPC());
1457 return ((uint64_t)fsth2
<< 32) | fstl2
;
1460 uint64_t helper_float_mulr_ps(CPUMIPSState
*env
, uint64_t fdt0
, uint64_t fdt1
)
1462 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1463 uint32_t fsth0
= fdt0
>> 32;
1464 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1465 uint32_t fsth1
= fdt1
>> 32;
1469 fstl2
= float32_mul(fstl0
, fsth0
, &env
->active_fpu
.fp_status
);
1470 fsth2
= float32_mul(fstl1
, fsth1
, &env
->active_fpu
.fp_status
);
1471 update_fcr31(env
, GETPC());
1472 return ((uint64_t)fsth2
<< 32) | fstl2
;
1476 uint32_t helper_float_max_s(CPUMIPSState
*env
, uint32_t fs
, uint32_t ft
)
1480 fdret
= float32_maxnum(fs
, ft
, &env
->active_fpu
.fp_status
);
1482 update_fcr31(env
, GETPC());
1486 uint64_t helper_float_max_d(CPUMIPSState
*env
, uint64_t fs
, uint64_t ft
)
1490 fdret
= float64_maxnum(fs
, ft
, &env
->active_fpu
.fp_status
);
1492 update_fcr31(env
, GETPC());
1496 uint32_t helper_float_maxa_s(CPUMIPSState
*env
, uint32_t fs
, uint32_t ft
)
1500 fdret
= float32_maxnummag(fs
, ft
, &env
->active_fpu
.fp_status
);
1502 update_fcr31(env
, GETPC());
1506 uint64_t helper_float_maxa_d(CPUMIPSState
*env
, uint64_t fs
, uint64_t ft
)
1510 fdret
= float64_maxnummag(fs
, ft
, &env
->active_fpu
.fp_status
);
1512 update_fcr31(env
, GETPC());
1516 uint32_t helper_float_min_s(CPUMIPSState
*env
, uint32_t fs
, uint32_t ft
)
1520 fdret
= float32_minnum(fs
, ft
, &env
->active_fpu
.fp_status
);
1522 update_fcr31(env
, GETPC());
1526 uint64_t helper_float_min_d(CPUMIPSState
*env
, uint64_t fs
, uint64_t ft
)
1530 fdret
= float64_minnum(fs
, ft
, &env
->active_fpu
.fp_status
);
1532 update_fcr31(env
, GETPC());
1536 uint32_t helper_float_mina_s(CPUMIPSState
*env
, uint32_t fs
, uint32_t ft
)
1540 fdret
= float32_minnummag(fs
, ft
, &env
->active_fpu
.fp_status
);
1542 update_fcr31(env
, GETPC());
1546 uint64_t helper_float_mina_d(CPUMIPSState
*env
, uint64_t fs
, uint64_t ft
)
1550 fdret
= float64_minnummag(fs
, ft
, &env
->active_fpu
.fp_status
);
1552 update_fcr31(env
, GETPC());
1557 /* ternary operations */
1559 uint64_t helper_float_madd_d(CPUMIPSState
*env
, uint64_t fst0
,
1560 uint64_t fst1
, uint64_t fst2
)
1562 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1563 fst0
= float64_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1565 update_fcr31(env
, GETPC());
1569 uint32_t helper_float_madd_s(CPUMIPSState
*env
, uint32_t fst0
,
1570 uint32_t fst1
, uint32_t fst2
)
1572 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1573 fst0
= float32_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1575 update_fcr31(env
, GETPC());
1579 uint64_t helper_float_madd_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1580 uint64_t fdt1
, uint64_t fdt2
)
1582 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1583 uint32_t fsth0
= fdt0
>> 32;
1584 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1585 uint32_t fsth1
= fdt1
>> 32;
1586 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1587 uint32_t fsth2
= fdt2
>> 32;
1589 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1590 fstl0
= float32_add(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1591 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1592 fsth0
= float32_add(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1594 update_fcr31(env
, GETPC());
1595 return ((uint64_t)fsth0
<< 32) | fstl0
;
1598 uint64_t helper_float_msub_d(CPUMIPSState
*env
, uint64_t fst0
,
1599 uint64_t fst1
, uint64_t fst2
)
1601 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1602 fst0
= float64_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1604 update_fcr31(env
, GETPC());
1608 uint32_t helper_float_msub_s(CPUMIPSState
*env
, uint32_t fst0
,
1609 uint32_t fst1
, uint32_t fst2
)
1611 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1612 fst0
= float32_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1614 update_fcr31(env
, GETPC());
1618 uint64_t helper_float_msub_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1619 uint64_t fdt1
, uint64_t fdt2
)
1621 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1622 uint32_t fsth0
= fdt0
>> 32;
1623 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1624 uint32_t fsth1
= fdt1
>> 32;
1625 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1626 uint32_t fsth2
= fdt2
>> 32;
1628 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1629 fstl0
= float32_sub(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1630 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1631 fsth0
= float32_sub(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1633 update_fcr31(env
, GETPC());
1634 return ((uint64_t)fsth0
<< 32) | fstl0
;
1637 uint64_t helper_float_nmadd_d(CPUMIPSState
*env
, uint64_t fst0
,
1638 uint64_t fst1
, uint64_t fst2
)
1640 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1641 fst0
= float64_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1642 fst0
= float64_chs(fst0
);
1644 update_fcr31(env
, GETPC());
1648 uint32_t helper_float_nmadd_s(CPUMIPSState
*env
, uint32_t fst0
,
1649 uint32_t fst1
, uint32_t fst2
)
1651 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1652 fst0
= float32_add(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1653 fst0
= float32_chs(fst0
);
1655 update_fcr31(env
, GETPC());
1659 uint64_t helper_float_nmadd_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1660 uint64_t fdt1
, uint64_t fdt2
)
1662 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1663 uint32_t fsth0
= fdt0
>> 32;
1664 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1665 uint32_t fsth1
= fdt1
>> 32;
1666 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1667 uint32_t fsth2
= fdt2
>> 32;
1669 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1670 fstl0
= float32_add(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1671 fstl0
= float32_chs(fstl0
);
1672 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1673 fsth0
= float32_add(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1674 fsth0
= float32_chs(fsth0
);
1676 update_fcr31(env
, GETPC());
1677 return ((uint64_t)fsth0
<< 32) | fstl0
;
1680 uint64_t helper_float_nmsub_d(CPUMIPSState
*env
, uint64_t fst0
,
1681 uint64_t fst1
, uint64_t fst2
)
1683 fst0
= float64_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1684 fst0
= float64_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1685 fst0
= float64_chs(fst0
);
1687 update_fcr31(env
, GETPC());
1691 uint32_t helper_float_nmsub_s(CPUMIPSState
*env
, uint32_t fst0
,
1692 uint32_t fst1
, uint32_t fst2
)
1694 fst0
= float32_mul(fst0
, fst1
, &env
->active_fpu
.fp_status
);
1695 fst0
= float32_sub(fst0
, fst2
, &env
->active_fpu
.fp_status
);
1696 fst0
= float32_chs(fst0
);
1698 update_fcr31(env
, GETPC());
1702 uint64_t helper_float_nmsub_ps(CPUMIPSState
*env
, uint64_t fdt0
,
1703 uint64_t fdt1
, uint64_t fdt2
)
1705 uint32_t fstl0
= fdt0
& 0XFFFFFFFF;
1706 uint32_t fsth0
= fdt0
>> 32;
1707 uint32_t fstl1
= fdt1
& 0XFFFFFFFF;
1708 uint32_t fsth1
= fdt1
>> 32;
1709 uint32_t fstl2
= fdt2
& 0XFFFFFFFF;
1710 uint32_t fsth2
= fdt2
>> 32;
1712 fstl0
= float32_mul(fstl0
, fstl1
, &env
->active_fpu
.fp_status
);
1713 fstl0
= float32_sub(fstl0
, fstl2
, &env
->active_fpu
.fp_status
);
1714 fstl0
= float32_chs(fstl0
);
1715 fsth0
= float32_mul(fsth0
, fsth1
, &env
->active_fpu
.fp_status
);
1716 fsth0
= float32_sub(fsth0
, fsth2
, &env
->active_fpu
.fp_status
);
1717 fsth0
= float32_chs(fsth0
);
1719 update_fcr31(env
, GETPC());
1720 return ((uint64_t)fsth0
<< 32) | fstl0
;
1724 uint32_t helper_float_maddf_s(CPUMIPSState
*env
, uint32_t fs
,
1725 uint32_t ft
, uint32_t fd
)
1729 fdret
= float32_muladd(fs
, ft
, fd
, 0,
1730 &env
->active_fpu
.fp_status
);
1732 update_fcr31(env
, GETPC());
1736 uint64_t helper_float_maddf_d(CPUMIPSState
*env
, uint64_t fs
,
1737 uint64_t ft
, uint64_t fd
)
1741 fdret
= float64_muladd(fs
, ft
, fd
, 0,
1742 &env
->active_fpu
.fp_status
);
1744 update_fcr31(env
, GETPC());
1748 uint32_t helper_float_msubf_s(CPUMIPSState
*env
, uint32_t fs
,
1749 uint32_t ft
, uint32_t fd
)
1753 fdret
= float32_muladd(fs
, ft
, fd
, float_muladd_negate_product
,
1754 &env
->active_fpu
.fp_status
);
1756 update_fcr31(env
, GETPC());
1760 uint64_t helper_float_msubf_d(CPUMIPSState
*env
, uint64_t fs
,
1761 uint64_t ft
, uint64_t fd
)
1765 fdret
= float64_muladd(fs
, ft
, fd
, float_muladd_negate_product
,
1766 &env
->active_fpu
.fp_status
);
1768 update_fcr31(env
, GETPC());
1773 /* compare operations */
1774 #define FOP_COND_D(op, cond) \
1775 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1776 uint64_t fdt1, int cc) \
1780 update_fcr31(env, GETPC()); \
1782 SET_FP_COND(cc, env->active_fpu); \
1784 CLEAR_FP_COND(cc, env->active_fpu); \
1786 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1787 uint64_t fdt1, int cc) \
1790 fdt0 = float64_abs(fdt0); \
1791 fdt1 = float64_abs(fdt1); \
1793 update_fcr31(env, GETPC()); \
1795 SET_FP_COND(cc, env->active_fpu); \
1797 CLEAR_FP_COND(cc, env->active_fpu); \
1801 * NOTE: the comma operator will make "cond" to eval to false,
1802 * but float64_unordered_quiet() is still called.
1804 FOP_COND_D(f
, (float64_unordered_quiet(fdt1
, fdt0
,
1805 &env
->active_fpu
.fp_status
), 0))
1806 FOP_COND_D(un
, float64_unordered_quiet(fdt1
, fdt0
,
1807 &env
->active_fpu
.fp_status
))
1808 FOP_COND_D(eq
, float64_eq_quiet(fdt0
, fdt1
,
1809 &env
->active_fpu
.fp_status
))
1810 FOP_COND_D(ueq
, float64_unordered_quiet(fdt1
, fdt0
,
1811 &env
->active_fpu
.fp_status
)
1812 || float64_eq_quiet(fdt0
, fdt1
,
1813 &env
->active_fpu
.fp_status
))
1814 FOP_COND_D(olt
, float64_lt_quiet(fdt0
, fdt1
,
1815 &env
->active_fpu
.fp_status
))
1816 FOP_COND_D(ult
, float64_unordered_quiet(fdt1
, fdt0
,
1817 &env
->active_fpu
.fp_status
)
1818 || float64_lt_quiet(fdt0
, fdt1
,
1819 &env
->active_fpu
.fp_status
))
1820 FOP_COND_D(ole
, float64_le_quiet(fdt0
, fdt1
,
1821 &env
->active_fpu
.fp_status
))
1822 FOP_COND_D(ule
, float64_unordered_quiet(fdt1
, fdt0
,
1823 &env
->active_fpu
.fp_status
)
1824 || float64_le_quiet(fdt0
, fdt1
,
1825 &env
->active_fpu
.fp_status
))
1827 * NOTE: the comma operator will make "cond" to eval to false,
1828 * but float64_unordered() is still called.
1830 FOP_COND_D(sf
, (float64_unordered(fdt1
, fdt0
,
1831 &env
->active_fpu
.fp_status
), 0))
1832 FOP_COND_D(ngle
, float64_unordered(fdt1
, fdt0
,
1833 &env
->active_fpu
.fp_status
))
1834 FOP_COND_D(seq
, float64_eq(fdt0
, fdt1
,
1835 &env
->active_fpu
.fp_status
))
1836 FOP_COND_D(ngl
, float64_unordered(fdt1
, fdt0
,
1837 &env
->active_fpu
.fp_status
)
1838 || float64_eq(fdt0
, fdt1
,
1839 &env
->active_fpu
.fp_status
))
1840 FOP_COND_D(lt
, float64_lt(fdt0
, fdt1
,
1841 &env
->active_fpu
.fp_status
))
1842 FOP_COND_D(nge
, float64_unordered(fdt1
, fdt0
,
1843 &env
->active_fpu
.fp_status
)
1844 || float64_lt(fdt0
, fdt1
,
1845 &env
->active_fpu
.fp_status
))
1846 FOP_COND_D(le
, float64_le(fdt0
, fdt1
,
1847 &env
->active_fpu
.fp_status
))
1848 FOP_COND_D(ngt
, float64_unordered(fdt1
, fdt0
,
1849 &env
->active_fpu
.fp_status
)
1850 || float64_le(fdt0
, fdt1
,
1851 &env
->active_fpu
.fp_status
))
1853 #define FOP_COND_S(op, cond) \
1854 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1855 uint32_t fst1, int cc) \
1859 update_fcr31(env, GETPC()); \
1861 SET_FP_COND(cc, env->active_fpu); \
1863 CLEAR_FP_COND(cc, env->active_fpu); \
1865 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
1866 uint32_t fst1, int cc) \
1869 fst0 = float32_abs(fst0); \
1870 fst1 = float32_abs(fst1); \
1872 update_fcr31(env, GETPC()); \
1874 SET_FP_COND(cc, env->active_fpu); \
1876 CLEAR_FP_COND(cc, env->active_fpu); \
1880 * NOTE: the comma operator will make "cond" to eval to false,
1881 * but float32_unordered_quiet() is still called.
1883 FOP_COND_S(f
, (float32_unordered_quiet(fst1
, fst0
,
1884 &env
->active_fpu
.fp_status
), 0))
1885 FOP_COND_S(un
, float32_unordered_quiet(fst1
, fst0
,
1886 &env
->active_fpu
.fp_status
))
1887 FOP_COND_S(eq
, float32_eq_quiet(fst0
, fst1
,
1888 &env
->active_fpu
.fp_status
))
1889 FOP_COND_S(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 FOP_COND_S(olt
, float32_lt_quiet(fst0
, fst1
,
1894 &env
->active_fpu
.fp_status
))
1895 FOP_COND_S(ult
, float32_unordered_quiet(fst1
, fst0
,
1896 &env
->active_fpu
.fp_status
)
1897 || float32_lt_quiet(fst0
, fst1
,
1898 &env
->active_fpu
.fp_status
))
1899 FOP_COND_S(ole
, float32_le_quiet(fst0
, fst1
,
1900 &env
->active_fpu
.fp_status
))
1901 FOP_COND_S(ule
, float32_unordered_quiet(fst1
, fst0
,
1902 &env
->active_fpu
.fp_status
)
1903 || float32_le_quiet(fst0
, fst1
,
1904 &env
->active_fpu
.fp_status
))
1906 * NOTE: the comma operator will make "cond" to eval to false,
1907 * but float32_unordered() is still called.
1909 FOP_COND_S(sf
, (float32_unordered(fst1
, fst0
,
1910 &env
->active_fpu
.fp_status
), 0))
1911 FOP_COND_S(ngle
, float32_unordered(fst1
, fst0
,
1912 &env
->active_fpu
.fp_status
))
1913 FOP_COND_S(seq
, float32_eq(fst0
, fst1
,
1914 &env
->active_fpu
.fp_status
))
1915 FOP_COND_S(ngl
, float32_unordered(fst1
, fst0
,
1916 &env
->active_fpu
.fp_status
)
1917 || float32_eq(fst0
, fst1
,
1918 &env
->active_fpu
.fp_status
))
1919 FOP_COND_S(lt
, float32_lt(fst0
, fst1
,
1920 &env
->active_fpu
.fp_status
))
1921 FOP_COND_S(nge
, float32_unordered(fst1
, fst0
,
1922 &env
->active_fpu
.fp_status
)
1923 || float32_lt(fst0
, fst1
,
1924 &env
->active_fpu
.fp_status
))
1925 FOP_COND_S(le
, float32_le(fst0
, fst1
,
1926 &env
->active_fpu
.fp_status
))
1927 FOP_COND_S(ngt
, float32_unordered(fst1
, fst0
,
1928 &env
->active_fpu
.fp_status
)
1929 || float32_le(fst0
, fst1
,
1930 &env
->active_fpu
.fp_status
))
1932 #define FOP_COND_PS(op, condl, condh) \
1933 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1934 uint64_t fdt1, int cc) \
1936 uint32_t fst0, fsth0, fst1, fsth1; \
1938 fst0 = fdt0 & 0XFFFFFFFF; \
1939 fsth0 = fdt0 >> 32; \
1940 fst1 = fdt1 & 0XFFFFFFFF; \
1941 fsth1 = fdt1 >> 32; \
1944 update_fcr31(env, GETPC()); \
1946 SET_FP_COND(cc, env->active_fpu); \
1948 CLEAR_FP_COND(cc, env->active_fpu); \
1950 SET_FP_COND(cc + 1, env->active_fpu); \
1952 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1954 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \
1955 uint64_t fdt1, int cc) \
1957 uint32_t fst0, fsth0, fst1, fsth1; \
1959 fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \
1960 fsth0 = float32_abs(fdt0 >> 32); \
1961 fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \
1962 fsth1 = float32_abs(fdt1 >> 32); \
1965 update_fcr31(env, GETPC()); \
1967 SET_FP_COND(cc, env->active_fpu); \
1969 CLEAR_FP_COND(cc, env->active_fpu); \
1971 SET_FP_COND(cc + 1, env->active_fpu); \
1973 CLEAR_FP_COND(cc + 1, env->active_fpu); \
1977 * NOTE: the comma operator will make "cond" to eval to false,
1978 * but float32_unordered_quiet() is still called.
1980 FOP_COND_PS(f
, (float32_unordered_quiet(fst1
, fst0
,
1981 &env
->active_fpu
.fp_status
), 0),
1982 (float32_unordered_quiet(fsth1
, fsth0
,
1983 &env
->active_fpu
.fp_status
), 0))
1984 FOP_COND_PS(un
, float32_unordered_quiet(fst1
, fst0
,
1985 &env
->active_fpu
.fp_status
),
1986 float32_unordered_quiet(fsth1
, fsth0
,
1987 &env
->active_fpu
.fp_status
))
1988 FOP_COND_PS(eq
, float32_eq_quiet(fst0
, fst1
,
1989 &env
->active_fpu
.fp_status
),
1990 float32_eq_quiet(fsth0
, fsth1
,
1991 &env
->active_fpu
.fp_status
))
1992 FOP_COND_PS(ueq
, float32_unordered_quiet(fst1
, fst0
,
1993 &env
->active_fpu
.fp_status
)
1994 || float32_eq_quiet(fst0
, fst1
,
1995 &env
->active_fpu
.fp_status
),
1996 float32_unordered_quiet(fsth1
, fsth0
,
1997 &env
->active_fpu
.fp_status
)
1998 || float32_eq_quiet(fsth0
, fsth1
,
1999 &env
->active_fpu
.fp_status
))
2000 FOP_COND_PS(olt
, float32_lt_quiet(fst0
, fst1
,
2001 &env
->active_fpu
.fp_status
),
2002 float32_lt_quiet(fsth0
, fsth1
,
2003 &env
->active_fpu
.fp_status
))
2004 FOP_COND_PS(ult
, float32_unordered_quiet(fst1
, fst0
,
2005 &env
->active_fpu
.fp_status
)
2006 || float32_lt_quiet(fst0
, fst1
,
2007 &env
->active_fpu
.fp_status
),
2008 float32_unordered_quiet(fsth1
, fsth0
,
2009 &env
->active_fpu
.fp_status
)
2010 || float32_lt_quiet(fsth0
, fsth1
,
2011 &env
->active_fpu
.fp_status
))
2012 FOP_COND_PS(ole
, float32_le_quiet(fst0
, fst1
,
2013 &env
->active_fpu
.fp_status
),
2014 float32_le_quiet(fsth0
, fsth1
,
2015 &env
->active_fpu
.fp_status
))
2016 FOP_COND_PS(ule
, float32_unordered_quiet(fst1
, fst0
,
2017 &env
->active_fpu
.fp_status
)
2018 || float32_le_quiet(fst0
, fst1
,
2019 &env
->active_fpu
.fp_status
),
2020 float32_unordered_quiet(fsth1
, fsth0
,
2021 &env
->active_fpu
.fp_status
)
2022 || float32_le_quiet(fsth0
, fsth1
,
2023 &env
->active_fpu
.fp_status
))
2025 * NOTE: the comma operator will make "cond" to eval to false,
2026 * but float32_unordered() is still called.
2028 FOP_COND_PS(sf
, (float32_unordered(fst1
, fst0
,
2029 &env
->active_fpu
.fp_status
), 0),
2030 (float32_unordered(fsth1
, fsth0
,
2031 &env
->active_fpu
.fp_status
), 0))
2032 FOP_COND_PS(ngle
, float32_unordered(fst1
, fst0
,
2033 &env
->active_fpu
.fp_status
),
2034 float32_unordered(fsth1
, fsth0
,
2035 &env
->active_fpu
.fp_status
))
2036 FOP_COND_PS(seq
, float32_eq(fst0
, fst1
,
2037 &env
->active_fpu
.fp_status
),
2038 float32_eq(fsth0
, fsth1
,
2039 &env
->active_fpu
.fp_status
))
2040 FOP_COND_PS(ngl
, float32_unordered(fst1
, fst0
,
2041 &env
->active_fpu
.fp_status
)
2042 || float32_eq(fst0
, fst1
,
2043 &env
->active_fpu
.fp_status
),
2044 float32_unordered(fsth1
, fsth0
,
2045 &env
->active_fpu
.fp_status
)
2046 || float32_eq(fsth0
, fsth1
,
2047 &env
->active_fpu
.fp_status
))
2048 FOP_COND_PS(lt
, float32_lt(fst0
, fst1
,
2049 &env
->active_fpu
.fp_status
),
2050 float32_lt(fsth0
, fsth1
,
2051 &env
->active_fpu
.fp_status
))
2052 FOP_COND_PS(nge
, float32_unordered(fst1
, fst0
,
2053 &env
->active_fpu
.fp_status
)
2054 || float32_lt(fst0
, fst1
,
2055 &env
->active_fpu
.fp_status
),
2056 float32_unordered(fsth1
, fsth0
,
2057 &env
->active_fpu
.fp_status
)
2058 || float32_lt(fsth0
, fsth1
,
2059 &env
->active_fpu
.fp_status
))
2060 FOP_COND_PS(le
, float32_le(fst0
, fst1
,
2061 &env
->active_fpu
.fp_status
),
2062 float32_le(fsth0
, fsth1
,
2063 &env
->active_fpu
.fp_status
))
2064 FOP_COND_PS(ngt
, float32_unordered(fst1
, fst0
,
2065 &env
->active_fpu
.fp_status
)
2066 || float32_le(fst0
, fst1
,
2067 &env
->active_fpu
.fp_status
),
2068 float32_unordered(fsth1
, fsth0
,
2069 &env
->active_fpu
.fp_status
)
2070 || float32_le(fsth0
, fsth1
,
2071 &env
->active_fpu
.fp_status
))
2073 /* R6 compare operations */
2074 #define FOP_CONDN_D(op, cond) \
2075 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \
2080 update_fcr31(env, GETPC()); \
2089 * NOTE: the comma operator will make "cond" to eval to false,
2090 * but float64_unordered_quiet() is still called.
2092 FOP_CONDN_D(af
, (float64_unordered_quiet(fdt1
, fdt0
,
2093 &env
->active_fpu
.fp_status
), 0))
2094 FOP_CONDN_D(un
, (float64_unordered_quiet(fdt1
, fdt0
,
2095 &env
->active_fpu
.fp_status
)))
2096 FOP_CONDN_D(eq
, (float64_eq_quiet(fdt0
, fdt1
,
2097 &env
->active_fpu
.fp_status
)))
2098 FOP_CONDN_D(ueq
, (float64_unordered_quiet(fdt1
, fdt0
,
2099 &env
->active_fpu
.fp_status
)
2100 || float64_eq_quiet(fdt0
, fdt1
,
2101 &env
->active_fpu
.fp_status
)))
2102 FOP_CONDN_D(lt
, (float64_lt_quiet(fdt0
, fdt1
,
2103 &env
->active_fpu
.fp_status
)))
2104 FOP_CONDN_D(ult
, (float64_unordered_quiet(fdt1
, fdt0
,
2105 &env
->active_fpu
.fp_status
)
2106 || float64_lt_quiet(fdt0
, fdt1
,
2107 &env
->active_fpu
.fp_status
)))
2108 FOP_CONDN_D(le
, (float64_le_quiet(fdt0
, fdt1
,
2109 &env
->active_fpu
.fp_status
)))
2110 FOP_CONDN_D(ule
, (float64_unordered_quiet(fdt1
, fdt0
,
2111 &env
->active_fpu
.fp_status
)
2112 || float64_le_quiet(fdt0
, fdt1
,
2113 &env
->active_fpu
.fp_status
)))
2115 * NOTE: the comma operator will make "cond" to eval to false,
2116 * but float64_unordered() is still called.\
2118 FOP_CONDN_D(saf
, (float64_unordered(fdt1
, fdt0
,
2119 &env
->active_fpu
.fp_status
), 0))
2120 FOP_CONDN_D(sun
, (float64_unordered(fdt1
, fdt0
,
2121 &env
->active_fpu
.fp_status
)))
2122 FOP_CONDN_D(seq
, (float64_eq(fdt0
, fdt1
,
2123 &env
->active_fpu
.fp_status
)))
2124 FOP_CONDN_D(sueq
, (float64_unordered(fdt1
, fdt0
,
2125 &env
->active_fpu
.fp_status
)
2126 || float64_eq(fdt0
, fdt1
,
2127 &env
->active_fpu
.fp_status
)))
2128 FOP_CONDN_D(slt
, (float64_lt(fdt0
, fdt1
,
2129 &env
->active_fpu
.fp_status
)))
2130 FOP_CONDN_D(sult
, (float64_unordered(fdt1
, fdt0
,
2131 &env
->active_fpu
.fp_status
)
2132 || float64_lt(fdt0
, fdt1
,
2133 &env
->active_fpu
.fp_status
)))
2134 FOP_CONDN_D(sle
, (float64_le(fdt0
, fdt1
,
2135 &env
->active_fpu
.fp_status
)))
2136 FOP_CONDN_D(sule
, (float64_unordered(fdt1
, fdt0
,
2137 &env
->active_fpu
.fp_status
)
2138 || float64_le(fdt0
, fdt1
,
2139 &env
->active_fpu
.fp_status
)))
2140 FOP_CONDN_D(or, (float64_le_quiet(fdt1
, fdt0
,
2141 &env
->active_fpu
.fp_status
)
2142 || float64_le_quiet(fdt0
, fdt1
,
2143 &env
->active_fpu
.fp_status
)))
2144 FOP_CONDN_D(une
, (float64_unordered_quiet(fdt1
, fdt0
,
2145 &env
->active_fpu
.fp_status
)
2146 || float64_lt_quiet(fdt1
, fdt0
,
2147 &env
->active_fpu
.fp_status
)
2148 || float64_lt_quiet(fdt0
, fdt1
,
2149 &env
->active_fpu
.fp_status
)))
2150 FOP_CONDN_D(ne
, (float64_lt_quiet(fdt1
, fdt0
,
2151 &env
->active_fpu
.fp_status
)
2152 || float64_lt_quiet(fdt0
, fdt1
,
2153 &env
->active_fpu
.fp_status
)))
2154 FOP_CONDN_D(sor
, (float64_le(fdt1
, fdt0
,
2155 &env
->active_fpu
.fp_status
)
2156 || float64_le(fdt0
, fdt1
,
2157 &env
->active_fpu
.fp_status
)))
2158 FOP_CONDN_D(sune
, (float64_unordered(fdt1
, fdt0
,
2159 &env
->active_fpu
.fp_status
)
2160 || float64_lt(fdt1
, fdt0
,
2161 &env
->active_fpu
.fp_status
)
2162 || float64_lt(fdt0
, fdt1
,
2163 &env
->active_fpu
.fp_status
)))
2164 FOP_CONDN_D(sne
, (float64_lt(fdt1
, fdt0
,
2165 &env
->active_fpu
.fp_status
)
2166 || float64_lt(fdt0
, fdt1
,
2167 &env
->active_fpu
.fp_status
)))
2169 #define FOP_CONDN_S(op, cond) \
2170 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \
2175 update_fcr31(env, GETPC()); \
2184 * NOTE: the comma operator will make "cond" to eval to false,
2185 * but float32_unordered_quiet() is still called.
2187 FOP_CONDN_S(af
, (float32_unordered_quiet(fst1
, fst0
,
2188 &env
->active_fpu
.fp_status
), 0))
2189 FOP_CONDN_S(un
, (float32_unordered_quiet(fst1
, fst0
,
2190 &env
->active_fpu
.fp_status
)))
2191 FOP_CONDN_S(eq
, (float32_eq_quiet(fst0
, fst1
,
2192 &env
->active_fpu
.fp_status
)))
2193 FOP_CONDN_S(ueq
, (float32_unordered_quiet(fst1
, fst0
,
2194 &env
->active_fpu
.fp_status
)
2195 || float32_eq_quiet(fst0
, fst1
,
2196 &env
->active_fpu
.fp_status
)))
2197 FOP_CONDN_S(lt
, (float32_lt_quiet(fst0
, fst1
,
2198 &env
->active_fpu
.fp_status
)))
2199 FOP_CONDN_S(ult
, (float32_unordered_quiet(fst1
, fst0
,
2200 &env
->active_fpu
.fp_status
)
2201 || float32_lt_quiet(fst0
, fst1
,
2202 &env
->active_fpu
.fp_status
)))
2203 FOP_CONDN_S(le
, (float32_le_quiet(fst0
, fst1
,
2204 &env
->active_fpu
.fp_status
)))
2205 FOP_CONDN_S(ule
, (float32_unordered_quiet(fst1
, fst0
,
2206 &env
->active_fpu
.fp_status
)
2207 || float32_le_quiet(fst0
, fst1
,
2208 &env
->active_fpu
.fp_status
)))
2210 * NOTE: the comma operator will make "cond" to eval to false,
2211 * but float32_unordered() is still called.
2213 FOP_CONDN_S(saf
, (float32_unordered(fst1
, fst0
,
2214 &env
->active_fpu
.fp_status
), 0))
2215 FOP_CONDN_S(sun
, (float32_unordered(fst1
, fst0
,
2216 &env
->active_fpu
.fp_status
)))
2217 FOP_CONDN_S(seq
, (float32_eq(fst0
, fst1
,
2218 &env
->active_fpu
.fp_status
)))
2219 FOP_CONDN_S(sueq
, (float32_unordered(fst1
, fst0
,
2220 &env
->active_fpu
.fp_status
)
2221 || float32_eq(fst0
, fst1
,
2222 &env
->active_fpu
.fp_status
)))
2223 FOP_CONDN_S(slt
, (float32_lt(fst0
, fst1
,
2224 &env
->active_fpu
.fp_status
)))
2225 FOP_CONDN_S(sult
, (float32_unordered(fst1
, fst0
,
2226 &env
->active_fpu
.fp_status
)
2227 || float32_lt(fst0
, fst1
,
2228 &env
->active_fpu
.fp_status
)))
2229 FOP_CONDN_S(sle
, (float32_le(fst0
, fst1
,
2230 &env
->active_fpu
.fp_status
)))
2231 FOP_CONDN_S(sule
, (float32_unordered(fst1
, fst0
,
2232 &env
->active_fpu
.fp_status
)
2233 || float32_le(fst0
, fst1
,
2234 &env
->active_fpu
.fp_status
)))
2235 FOP_CONDN_S(or, (float32_le_quiet(fst1
, fst0
,
2236 &env
->active_fpu
.fp_status
)
2237 || float32_le_quiet(fst0
, fst1
,
2238 &env
->active_fpu
.fp_status
)))
2239 FOP_CONDN_S(une
, (float32_unordered_quiet(fst1
, fst0
,
2240 &env
->active_fpu
.fp_status
)
2241 || float32_lt_quiet(fst1
, fst0
,
2242 &env
->active_fpu
.fp_status
)
2243 || float32_lt_quiet(fst0
, fst1
,
2244 &env
->active_fpu
.fp_status
)))
2245 FOP_CONDN_S(ne
, (float32_lt_quiet(fst1
, fst0
,
2246 &env
->active_fpu
.fp_status
)
2247 || float32_lt_quiet(fst0
, fst1
,
2248 &env
->active_fpu
.fp_status
)))
2249 FOP_CONDN_S(sor
, (float32_le(fst1
, fst0
,
2250 &env
->active_fpu
.fp_status
)
2251 || float32_le(fst0
, fst1
,
2252 &env
->active_fpu
.fp_status
)))
2253 FOP_CONDN_S(sune
, (float32_unordered(fst1
, fst0
,
2254 &env
->active_fpu
.fp_status
)
2255 || float32_lt(fst1
, fst0
,
2256 &env
->active_fpu
.fp_status
)
2257 || float32_lt(fst0
, fst1
,
2258 &env
->active_fpu
.fp_status
)))
2259 FOP_CONDN_S(sne
, (float32_lt(fst1
, fst0
,
2260 &env
->active_fpu
.fp_status
)
2261 || float32_lt(fst0
, fst1
,
2262 &env
->active_fpu
.fp_status
)))