xref: /qemu/target/mips/tcg/fpu_helper.c (revision bcca8c4b1a044e8ef4ad2c88cbde217e1a38baeb)
17b77f048SAleksandar Markovic /*
27b77f048SAleksandar Markovic  *  Helpers for emulation of FPU-related MIPS instructions.
37b77f048SAleksandar Markovic  *
47b77f048SAleksandar Markovic  *  Copyright (C) 2004-2005  Jocelyn Mayer
57b77f048SAleksandar Markovic  *  Copyright (C) 2020  Wave Computing, Inc.
67b77f048SAleksandar Markovic  *  Copyright (C) 2020  Aleksandar Markovic <amarkovic@wavecomp.com>
77b77f048SAleksandar Markovic  *
87b77f048SAleksandar Markovic  * This library is free software; you can redistribute it and/or
97b77f048SAleksandar Markovic  * modify it under the terms of the GNU Lesser General Public
107b77f048SAleksandar Markovic  * License as published by the Free Software Foundation; either
117b77f048SAleksandar Markovic  * version 2 of the License, or (at your option) any later version.
127b77f048SAleksandar Markovic  *
137b77f048SAleksandar Markovic  * This library is distributed in the hope that it will be useful,
147b77f048SAleksandar Markovic  * but WITHOUT ANY WARRANTY; without even the implied warranty of
157b77f048SAleksandar Markovic  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
167b77f048SAleksandar Markovic  * Lesser General Public License for more details.
177b77f048SAleksandar Markovic  *
187b77f048SAleksandar Markovic  * You should have received a copy of the GNU Lesser General Public
197b77f048SAleksandar Markovic  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
207b77f048SAleksandar Markovic  *
217b77f048SAleksandar Markovic  */
227b77f048SAleksandar Markovic 
237b77f048SAleksandar Markovic #include "qemu/osdep.h"
247b77f048SAleksandar Markovic #include "qemu/main-loop.h"
257b77f048SAleksandar Markovic #include "cpu.h"
267b77f048SAleksandar Markovic #include "internal.h"
277b77f048SAleksandar Markovic #include "qemu/host-utils.h"
287b77f048SAleksandar Markovic #include "exec/helper-proto.h"
297b77f048SAleksandar Markovic #include "exec/exec-all.h"
307b77f048SAleksandar Markovic #include "exec/cpu_ldst.h"
317b77f048SAleksandar Markovic #include "exec/memop.h"
327b77f048SAleksandar Markovic #include "sysemu/kvm.h"
337b77f048SAleksandar Markovic #include "fpu/softfloat.h"
347b77f048SAleksandar Markovic 
357b77f048SAleksandar Markovic 
367b77f048SAleksandar Markovic /* Complex FPU operations which may need stack space. */
377b77f048SAleksandar Markovic 
387b77f048SAleksandar Markovic #define FLOAT_TWO32 make_float32(1 << 30)
397b77f048SAleksandar Markovic #define FLOAT_TWO64 make_float64(1ULL << 62)
407b77f048SAleksandar Markovic 
417b77f048SAleksandar Markovic #define FP_TO_INT32_OVERFLOW 0x7fffffff
427b77f048SAleksandar Markovic #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
437b77f048SAleksandar Markovic 
447b77f048SAleksandar Markovic /* convert MIPS rounding mode in FCR31 to IEEE library */
457b77f048SAleksandar Markovic unsigned int ieee_rm[] = {
467b77f048SAleksandar Markovic     float_round_nearest_even,
477b77f048SAleksandar Markovic     float_round_to_zero,
487b77f048SAleksandar Markovic     float_round_up,
497b77f048SAleksandar Markovic     float_round_down
507b77f048SAleksandar Markovic };
517b77f048SAleksandar Markovic 
527b77f048SAleksandar Markovic target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
537b77f048SAleksandar Markovic {
547b77f048SAleksandar Markovic     target_ulong arg1 = 0;
557b77f048SAleksandar Markovic 
567b77f048SAleksandar Markovic     switch (reg) {
577b77f048SAleksandar Markovic     case 0:
587b77f048SAleksandar Markovic         arg1 = (int32_t)env->active_fpu.fcr0;
597b77f048SAleksandar Markovic         break;
607b77f048SAleksandar Markovic     case 1:
617b77f048SAleksandar Markovic         /* UFR Support - Read Status FR */
627b77f048SAleksandar Markovic         if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
637b77f048SAleksandar Markovic             if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
647b77f048SAleksandar Markovic                 arg1 = (int32_t)
657b77f048SAleksandar Markovic                        ((env->CP0_Status & (1  << CP0St_FR)) >> CP0St_FR);
667b77f048SAleksandar Markovic             } else {
677b77f048SAleksandar Markovic                 do_raise_exception(env, EXCP_RI, GETPC());
687b77f048SAleksandar Markovic             }
697b77f048SAleksandar Markovic         }
707b77f048SAleksandar Markovic         break;
717b77f048SAleksandar Markovic     case 5:
727b77f048SAleksandar Markovic         /* FRE Support - read Config5.FRE bit */
737b77f048SAleksandar Markovic         if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
747b77f048SAleksandar Markovic             if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
757b77f048SAleksandar Markovic                 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
767b77f048SAleksandar Markovic             } else {
777b77f048SAleksandar Markovic                 helper_raise_exception(env, EXCP_RI);
787b77f048SAleksandar Markovic             }
797b77f048SAleksandar Markovic         }
807b77f048SAleksandar Markovic         break;
817b77f048SAleksandar Markovic     case 25:
827b77f048SAleksandar Markovic         arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
837b77f048SAleksandar Markovic                ((env->active_fpu.fcr31 >> 23) & 0x1);
847b77f048SAleksandar Markovic         break;
857b77f048SAleksandar Markovic     case 26:
867b77f048SAleksandar Markovic         arg1 = env->active_fpu.fcr31 & 0x0003f07c;
877b77f048SAleksandar Markovic         break;
887b77f048SAleksandar Markovic     case 28:
897b77f048SAleksandar Markovic         arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
907b77f048SAleksandar Markovic                ((env->active_fpu.fcr31 >> 22) & 0x4);
917b77f048SAleksandar Markovic         break;
927b77f048SAleksandar Markovic     default:
937b77f048SAleksandar Markovic         arg1 = (int32_t)env->active_fpu.fcr31;
947b77f048SAleksandar Markovic         break;
957b77f048SAleksandar Markovic     }
967b77f048SAleksandar Markovic 
977b77f048SAleksandar Markovic     return arg1;
987b77f048SAleksandar Markovic }
997b77f048SAleksandar Markovic 
1007b77f048SAleksandar Markovic void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
1017b77f048SAleksandar Markovic {
1027b77f048SAleksandar Markovic     switch (fs) {
1037b77f048SAleksandar Markovic     case 1:
1047b77f048SAleksandar Markovic         /* UFR Alias - Reset Status FR */
1057b77f048SAleksandar Markovic         if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
1067b77f048SAleksandar Markovic             return;
1077b77f048SAleksandar Markovic         }
1087b77f048SAleksandar Markovic         if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
1097b77f048SAleksandar Markovic             env->CP0_Status &= ~(1 << CP0St_FR);
1107b77f048SAleksandar Markovic             compute_hflags(env);
1117b77f048SAleksandar Markovic         } else {
1127b77f048SAleksandar Markovic             do_raise_exception(env, EXCP_RI, GETPC());
1137b77f048SAleksandar Markovic         }
1147b77f048SAleksandar Markovic         break;
1157b77f048SAleksandar Markovic     case 4:
1167b77f048SAleksandar Markovic         /* UNFR Alias - Set Status FR */
1177b77f048SAleksandar Markovic         if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
1187b77f048SAleksandar Markovic             return;
1197b77f048SAleksandar Markovic         }
1207b77f048SAleksandar Markovic         if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
1217b77f048SAleksandar Markovic             env->CP0_Status |= (1 << CP0St_FR);
1227b77f048SAleksandar Markovic             compute_hflags(env);
1237b77f048SAleksandar Markovic         } else {
1247b77f048SAleksandar Markovic             do_raise_exception(env, EXCP_RI, GETPC());
1257b77f048SAleksandar Markovic         }
1267b77f048SAleksandar Markovic         break;
1277b77f048SAleksandar Markovic     case 5:
1287b77f048SAleksandar Markovic         /* FRE Support - clear Config5.FRE bit */
1297b77f048SAleksandar Markovic         if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
1307b77f048SAleksandar Markovic             return;
1317b77f048SAleksandar Markovic         }
1327b77f048SAleksandar Markovic         if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
1337b77f048SAleksandar Markovic             env->CP0_Config5 &= ~(1 << CP0C5_FRE);
1347b77f048SAleksandar Markovic             compute_hflags(env);
1357b77f048SAleksandar Markovic         } else {
1367b77f048SAleksandar Markovic             helper_raise_exception(env, EXCP_RI);
1377b77f048SAleksandar Markovic         }
1387b77f048SAleksandar Markovic         break;
1397b77f048SAleksandar Markovic     case 6:
1407b77f048SAleksandar Markovic         /* FRE Support - set Config5.FRE bit */
1417b77f048SAleksandar Markovic         if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
1427b77f048SAleksandar Markovic             return;
1437b77f048SAleksandar Markovic         }
1447b77f048SAleksandar Markovic         if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
1457b77f048SAleksandar Markovic             env->CP0_Config5 |= (1 << CP0C5_FRE);
1467b77f048SAleksandar Markovic             compute_hflags(env);
1477b77f048SAleksandar Markovic         } else {
1487b77f048SAleksandar Markovic             helper_raise_exception(env, EXCP_RI);
1497b77f048SAleksandar Markovic         }
1507b77f048SAleksandar Markovic         break;
1517b77f048SAleksandar Markovic     case 25:
1527b77f048SAleksandar Markovic         if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) {
1537b77f048SAleksandar Markovic             return;
1547b77f048SAleksandar Markovic         }
1557b77f048SAleksandar Markovic         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
1567b77f048SAleksandar Markovic                                 ((arg1 & 0xfe) << 24) |
1577b77f048SAleksandar Markovic                                 ((arg1 & 0x1) << 23);
1587b77f048SAleksandar Markovic         break;
1597b77f048SAleksandar Markovic     case 26:
1607b77f048SAleksandar Markovic         if (arg1 & 0x007c0000) {
1617b77f048SAleksandar Markovic             return;
1627b77f048SAleksandar Markovic         }
1637b77f048SAleksandar Markovic         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
1647b77f048SAleksandar Markovic                                 (arg1 & 0x0003f07c);
1657b77f048SAleksandar Markovic         break;
1667b77f048SAleksandar Markovic     case 28:
1677b77f048SAleksandar Markovic         if (arg1 & 0x007c0000) {
1687b77f048SAleksandar Markovic             return;
1697b77f048SAleksandar Markovic         }
1707b77f048SAleksandar Markovic         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
1717b77f048SAleksandar Markovic                                 (arg1 & 0x00000f83) |
1727b77f048SAleksandar Markovic                                 ((arg1 & 0x4) << 22);
1737b77f048SAleksandar Markovic         break;
1747b77f048SAleksandar Markovic     case 31:
1757b77f048SAleksandar Markovic         env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
1767b77f048SAleksandar Markovic                (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
1777b77f048SAleksandar Markovic         break;
1787b77f048SAleksandar Markovic     default:
1797b77f048SAleksandar Markovic         if (env->insn_flags & ISA_MIPS32R6) {
1807b77f048SAleksandar Markovic             do_raise_exception(env, EXCP_RI, GETPC());
1817b77f048SAleksandar Markovic         }
1827b77f048SAleksandar Markovic         return;
1837b77f048SAleksandar Markovic     }
1847b77f048SAleksandar Markovic     restore_fp_status(env);
1857b77f048SAleksandar Markovic     set_float_exception_flags(0, &env->active_fpu.fp_status);
1867b77f048SAleksandar Markovic     if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
1877b77f048SAleksandar Markovic         GET_FP_CAUSE(env->active_fpu.fcr31)) {
1887b77f048SAleksandar Markovic         do_raise_exception(env, EXCP_FPE, GETPC());
1897b77f048SAleksandar Markovic     }
1907b77f048SAleksandar Markovic }
1917b77f048SAleksandar Markovic 
1927b77f048SAleksandar Markovic int ieee_ex_to_mips(int xcpt)
1937b77f048SAleksandar Markovic {
1947b77f048SAleksandar Markovic     int ret = 0;
1957b77f048SAleksandar Markovic     if (xcpt) {
1967b77f048SAleksandar Markovic         if (xcpt & float_flag_invalid) {
1977b77f048SAleksandar Markovic             ret |= FP_INVALID;
1987b77f048SAleksandar Markovic         }
1997b77f048SAleksandar Markovic         if (xcpt & float_flag_overflow) {
2007b77f048SAleksandar Markovic             ret |= FP_OVERFLOW;
2017b77f048SAleksandar Markovic         }
2027b77f048SAleksandar Markovic         if (xcpt & float_flag_underflow) {
2037b77f048SAleksandar Markovic             ret |= FP_UNDERFLOW;
2047b77f048SAleksandar Markovic         }
2057b77f048SAleksandar Markovic         if (xcpt & float_flag_divbyzero) {
2067b77f048SAleksandar Markovic             ret |= FP_DIV0;
2077b77f048SAleksandar Markovic         }
2087b77f048SAleksandar Markovic         if (xcpt & float_flag_inexact) {
2097b77f048SAleksandar Markovic             ret |= FP_INEXACT;
2107b77f048SAleksandar Markovic         }
2117b77f048SAleksandar Markovic     }
2127b77f048SAleksandar Markovic     return ret;
2137b77f048SAleksandar Markovic }
2147b77f048SAleksandar Markovic 
2157b77f048SAleksandar Markovic static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
2167b77f048SAleksandar Markovic {
2177b77f048SAleksandar Markovic     int tmp = ieee_ex_to_mips(get_float_exception_flags(
2187b77f048SAleksandar Markovic                                   &env->active_fpu.fp_status));
2197b77f048SAleksandar Markovic 
2207b77f048SAleksandar Markovic     SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
2217b77f048SAleksandar Markovic 
2227b77f048SAleksandar Markovic     if (tmp) {
2237b77f048SAleksandar Markovic         set_float_exception_flags(0, &env->active_fpu.fp_status);
2247b77f048SAleksandar Markovic 
2257b77f048SAleksandar Markovic         if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp) {
2267b77f048SAleksandar Markovic             do_raise_exception(env, EXCP_FPE, pc);
2277b77f048SAleksandar Markovic         } else {
2287b77f048SAleksandar Markovic             UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
2297b77f048SAleksandar Markovic         }
2307b77f048SAleksandar Markovic     }
2317b77f048SAleksandar Markovic }
2327b77f048SAleksandar Markovic 
2337b77f048SAleksandar Markovic /*
2347b77f048SAleksandar Markovic  * Float support.
2357b77f048SAleksandar Markovic  * Single precition routines have a "s" suffix, double precision a
2367b77f048SAleksandar Markovic  * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
2377b77f048SAleksandar Markovic  * paired single lower "pl", paired single upper "pu".
2387b77f048SAleksandar Markovic  */
2397b77f048SAleksandar Markovic 
2407b77f048SAleksandar Markovic /* unary operations, modifying fp status  */
2417b77f048SAleksandar Markovic uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
2427b77f048SAleksandar Markovic {
2437b77f048SAleksandar Markovic     fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
2447b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2457b77f048SAleksandar Markovic     return fdt0;
2467b77f048SAleksandar Markovic }
2477b77f048SAleksandar Markovic 
2487b77f048SAleksandar Markovic uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
2497b77f048SAleksandar Markovic {
2507b77f048SAleksandar Markovic     fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
2517b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2527b77f048SAleksandar Markovic     return fst0;
2537b77f048SAleksandar Markovic }
2547b77f048SAleksandar Markovic 
2557b77f048SAleksandar Markovic uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
2567b77f048SAleksandar Markovic {
2577b77f048SAleksandar Markovic     uint64_t fdt2;
2587b77f048SAleksandar Markovic 
2597b77f048SAleksandar Markovic     fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
2607b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2617b77f048SAleksandar Markovic     return fdt2;
2627b77f048SAleksandar Markovic }
2637b77f048SAleksandar Markovic 
2647b77f048SAleksandar Markovic uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
2657b77f048SAleksandar Markovic {
2667b77f048SAleksandar Markovic     uint64_t fdt2;
2677b77f048SAleksandar Markovic 
2687b77f048SAleksandar Markovic     fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
2697b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2707b77f048SAleksandar Markovic     return fdt2;
2717b77f048SAleksandar Markovic }
2727b77f048SAleksandar Markovic 
2737b77f048SAleksandar Markovic uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
2747b77f048SAleksandar Markovic {
2757b77f048SAleksandar Markovic     uint64_t fdt2;
2767b77f048SAleksandar Markovic 
2777b77f048SAleksandar Markovic     fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
2787b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2797b77f048SAleksandar Markovic     return fdt2;
2807b77f048SAleksandar Markovic }
2817b77f048SAleksandar Markovic 
2827b77f048SAleksandar Markovic uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
2837b77f048SAleksandar Markovic {
2847b77f048SAleksandar Markovic     uint64_t dt2;
2857b77f048SAleksandar Markovic 
2867b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
2877b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
2887b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
2897b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
2907b77f048SAleksandar Markovic     }
2917b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2927b77f048SAleksandar Markovic     return dt2;
2937b77f048SAleksandar Markovic }
2947b77f048SAleksandar Markovic 
2957b77f048SAleksandar Markovic uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
2967b77f048SAleksandar Markovic {
2977b77f048SAleksandar Markovic     uint64_t dt2;
2987b77f048SAleksandar Markovic 
2997b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
3007b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
3017b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
3027b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
3037b77f048SAleksandar Markovic     }
3047b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3057b77f048SAleksandar Markovic     return dt2;
3067b77f048SAleksandar Markovic }
3077b77f048SAleksandar Markovic 
3087b77f048SAleksandar Markovic uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
3097b77f048SAleksandar Markovic {
3107b77f048SAleksandar Markovic     uint32_t fst2;
3117b77f048SAleksandar Markovic     uint32_t fsth2;
3127b77f048SAleksandar Markovic 
3137b77f048SAleksandar Markovic     fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
3147b77f048SAleksandar Markovic     fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
3157b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3167b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
3177b77f048SAleksandar Markovic }
3187b77f048SAleksandar Markovic 
3197b77f048SAleksandar Markovic uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
3207b77f048SAleksandar Markovic {
3217b77f048SAleksandar Markovic     uint32_t wt2;
3227b77f048SAleksandar Markovic     uint32_t wth2;
3237b77f048SAleksandar Markovic     int excp, excph;
3247b77f048SAleksandar Markovic 
3257b77f048SAleksandar Markovic     wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
3267b77f048SAleksandar Markovic     excp = get_float_exception_flags(&env->active_fpu.fp_status);
3277b77f048SAleksandar Markovic     if (excp & (float_flag_overflow | float_flag_invalid)) {
3287b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
3297b77f048SAleksandar Markovic     }
3307b77f048SAleksandar Markovic 
3317b77f048SAleksandar Markovic     set_float_exception_flags(0, &env->active_fpu.fp_status);
3327b77f048SAleksandar Markovic     wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
3337b77f048SAleksandar Markovic     excph = get_float_exception_flags(&env->active_fpu.fp_status);
3347b77f048SAleksandar Markovic     if (excph & (float_flag_overflow | float_flag_invalid)) {
3357b77f048SAleksandar Markovic         wth2 = FP_TO_INT32_OVERFLOW;
3367b77f048SAleksandar Markovic     }
3377b77f048SAleksandar Markovic 
3387b77f048SAleksandar Markovic     set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
3397b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3407b77f048SAleksandar Markovic 
3417b77f048SAleksandar Markovic     return ((uint64_t)wth2 << 32) | wt2;
3427b77f048SAleksandar Markovic }
3437b77f048SAleksandar Markovic 
3447b77f048SAleksandar Markovic uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
3457b77f048SAleksandar Markovic {
3467b77f048SAleksandar Markovic     uint32_t fst2;
3477b77f048SAleksandar Markovic 
3487b77f048SAleksandar Markovic     fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
3497b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3507b77f048SAleksandar Markovic     return fst2;
3517b77f048SAleksandar Markovic }
3527b77f048SAleksandar Markovic 
3537b77f048SAleksandar Markovic uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
3547b77f048SAleksandar Markovic {
3557b77f048SAleksandar Markovic     uint32_t fst2;
3567b77f048SAleksandar Markovic 
3577b77f048SAleksandar Markovic     fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
3587b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3597b77f048SAleksandar Markovic     return fst2;
3607b77f048SAleksandar Markovic }
3617b77f048SAleksandar Markovic 
3627b77f048SAleksandar Markovic uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
3637b77f048SAleksandar Markovic {
3647b77f048SAleksandar Markovic     uint32_t fst2;
3657b77f048SAleksandar Markovic 
3667b77f048SAleksandar Markovic     fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
3677b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3687b77f048SAleksandar Markovic     return fst2;
3697b77f048SAleksandar Markovic }
3707b77f048SAleksandar Markovic 
3717b77f048SAleksandar Markovic uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
3727b77f048SAleksandar Markovic {
3737b77f048SAleksandar Markovic     uint32_t wt2;
3747b77f048SAleksandar Markovic 
3757b77f048SAleksandar Markovic     wt2 = wt0;
3767b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3777b77f048SAleksandar Markovic     return wt2;
3787b77f048SAleksandar Markovic }
3797b77f048SAleksandar Markovic 
3807b77f048SAleksandar Markovic uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
3817b77f048SAleksandar Markovic {
3827b77f048SAleksandar Markovic     uint32_t wt2;
3837b77f048SAleksandar Markovic 
3847b77f048SAleksandar Markovic     wt2 = wth0;
3857b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3867b77f048SAleksandar Markovic     return wt2;
3877b77f048SAleksandar Markovic }
3887b77f048SAleksandar Markovic 
3897b77f048SAleksandar Markovic uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
3907b77f048SAleksandar Markovic {
3917b77f048SAleksandar Markovic     uint32_t wt2;
3927b77f048SAleksandar Markovic 
3937b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
3947b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
3957b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
3967b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
3977b77f048SAleksandar Markovic     }
3987b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3997b77f048SAleksandar Markovic     return wt2;
4007b77f048SAleksandar Markovic }
4017b77f048SAleksandar Markovic 
4027b77f048SAleksandar Markovic uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
4037b77f048SAleksandar Markovic {
4047b77f048SAleksandar Markovic     uint32_t wt2;
4057b77f048SAleksandar Markovic 
4067b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
4077b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4087b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4097b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4107b77f048SAleksandar Markovic     }
4117b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4127b77f048SAleksandar Markovic     return wt2;
4137b77f048SAleksandar Markovic }
4147b77f048SAleksandar Markovic 
4157b77f048SAleksandar Markovic uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
4167b77f048SAleksandar Markovic {
4177b77f048SAleksandar Markovic     uint64_t dt2;
4187b77f048SAleksandar Markovic 
4197b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4207b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4217b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
4227b77f048SAleksandar Markovic     restore_rounding_mode(env);
4237b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4247b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4257b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
4267b77f048SAleksandar Markovic     }
4277b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4287b77f048SAleksandar Markovic     return dt2;
4297b77f048SAleksandar Markovic }
4307b77f048SAleksandar Markovic 
4317b77f048SAleksandar Markovic uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
4327b77f048SAleksandar Markovic {
4337b77f048SAleksandar Markovic     uint64_t dt2;
4347b77f048SAleksandar Markovic 
4357b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4367b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4377b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
4387b77f048SAleksandar Markovic     restore_rounding_mode(env);
4397b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4407b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4417b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
4427b77f048SAleksandar Markovic     }
4437b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4447b77f048SAleksandar Markovic     return dt2;
4457b77f048SAleksandar Markovic }
4467b77f048SAleksandar Markovic 
4477b77f048SAleksandar Markovic uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
4487b77f048SAleksandar Markovic {
4497b77f048SAleksandar Markovic     uint32_t wt2;
4507b77f048SAleksandar Markovic 
4517b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4527b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4537b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
4547b77f048SAleksandar Markovic     restore_rounding_mode(env);
4557b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4567b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4577b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4587b77f048SAleksandar Markovic     }
4597b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4607b77f048SAleksandar Markovic     return wt2;
4617b77f048SAleksandar Markovic }
4627b77f048SAleksandar Markovic 
4637b77f048SAleksandar Markovic uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
4647b77f048SAleksandar Markovic {
4657b77f048SAleksandar Markovic     uint32_t wt2;
4667b77f048SAleksandar Markovic 
4677b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4687b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4697b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
4707b77f048SAleksandar Markovic     restore_rounding_mode(env);
4717b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4727b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4737b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4747b77f048SAleksandar Markovic     }
4757b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4767b77f048SAleksandar Markovic     return wt2;
4777b77f048SAleksandar Markovic }
4787b77f048SAleksandar Markovic 
4797b77f048SAleksandar Markovic uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
4807b77f048SAleksandar Markovic {
4817b77f048SAleksandar Markovic     uint64_t dt2;
4827b77f048SAleksandar Markovic 
4837b77f048SAleksandar Markovic     dt2 = float64_to_int64_round_to_zero(fdt0,
4847b77f048SAleksandar Markovic                                          &env->active_fpu.fp_status);
4857b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4867b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4877b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
4887b77f048SAleksandar Markovic     }
4897b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4907b77f048SAleksandar Markovic     return dt2;
4917b77f048SAleksandar Markovic }
4927b77f048SAleksandar Markovic 
4937b77f048SAleksandar Markovic uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
4947b77f048SAleksandar Markovic {
4957b77f048SAleksandar Markovic     uint64_t dt2;
4967b77f048SAleksandar Markovic 
4977b77f048SAleksandar Markovic     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
4987b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4997b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5007b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
5017b77f048SAleksandar Markovic     }
5027b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5037b77f048SAleksandar Markovic     return dt2;
5047b77f048SAleksandar Markovic }
5057b77f048SAleksandar Markovic 
5067b77f048SAleksandar Markovic uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
5077b77f048SAleksandar Markovic {
5087b77f048SAleksandar Markovic     uint32_t wt2;
5097b77f048SAleksandar Markovic 
5107b77f048SAleksandar Markovic     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
5117b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5127b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5137b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5147b77f048SAleksandar Markovic     }
5157b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5167b77f048SAleksandar Markovic     return wt2;
5177b77f048SAleksandar Markovic }
5187b77f048SAleksandar Markovic 
5197b77f048SAleksandar Markovic uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
5207b77f048SAleksandar Markovic {
5217b77f048SAleksandar Markovic     uint32_t wt2;
5227b77f048SAleksandar Markovic 
5237b77f048SAleksandar Markovic     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
5247b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5257b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5267b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5277b77f048SAleksandar Markovic     }
5287b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5297b77f048SAleksandar Markovic     return wt2;
5307b77f048SAleksandar Markovic }
5317b77f048SAleksandar Markovic 
5327b77f048SAleksandar Markovic uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
5337b77f048SAleksandar Markovic {
5347b77f048SAleksandar Markovic     uint64_t dt2;
5357b77f048SAleksandar Markovic 
5367b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5377b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
5387b77f048SAleksandar Markovic     restore_rounding_mode(env);
5397b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5407b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5417b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
5427b77f048SAleksandar Markovic     }
5437b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5447b77f048SAleksandar Markovic     return dt2;
5457b77f048SAleksandar Markovic }
5467b77f048SAleksandar Markovic 
5477b77f048SAleksandar Markovic uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
5487b77f048SAleksandar Markovic {
5497b77f048SAleksandar Markovic     uint64_t dt2;
5507b77f048SAleksandar Markovic 
5517b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5527b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
5537b77f048SAleksandar Markovic     restore_rounding_mode(env);
5547b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5557b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5567b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
5577b77f048SAleksandar Markovic     }
5587b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5597b77f048SAleksandar Markovic     return dt2;
5607b77f048SAleksandar Markovic }
5617b77f048SAleksandar Markovic 
5627b77f048SAleksandar Markovic uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
5637b77f048SAleksandar Markovic {
5647b77f048SAleksandar Markovic     uint32_t wt2;
5657b77f048SAleksandar Markovic 
5667b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5677b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
5687b77f048SAleksandar Markovic     restore_rounding_mode(env);
5697b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5707b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5717b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5727b77f048SAleksandar Markovic     }
5737b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5747b77f048SAleksandar Markovic     return wt2;
5757b77f048SAleksandar Markovic }
5767b77f048SAleksandar Markovic 
5777b77f048SAleksandar Markovic uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
5787b77f048SAleksandar Markovic {
5797b77f048SAleksandar Markovic     uint32_t wt2;
5807b77f048SAleksandar Markovic 
5817b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5827b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
5837b77f048SAleksandar Markovic     restore_rounding_mode(env);
5847b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5857b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5867b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5877b77f048SAleksandar Markovic     }
5887b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5897b77f048SAleksandar Markovic     return wt2;
5907b77f048SAleksandar Markovic }
5917b77f048SAleksandar Markovic 
5927b77f048SAleksandar Markovic uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
5937b77f048SAleksandar Markovic {
5947b77f048SAleksandar Markovic     uint64_t dt2;
5957b77f048SAleksandar Markovic 
5967b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
5977b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
5987b77f048SAleksandar Markovic     restore_rounding_mode(env);
5997b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6007b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6017b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
6027b77f048SAleksandar Markovic     }
6037b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6047b77f048SAleksandar Markovic     return dt2;
6057b77f048SAleksandar Markovic }
6067b77f048SAleksandar Markovic 
6077b77f048SAleksandar Markovic uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
6087b77f048SAleksandar Markovic {
6097b77f048SAleksandar Markovic     uint64_t dt2;
6107b77f048SAleksandar Markovic 
6117b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6127b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
6137b77f048SAleksandar Markovic     restore_rounding_mode(env);
6147b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6157b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6167b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
6177b77f048SAleksandar Markovic     }
6187b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6197b77f048SAleksandar Markovic     return dt2;
6207b77f048SAleksandar Markovic }
6217b77f048SAleksandar Markovic 
6227b77f048SAleksandar Markovic uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
6237b77f048SAleksandar Markovic {
6247b77f048SAleksandar Markovic     uint32_t wt2;
6257b77f048SAleksandar Markovic 
6267b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6277b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
6287b77f048SAleksandar Markovic     restore_rounding_mode(env);
6297b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6307b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6317b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
6327b77f048SAleksandar Markovic     }
6337b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6347b77f048SAleksandar Markovic     return wt2;
6357b77f048SAleksandar Markovic }
6367b77f048SAleksandar Markovic 
6377b77f048SAleksandar Markovic uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
6387b77f048SAleksandar Markovic {
6397b77f048SAleksandar Markovic     uint32_t wt2;
6407b77f048SAleksandar Markovic 
6417b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6427b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
6437b77f048SAleksandar Markovic     restore_rounding_mode(env);
6447b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6457b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6467b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
6477b77f048SAleksandar Markovic     }
6487b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6497b77f048SAleksandar Markovic     return wt2;
6507b77f048SAleksandar Markovic }
6517b77f048SAleksandar Markovic 
6527b77f048SAleksandar Markovic uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
6537b77f048SAleksandar Markovic {
6547b77f048SAleksandar Markovic     uint64_t dt2;
6557b77f048SAleksandar Markovic 
6567b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
6577b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6587b77f048SAleksandar Markovic             & float_flag_invalid) {
6597b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
6607b77f048SAleksandar Markovic             dt2 = 0;
6617b77f048SAleksandar Markovic         }
6627b77f048SAleksandar Markovic     }
6637b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6647b77f048SAleksandar Markovic     return dt2;
6657b77f048SAleksandar Markovic }
6667b77f048SAleksandar Markovic 
6677b77f048SAleksandar Markovic uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
6687b77f048SAleksandar Markovic {
6697b77f048SAleksandar Markovic     uint64_t dt2;
6707b77f048SAleksandar Markovic 
6717b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
6727b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6737b77f048SAleksandar Markovic             & float_flag_invalid) {
6747b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
6757b77f048SAleksandar Markovic             dt2 = 0;
6767b77f048SAleksandar Markovic         }
6777b77f048SAleksandar Markovic     }
6787b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6797b77f048SAleksandar Markovic     return dt2;
6807b77f048SAleksandar Markovic }
6817b77f048SAleksandar Markovic 
6827b77f048SAleksandar Markovic uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
6837b77f048SAleksandar Markovic {
6847b77f048SAleksandar Markovic     uint32_t wt2;
6857b77f048SAleksandar Markovic 
6867b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
6877b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6887b77f048SAleksandar Markovic             & float_flag_invalid) {
6897b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
6907b77f048SAleksandar Markovic             wt2 = 0;
6917b77f048SAleksandar Markovic         }
6927b77f048SAleksandar Markovic     }
6937b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6947b77f048SAleksandar Markovic     return wt2;
6957b77f048SAleksandar Markovic }
6967b77f048SAleksandar Markovic 
6977b77f048SAleksandar Markovic uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
6987b77f048SAleksandar Markovic {
6997b77f048SAleksandar Markovic     uint32_t wt2;
7007b77f048SAleksandar Markovic 
7017b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
7027b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7037b77f048SAleksandar Markovic             & float_flag_invalid) {
7047b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
7057b77f048SAleksandar Markovic             wt2 = 0;
7067b77f048SAleksandar Markovic         }
7077b77f048SAleksandar Markovic     }
7087b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7097b77f048SAleksandar Markovic     return wt2;
7107b77f048SAleksandar Markovic }
7117b77f048SAleksandar Markovic 
7127b77f048SAleksandar Markovic uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
7137b77f048SAleksandar Markovic {
7147b77f048SAleksandar Markovic     uint64_t dt2;
7157b77f048SAleksandar Markovic 
7167b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7177b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7187b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
7197b77f048SAleksandar Markovic     restore_rounding_mode(env);
7207b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7217b77f048SAleksandar Markovic             & float_flag_invalid) {
7227b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
7237b77f048SAleksandar Markovic             dt2 = 0;
7247b77f048SAleksandar Markovic         }
7257b77f048SAleksandar Markovic     }
7267b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7277b77f048SAleksandar Markovic     return dt2;
7287b77f048SAleksandar Markovic }
7297b77f048SAleksandar Markovic 
7307b77f048SAleksandar Markovic uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
7317b77f048SAleksandar Markovic {
7327b77f048SAleksandar Markovic     uint64_t dt2;
7337b77f048SAleksandar Markovic 
7347b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7357b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7367b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
7377b77f048SAleksandar Markovic     restore_rounding_mode(env);
7387b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7397b77f048SAleksandar Markovic             & float_flag_invalid) {
7407b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
7417b77f048SAleksandar Markovic             dt2 = 0;
7427b77f048SAleksandar Markovic         }
7437b77f048SAleksandar Markovic     }
7447b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7457b77f048SAleksandar Markovic     return dt2;
7467b77f048SAleksandar Markovic }
7477b77f048SAleksandar Markovic 
7487b77f048SAleksandar Markovic uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
7497b77f048SAleksandar Markovic {
7507b77f048SAleksandar Markovic     uint32_t wt2;
7517b77f048SAleksandar Markovic 
7527b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7537b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7547b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
7557b77f048SAleksandar Markovic     restore_rounding_mode(env);
7567b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7577b77f048SAleksandar Markovic             & float_flag_invalid) {
7587b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
7597b77f048SAleksandar Markovic             wt2 = 0;
7607b77f048SAleksandar Markovic         }
7617b77f048SAleksandar Markovic     }
7627b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7637b77f048SAleksandar Markovic     return wt2;
7647b77f048SAleksandar Markovic }
7657b77f048SAleksandar Markovic 
7667b77f048SAleksandar Markovic uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
7677b77f048SAleksandar Markovic {
7687b77f048SAleksandar Markovic     uint32_t wt2;
7697b77f048SAleksandar Markovic 
7707b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7717b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7727b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
7737b77f048SAleksandar Markovic     restore_rounding_mode(env);
7747b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7757b77f048SAleksandar Markovic             & float_flag_invalid) {
7767b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
7777b77f048SAleksandar Markovic             wt2 = 0;
7787b77f048SAleksandar Markovic         }
7797b77f048SAleksandar Markovic     }
7807b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7817b77f048SAleksandar Markovic     return wt2;
7827b77f048SAleksandar Markovic }
7837b77f048SAleksandar Markovic 
7847b77f048SAleksandar Markovic uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
7857b77f048SAleksandar Markovic {
7867b77f048SAleksandar Markovic     uint64_t dt2;
7877b77f048SAleksandar Markovic 
7887b77f048SAleksandar Markovic     dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
7897b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7907b77f048SAleksandar Markovic             & float_flag_invalid) {
7917b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
7927b77f048SAleksandar Markovic             dt2 = 0;
7937b77f048SAleksandar Markovic         }
7947b77f048SAleksandar Markovic     }
7957b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7967b77f048SAleksandar Markovic     return dt2;
7977b77f048SAleksandar Markovic }
7987b77f048SAleksandar Markovic 
7997b77f048SAleksandar Markovic uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
8007b77f048SAleksandar Markovic {
8017b77f048SAleksandar Markovic     uint64_t dt2;
8027b77f048SAleksandar Markovic 
8037b77f048SAleksandar Markovic     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
8047b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8057b77f048SAleksandar Markovic             & float_flag_invalid) {
8067b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
8077b77f048SAleksandar Markovic             dt2 = 0;
8087b77f048SAleksandar Markovic         }
8097b77f048SAleksandar Markovic     }
8107b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8117b77f048SAleksandar Markovic     return dt2;
8127b77f048SAleksandar Markovic }
8137b77f048SAleksandar Markovic 
8147b77f048SAleksandar Markovic uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
8157b77f048SAleksandar Markovic {
8167b77f048SAleksandar Markovic     uint32_t wt2;
8177b77f048SAleksandar Markovic 
8187b77f048SAleksandar Markovic     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
8197b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8207b77f048SAleksandar Markovic             & float_flag_invalid) {
8217b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
8227b77f048SAleksandar Markovic             wt2 = 0;
8237b77f048SAleksandar Markovic         }
8247b77f048SAleksandar Markovic     }
8257b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8267b77f048SAleksandar Markovic     return wt2;
8277b77f048SAleksandar Markovic }
8287b77f048SAleksandar Markovic 
8297b77f048SAleksandar Markovic uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
8307b77f048SAleksandar Markovic {
8317b77f048SAleksandar Markovic     uint32_t wt2;
8327b77f048SAleksandar Markovic 
8337b77f048SAleksandar Markovic     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
8347b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8357b77f048SAleksandar Markovic             & float_flag_invalid) {
8367b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
8377b77f048SAleksandar Markovic             wt2 = 0;
8387b77f048SAleksandar Markovic         }
8397b77f048SAleksandar Markovic     }
8407b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8417b77f048SAleksandar Markovic     return wt2;
8427b77f048SAleksandar Markovic }
8437b77f048SAleksandar Markovic 
8447b77f048SAleksandar Markovic uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
8457b77f048SAleksandar Markovic {
8467b77f048SAleksandar Markovic     uint64_t dt2;
8477b77f048SAleksandar Markovic 
8487b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
8497b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
8507b77f048SAleksandar Markovic     restore_rounding_mode(env);
8517b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8527b77f048SAleksandar Markovic             & float_flag_invalid) {
8537b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
8547b77f048SAleksandar Markovic             dt2 = 0;
8557b77f048SAleksandar Markovic         }
8567b77f048SAleksandar Markovic     }
8577b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8587b77f048SAleksandar Markovic     return dt2;
8597b77f048SAleksandar Markovic }
8607b77f048SAleksandar Markovic 
8617b77f048SAleksandar Markovic uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
8627b77f048SAleksandar Markovic {
8637b77f048SAleksandar Markovic     uint64_t dt2;
8647b77f048SAleksandar Markovic 
8657b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
8667b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
8677b77f048SAleksandar Markovic     restore_rounding_mode(env);
8687b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8697b77f048SAleksandar Markovic             & float_flag_invalid) {
8707b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
8717b77f048SAleksandar Markovic             dt2 = 0;
8727b77f048SAleksandar Markovic         }
8737b77f048SAleksandar Markovic     }
8747b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8757b77f048SAleksandar Markovic     return dt2;
8767b77f048SAleksandar Markovic }
8777b77f048SAleksandar Markovic 
8787b77f048SAleksandar Markovic uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
8797b77f048SAleksandar Markovic {
8807b77f048SAleksandar Markovic     uint32_t wt2;
8817b77f048SAleksandar Markovic 
8827b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
8837b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
8847b77f048SAleksandar Markovic     restore_rounding_mode(env);
8857b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8867b77f048SAleksandar Markovic             & float_flag_invalid) {
8877b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
8887b77f048SAleksandar Markovic             wt2 = 0;
8897b77f048SAleksandar Markovic         }
8907b77f048SAleksandar Markovic     }
8917b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8927b77f048SAleksandar Markovic     return wt2;
8937b77f048SAleksandar Markovic }
8947b77f048SAleksandar Markovic 
8957b77f048SAleksandar Markovic uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
8967b77f048SAleksandar Markovic {
8977b77f048SAleksandar Markovic     uint32_t wt2;
8987b77f048SAleksandar Markovic 
8997b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
9007b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
9017b77f048SAleksandar Markovic     restore_rounding_mode(env);
9027b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9037b77f048SAleksandar Markovic             & float_flag_invalid) {
9047b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
9057b77f048SAleksandar Markovic             wt2 = 0;
9067b77f048SAleksandar Markovic         }
9077b77f048SAleksandar Markovic     }
9087b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9097b77f048SAleksandar Markovic     return wt2;
9107b77f048SAleksandar Markovic }
9117b77f048SAleksandar Markovic 
9127b77f048SAleksandar Markovic uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
9137b77f048SAleksandar Markovic {
9147b77f048SAleksandar Markovic     uint64_t dt2;
9157b77f048SAleksandar Markovic 
9167b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9177b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
9187b77f048SAleksandar Markovic     restore_rounding_mode(env);
9197b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9207b77f048SAleksandar Markovic             & float_flag_invalid) {
9217b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
9227b77f048SAleksandar Markovic             dt2 = 0;
9237b77f048SAleksandar Markovic         }
9247b77f048SAleksandar Markovic     }
9257b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9267b77f048SAleksandar Markovic     return dt2;
9277b77f048SAleksandar Markovic }
9287b77f048SAleksandar Markovic 
9297b77f048SAleksandar Markovic uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
9307b77f048SAleksandar Markovic {
9317b77f048SAleksandar Markovic     uint64_t dt2;
9327b77f048SAleksandar Markovic 
9337b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9347b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
9357b77f048SAleksandar Markovic     restore_rounding_mode(env);
9367b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9377b77f048SAleksandar Markovic             & float_flag_invalid) {
9387b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
9397b77f048SAleksandar Markovic             dt2 = 0;
9407b77f048SAleksandar Markovic         }
9417b77f048SAleksandar Markovic     }
9427b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9437b77f048SAleksandar Markovic     return dt2;
9447b77f048SAleksandar Markovic }
9457b77f048SAleksandar Markovic 
9467b77f048SAleksandar Markovic uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
9477b77f048SAleksandar Markovic {
9487b77f048SAleksandar Markovic     uint32_t wt2;
9497b77f048SAleksandar Markovic 
9507b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9517b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
9527b77f048SAleksandar Markovic     restore_rounding_mode(env);
9537b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9547b77f048SAleksandar Markovic             & float_flag_invalid) {
9557b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
9567b77f048SAleksandar Markovic             wt2 = 0;
9577b77f048SAleksandar Markovic         }
9587b77f048SAleksandar Markovic     }
9597b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9607b77f048SAleksandar Markovic     return wt2;
9617b77f048SAleksandar Markovic }
9627b77f048SAleksandar Markovic 
9637b77f048SAleksandar Markovic uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
9647b77f048SAleksandar Markovic {
9657b77f048SAleksandar Markovic     uint32_t wt2;
9667b77f048SAleksandar Markovic 
9677b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9687b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
9697b77f048SAleksandar Markovic     restore_rounding_mode(env);
9707b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9717b77f048SAleksandar Markovic             & float_flag_invalid) {
9727b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
9737b77f048SAleksandar Markovic             wt2 = 0;
9747b77f048SAleksandar Markovic         }
9757b77f048SAleksandar Markovic     }
9767b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9777b77f048SAleksandar Markovic     return wt2;
9787b77f048SAleksandar Markovic }
9797b77f048SAleksandar Markovic 
9807b77f048SAleksandar Markovic /* unary operations, not modifying fp status  */
9817b77f048SAleksandar Markovic #define FLOAT_UNOP(name)                                       \
9827b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _d(uint64_t fdt0)                \
9837b77f048SAleksandar Markovic {                                                              \
9847b77f048SAleksandar Markovic     return float64_ ## name(fdt0);                             \
9857b77f048SAleksandar Markovic }                                                              \
9867b77f048SAleksandar Markovic uint32_t helper_float_ ## name ## _s(uint32_t fst0)                \
9877b77f048SAleksandar Markovic {                                                              \
9887b77f048SAleksandar Markovic     return float32_ ## name(fst0);                             \
9897b77f048SAleksandar Markovic }                                                              \
9907b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _ps(uint64_t fdt0)               \
9917b77f048SAleksandar Markovic {                                                              \
9927b77f048SAleksandar Markovic     uint32_t wt0;                                              \
9937b77f048SAleksandar Markovic     uint32_t wth0;                                             \
9947b77f048SAleksandar Markovic                                                                \
9957b77f048SAleksandar Markovic     wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF);                 \
9967b77f048SAleksandar Markovic     wth0 = float32_ ## name(fdt0 >> 32);                       \
9977b77f048SAleksandar Markovic     return ((uint64_t)wth0 << 32) | wt0;                       \
9987b77f048SAleksandar Markovic }
9997b77f048SAleksandar Markovic FLOAT_UNOP(abs)
10007b77f048SAleksandar Markovic FLOAT_UNOP(chs)
10017b77f048SAleksandar Markovic #undef FLOAT_UNOP
10027b77f048SAleksandar Markovic 
10037b77f048SAleksandar Markovic /* MIPS specific unary operations */
10047b77f048SAleksandar Markovic uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
10057b77f048SAleksandar Markovic {
10067b77f048SAleksandar Markovic     uint64_t fdt2;
10077b77f048SAleksandar Markovic 
10087b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
10097b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10107b77f048SAleksandar Markovic     return fdt2;
10117b77f048SAleksandar Markovic }
10127b77f048SAleksandar Markovic 
10137b77f048SAleksandar Markovic uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
10147b77f048SAleksandar Markovic {
10157b77f048SAleksandar Markovic     uint32_t fst2;
10167b77f048SAleksandar Markovic 
10177b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
10187b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10197b77f048SAleksandar Markovic     return fst2;
10207b77f048SAleksandar Markovic }
10217b77f048SAleksandar Markovic 
10227b77f048SAleksandar Markovic uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
10237b77f048SAleksandar Markovic {
10247b77f048SAleksandar Markovic     uint64_t fdt2;
10257b77f048SAleksandar Markovic 
10267b77f048SAleksandar Markovic     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
10277b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
10287b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10297b77f048SAleksandar Markovic     return fdt2;
10307b77f048SAleksandar Markovic }
10317b77f048SAleksandar Markovic 
10327b77f048SAleksandar Markovic uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
10337b77f048SAleksandar Markovic {
10347b77f048SAleksandar Markovic     uint32_t fst2;
10357b77f048SAleksandar Markovic 
10367b77f048SAleksandar Markovic     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
10377b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
10387b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10397b77f048SAleksandar Markovic     return fst2;
10407b77f048SAleksandar Markovic }
10417b77f048SAleksandar Markovic 
10427b77f048SAleksandar Markovic uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
10437b77f048SAleksandar Markovic {
10447b77f048SAleksandar Markovic     uint64_t fdt2;
10457b77f048SAleksandar Markovic 
10467b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
10477b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10487b77f048SAleksandar Markovic     return fdt2;
10497b77f048SAleksandar Markovic }
10507b77f048SAleksandar Markovic 
10517b77f048SAleksandar Markovic uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
10527b77f048SAleksandar Markovic {
10537b77f048SAleksandar Markovic     uint32_t fst2;
10547b77f048SAleksandar Markovic 
10557b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
10567b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10577b77f048SAleksandar Markovic     return fst2;
10587b77f048SAleksandar Markovic }
10597b77f048SAleksandar Markovic 
10607b77f048SAleksandar Markovic uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
10617b77f048SAleksandar Markovic {
10627b77f048SAleksandar Markovic     uint32_t fst2;
10637b77f048SAleksandar Markovic     uint32_t fsth2;
10647b77f048SAleksandar Markovic 
10657b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
10667b77f048SAleksandar Markovic                        &env->active_fpu.fp_status);
10677b77f048SAleksandar Markovic     fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
10687b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10697b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
10707b77f048SAleksandar Markovic }
10717b77f048SAleksandar Markovic 
10727b77f048SAleksandar Markovic uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
10737b77f048SAleksandar Markovic {
10747b77f048SAleksandar Markovic     uint64_t fdt2;
10757b77f048SAleksandar Markovic 
10767b77f048SAleksandar Markovic     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
10777b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
10787b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10797b77f048SAleksandar Markovic     return fdt2;
10807b77f048SAleksandar Markovic }
10817b77f048SAleksandar Markovic 
10827b77f048SAleksandar Markovic uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
10837b77f048SAleksandar Markovic {
10847b77f048SAleksandar Markovic     uint32_t fst2;
10857b77f048SAleksandar Markovic 
10867b77f048SAleksandar Markovic     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
10877b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
10887b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10897b77f048SAleksandar Markovic     return fst2;
10907b77f048SAleksandar Markovic }
10917b77f048SAleksandar Markovic 
10927b77f048SAleksandar Markovic uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
10937b77f048SAleksandar Markovic {
10947b77f048SAleksandar Markovic     uint32_t fst2;
10957b77f048SAleksandar Markovic     uint32_t fsth2;
10967b77f048SAleksandar Markovic 
10977b77f048SAleksandar Markovic     fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
10987b77f048SAleksandar Markovic     fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
10997b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
11007b77f048SAleksandar Markovic     fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
11017b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
11027b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
11037b77f048SAleksandar Markovic }
11047b77f048SAleksandar Markovic 
11057b77f048SAleksandar Markovic #define FLOAT_RINT(name, bits)                                              \
11067b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,                 \
11077b77f048SAleksandar Markovic                                          uint ## bits ## _t fs)             \
11087b77f048SAleksandar Markovic {                                                                           \
11097b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                               \
11107b77f048SAleksandar Markovic                                                                             \
11117b77f048SAleksandar Markovic     fdret = float ## bits ## _round_to_int(fs, &env->active_fpu.fp_status); \
11127b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                             \
11137b77f048SAleksandar Markovic     return fdret;                                                           \
11147b77f048SAleksandar Markovic }
11157b77f048SAleksandar Markovic 
11167b77f048SAleksandar Markovic FLOAT_RINT(rint_s, 32)
11177b77f048SAleksandar Markovic FLOAT_RINT(rint_d, 64)
11187b77f048SAleksandar Markovic #undef FLOAT_RINT
11197b77f048SAleksandar Markovic 
11207b77f048SAleksandar Markovic #define FLOAT_CLASS_SIGNALING_NAN      0x001
11217b77f048SAleksandar Markovic #define FLOAT_CLASS_QUIET_NAN          0x002
11227b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
11237b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_NORMAL    0x008
11247b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
11257b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_ZERO      0x020
11267b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_INFINITY  0x040
11277b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_NORMAL    0x080
11287b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
11297b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_ZERO      0x200
11307b77f048SAleksandar Markovic 
11317b77f048SAleksandar Markovic #define FLOAT_CLASS(name, bits)                                      \
11327b77f048SAleksandar Markovic uint ## bits ## _t float_ ## name(uint ## bits ## _t arg,            \
11337b77f048SAleksandar Markovic                                   float_status *status)              \
11347b77f048SAleksandar Markovic {                                                                    \
11357b77f048SAleksandar Markovic     if (float ## bits ## _is_signaling_nan(arg, status)) {           \
11367b77f048SAleksandar Markovic         return FLOAT_CLASS_SIGNALING_NAN;                            \
11377b77f048SAleksandar Markovic     } else if (float ## bits ## _is_quiet_nan(arg, status)) {        \
11387b77f048SAleksandar Markovic         return FLOAT_CLASS_QUIET_NAN;                                \
11397b77f048SAleksandar Markovic     } else if (float ## bits ## _is_neg(arg)) {                      \
11407b77f048SAleksandar Markovic         if (float ## bits ## _is_infinity(arg)) {                    \
11417b77f048SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_INFINITY;                    \
11427b77f048SAleksandar Markovic         } else if (float ## bits ## _is_zero(arg)) {                 \
11437b77f048SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_ZERO;                        \
11447b77f048SAleksandar Markovic         } else if (float ## bits ## _is_zero_or_denormal(arg)) {     \
11457b77f048SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;                   \
11467b77f048SAleksandar Markovic         } else {                                                     \
11477b77f048SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_NORMAL;                      \
11487b77f048SAleksandar Markovic         }                                                            \
11497b77f048SAleksandar Markovic     } else {                                                         \
11507b77f048SAleksandar Markovic         if (float ## bits ## _is_infinity(arg)) {                    \
11517b77f048SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_INFINITY;                    \
11527b77f048SAleksandar Markovic         } else if (float ## bits ## _is_zero(arg)) {                 \
11537b77f048SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_ZERO;                        \
11547b77f048SAleksandar Markovic         } else if (float ## bits ## _is_zero_or_denormal(arg)) {     \
11557b77f048SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_SUBNORMAL;                   \
11567b77f048SAleksandar Markovic         } else {                                                     \
11577b77f048SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_NORMAL;                      \
11587b77f048SAleksandar Markovic         }                                                            \
11597b77f048SAleksandar Markovic     }                                                                \
11607b77f048SAleksandar Markovic }                                                                    \
11617b77f048SAleksandar Markovic                                                                      \
11627b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,          \
11637b77f048SAleksandar Markovic                                          uint ## bits ## _t arg)     \
11647b77f048SAleksandar Markovic {                                                                    \
11657b77f048SAleksandar Markovic     return float_ ## name(arg, &env->active_fpu.fp_status);          \
11667b77f048SAleksandar Markovic }
11677b77f048SAleksandar Markovic 
11687b77f048SAleksandar Markovic FLOAT_CLASS(class_s, 32)
11697b77f048SAleksandar Markovic FLOAT_CLASS(class_d, 64)
11707b77f048SAleksandar Markovic #undef FLOAT_CLASS
11717b77f048SAleksandar Markovic 
11727b77f048SAleksandar Markovic /* binary operations */
11737b77f048SAleksandar Markovic #define FLOAT_BINOP(name)                                          \
11747b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,            \
11757b77f048SAleksandar Markovic                                      uint64_t fdt0, uint64_t fdt1) \
11767b77f048SAleksandar Markovic {                                                                  \
11777b77f048SAleksandar Markovic     uint64_t dt2;                                                  \
11787b77f048SAleksandar Markovic                                                                    \
11797b77f048SAleksandar Markovic     dt2 = float64_ ## name(fdt0, fdt1, &env->active_fpu.fp_status);\
11807b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                    \
11817b77f048SAleksandar Markovic     return dt2;                                                    \
11827b77f048SAleksandar Markovic }                                                                  \
11837b77f048SAleksandar Markovic                                                                    \
11847b77f048SAleksandar Markovic uint32_t helper_float_ ## name ## _s(CPUMIPSState *env,            \
11857b77f048SAleksandar Markovic                                      uint32_t fst0, uint32_t fst1) \
11867b77f048SAleksandar Markovic {                                                                  \
11877b77f048SAleksandar Markovic     uint32_t wt2;                                                  \
11887b77f048SAleksandar Markovic                                                                    \
11897b77f048SAleksandar Markovic     wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);\
11907b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                    \
11917b77f048SAleksandar Markovic     return wt2;                                                    \
11927b77f048SAleksandar Markovic }                                                                  \
11937b77f048SAleksandar Markovic                                                                    \
11947b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,           \
11957b77f048SAleksandar Markovic                                       uint64_t fdt0,               \
11967b77f048SAleksandar Markovic                                       uint64_t fdt1)               \
11977b77f048SAleksandar Markovic {                                                                  \
11987b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;                             \
11997b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;                                   \
12007b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;                             \
12017b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;                                   \
12027b77f048SAleksandar Markovic     uint32_t wt2;                                                  \
12037b77f048SAleksandar Markovic     uint32_t wth2;                                                 \
12047b77f048SAleksandar Markovic                                                                    \
12057b77f048SAleksandar Markovic     wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);     \
12067b77f048SAleksandar Markovic     wth2 = float32_ ## name(fsth0, fsth1, &env->active_fpu.fp_status);  \
12077b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                    \
12087b77f048SAleksandar Markovic     return ((uint64_t)wth2 << 32) | wt2;                           \
12097b77f048SAleksandar Markovic }
12107b77f048SAleksandar Markovic 
12117b77f048SAleksandar Markovic #undef FLOAT_BINOP
12127b77f048SAleksandar Markovic 
12131ace099fSAleksandar Markovic uint64_t helper_float_add_d(CPUMIPSState *env,
12141ace099fSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
12151ace099fSAleksandar Markovic {
12161ace099fSAleksandar Markovic     uint64_t dt2;
12171ace099fSAleksandar Markovic 
12181ace099fSAleksandar Markovic     dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
12191ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12201ace099fSAleksandar Markovic     return dt2;
12211ace099fSAleksandar Markovic }
12221ace099fSAleksandar Markovic 
12231ace099fSAleksandar Markovic uint32_t helper_float_add_s(CPUMIPSState *env,
12241ace099fSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
12251ace099fSAleksandar Markovic {
12261ace099fSAleksandar Markovic     uint32_t wt2;
12271ace099fSAleksandar Markovic 
12281ace099fSAleksandar Markovic     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
12291ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12301ace099fSAleksandar Markovic     return wt2;
12311ace099fSAleksandar Markovic }
12321ace099fSAleksandar Markovic 
12331ace099fSAleksandar Markovic uint64_t helper_float_add_ps(CPUMIPSState *env,
12341ace099fSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
12351ace099fSAleksandar Markovic {
12361ace099fSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
12371ace099fSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
12381ace099fSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
12391ace099fSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
12401ace099fSAleksandar Markovic     uint32_t wtl2;
12411ace099fSAleksandar Markovic     uint32_t wth2;
12421ace099fSAleksandar Markovic 
12431ace099fSAleksandar Markovic     wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
12441ace099fSAleksandar Markovic     wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
12451ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12461ace099fSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
12471ace099fSAleksandar Markovic }
12481ace099fSAleksandar Markovic 
124992ebdd7fSAleksandar Markovic uint64_t helper_float_sub_d(CPUMIPSState *env,
125092ebdd7fSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
125192ebdd7fSAleksandar Markovic {
125292ebdd7fSAleksandar Markovic     uint64_t dt2;
125392ebdd7fSAleksandar Markovic 
125492ebdd7fSAleksandar Markovic     dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
125592ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
125692ebdd7fSAleksandar Markovic     return dt2;
125792ebdd7fSAleksandar Markovic }
125892ebdd7fSAleksandar Markovic 
125992ebdd7fSAleksandar Markovic uint32_t helper_float_sub_s(CPUMIPSState *env,
126092ebdd7fSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
126192ebdd7fSAleksandar Markovic {
126292ebdd7fSAleksandar Markovic     uint32_t wt2;
126392ebdd7fSAleksandar Markovic 
126492ebdd7fSAleksandar Markovic     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
126592ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
126692ebdd7fSAleksandar Markovic     return wt2;
126792ebdd7fSAleksandar Markovic }
126892ebdd7fSAleksandar Markovic 
126992ebdd7fSAleksandar Markovic uint64_t helper_float_sub_ps(CPUMIPSState *env,
127092ebdd7fSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
127192ebdd7fSAleksandar Markovic {
127292ebdd7fSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
127392ebdd7fSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
127492ebdd7fSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
127592ebdd7fSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
127692ebdd7fSAleksandar Markovic     uint32_t wtl2;
127792ebdd7fSAleksandar Markovic     uint32_t wth2;
127892ebdd7fSAleksandar Markovic 
127992ebdd7fSAleksandar Markovic     wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
128092ebdd7fSAleksandar Markovic     wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
128192ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
128292ebdd7fSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
128392ebdd7fSAleksandar Markovic }
128492ebdd7fSAleksandar Markovic 
128511811198SAleksandar Markovic uint64_t helper_float_mul_d(CPUMIPSState *env,
128611811198SAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
128711811198SAleksandar Markovic {
128811811198SAleksandar Markovic     uint64_t dt2;
128911811198SAleksandar Markovic 
129011811198SAleksandar Markovic     dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
129111811198SAleksandar Markovic     update_fcr31(env, GETPC());
129211811198SAleksandar Markovic     return dt2;
129311811198SAleksandar Markovic }
129411811198SAleksandar Markovic 
129511811198SAleksandar Markovic uint32_t helper_float_mul_s(CPUMIPSState *env,
129611811198SAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
129711811198SAleksandar Markovic {
129811811198SAleksandar Markovic     uint32_t wt2;
129911811198SAleksandar Markovic 
130011811198SAleksandar Markovic     wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
130111811198SAleksandar Markovic     update_fcr31(env, GETPC());
130211811198SAleksandar Markovic     return wt2;
130311811198SAleksandar Markovic }
130411811198SAleksandar Markovic 
130511811198SAleksandar Markovic uint64_t helper_float_mul_ps(CPUMIPSState *env,
130611811198SAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
130711811198SAleksandar Markovic {
130811811198SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
130911811198SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
131011811198SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
131111811198SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
131211811198SAleksandar Markovic     uint32_t wtl2;
131311811198SAleksandar Markovic     uint32_t wth2;
131411811198SAleksandar Markovic 
131511811198SAleksandar Markovic     wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
131611811198SAleksandar Markovic     wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
131711811198SAleksandar Markovic     update_fcr31(env, GETPC());
131811811198SAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
131911811198SAleksandar Markovic }
132011811198SAleksandar Markovic 
1321*bcca8c4bSAleksandar Markovic uint64_t helper_float_div_d(CPUMIPSState *env,
1322*bcca8c4bSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
1323*bcca8c4bSAleksandar Markovic {
1324*bcca8c4bSAleksandar Markovic     uint64_t dt2;
1325*bcca8c4bSAleksandar Markovic 
1326*bcca8c4bSAleksandar Markovic     dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1327*bcca8c4bSAleksandar Markovic     update_fcr31(env, GETPC());
1328*bcca8c4bSAleksandar Markovic     return dt2;
1329*bcca8c4bSAleksandar Markovic }
1330*bcca8c4bSAleksandar Markovic 
1331*bcca8c4bSAleksandar Markovic uint32_t helper_float_div_s(CPUMIPSState *env,
1332*bcca8c4bSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
1333*bcca8c4bSAleksandar Markovic {
1334*bcca8c4bSAleksandar Markovic     uint32_t wt2;
1335*bcca8c4bSAleksandar Markovic 
1336*bcca8c4bSAleksandar Markovic     wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1337*bcca8c4bSAleksandar Markovic     update_fcr31(env, GETPC());
1338*bcca8c4bSAleksandar Markovic     return wt2;
1339*bcca8c4bSAleksandar Markovic }
1340*bcca8c4bSAleksandar Markovic 
1341*bcca8c4bSAleksandar Markovic uint64_t helper_float_div_ps(CPUMIPSState *env,
1342*bcca8c4bSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
1343*bcca8c4bSAleksandar Markovic {
1344*bcca8c4bSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1345*bcca8c4bSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1346*bcca8c4bSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1347*bcca8c4bSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
1348*bcca8c4bSAleksandar Markovic     uint32_t wtl2;
1349*bcca8c4bSAleksandar Markovic     uint32_t wth2;
1350*bcca8c4bSAleksandar Markovic 
1351*bcca8c4bSAleksandar Markovic     wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1352*bcca8c4bSAleksandar Markovic     wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1353*bcca8c4bSAleksandar Markovic     update_fcr31(env, GETPC());
1354*bcca8c4bSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
1355*bcca8c4bSAleksandar Markovic }
1356*bcca8c4bSAleksandar Markovic 
13571ace099fSAleksandar Markovic 
13587b77f048SAleksandar Markovic /* MIPS specific binary operations */
13597b77f048SAleksandar Markovic uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13607b77f048SAleksandar Markovic {
13617b77f048SAleksandar Markovic     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
13627b77f048SAleksandar Markovic     fdt2 = float64_chs(float64_sub(fdt2, float64_one,
13637b77f048SAleksandar Markovic                                    &env->active_fpu.fp_status));
13647b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13657b77f048SAleksandar Markovic     return fdt2;
13667b77f048SAleksandar Markovic }
13677b77f048SAleksandar Markovic 
13687b77f048SAleksandar Markovic uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
13697b77f048SAleksandar Markovic {
13707b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13717b77f048SAleksandar Markovic     fst2 = float32_chs(float32_sub(fst2, float32_one,
13727b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13737b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13747b77f048SAleksandar Markovic     return fst2;
13757b77f048SAleksandar Markovic }
13767b77f048SAleksandar Markovic 
13777b77f048SAleksandar Markovic uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13787b77f048SAleksandar Markovic {
13797b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
13807b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
13817b77f048SAleksandar Markovic     uint32_t fst2 = fdt2 & 0XFFFFFFFF;
13827b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
13837b77f048SAleksandar Markovic 
13847b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13857b77f048SAleksandar Markovic     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
13867b77f048SAleksandar Markovic     fst2 = float32_chs(float32_sub(fst2, float32_one,
13877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13887b77f048SAleksandar Markovic     fsth2 = float32_chs(float32_sub(fsth2, float32_one,
13897b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13907b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13917b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
13927b77f048SAleksandar Markovic }
13937b77f048SAleksandar Markovic 
13947b77f048SAleksandar Markovic uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13957b77f048SAleksandar Markovic {
13967b77f048SAleksandar Markovic     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
13977b77f048SAleksandar Markovic     fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
13987b77f048SAleksandar Markovic     fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
13997b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14007b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
14017b77f048SAleksandar Markovic     return fdt2;
14027b77f048SAleksandar Markovic }
14037b77f048SAleksandar Markovic 
14047b77f048SAleksandar Markovic uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
14057b77f048SAleksandar Markovic {
14067b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
14077b77f048SAleksandar Markovic     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
14087b77f048SAleksandar Markovic     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
14097b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14107b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
14117b77f048SAleksandar Markovic     return fst2;
14127b77f048SAleksandar Markovic }
14137b77f048SAleksandar Markovic 
14147b77f048SAleksandar Markovic uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
14157b77f048SAleksandar Markovic {
14167b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
14177b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
14187b77f048SAleksandar Markovic     uint32_t fst2 = fdt2 & 0XFFFFFFFF;
14197b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
14207b77f048SAleksandar Markovic 
14217b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
14227b77f048SAleksandar Markovic     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
14237b77f048SAleksandar Markovic     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
14247b77f048SAleksandar Markovic     fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
14257b77f048SAleksandar Markovic     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
14267b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14277b77f048SAleksandar Markovic     fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
14287b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14297b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
14307b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
14317b77f048SAleksandar Markovic }
14327b77f048SAleksandar Markovic 
14337b77f048SAleksandar Markovic uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
14347b77f048SAleksandar Markovic {
14357b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
14367b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
14377b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;
14387b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
14397b77f048SAleksandar Markovic     uint32_t fst2;
14407b77f048SAleksandar Markovic     uint32_t fsth2;
14417b77f048SAleksandar Markovic 
14427b77f048SAleksandar Markovic     fst2 = float32_add(fst0, fsth0, &env->active_fpu.fp_status);
14437b77f048SAleksandar Markovic     fsth2 = float32_add(fst1, fsth1, &env->active_fpu.fp_status);
14447b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
14457b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
14467b77f048SAleksandar Markovic }
14477b77f048SAleksandar Markovic 
14487b77f048SAleksandar Markovic uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
14497b77f048SAleksandar Markovic {
14507b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
14517b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
14527b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;
14537b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
14547b77f048SAleksandar Markovic     uint32_t fst2;
14557b77f048SAleksandar Markovic     uint32_t fsth2;
14567b77f048SAleksandar Markovic 
14577b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fsth0, &env->active_fpu.fp_status);
14587b77f048SAleksandar Markovic     fsth2 = float32_mul(fst1, fsth1, &env->active_fpu.fp_status);
14597b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
14607b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
14617b77f048SAleksandar Markovic }
14627b77f048SAleksandar Markovic 
14637b77f048SAleksandar Markovic #define FLOAT_MINMAX(name, bits, minmaxfunc)                            \
14647b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,             \
14657b77f048SAleksandar Markovic                                          uint ## bits ## _t fs,         \
14667b77f048SAleksandar Markovic                                          uint ## bits ## _t ft)         \
14677b77f048SAleksandar Markovic {                                                                       \
14687b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                           \
14697b77f048SAleksandar Markovic                                                                         \
14707b77f048SAleksandar Markovic     fdret = float ## bits ## _ ## minmaxfunc(fs, ft,                    \
14717b77f048SAleksandar Markovic                                            &env->active_fpu.fp_status); \
14727b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                         \
14737b77f048SAleksandar Markovic     return fdret;                                                       \
14747b77f048SAleksandar Markovic }
14757b77f048SAleksandar Markovic 
14767b77f048SAleksandar Markovic FLOAT_MINMAX(max_s, 32, maxnum)
14777b77f048SAleksandar Markovic FLOAT_MINMAX(max_d, 64, maxnum)
14787b77f048SAleksandar Markovic FLOAT_MINMAX(maxa_s, 32, maxnummag)
14797b77f048SAleksandar Markovic FLOAT_MINMAX(maxa_d, 64, maxnummag)
14807b77f048SAleksandar Markovic 
14817b77f048SAleksandar Markovic FLOAT_MINMAX(min_s, 32, minnum)
14827b77f048SAleksandar Markovic FLOAT_MINMAX(min_d, 64, minnum)
14837b77f048SAleksandar Markovic FLOAT_MINMAX(mina_s, 32, minnummag)
14847b77f048SAleksandar Markovic FLOAT_MINMAX(mina_d, 64, minnummag)
14857b77f048SAleksandar Markovic #undef FLOAT_MINMAX
14867b77f048SAleksandar Markovic 
14877b77f048SAleksandar Markovic /* ternary operations */
14887b77f048SAleksandar Markovic #define UNFUSED_FMA(prefix, a, b, c, flags)                          \
14897b77f048SAleksandar Markovic {                                                                    \
14907b77f048SAleksandar Markovic     a = prefix##_mul(a, b, &env->active_fpu.fp_status);              \
14917b77f048SAleksandar Markovic     if ((flags) & float_muladd_negate_c) {                           \
14927b77f048SAleksandar Markovic         a = prefix##_sub(a, c, &env->active_fpu.fp_status);          \
14937b77f048SAleksandar Markovic     } else {                                                         \
14947b77f048SAleksandar Markovic         a = prefix##_add(a, c, &env->active_fpu.fp_status);          \
14957b77f048SAleksandar Markovic     }                                                                \
14967b77f048SAleksandar Markovic     if ((flags) & float_muladd_negate_result) {                      \
14977b77f048SAleksandar Markovic         a = prefix##_chs(a);                                         \
14987b77f048SAleksandar Markovic     }                                                                \
14997b77f048SAleksandar Markovic }
15007b77f048SAleksandar Markovic 
15017b77f048SAleksandar Markovic /* FMA based operations */
15027b77f048SAleksandar Markovic #define FLOAT_FMA(name, type)                                        \
15037b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,              \
15047b77f048SAleksandar Markovic                                      uint64_t fdt0, uint64_t fdt1,   \
15057b77f048SAleksandar Markovic                                      uint64_t fdt2)                  \
15067b77f048SAleksandar Markovic {                                                                    \
15077b77f048SAleksandar Markovic     UNFUSED_FMA(float64, fdt0, fdt1, fdt2, type);                    \
15087b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                      \
15097b77f048SAleksandar Markovic     return fdt0;                                                     \
15107b77f048SAleksandar Markovic }                                                                    \
15117b77f048SAleksandar Markovic                                                                      \
15127b77f048SAleksandar Markovic uint32_t helper_float_ ## name ## _s(CPUMIPSState *env,              \
15137b77f048SAleksandar Markovic                                      uint32_t fst0, uint32_t fst1,   \
15147b77f048SAleksandar Markovic                                      uint32_t fst2)                  \
15157b77f048SAleksandar Markovic {                                                                    \
15167b77f048SAleksandar Markovic     UNFUSED_FMA(float32, fst0, fst1, fst2, type);                    \
15177b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                      \
15187b77f048SAleksandar Markovic     return fst0;                                                     \
15197b77f048SAleksandar Markovic }                                                                    \
15207b77f048SAleksandar Markovic                                                                      \
15217b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,             \
15227b77f048SAleksandar Markovic                                       uint64_t fdt0, uint64_t fdt1,  \
15237b77f048SAleksandar Markovic                                       uint64_t fdt2)                 \
15247b77f048SAleksandar Markovic {                                                                    \
15257b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;                               \
15267b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;                                     \
15277b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;                               \
15287b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;                                     \
15297b77f048SAleksandar Markovic     uint32_t fst2 = fdt2 & 0XFFFFFFFF;                               \
15307b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;                                     \
15317b77f048SAleksandar Markovic                                                                      \
15327b77f048SAleksandar Markovic     UNFUSED_FMA(float32, fst0, fst1, fst2, type);                    \
15337b77f048SAleksandar Markovic     UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type);                 \
15347b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                      \
15357b77f048SAleksandar Markovic     return ((uint64_t)fsth0 << 32) | fst0;                           \
15367b77f048SAleksandar Markovic }
15377b77f048SAleksandar Markovic FLOAT_FMA(madd, 0)
15387b77f048SAleksandar Markovic FLOAT_FMA(msub, float_muladd_negate_c)
15397b77f048SAleksandar Markovic FLOAT_FMA(nmadd, float_muladd_negate_result)
15407b77f048SAleksandar Markovic FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c)
15417b77f048SAleksandar Markovic #undef FLOAT_FMA
15427b77f048SAleksandar Markovic 
15437b77f048SAleksandar Markovic #define FLOAT_FMADDSUB(name, bits, muladd_arg)                          \
15447b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,             \
15457b77f048SAleksandar Markovic                                          uint ## bits ## _t fs,         \
15467b77f048SAleksandar Markovic                                          uint ## bits ## _t ft,         \
15477b77f048SAleksandar Markovic                                          uint ## bits ## _t fd)         \
15487b77f048SAleksandar Markovic {                                                                       \
15497b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                           \
15507b77f048SAleksandar Markovic                                                                         \
15517b77f048SAleksandar Markovic     fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg,            \
15527b77f048SAleksandar Markovic                                      &env->active_fpu.fp_status);       \
15537b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                         \
15547b77f048SAleksandar Markovic     return fdret;                                                       \
15557b77f048SAleksandar Markovic }
15567b77f048SAleksandar Markovic 
15577b77f048SAleksandar Markovic FLOAT_FMADDSUB(maddf_s, 32, 0)
15587b77f048SAleksandar Markovic FLOAT_FMADDSUB(maddf_d, 64, 0)
15597b77f048SAleksandar Markovic FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product)
15607b77f048SAleksandar Markovic FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product)
15617b77f048SAleksandar Markovic #undef FLOAT_FMADDSUB
15627b77f048SAleksandar Markovic 
15637b77f048SAleksandar Markovic /* compare operations */
15647b77f048SAleksandar Markovic #define FOP_COND_D(op, cond)                                   \
15657b77f048SAleksandar Markovic void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
15667b77f048SAleksandar Markovic                          uint64_t fdt1, int cc)                \
15677b77f048SAleksandar Markovic {                                                              \
15687b77f048SAleksandar Markovic     int c;                                                     \
15697b77f048SAleksandar Markovic     c = cond;                                                  \
15707b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
15717b77f048SAleksandar Markovic     if (c)                                                     \
15727b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
15737b77f048SAleksandar Markovic     else                                                       \
15747b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
15757b77f048SAleksandar Markovic }                                                              \
15767b77f048SAleksandar Markovic void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
15777b77f048SAleksandar Markovic                             uint64_t fdt1, int cc)             \
15787b77f048SAleksandar Markovic {                                                              \
15797b77f048SAleksandar Markovic     int c;                                                     \
15807b77f048SAleksandar Markovic     fdt0 = float64_abs(fdt0);                                  \
15817b77f048SAleksandar Markovic     fdt1 = float64_abs(fdt1);                                  \
15827b77f048SAleksandar Markovic     c = cond;                                                  \
15837b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
15847b77f048SAleksandar Markovic     if (c)                                                     \
15857b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
15867b77f048SAleksandar Markovic     else                                                       \
15877b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
15887b77f048SAleksandar Markovic }
15897b77f048SAleksandar Markovic 
15907b77f048SAleksandar Markovic /*
15917b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
15927b77f048SAleksandar Markovic  * but float64_unordered_quiet() is still called.
15937b77f048SAleksandar Markovic  */
15947b77f048SAleksandar Markovic FOP_COND_D(f,    (float64_unordered_quiet(fdt1, fdt0,
15957b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
15967b77f048SAleksandar Markovic FOP_COND_D(un,   float64_unordered_quiet(fdt1, fdt0,
15977b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15987b77f048SAleksandar Markovic FOP_COND_D(eq,   float64_eq_quiet(fdt0, fdt1,
15997b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16007b77f048SAleksandar Markovic FOP_COND_D(ueq,  float64_unordered_quiet(fdt1, fdt0,
16017b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16027b77f048SAleksandar Markovic                  || float64_eq_quiet(fdt0, fdt1,
16037b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16047b77f048SAleksandar Markovic FOP_COND_D(olt,  float64_lt_quiet(fdt0, fdt1,
16057b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16067b77f048SAleksandar Markovic FOP_COND_D(ult,  float64_unordered_quiet(fdt1, fdt0,
16077b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16087b77f048SAleksandar Markovic                  || float64_lt_quiet(fdt0, fdt1,
16097b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16107b77f048SAleksandar Markovic FOP_COND_D(ole,  float64_le_quiet(fdt0, fdt1,
16117b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16127b77f048SAleksandar Markovic FOP_COND_D(ule,  float64_unordered_quiet(fdt1, fdt0,
16137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16147b77f048SAleksandar Markovic                  || float64_le_quiet(fdt0, fdt1,
16157b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16167b77f048SAleksandar Markovic /*
16177b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16187b77f048SAleksandar Markovic  * but float64_unordered() is still called.
16197b77f048SAleksandar Markovic  */
16207b77f048SAleksandar Markovic FOP_COND_D(sf,   (float64_unordered(fdt1, fdt0,
16217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
16227b77f048SAleksandar Markovic FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
16237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16247b77f048SAleksandar Markovic FOP_COND_D(seq,  float64_eq(fdt0, fdt1,
16257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16267b77f048SAleksandar Markovic FOP_COND_D(ngl,  float64_unordered(fdt1, fdt0,
16277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16287b77f048SAleksandar Markovic                  || float64_eq(fdt0, fdt1,
16297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16307b77f048SAleksandar Markovic FOP_COND_D(lt,   float64_lt(fdt0, fdt1,
16317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16327b77f048SAleksandar Markovic FOP_COND_D(nge,  float64_unordered(fdt1, fdt0,
16337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16347b77f048SAleksandar Markovic                  || float64_lt(fdt0, fdt1,
16357b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16367b77f048SAleksandar Markovic FOP_COND_D(le,   float64_le(fdt0, fdt1,
16377b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16387b77f048SAleksandar Markovic FOP_COND_D(ngt,  float64_unordered(fdt1, fdt0,
16397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16407b77f048SAleksandar Markovic                  || float64_le(fdt0, fdt1,
16417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16427b77f048SAleksandar Markovic 
16437b77f048SAleksandar Markovic #define FOP_COND_S(op, cond)                                   \
16447b77f048SAleksandar Markovic void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
16457b77f048SAleksandar Markovic                          uint32_t fst1, int cc)                \
16467b77f048SAleksandar Markovic {                                                              \
16477b77f048SAleksandar Markovic     int c;                                                     \
16487b77f048SAleksandar Markovic     c = cond;                                                  \
16497b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
16507b77f048SAleksandar Markovic     if (c)                                                     \
16517b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
16527b77f048SAleksandar Markovic     else                                                       \
16537b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
16547b77f048SAleksandar Markovic }                                                              \
16557b77f048SAleksandar Markovic void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
16567b77f048SAleksandar Markovic                             uint32_t fst1, int cc)             \
16577b77f048SAleksandar Markovic {                                                              \
16587b77f048SAleksandar Markovic     int c;                                                     \
16597b77f048SAleksandar Markovic     fst0 = float32_abs(fst0);                                  \
16607b77f048SAleksandar Markovic     fst1 = float32_abs(fst1);                                  \
16617b77f048SAleksandar Markovic     c = cond;                                                  \
16627b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
16637b77f048SAleksandar Markovic     if (c)                                                     \
16647b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
16657b77f048SAleksandar Markovic     else                                                       \
16667b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
16677b77f048SAleksandar Markovic }
16687b77f048SAleksandar Markovic 
16697b77f048SAleksandar Markovic /*
16707b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16717b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
16727b77f048SAleksandar Markovic  */
16737b77f048SAleksandar Markovic FOP_COND_S(f,    (float32_unordered_quiet(fst1, fst0,
16747b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
16757b77f048SAleksandar Markovic FOP_COND_S(un,   float32_unordered_quiet(fst1, fst0,
16767b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16777b77f048SAleksandar Markovic FOP_COND_S(eq,   float32_eq_quiet(fst0, fst1,
16787b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16797b77f048SAleksandar Markovic FOP_COND_S(ueq,  float32_unordered_quiet(fst1, fst0,
16807b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16817b77f048SAleksandar Markovic                  || float32_eq_quiet(fst0, fst1,
16827b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16837b77f048SAleksandar Markovic FOP_COND_S(olt,  float32_lt_quiet(fst0, fst1,
16847b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16857b77f048SAleksandar Markovic FOP_COND_S(ult,  float32_unordered_quiet(fst1, fst0,
16867b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16877b77f048SAleksandar Markovic                  || float32_lt_quiet(fst0, fst1,
16887b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16897b77f048SAleksandar Markovic FOP_COND_S(ole,  float32_le_quiet(fst0, fst1,
16907b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16917b77f048SAleksandar Markovic FOP_COND_S(ule,  float32_unordered_quiet(fst1, fst0,
16927b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16937b77f048SAleksandar Markovic                  || float32_le_quiet(fst0, fst1,
16947b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16957b77f048SAleksandar Markovic /*
16967b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16977b77f048SAleksandar Markovic  * but float32_unordered() is still called.
16987b77f048SAleksandar Markovic  */
16997b77f048SAleksandar Markovic FOP_COND_S(sf,   (float32_unordered(fst1, fst0,
17007b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17017b77f048SAleksandar Markovic FOP_COND_S(ngle, float32_unordered(fst1, fst0,
17027b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17037b77f048SAleksandar Markovic FOP_COND_S(seq,  float32_eq(fst0, fst1,
17047b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17057b77f048SAleksandar Markovic FOP_COND_S(ngl,  float32_unordered(fst1, fst0,
17067b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17077b77f048SAleksandar Markovic                  || float32_eq(fst0, fst1,
17087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17097b77f048SAleksandar Markovic FOP_COND_S(lt,   float32_lt(fst0, fst1,
17107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17117b77f048SAleksandar Markovic FOP_COND_S(nge,  float32_unordered(fst1, fst0,
17127b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17137b77f048SAleksandar Markovic                  || float32_lt(fst0, fst1,
17147b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17157b77f048SAleksandar Markovic FOP_COND_S(le,   float32_le(fst0, fst1,
17167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17177b77f048SAleksandar Markovic FOP_COND_S(ngt,  float32_unordered(fst1, fst0,
17187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17197b77f048SAleksandar Markovic                  || float32_le(fst0, fst1,
17207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17217b77f048SAleksandar Markovic 
17227b77f048SAleksandar Markovic #define FOP_COND_PS(op, condl, condh)                           \
17237b77f048SAleksandar Markovic void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
17247b77f048SAleksandar Markovic                           uint64_t fdt1, int cc)                \
17257b77f048SAleksandar Markovic {                                                               \
17267b77f048SAleksandar Markovic     uint32_t fst0, fsth0, fst1, fsth1;                          \
17277b77f048SAleksandar Markovic     int ch, cl;                                                 \
17287b77f048SAleksandar Markovic     fst0 = fdt0 & 0XFFFFFFFF;                                   \
17297b77f048SAleksandar Markovic     fsth0 = fdt0 >> 32;                                         \
17307b77f048SAleksandar Markovic     fst1 = fdt1 & 0XFFFFFFFF;                                   \
17317b77f048SAleksandar Markovic     fsth1 = fdt1 >> 32;                                         \
17327b77f048SAleksandar Markovic     cl = condl;                                                 \
17337b77f048SAleksandar Markovic     ch = condh;                                                 \
17347b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                 \
17357b77f048SAleksandar Markovic     if (cl)                                                     \
17367b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                       \
17377b77f048SAleksandar Markovic     else                                                        \
17387b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                     \
17397b77f048SAleksandar Markovic     if (ch)                                                     \
17407b77f048SAleksandar Markovic         SET_FP_COND(cc + 1, env->active_fpu);                   \
17417b77f048SAleksandar Markovic     else                                                        \
17427b77f048SAleksandar Markovic         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
17437b77f048SAleksandar Markovic }                                                               \
17447b77f048SAleksandar Markovic void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
17457b77f048SAleksandar Markovic                              uint64_t fdt1, int cc)             \
17467b77f048SAleksandar Markovic {                                                               \
17477b77f048SAleksandar Markovic     uint32_t fst0, fsth0, fst1, fsth1;                          \
17487b77f048SAleksandar Markovic     int ch, cl;                                                 \
17497b77f048SAleksandar Markovic     fst0 = float32_abs(fdt0 & 0XFFFFFFFF);                      \
17507b77f048SAleksandar Markovic     fsth0 = float32_abs(fdt0 >> 32);                            \
17517b77f048SAleksandar Markovic     fst1 = float32_abs(fdt1 & 0XFFFFFFFF);                      \
17527b77f048SAleksandar Markovic     fsth1 = float32_abs(fdt1 >> 32);                            \
17537b77f048SAleksandar Markovic     cl = condl;                                                 \
17547b77f048SAleksandar Markovic     ch = condh;                                                 \
17557b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                 \
17567b77f048SAleksandar Markovic     if (cl)                                                     \
17577b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                       \
17587b77f048SAleksandar Markovic     else                                                        \
17597b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                     \
17607b77f048SAleksandar Markovic     if (ch)                                                     \
17617b77f048SAleksandar Markovic         SET_FP_COND(cc + 1, env->active_fpu);                   \
17627b77f048SAleksandar Markovic     else                                                        \
17637b77f048SAleksandar Markovic         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
17647b77f048SAleksandar Markovic }
17657b77f048SAleksandar Markovic 
17667b77f048SAleksandar Markovic /*
17677b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
17687b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
17697b77f048SAleksandar Markovic  */
17707b77f048SAleksandar Markovic FOP_COND_PS(f,    (float32_unordered_quiet(fst1, fst0,
17717b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0),
17727b77f048SAleksandar Markovic                   (float32_unordered_quiet(fsth1, fsth0,
17737b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17747b77f048SAleksandar Markovic FOP_COND_PS(un,   float32_unordered_quiet(fst1, fst0,
17757b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17767b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17777b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17787b77f048SAleksandar Markovic FOP_COND_PS(eq,   float32_eq_quiet(fst0, fst1,
17797b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17807b77f048SAleksandar Markovic                   float32_eq_quiet(fsth0, fsth1,
17817b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17827b77f048SAleksandar Markovic FOP_COND_PS(ueq,  float32_unordered_quiet(fst1, fst0,
17837b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17847b77f048SAleksandar Markovic                   || float32_eq_quiet(fst0, fst1,
17857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17867b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17887b77f048SAleksandar Markovic                   || float32_eq_quiet(fsth0, fsth1,
17897b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17907b77f048SAleksandar Markovic FOP_COND_PS(olt,  float32_lt_quiet(fst0, fst1,
17917b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17927b77f048SAleksandar Markovic                   float32_lt_quiet(fsth0, fsth1,
17937b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17947b77f048SAleksandar Markovic FOP_COND_PS(ult,  float32_unordered_quiet(fst1, fst0,
17957b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17967b77f048SAleksandar Markovic                   || float32_lt_quiet(fst0, fst1,
17977b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17987b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17997b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18007b77f048SAleksandar Markovic                   || float32_lt_quiet(fsth0, fsth1,
18017b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18027b77f048SAleksandar Markovic FOP_COND_PS(ole,  float32_le_quiet(fst0, fst1,
18037b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18047b77f048SAleksandar Markovic                   float32_le_quiet(fsth0, fsth1,
18057b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18067b77f048SAleksandar Markovic FOP_COND_PS(ule,  float32_unordered_quiet(fst1, fst0,
18077b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18087b77f048SAleksandar Markovic                   || float32_le_quiet(fst0, fst1,
18097b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18107b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
18117b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18127b77f048SAleksandar Markovic                   || float32_le_quiet(fsth0, fsth1,
18137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18147b77f048SAleksandar Markovic /*
18157b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
18167b77f048SAleksandar Markovic  * but float32_unordered() is still called.
18177b77f048SAleksandar Markovic  */
18187b77f048SAleksandar Markovic FOP_COND_PS(sf,   (float32_unordered(fst1, fst0,
18197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0),
18207b77f048SAleksandar Markovic                   (float32_unordered(fsth1, fsth0,
18217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
18227b77f048SAleksandar Markovic FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
18237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18247b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
18257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18267b77f048SAleksandar Markovic FOP_COND_PS(seq,  float32_eq(fst0, fst1,
18277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18287b77f048SAleksandar Markovic                   float32_eq(fsth0, fsth1,
18297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18307b77f048SAleksandar Markovic FOP_COND_PS(ngl,  float32_unordered(fst1, fst0,
18317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18327b77f048SAleksandar Markovic                   || float32_eq(fst0, fst1,
18337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18347b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
18357b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18367b77f048SAleksandar Markovic                   || float32_eq(fsth0, fsth1,
18377b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18387b77f048SAleksandar Markovic FOP_COND_PS(lt,   float32_lt(fst0, fst1,
18397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18407b77f048SAleksandar Markovic                   float32_lt(fsth0, fsth1,
18417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18427b77f048SAleksandar Markovic FOP_COND_PS(nge,  float32_unordered(fst1, fst0,
18437b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18447b77f048SAleksandar Markovic                   || float32_lt(fst0, fst1,
18457b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18467b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
18477b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18487b77f048SAleksandar Markovic                   || float32_lt(fsth0, fsth1,
18497b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18507b77f048SAleksandar Markovic FOP_COND_PS(le,   float32_le(fst0, fst1,
18517b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18527b77f048SAleksandar Markovic                   float32_le(fsth0, fsth1,
18537b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18547b77f048SAleksandar Markovic FOP_COND_PS(ngt,  float32_unordered(fst1, fst0,
18557b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18567b77f048SAleksandar Markovic                   || float32_le(fst0, fst1,
18577b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18587b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
18597b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18607b77f048SAleksandar Markovic                   || float32_le(fsth0, fsth1,
18617b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18627b77f048SAleksandar Markovic 
18637b77f048SAleksandar Markovic /* R6 compare operations */
18647b77f048SAleksandar Markovic #define FOP_CONDN_D(op, cond)                                       \
18657b77f048SAleksandar Markovic uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,   \
18667b77f048SAleksandar Markovic                                 uint64_t fdt1)                      \
18677b77f048SAleksandar Markovic {                                                                   \
18687b77f048SAleksandar Markovic     uint64_t c;                                                     \
18697b77f048SAleksandar Markovic     c = cond;                                                       \
18707b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                     \
18717b77f048SAleksandar Markovic     if (c) {                                                        \
18727b77f048SAleksandar Markovic         return -1;                                                  \
18737b77f048SAleksandar Markovic     } else {                                                        \
18747b77f048SAleksandar Markovic         return 0;                                                   \
18757b77f048SAleksandar Markovic     }                                                               \
18767b77f048SAleksandar Markovic }
18777b77f048SAleksandar Markovic 
18787b77f048SAleksandar Markovic /*
18797b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
18807b77f048SAleksandar Markovic  * but float64_unordered_quiet() is still called.
18817b77f048SAleksandar Markovic  */
18827b77f048SAleksandar Markovic FOP_CONDN_D(af,  (float64_unordered_quiet(fdt1, fdt0,
18837b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
18847b77f048SAleksandar Markovic FOP_CONDN_D(un,  (float64_unordered_quiet(fdt1, fdt0,
18857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18867b77f048SAleksandar Markovic FOP_CONDN_D(eq,  (float64_eq_quiet(fdt0, fdt1,
18877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18887b77f048SAleksandar Markovic FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
18897b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18907b77f048SAleksandar Markovic                  || float64_eq_quiet(fdt0, fdt1,
18917b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18927b77f048SAleksandar Markovic FOP_CONDN_D(lt,  (float64_lt_quiet(fdt0, fdt1,
18937b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18947b77f048SAleksandar Markovic FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
18957b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18967b77f048SAleksandar Markovic                  || float64_lt_quiet(fdt0, fdt1,
18977b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18987b77f048SAleksandar Markovic FOP_CONDN_D(le,  (float64_le_quiet(fdt0, fdt1,
18997b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19007b77f048SAleksandar Markovic FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
19017b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19027b77f048SAleksandar Markovic                  || float64_le_quiet(fdt0, fdt1,
19037b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19047b77f048SAleksandar Markovic /*
19057b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
19067b77f048SAleksandar Markovic  * but float64_unordered() is still called.\
19077b77f048SAleksandar Markovic  */
19087b77f048SAleksandar Markovic FOP_CONDN_D(saf,  (float64_unordered(fdt1, fdt0,
19097b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
19107b77f048SAleksandar Markovic FOP_CONDN_D(sun,  (float64_unordered(fdt1, fdt0,
19117b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19127b77f048SAleksandar Markovic FOP_CONDN_D(seq,  (float64_eq(fdt0, fdt1,
19137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19147b77f048SAleksandar Markovic FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
19157b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19167b77f048SAleksandar Markovic                    || float64_eq(fdt0, fdt1,
19177b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19187b77f048SAleksandar Markovic FOP_CONDN_D(slt,  (float64_lt(fdt0, fdt1,
19197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19207b77f048SAleksandar Markovic FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
19217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19227b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
19237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19247b77f048SAleksandar Markovic FOP_CONDN_D(sle,  (float64_le(fdt0, fdt1,
19257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19267b77f048SAleksandar Markovic FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
19277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19287b77f048SAleksandar Markovic                    || float64_le(fdt0, fdt1,
19297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19307b77f048SAleksandar Markovic FOP_CONDN_D(or,   (float64_le_quiet(fdt1, fdt0,
19317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19327b77f048SAleksandar Markovic                    || float64_le_quiet(fdt0, fdt1,
19337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19347b77f048SAleksandar Markovic FOP_CONDN_D(une,  (float64_unordered_quiet(fdt1, fdt0,
19357b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19367b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt1, fdt0,
19377b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19387b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt0, fdt1,
19397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19407b77f048SAleksandar Markovic FOP_CONDN_D(ne,   (float64_lt_quiet(fdt1, fdt0,
19417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19427b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt0, fdt1,
19437b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19447b77f048SAleksandar Markovic FOP_CONDN_D(sor,  (float64_le(fdt1, fdt0,
19457b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19467b77f048SAleksandar Markovic                    || float64_le(fdt0, fdt1,
19477b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19487b77f048SAleksandar Markovic FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
19497b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19507b77f048SAleksandar Markovic                    || float64_lt(fdt1, fdt0,
19517b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19527b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
19537b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19547b77f048SAleksandar Markovic FOP_CONDN_D(sne,  (float64_lt(fdt1, fdt0,
19557b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19567b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
19577b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19587b77f048SAleksandar Markovic 
19597b77f048SAleksandar Markovic #define FOP_CONDN_S(op, cond)                                       \
19607b77f048SAleksandar Markovic uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,   \
19617b77f048SAleksandar Markovic                                 uint32_t fst1)                      \
19627b77f048SAleksandar Markovic {                                                                   \
19637b77f048SAleksandar Markovic     uint64_t c;                                                     \
19647b77f048SAleksandar Markovic     c = cond;                                                       \
19657b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                     \
19667b77f048SAleksandar Markovic     if (c) {                                                        \
19677b77f048SAleksandar Markovic         return -1;                                                  \
19687b77f048SAleksandar Markovic     } else {                                                        \
19697b77f048SAleksandar Markovic         return 0;                                                   \
19707b77f048SAleksandar Markovic     }                                                               \
19717b77f048SAleksandar Markovic }
19727b77f048SAleksandar Markovic 
19737b77f048SAleksandar Markovic /*
19747b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
19757b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
19767b77f048SAleksandar Markovic  */
19777b77f048SAleksandar Markovic FOP_CONDN_S(af,   (float32_unordered_quiet(fst1, fst0,
19787b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
19797b77f048SAleksandar Markovic FOP_CONDN_S(un,   (float32_unordered_quiet(fst1, fst0,
19807b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19817b77f048SAleksandar Markovic FOP_CONDN_S(eq,   (float32_eq_quiet(fst0, fst1,
19827b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19837b77f048SAleksandar Markovic FOP_CONDN_S(ueq,  (float32_unordered_quiet(fst1, fst0,
19847b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19857b77f048SAleksandar Markovic                    || float32_eq_quiet(fst0, fst1,
19867b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19877b77f048SAleksandar Markovic FOP_CONDN_S(lt,   (float32_lt_quiet(fst0, fst1,
19887b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19897b77f048SAleksandar Markovic FOP_CONDN_S(ult,  (float32_unordered_quiet(fst1, fst0,
19907b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19917b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
19927b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19937b77f048SAleksandar Markovic FOP_CONDN_S(le,   (float32_le_quiet(fst0, fst1,
19947b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19957b77f048SAleksandar Markovic FOP_CONDN_S(ule,  (float32_unordered_quiet(fst1, fst0,
19967b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19977b77f048SAleksandar Markovic                    || float32_le_quiet(fst0, fst1,
19987b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19997b77f048SAleksandar Markovic /*
20007b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
20017b77f048SAleksandar Markovic  * but float32_unordered() is still called.
20027b77f048SAleksandar Markovic  */
20037b77f048SAleksandar Markovic FOP_CONDN_S(saf,  (float32_unordered(fst1, fst0,
20047b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
20057b77f048SAleksandar Markovic FOP_CONDN_S(sun,  (float32_unordered(fst1, fst0,
20067b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20077b77f048SAleksandar Markovic FOP_CONDN_S(seq,  (float32_eq(fst0, fst1,
20087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20097b77f048SAleksandar Markovic FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
20107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20117b77f048SAleksandar Markovic                    || float32_eq(fst0, fst1,
20127b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20137b77f048SAleksandar Markovic FOP_CONDN_S(slt,  (float32_lt(fst0, fst1,
20147b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20157b77f048SAleksandar Markovic FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
20167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20177b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
20187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20197b77f048SAleksandar Markovic FOP_CONDN_S(sle,  (float32_le(fst0, fst1,
20207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20217b77f048SAleksandar Markovic FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
20227b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20237b77f048SAleksandar Markovic                    || float32_le(fst0, fst1,
20247b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20257b77f048SAleksandar Markovic FOP_CONDN_S(or,   (float32_le_quiet(fst1, fst0,
20267b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20277b77f048SAleksandar Markovic                    || float32_le_quiet(fst0, fst1,
20287b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20297b77f048SAleksandar Markovic FOP_CONDN_S(une,  (float32_unordered_quiet(fst1, fst0,
20307b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20317b77f048SAleksandar Markovic                    || float32_lt_quiet(fst1, fst0,
20327b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20337b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
20347b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20357b77f048SAleksandar Markovic FOP_CONDN_S(ne,   (float32_lt_quiet(fst1, fst0,
20367b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20377b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
20387b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20397b77f048SAleksandar Markovic FOP_CONDN_S(sor,  (float32_le(fst1, fst0,
20407b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20417b77f048SAleksandar Markovic                    || float32_le(fst0, fst1,
20427b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20437b77f048SAleksandar Markovic FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
20447b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20457b77f048SAleksandar Markovic                    || float32_lt(fst1, fst0,
20467b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20477b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
20487b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20497b77f048SAleksandar Markovic FOP_CONDN_S(sne,  (float32_lt(fst1, fst0,
20507b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20517b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
20527b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
2053