xref: /qemu/target/mips/tcg/fpu_helper.c (revision 92ebdd7fa4f48e09f0da3973fe3136131cfee94f)
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 FLOAT_BINOP(mul)
12127b77f048SAleksandar Markovic FLOAT_BINOP(div)
12137b77f048SAleksandar Markovic #undef FLOAT_BINOP
12147b77f048SAleksandar Markovic 
12151ace099fSAleksandar Markovic uint64_t helper_float_add_d(CPUMIPSState *env,
12161ace099fSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
12171ace099fSAleksandar Markovic {
12181ace099fSAleksandar Markovic     uint64_t dt2;
12191ace099fSAleksandar Markovic 
12201ace099fSAleksandar Markovic     dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
12211ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12221ace099fSAleksandar Markovic     return dt2;
12231ace099fSAleksandar Markovic }
12241ace099fSAleksandar Markovic 
12251ace099fSAleksandar Markovic uint32_t helper_float_add_s(CPUMIPSState *env,
12261ace099fSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
12271ace099fSAleksandar Markovic {
12281ace099fSAleksandar Markovic     uint32_t wt2;
12291ace099fSAleksandar Markovic 
12301ace099fSAleksandar Markovic     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
12311ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12321ace099fSAleksandar Markovic     return wt2;
12331ace099fSAleksandar Markovic }
12341ace099fSAleksandar Markovic 
12351ace099fSAleksandar Markovic uint64_t helper_float_add_ps(CPUMIPSState *env,
12361ace099fSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
12371ace099fSAleksandar Markovic {
12381ace099fSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
12391ace099fSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
12401ace099fSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
12411ace099fSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
12421ace099fSAleksandar Markovic     uint32_t wtl2;
12431ace099fSAleksandar Markovic     uint32_t wth2;
12441ace099fSAleksandar Markovic 
12451ace099fSAleksandar Markovic     wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
12461ace099fSAleksandar Markovic     wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
12471ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12481ace099fSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
12491ace099fSAleksandar Markovic }
12501ace099fSAleksandar Markovic 
1251*92ebdd7fSAleksandar Markovic uint64_t helper_float_sub_d(CPUMIPSState *env,
1252*92ebdd7fSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
1253*92ebdd7fSAleksandar Markovic {
1254*92ebdd7fSAleksandar Markovic     uint64_t dt2;
1255*92ebdd7fSAleksandar Markovic 
1256*92ebdd7fSAleksandar Markovic     dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
1257*92ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
1258*92ebdd7fSAleksandar Markovic     return dt2;
1259*92ebdd7fSAleksandar Markovic }
1260*92ebdd7fSAleksandar Markovic 
1261*92ebdd7fSAleksandar Markovic uint32_t helper_float_sub_s(CPUMIPSState *env,
1262*92ebdd7fSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
1263*92ebdd7fSAleksandar Markovic {
1264*92ebdd7fSAleksandar Markovic     uint32_t wt2;
1265*92ebdd7fSAleksandar Markovic 
1266*92ebdd7fSAleksandar Markovic     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
1267*92ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
1268*92ebdd7fSAleksandar Markovic     return wt2;
1269*92ebdd7fSAleksandar Markovic }
1270*92ebdd7fSAleksandar Markovic 
1271*92ebdd7fSAleksandar Markovic uint64_t helper_float_sub_ps(CPUMIPSState *env,
1272*92ebdd7fSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
1273*92ebdd7fSAleksandar Markovic {
1274*92ebdd7fSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1275*92ebdd7fSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1276*92ebdd7fSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1277*92ebdd7fSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
1278*92ebdd7fSAleksandar Markovic     uint32_t wtl2;
1279*92ebdd7fSAleksandar Markovic     uint32_t wth2;
1280*92ebdd7fSAleksandar Markovic 
1281*92ebdd7fSAleksandar Markovic     wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
1282*92ebdd7fSAleksandar Markovic     wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
1283*92ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
1284*92ebdd7fSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
1285*92ebdd7fSAleksandar Markovic }
1286*92ebdd7fSAleksandar Markovic 
12871ace099fSAleksandar Markovic 
12887b77f048SAleksandar Markovic /* MIPS specific binary operations */
12897b77f048SAleksandar Markovic uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
12907b77f048SAleksandar Markovic {
12917b77f048SAleksandar Markovic     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
12927b77f048SAleksandar Markovic     fdt2 = float64_chs(float64_sub(fdt2, float64_one,
12937b77f048SAleksandar Markovic                                    &env->active_fpu.fp_status));
12947b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
12957b77f048SAleksandar Markovic     return fdt2;
12967b77f048SAleksandar Markovic }
12977b77f048SAleksandar Markovic 
12987b77f048SAleksandar Markovic uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
12997b77f048SAleksandar Markovic {
13007b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13017b77f048SAleksandar Markovic     fst2 = float32_chs(float32_sub(fst2, float32_one,
13027b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13037b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13047b77f048SAleksandar Markovic     return fst2;
13057b77f048SAleksandar Markovic }
13067b77f048SAleksandar Markovic 
13077b77f048SAleksandar Markovic uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13087b77f048SAleksandar Markovic {
13097b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
13107b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
13117b77f048SAleksandar Markovic     uint32_t fst2 = fdt2 & 0XFFFFFFFF;
13127b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
13137b77f048SAleksandar Markovic 
13147b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13157b77f048SAleksandar Markovic     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
13167b77f048SAleksandar Markovic     fst2 = float32_chs(float32_sub(fst2, float32_one,
13177b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13187b77f048SAleksandar Markovic     fsth2 = float32_chs(float32_sub(fsth2, float32_one,
13197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13207b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13217b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
13227b77f048SAleksandar Markovic }
13237b77f048SAleksandar Markovic 
13247b77f048SAleksandar Markovic uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13257b77f048SAleksandar Markovic {
13267b77f048SAleksandar Markovic     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
13277b77f048SAleksandar Markovic     fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
13287b77f048SAleksandar Markovic     fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
13297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13307b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13317b77f048SAleksandar Markovic     return fdt2;
13327b77f048SAleksandar Markovic }
13337b77f048SAleksandar Markovic 
13347b77f048SAleksandar Markovic uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
13357b77f048SAleksandar Markovic {
13367b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13377b77f048SAleksandar Markovic     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
13387b77f048SAleksandar Markovic     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
13397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13407b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13417b77f048SAleksandar Markovic     return fst2;
13427b77f048SAleksandar Markovic }
13437b77f048SAleksandar Markovic 
13447b77f048SAleksandar Markovic uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13457b77f048SAleksandar Markovic {
13467b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
13477b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
13487b77f048SAleksandar Markovic     uint32_t fst2 = fdt2 & 0XFFFFFFFF;
13497b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
13507b77f048SAleksandar Markovic 
13517b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13527b77f048SAleksandar Markovic     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
13537b77f048SAleksandar Markovic     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
13547b77f048SAleksandar Markovic     fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
13557b77f048SAleksandar Markovic     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
13567b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13577b77f048SAleksandar Markovic     fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
13587b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13597b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13607b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
13617b77f048SAleksandar Markovic }
13627b77f048SAleksandar Markovic 
13637b77f048SAleksandar Markovic uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
13647b77f048SAleksandar Markovic {
13657b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
13667b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
13677b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;
13687b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
13697b77f048SAleksandar Markovic     uint32_t fst2;
13707b77f048SAleksandar Markovic     uint32_t fsth2;
13717b77f048SAleksandar Markovic 
13727b77f048SAleksandar Markovic     fst2 = float32_add(fst0, fsth0, &env->active_fpu.fp_status);
13737b77f048SAleksandar Markovic     fsth2 = float32_add(fst1, fsth1, &env->active_fpu.fp_status);
13747b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13757b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
13767b77f048SAleksandar Markovic }
13777b77f048SAleksandar Markovic 
13787b77f048SAleksandar Markovic uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
13797b77f048SAleksandar Markovic {
13807b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;
13817b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
13827b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;
13837b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
13847b77f048SAleksandar Markovic     uint32_t fst2;
13857b77f048SAleksandar Markovic     uint32_t fsth2;
13867b77f048SAleksandar Markovic 
13877b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fsth0, &env->active_fpu.fp_status);
13887b77f048SAleksandar Markovic     fsth2 = float32_mul(fst1, fsth1, &env->active_fpu.fp_status);
13897b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13907b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
13917b77f048SAleksandar Markovic }
13927b77f048SAleksandar Markovic 
13937b77f048SAleksandar Markovic #define FLOAT_MINMAX(name, bits, minmaxfunc)                            \
13947b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,             \
13957b77f048SAleksandar Markovic                                          uint ## bits ## _t fs,         \
13967b77f048SAleksandar Markovic                                          uint ## bits ## _t ft)         \
13977b77f048SAleksandar Markovic {                                                                       \
13987b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                           \
13997b77f048SAleksandar Markovic                                                                         \
14007b77f048SAleksandar Markovic     fdret = float ## bits ## _ ## minmaxfunc(fs, ft,                    \
14017b77f048SAleksandar Markovic                                            &env->active_fpu.fp_status); \
14027b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                         \
14037b77f048SAleksandar Markovic     return fdret;                                                       \
14047b77f048SAleksandar Markovic }
14057b77f048SAleksandar Markovic 
14067b77f048SAleksandar Markovic FLOAT_MINMAX(max_s, 32, maxnum)
14077b77f048SAleksandar Markovic FLOAT_MINMAX(max_d, 64, maxnum)
14087b77f048SAleksandar Markovic FLOAT_MINMAX(maxa_s, 32, maxnummag)
14097b77f048SAleksandar Markovic FLOAT_MINMAX(maxa_d, 64, maxnummag)
14107b77f048SAleksandar Markovic 
14117b77f048SAleksandar Markovic FLOAT_MINMAX(min_s, 32, minnum)
14127b77f048SAleksandar Markovic FLOAT_MINMAX(min_d, 64, minnum)
14137b77f048SAleksandar Markovic FLOAT_MINMAX(mina_s, 32, minnummag)
14147b77f048SAleksandar Markovic FLOAT_MINMAX(mina_d, 64, minnummag)
14157b77f048SAleksandar Markovic #undef FLOAT_MINMAX
14167b77f048SAleksandar Markovic 
14177b77f048SAleksandar Markovic /* ternary operations */
14187b77f048SAleksandar Markovic #define UNFUSED_FMA(prefix, a, b, c, flags)                          \
14197b77f048SAleksandar Markovic {                                                                    \
14207b77f048SAleksandar Markovic     a = prefix##_mul(a, b, &env->active_fpu.fp_status);              \
14217b77f048SAleksandar Markovic     if ((flags) & float_muladd_negate_c) {                           \
14227b77f048SAleksandar Markovic         a = prefix##_sub(a, c, &env->active_fpu.fp_status);          \
14237b77f048SAleksandar Markovic     } else {                                                         \
14247b77f048SAleksandar Markovic         a = prefix##_add(a, c, &env->active_fpu.fp_status);          \
14257b77f048SAleksandar Markovic     }                                                                \
14267b77f048SAleksandar Markovic     if ((flags) & float_muladd_negate_result) {                      \
14277b77f048SAleksandar Markovic         a = prefix##_chs(a);                                         \
14287b77f048SAleksandar Markovic     }                                                                \
14297b77f048SAleksandar Markovic }
14307b77f048SAleksandar Markovic 
14317b77f048SAleksandar Markovic /* FMA based operations */
14327b77f048SAleksandar Markovic #define FLOAT_FMA(name, type)                                        \
14337b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _d(CPUMIPSState *env,              \
14347b77f048SAleksandar Markovic                                      uint64_t fdt0, uint64_t fdt1,   \
14357b77f048SAleksandar Markovic                                      uint64_t fdt2)                  \
14367b77f048SAleksandar Markovic {                                                                    \
14377b77f048SAleksandar Markovic     UNFUSED_FMA(float64, fdt0, fdt1, fdt2, type);                    \
14387b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                      \
14397b77f048SAleksandar Markovic     return fdt0;                                                     \
14407b77f048SAleksandar Markovic }                                                                    \
14417b77f048SAleksandar Markovic                                                                      \
14427b77f048SAleksandar Markovic uint32_t helper_float_ ## name ## _s(CPUMIPSState *env,              \
14437b77f048SAleksandar Markovic                                      uint32_t fst0, uint32_t fst1,   \
14447b77f048SAleksandar Markovic                                      uint32_t fst2)                  \
14457b77f048SAleksandar Markovic {                                                                    \
14467b77f048SAleksandar Markovic     UNFUSED_FMA(float32, fst0, fst1, fst2, type);                    \
14477b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                      \
14487b77f048SAleksandar Markovic     return fst0;                                                     \
14497b77f048SAleksandar Markovic }                                                                    \
14507b77f048SAleksandar Markovic                                                                      \
14517b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env,             \
14527b77f048SAleksandar Markovic                                       uint64_t fdt0, uint64_t fdt1,  \
14537b77f048SAleksandar Markovic                                       uint64_t fdt2)                 \
14547b77f048SAleksandar Markovic {                                                                    \
14557b77f048SAleksandar Markovic     uint32_t fst0 = fdt0 & 0XFFFFFFFF;                               \
14567b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;                                     \
14577b77f048SAleksandar Markovic     uint32_t fst1 = fdt1 & 0XFFFFFFFF;                               \
14587b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;                                     \
14597b77f048SAleksandar Markovic     uint32_t fst2 = fdt2 & 0XFFFFFFFF;                               \
14607b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;                                     \
14617b77f048SAleksandar Markovic                                                                      \
14627b77f048SAleksandar Markovic     UNFUSED_FMA(float32, fst0, fst1, fst2, type);                    \
14637b77f048SAleksandar Markovic     UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type);                 \
14647b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                      \
14657b77f048SAleksandar Markovic     return ((uint64_t)fsth0 << 32) | fst0;                           \
14667b77f048SAleksandar Markovic }
14677b77f048SAleksandar Markovic FLOAT_FMA(madd, 0)
14687b77f048SAleksandar Markovic FLOAT_FMA(msub, float_muladd_negate_c)
14697b77f048SAleksandar Markovic FLOAT_FMA(nmadd, float_muladd_negate_result)
14707b77f048SAleksandar Markovic FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c)
14717b77f048SAleksandar Markovic #undef FLOAT_FMA
14727b77f048SAleksandar Markovic 
14737b77f048SAleksandar Markovic #define FLOAT_FMADDSUB(name, bits, muladd_arg)                          \
14747b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,             \
14757b77f048SAleksandar Markovic                                          uint ## bits ## _t fs,         \
14767b77f048SAleksandar Markovic                                          uint ## bits ## _t ft,         \
14777b77f048SAleksandar Markovic                                          uint ## bits ## _t fd)         \
14787b77f048SAleksandar Markovic {                                                                       \
14797b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                           \
14807b77f048SAleksandar Markovic                                                                         \
14817b77f048SAleksandar Markovic     fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg,            \
14827b77f048SAleksandar Markovic                                      &env->active_fpu.fp_status);       \
14837b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                         \
14847b77f048SAleksandar Markovic     return fdret;                                                       \
14857b77f048SAleksandar Markovic }
14867b77f048SAleksandar Markovic 
14877b77f048SAleksandar Markovic FLOAT_FMADDSUB(maddf_s, 32, 0)
14887b77f048SAleksandar Markovic FLOAT_FMADDSUB(maddf_d, 64, 0)
14897b77f048SAleksandar Markovic FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product)
14907b77f048SAleksandar Markovic FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product)
14917b77f048SAleksandar Markovic #undef FLOAT_FMADDSUB
14927b77f048SAleksandar Markovic 
14937b77f048SAleksandar Markovic /* compare operations */
14947b77f048SAleksandar Markovic #define FOP_COND_D(op, cond)                                   \
14957b77f048SAleksandar Markovic void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
14967b77f048SAleksandar Markovic                          uint64_t fdt1, int cc)                \
14977b77f048SAleksandar Markovic {                                                              \
14987b77f048SAleksandar Markovic     int c;                                                     \
14997b77f048SAleksandar Markovic     c = cond;                                                  \
15007b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
15017b77f048SAleksandar Markovic     if (c)                                                     \
15027b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
15037b77f048SAleksandar Markovic     else                                                       \
15047b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
15057b77f048SAleksandar Markovic }                                                              \
15067b77f048SAleksandar Markovic void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
15077b77f048SAleksandar Markovic                             uint64_t fdt1, int cc)             \
15087b77f048SAleksandar Markovic {                                                              \
15097b77f048SAleksandar Markovic     int c;                                                     \
15107b77f048SAleksandar Markovic     fdt0 = float64_abs(fdt0);                                  \
15117b77f048SAleksandar Markovic     fdt1 = float64_abs(fdt1);                                  \
15127b77f048SAleksandar Markovic     c = cond;                                                  \
15137b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
15147b77f048SAleksandar Markovic     if (c)                                                     \
15157b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
15167b77f048SAleksandar Markovic     else                                                       \
15177b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
15187b77f048SAleksandar Markovic }
15197b77f048SAleksandar Markovic 
15207b77f048SAleksandar Markovic /*
15217b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
15227b77f048SAleksandar Markovic  * but float64_unordered_quiet() is still called.
15237b77f048SAleksandar Markovic  */
15247b77f048SAleksandar Markovic FOP_COND_D(f,    (float64_unordered_quiet(fdt1, fdt0,
15257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
15267b77f048SAleksandar Markovic FOP_COND_D(un,   float64_unordered_quiet(fdt1, fdt0,
15277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15287b77f048SAleksandar Markovic FOP_COND_D(eq,   float64_eq_quiet(fdt0, fdt1,
15297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15307b77f048SAleksandar Markovic FOP_COND_D(ueq,  float64_unordered_quiet(fdt1, fdt0,
15317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
15327b77f048SAleksandar Markovic                  || float64_eq_quiet(fdt0, fdt1,
15337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15347b77f048SAleksandar Markovic FOP_COND_D(olt,  float64_lt_quiet(fdt0, fdt1,
15357b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15367b77f048SAleksandar Markovic FOP_COND_D(ult,  float64_unordered_quiet(fdt1, fdt0,
15377b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
15387b77f048SAleksandar Markovic                  || float64_lt_quiet(fdt0, fdt1,
15397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15407b77f048SAleksandar Markovic FOP_COND_D(ole,  float64_le_quiet(fdt0, fdt1,
15417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15427b77f048SAleksandar Markovic FOP_COND_D(ule,  float64_unordered_quiet(fdt1, fdt0,
15437b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
15447b77f048SAleksandar Markovic                  || float64_le_quiet(fdt0, fdt1,
15457b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15467b77f048SAleksandar Markovic /*
15477b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
15487b77f048SAleksandar Markovic  * but float64_unordered() is still called.
15497b77f048SAleksandar Markovic  */
15507b77f048SAleksandar Markovic FOP_COND_D(sf,   (float64_unordered(fdt1, fdt0,
15517b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
15527b77f048SAleksandar Markovic FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
15537b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15547b77f048SAleksandar Markovic FOP_COND_D(seq,  float64_eq(fdt0, fdt1,
15557b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15567b77f048SAleksandar Markovic FOP_COND_D(ngl,  float64_unordered(fdt1, fdt0,
15577b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
15587b77f048SAleksandar Markovic                  || float64_eq(fdt0, fdt1,
15597b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15607b77f048SAleksandar Markovic FOP_COND_D(lt,   float64_lt(fdt0, fdt1,
15617b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15627b77f048SAleksandar Markovic FOP_COND_D(nge,  float64_unordered(fdt1, fdt0,
15637b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
15647b77f048SAleksandar Markovic                  || float64_lt(fdt0, fdt1,
15657b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15667b77f048SAleksandar Markovic FOP_COND_D(le,   float64_le(fdt0, fdt1,
15677b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15687b77f048SAleksandar Markovic FOP_COND_D(ngt,  float64_unordered(fdt1, fdt0,
15697b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
15707b77f048SAleksandar Markovic                  || float64_le(fdt0, fdt1,
15717b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
15727b77f048SAleksandar Markovic 
15737b77f048SAleksandar Markovic #define FOP_COND_S(op, cond)                                   \
15747b77f048SAleksandar Markovic void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
15757b77f048SAleksandar Markovic                          uint32_t fst1, int cc)                \
15767b77f048SAleksandar Markovic {                                                              \
15777b77f048SAleksandar Markovic     int c;                                                     \
15787b77f048SAleksandar Markovic     c = cond;                                                  \
15797b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
15807b77f048SAleksandar Markovic     if (c)                                                     \
15817b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
15827b77f048SAleksandar Markovic     else                                                       \
15837b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
15847b77f048SAleksandar Markovic }                                                              \
15857b77f048SAleksandar Markovic void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
15867b77f048SAleksandar Markovic                             uint32_t fst1, int cc)             \
15877b77f048SAleksandar Markovic {                                                              \
15887b77f048SAleksandar Markovic     int c;                                                     \
15897b77f048SAleksandar Markovic     fst0 = float32_abs(fst0);                                  \
15907b77f048SAleksandar Markovic     fst1 = float32_abs(fst1);                                  \
15917b77f048SAleksandar Markovic     c = cond;                                                  \
15927b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
15937b77f048SAleksandar Markovic     if (c)                                                     \
15947b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
15957b77f048SAleksandar Markovic     else                                                       \
15967b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
15977b77f048SAleksandar Markovic }
15987b77f048SAleksandar Markovic 
15997b77f048SAleksandar Markovic /*
16007b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16017b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
16027b77f048SAleksandar Markovic  */
16037b77f048SAleksandar Markovic FOP_COND_S(f,    (float32_unordered_quiet(fst1, fst0,
16047b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
16057b77f048SAleksandar Markovic FOP_COND_S(un,   float32_unordered_quiet(fst1, fst0,
16067b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16077b77f048SAleksandar Markovic FOP_COND_S(eq,   float32_eq_quiet(fst0, fst1,
16087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16097b77f048SAleksandar Markovic FOP_COND_S(ueq,  float32_unordered_quiet(fst1, fst0,
16107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16117b77f048SAleksandar Markovic                  || float32_eq_quiet(fst0, fst1,
16127b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16137b77f048SAleksandar Markovic FOP_COND_S(olt,  float32_lt_quiet(fst0, fst1,
16147b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16157b77f048SAleksandar Markovic FOP_COND_S(ult,  float32_unordered_quiet(fst1, fst0,
16167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16177b77f048SAleksandar Markovic                  || float32_lt_quiet(fst0, fst1,
16187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16197b77f048SAleksandar Markovic FOP_COND_S(ole,  float32_le_quiet(fst0, fst1,
16207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16217b77f048SAleksandar Markovic FOP_COND_S(ule,  float32_unordered_quiet(fst1, fst0,
16227b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16237b77f048SAleksandar Markovic                  || float32_le_quiet(fst0, fst1,
16247b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16257b77f048SAleksandar Markovic /*
16267b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16277b77f048SAleksandar Markovic  * but float32_unordered() is still called.
16287b77f048SAleksandar Markovic  */
16297b77f048SAleksandar Markovic FOP_COND_S(sf,   (float32_unordered(fst1, fst0,
16307b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
16317b77f048SAleksandar Markovic FOP_COND_S(ngle, float32_unordered(fst1, fst0,
16327b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16337b77f048SAleksandar Markovic FOP_COND_S(seq,  float32_eq(fst0, fst1,
16347b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16357b77f048SAleksandar Markovic FOP_COND_S(ngl,  float32_unordered(fst1, fst0,
16367b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16377b77f048SAleksandar Markovic                  || float32_eq(fst0, fst1,
16387b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16397b77f048SAleksandar Markovic FOP_COND_S(lt,   float32_lt(fst0, fst1,
16407b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16417b77f048SAleksandar Markovic FOP_COND_S(nge,  float32_unordered(fst1, fst0,
16427b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16437b77f048SAleksandar Markovic                  || float32_lt(fst0, fst1,
16447b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16457b77f048SAleksandar Markovic FOP_COND_S(le,   float32_le(fst0, fst1,
16467b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16477b77f048SAleksandar Markovic FOP_COND_S(ngt,  float32_unordered(fst1, fst0,
16487b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
16497b77f048SAleksandar Markovic                  || float32_le(fst0, fst1,
16507b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
16517b77f048SAleksandar Markovic 
16527b77f048SAleksandar Markovic #define FOP_COND_PS(op, condl, condh)                           \
16537b77f048SAleksandar Markovic void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
16547b77f048SAleksandar Markovic                           uint64_t fdt1, int cc)                \
16557b77f048SAleksandar Markovic {                                                               \
16567b77f048SAleksandar Markovic     uint32_t fst0, fsth0, fst1, fsth1;                          \
16577b77f048SAleksandar Markovic     int ch, cl;                                                 \
16587b77f048SAleksandar Markovic     fst0 = fdt0 & 0XFFFFFFFF;                                   \
16597b77f048SAleksandar Markovic     fsth0 = fdt0 >> 32;                                         \
16607b77f048SAleksandar Markovic     fst1 = fdt1 & 0XFFFFFFFF;                                   \
16617b77f048SAleksandar Markovic     fsth1 = fdt1 >> 32;                                         \
16627b77f048SAleksandar Markovic     cl = condl;                                                 \
16637b77f048SAleksandar Markovic     ch = condh;                                                 \
16647b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                 \
16657b77f048SAleksandar Markovic     if (cl)                                                     \
16667b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                       \
16677b77f048SAleksandar Markovic     else                                                        \
16687b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                     \
16697b77f048SAleksandar Markovic     if (ch)                                                     \
16707b77f048SAleksandar Markovic         SET_FP_COND(cc + 1, env->active_fpu);                   \
16717b77f048SAleksandar Markovic     else                                                        \
16727b77f048SAleksandar Markovic         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
16737b77f048SAleksandar Markovic }                                                               \
16747b77f048SAleksandar Markovic void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
16757b77f048SAleksandar Markovic                              uint64_t fdt1, int cc)             \
16767b77f048SAleksandar Markovic {                                                               \
16777b77f048SAleksandar Markovic     uint32_t fst0, fsth0, fst1, fsth1;                          \
16787b77f048SAleksandar Markovic     int ch, cl;                                                 \
16797b77f048SAleksandar Markovic     fst0 = float32_abs(fdt0 & 0XFFFFFFFF);                      \
16807b77f048SAleksandar Markovic     fsth0 = float32_abs(fdt0 >> 32);                            \
16817b77f048SAleksandar Markovic     fst1 = float32_abs(fdt1 & 0XFFFFFFFF);                      \
16827b77f048SAleksandar Markovic     fsth1 = float32_abs(fdt1 >> 32);                            \
16837b77f048SAleksandar Markovic     cl = condl;                                                 \
16847b77f048SAleksandar Markovic     ch = condh;                                                 \
16857b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                 \
16867b77f048SAleksandar Markovic     if (cl)                                                     \
16877b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                       \
16887b77f048SAleksandar Markovic     else                                                        \
16897b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                     \
16907b77f048SAleksandar Markovic     if (ch)                                                     \
16917b77f048SAleksandar Markovic         SET_FP_COND(cc + 1, env->active_fpu);                   \
16927b77f048SAleksandar Markovic     else                                                        \
16937b77f048SAleksandar Markovic         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
16947b77f048SAleksandar Markovic }
16957b77f048SAleksandar Markovic 
16967b77f048SAleksandar Markovic /*
16977b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16987b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
16997b77f048SAleksandar Markovic  */
17007b77f048SAleksandar Markovic FOP_COND_PS(f,    (float32_unordered_quiet(fst1, fst0,
17017b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0),
17027b77f048SAleksandar Markovic                   (float32_unordered_quiet(fsth1, fsth0,
17037b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17047b77f048SAleksandar Markovic FOP_COND_PS(un,   float32_unordered_quiet(fst1, fst0,
17057b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17067b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17077b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17087b77f048SAleksandar Markovic FOP_COND_PS(eq,   float32_eq_quiet(fst0, fst1,
17097b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17107b77f048SAleksandar Markovic                   float32_eq_quiet(fsth0, fsth1,
17117b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17127b77f048SAleksandar Markovic FOP_COND_PS(ueq,  float32_unordered_quiet(fst1, fst0,
17137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17147b77f048SAleksandar Markovic                   || float32_eq_quiet(fst0, fst1,
17157b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17167b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17177b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17187b77f048SAleksandar Markovic                   || float32_eq_quiet(fsth0, fsth1,
17197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17207b77f048SAleksandar Markovic FOP_COND_PS(olt,  float32_lt_quiet(fst0, fst1,
17217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17227b77f048SAleksandar Markovic                   float32_lt_quiet(fsth0, fsth1,
17237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17247b77f048SAleksandar Markovic FOP_COND_PS(ult,  float32_unordered_quiet(fst1, fst0,
17257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17267b77f048SAleksandar Markovic                   || float32_lt_quiet(fst0, fst1,
17277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17287b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17307b77f048SAleksandar Markovic                   || float32_lt_quiet(fsth0, fsth1,
17317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17327b77f048SAleksandar Markovic FOP_COND_PS(ole,  float32_le_quiet(fst0, fst1,
17337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17347b77f048SAleksandar Markovic                   float32_le_quiet(fsth0, fsth1,
17357b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17367b77f048SAleksandar Markovic FOP_COND_PS(ule,  float32_unordered_quiet(fst1, fst0,
17377b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17387b77f048SAleksandar Markovic                   || float32_le_quiet(fst0, fst1,
17397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17407b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
17417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17427b77f048SAleksandar Markovic                   || float32_le_quiet(fsth0, fsth1,
17437b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17447b77f048SAleksandar Markovic /*
17457b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
17467b77f048SAleksandar Markovic  * but float32_unordered() is still called.
17477b77f048SAleksandar Markovic  */
17487b77f048SAleksandar Markovic FOP_COND_PS(sf,   (float32_unordered(fst1, fst0,
17497b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0),
17507b77f048SAleksandar Markovic                   (float32_unordered(fsth1, fsth0,
17517b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17527b77f048SAleksandar Markovic FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
17537b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17547b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
17557b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17567b77f048SAleksandar Markovic FOP_COND_PS(seq,  float32_eq(fst0, fst1,
17577b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17587b77f048SAleksandar Markovic                   float32_eq(fsth0, fsth1,
17597b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17607b77f048SAleksandar Markovic FOP_COND_PS(ngl,  float32_unordered(fst1, fst0,
17617b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17627b77f048SAleksandar Markovic                   || float32_eq(fst0, fst1,
17637b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17647b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
17657b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17667b77f048SAleksandar Markovic                   || float32_eq(fsth0, fsth1,
17677b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17687b77f048SAleksandar Markovic FOP_COND_PS(lt,   float32_lt(fst0, fst1,
17697b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17707b77f048SAleksandar Markovic                   float32_lt(fsth0, fsth1,
17717b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17727b77f048SAleksandar Markovic FOP_COND_PS(nge,  float32_unordered(fst1, fst0,
17737b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17747b77f048SAleksandar Markovic                   || float32_lt(fst0, fst1,
17757b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17767b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
17777b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17787b77f048SAleksandar Markovic                   || float32_lt(fsth0, fsth1,
17797b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17807b77f048SAleksandar Markovic FOP_COND_PS(le,   float32_le(fst0, fst1,
17817b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17827b77f048SAleksandar Markovic                   float32_le(fsth0, fsth1,
17837b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17847b77f048SAleksandar Markovic FOP_COND_PS(ngt,  float32_unordered(fst1, fst0,
17857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17867b77f048SAleksandar Markovic                   || float32_le(fst0, fst1,
17877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
17887b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
17897b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17907b77f048SAleksandar Markovic                   || float32_le(fsth0, fsth1,
17917b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17927b77f048SAleksandar Markovic 
17937b77f048SAleksandar Markovic /* R6 compare operations */
17947b77f048SAleksandar Markovic #define FOP_CONDN_D(op, cond)                                       \
17957b77f048SAleksandar Markovic uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,   \
17967b77f048SAleksandar Markovic                                 uint64_t fdt1)                      \
17977b77f048SAleksandar Markovic {                                                                   \
17987b77f048SAleksandar Markovic     uint64_t c;                                                     \
17997b77f048SAleksandar Markovic     c = cond;                                                       \
18007b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                     \
18017b77f048SAleksandar Markovic     if (c) {                                                        \
18027b77f048SAleksandar Markovic         return -1;                                                  \
18037b77f048SAleksandar Markovic     } else {                                                        \
18047b77f048SAleksandar Markovic         return 0;                                                   \
18057b77f048SAleksandar Markovic     }                                                               \
18067b77f048SAleksandar Markovic }
18077b77f048SAleksandar Markovic 
18087b77f048SAleksandar Markovic /*
18097b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
18107b77f048SAleksandar Markovic  * but float64_unordered_quiet() is still called.
18117b77f048SAleksandar Markovic  */
18127b77f048SAleksandar Markovic FOP_CONDN_D(af,  (float64_unordered_quiet(fdt1, fdt0,
18137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
18147b77f048SAleksandar Markovic FOP_CONDN_D(un,  (float64_unordered_quiet(fdt1, fdt0,
18157b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18167b77f048SAleksandar Markovic FOP_CONDN_D(eq,  (float64_eq_quiet(fdt0, fdt1,
18177b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18187b77f048SAleksandar Markovic FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
18197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18207b77f048SAleksandar Markovic                  || float64_eq_quiet(fdt0, fdt1,
18217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18227b77f048SAleksandar Markovic FOP_CONDN_D(lt,  (float64_lt_quiet(fdt0, fdt1,
18237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18247b77f048SAleksandar Markovic FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
18257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18267b77f048SAleksandar Markovic                  || float64_lt_quiet(fdt0, fdt1,
18277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18287b77f048SAleksandar Markovic FOP_CONDN_D(le,  (float64_le_quiet(fdt0, fdt1,
18297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18307b77f048SAleksandar Markovic FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
18317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18327b77f048SAleksandar Markovic                  || float64_le_quiet(fdt0, fdt1,
18337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18347b77f048SAleksandar Markovic /*
18357b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
18367b77f048SAleksandar Markovic  * but float64_unordered() is still called.\
18377b77f048SAleksandar Markovic  */
18387b77f048SAleksandar Markovic FOP_CONDN_D(saf,  (float64_unordered(fdt1, fdt0,
18397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
18407b77f048SAleksandar Markovic FOP_CONDN_D(sun,  (float64_unordered(fdt1, fdt0,
18417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18427b77f048SAleksandar Markovic FOP_CONDN_D(seq,  (float64_eq(fdt0, fdt1,
18437b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18447b77f048SAleksandar Markovic FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
18457b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18467b77f048SAleksandar Markovic                    || float64_eq(fdt0, fdt1,
18477b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18487b77f048SAleksandar Markovic FOP_CONDN_D(slt,  (float64_lt(fdt0, fdt1,
18497b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18507b77f048SAleksandar Markovic FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
18517b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18527b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
18537b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18547b77f048SAleksandar Markovic FOP_CONDN_D(sle,  (float64_le(fdt0, fdt1,
18557b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18567b77f048SAleksandar Markovic FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
18577b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18587b77f048SAleksandar Markovic                    || float64_le(fdt0, fdt1,
18597b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18607b77f048SAleksandar Markovic FOP_CONDN_D(or,   (float64_le_quiet(fdt1, fdt0,
18617b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18627b77f048SAleksandar Markovic                    || float64_le_quiet(fdt0, fdt1,
18637b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18647b77f048SAleksandar Markovic FOP_CONDN_D(une,  (float64_unordered_quiet(fdt1, fdt0,
18657b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18667b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt1, fdt0,
18677b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18687b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt0, fdt1,
18697b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18707b77f048SAleksandar Markovic FOP_CONDN_D(ne,   (float64_lt_quiet(fdt1, fdt0,
18717b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18727b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt0, fdt1,
18737b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18747b77f048SAleksandar Markovic FOP_CONDN_D(sor,  (float64_le(fdt1, fdt0,
18757b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18767b77f048SAleksandar Markovic                    || float64_le(fdt0, fdt1,
18777b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18787b77f048SAleksandar Markovic FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
18797b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18807b77f048SAleksandar Markovic                    || float64_lt(fdt1, fdt0,
18817b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18827b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
18837b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18847b77f048SAleksandar Markovic FOP_CONDN_D(sne,  (float64_lt(fdt1, fdt0,
18857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18867b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
18877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
18887b77f048SAleksandar Markovic 
18897b77f048SAleksandar Markovic #define FOP_CONDN_S(op, cond)                                       \
18907b77f048SAleksandar Markovic uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,   \
18917b77f048SAleksandar Markovic                                 uint32_t fst1)                      \
18927b77f048SAleksandar Markovic {                                                                   \
18937b77f048SAleksandar Markovic     uint64_t c;                                                     \
18947b77f048SAleksandar Markovic     c = cond;                                                       \
18957b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                     \
18967b77f048SAleksandar Markovic     if (c) {                                                        \
18977b77f048SAleksandar Markovic         return -1;                                                  \
18987b77f048SAleksandar Markovic     } else {                                                        \
18997b77f048SAleksandar Markovic         return 0;                                                   \
19007b77f048SAleksandar Markovic     }                                                               \
19017b77f048SAleksandar Markovic }
19027b77f048SAleksandar Markovic 
19037b77f048SAleksandar Markovic /*
19047b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
19057b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
19067b77f048SAleksandar Markovic  */
19077b77f048SAleksandar Markovic FOP_CONDN_S(af,   (float32_unordered_quiet(fst1, fst0,
19087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
19097b77f048SAleksandar Markovic FOP_CONDN_S(un,   (float32_unordered_quiet(fst1, fst0,
19107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19117b77f048SAleksandar Markovic FOP_CONDN_S(eq,   (float32_eq_quiet(fst0, fst1,
19127b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19137b77f048SAleksandar Markovic FOP_CONDN_S(ueq,  (float32_unordered_quiet(fst1, fst0,
19147b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19157b77f048SAleksandar Markovic                    || float32_eq_quiet(fst0, fst1,
19167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19177b77f048SAleksandar Markovic FOP_CONDN_S(lt,   (float32_lt_quiet(fst0, fst1,
19187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19197b77f048SAleksandar Markovic FOP_CONDN_S(ult,  (float32_unordered_quiet(fst1, fst0,
19207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19217b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
19227b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19237b77f048SAleksandar Markovic FOP_CONDN_S(le,   (float32_le_quiet(fst0, fst1,
19247b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19257b77f048SAleksandar Markovic FOP_CONDN_S(ule,  (float32_unordered_quiet(fst1, fst0,
19267b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19277b77f048SAleksandar Markovic                    || float32_le_quiet(fst0, fst1,
19287b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19297b77f048SAleksandar Markovic /*
19307b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
19317b77f048SAleksandar Markovic  * but float32_unordered() is still called.
19327b77f048SAleksandar Markovic  */
19337b77f048SAleksandar Markovic FOP_CONDN_S(saf,  (float32_unordered(fst1, fst0,
19347b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
19357b77f048SAleksandar Markovic FOP_CONDN_S(sun,  (float32_unordered(fst1, fst0,
19367b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19377b77f048SAleksandar Markovic FOP_CONDN_S(seq,  (float32_eq(fst0, fst1,
19387b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19397b77f048SAleksandar Markovic FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
19407b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19417b77f048SAleksandar Markovic                    || float32_eq(fst0, fst1,
19427b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19437b77f048SAleksandar Markovic FOP_CONDN_S(slt,  (float32_lt(fst0, fst1,
19447b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19457b77f048SAleksandar Markovic FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
19467b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19477b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
19487b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19497b77f048SAleksandar Markovic FOP_CONDN_S(sle,  (float32_le(fst0, fst1,
19507b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19517b77f048SAleksandar Markovic FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
19527b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19537b77f048SAleksandar Markovic                    || float32_le(fst0, fst1,
19547b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19557b77f048SAleksandar Markovic FOP_CONDN_S(or,   (float32_le_quiet(fst1, fst0,
19567b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19577b77f048SAleksandar Markovic                    || float32_le_quiet(fst0, fst1,
19587b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19597b77f048SAleksandar Markovic FOP_CONDN_S(une,  (float32_unordered_quiet(fst1, fst0,
19607b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19617b77f048SAleksandar Markovic                    || float32_lt_quiet(fst1, fst0,
19627b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19637b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
19647b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19657b77f048SAleksandar Markovic FOP_CONDN_S(ne,   (float32_lt_quiet(fst1, fst0,
19667b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19677b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
19687b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19697b77f048SAleksandar Markovic FOP_CONDN_S(sor,  (float32_le(fst1, fst0,
19707b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19717b77f048SAleksandar Markovic                    || float32_le(fst0, fst1,
19727b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19737b77f048SAleksandar Markovic FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
19747b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19757b77f048SAleksandar Markovic                    || float32_lt(fst1, fst0,
19767b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19777b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
19787b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19797b77f048SAleksandar Markovic FOP_CONDN_S(sne,  (float32_lt(fst1, fst0,
19807b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19817b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
19827b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
1983