xref: /qemu/target/mips/tcg/fpu_helper.c (revision 9579f7816855757c747f9428a8e53d0fe0a0e9b7)
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 
192*9579f781SAleksandar Markovic static inline int ieee_to_mips_xcpt(int ieee_xcpt)
1937b77f048SAleksandar Markovic {
194*9579f781SAleksandar Markovic     int mips_xcpt = 0;
195*9579f781SAleksandar Markovic 
196*9579f781SAleksandar Markovic     if (ieee_xcpt & float_flag_invalid) {
197*9579f781SAleksandar Markovic         mips_xcpt |= FP_INVALID;
1987b77f048SAleksandar Markovic     }
199*9579f781SAleksandar Markovic     if (ieee_xcpt & float_flag_overflow) {
200*9579f781SAleksandar Markovic         mips_xcpt |= FP_OVERFLOW;
2017b77f048SAleksandar Markovic     }
202*9579f781SAleksandar Markovic     if (ieee_xcpt & float_flag_underflow) {
203*9579f781SAleksandar Markovic         mips_xcpt |= FP_UNDERFLOW;
2047b77f048SAleksandar Markovic     }
205*9579f781SAleksandar Markovic     if (ieee_xcpt & float_flag_divbyzero) {
206*9579f781SAleksandar Markovic         mips_xcpt |= FP_DIV0;
2077b77f048SAleksandar Markovic     }
208*9579f781SAleksandar Markovic     if (ieee_xcpt & float_flag_inexact) {
209*9579f781SAleksandar Markovic         mips_xcpt |= FP_INEXACT;
2107b77f048SAleksandar Markovic     }
211*9579f781SAleksandar Markovic 
212*9579f781SAleksandar Markovic     return mips_xcpt;
2137b77f048SAleksandar Markovic }
2147b77f048SAleksandar Markovic 
2157b77f048SAleksandar Markovic static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
2167b77f048SAleksandar Markovic {
217*9579f781SAleksandar Markovic     int ieee_exception_flags = get_float_exception_flags(
218*9579f781SAleksandar Markovic                                    &env->active_fpu.fp_status);
219*9579f781SAleksandar Markovic     int mips_exception_flags = 0;
2207b77f048SAleksandar Markovic 
221*9579f781SAleksandar Markovic     if (ieee_exception_flags) {
222*9579f781SAleksandar Markovic         mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
223*9579f781SAleksandar Markovic     }
2247b77f048SAleksandar Markovic 
225*9579f781SAleksandar Markovic     SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
226*9579f781SAleksandar Markovic 
227*9579f781SAleksandar Markovic     if (mips_exception_flags)  {
2287b77f048SAleksandar Markovic         set_float_exception_flags(0, &env->active_fpu.fp_status);
2297b77f048SAleksandar Markovic 
230*9579f781SAleksandar Markovic         if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
2317b77f048SAleksandar Markovic             do_raise_exception(env, EXCP_FPE, pc);
2327b77f048SAleksandar Markovic         } else {
233*9579f781SAleksandar Markovic             UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
2347b77f048SAleksandar Markovic         }
2357b77f048SAleksandar Markovic     }
2367b77f048SAleksandar Markovic }
2377b77f048SAleksandar Markovic 
2387b77f048SAleksandar Markovic /*
2397b77f048SAleksandar Markovic  * Float support.
2407b77f048SAleksandar Markovic  * Single precition routines have a "s" suffix, double precision a
2417b77f048SAleksandar Markovic  * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
2427b77f048SAleksandar Markovic  * paired single lower "pl", paired single upper "pu".
2437b77f048SAleksandar Markovic  */
2447b77f048SAleksandar Markovic 
2457b77f048SAleksandar Markovic /* unary operations, modifying fp status  */
2467b77f048SAleksandar Markovic uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
2477b77f048SAleksandar Markovic {
2487b77f048SAleksandar Markovic     fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
2497b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2507b77f048SAleksandar Markovic     return fdt0;
2517b77f048SAleksandar Markovic }
2527b77f048SAleksandar Markovic 
2537b77f048SAleksandar Markovic uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
2547b77f048SAleksandar Markovic {
2557b77f048SAleksandar Markovic     fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
2567b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2577b77f048SAleksandar Markovic     return fst0;
2587b77f048SAleksandar Markovic }
2597b77f048SAleksandar Markovic 
2607b77f048SAleksandar Markovic uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
2617b77f048SAleksandar Markovic {
2627b77f048SAleksandar Markovic     uint64_t fdt2;
2637b77f048SAleksandar Markovic 
2647b77f048SAleksandar Markovic     fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
2657b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2667b77f048SAleksandar Markovic     return fdt2;
2677b77f048SAleksandar Markovic }
2687b77f048SAleksandar Markovic 
2697b77f048SAleksandar Markovic uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
2707b77f048SAleksandar Markovic {
2717b77f048SAleksandar Markovic     uint64_t fdt2;
2727b77f048SAleksandar Markovic 
2737b77f048SAleksandar Markovic     fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
2747b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2757b77f048SAleksandar Markovic     return fdt2;
2767b77f048SAleksandar Markovic }
2777b77f048SAleksandar Markovic 
2787b77f048SAleksandar Markovic uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
2797b77f048SAleksandar Markovic {
2807b77f048SAleksandar Markovic     uint64_t fdt2;
2817b77f048SAleksandar Markovic 
2827b77f048SAleksandar Markovic     fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
2837b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2847b77f048SAleksandar Markovic     return fdt2;
2857b77f048SAleksandar Markovic }
2867b77f048SAleksandar Markovic 
2877b77f048SAleksandar Markovic uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
2887b77f048SAleksandar Markovic {
2897b77f048SAleksandar Markovic     uint64_t dt2;
2907b77f048SAleksandar Markovic 
2917b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
2927b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
2937b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
2947b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
2957b77f048SAleksandar Markovic     }
2967b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
2977b77f048SAleksandar Markovic     return dt2;
2987b77f048SAleksandar Markovic }
2997b77f048SAleksandar Markovic 
3007b77f048SAleksandar Markovic uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
3017b77f048SAleksandar Markovic {
3027b77f048SAleksandar Markovic     uint64_t dt2;
3037b77f048SAleksandar Markovic 
3047b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
3057b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
3067b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
3077b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
3087b77f048SAleksandar Markovic     }
3097b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3107b77f048SAleksandar Markovic     return dt2;
3117b77f048SAleksandar Markovic }
3127b77f048SAleksandar Markovic 
3137b77f048SAleksandar Markovic uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
3147b77f048SAleksandar Markovic {
3157b77f048SAleksandar Markovic     uint32_t fst2;
3167b77f048SAleksandar Markovic     uint32_t fsth2;
3177b77f048SAleksandar Markovic 
3187b77f048SAleksandar Markovic     fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
3197b77f048SAleksandar Markovic     fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
3207b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3217b77f048SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fst2;
3227b77f048SAleksandar Markovic }
3237b77f048SAleksandar Markovic 
3247b77f048SAleksandar Markovic uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
3257b77f048SAleksandar Markovic {
3267b77f048SAleksandar Markovic     uint32_t wt2;
3277b77f048SAleksandar Markovic     uint32_t wth2;
3287b77f048SAleksandar Markovic     int excp, excph;
3297b77f048SAleksandar Markovic 
3307b77f048SAleksandar Markovic     wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
3317b77f048SAleksandar Markovic     excp = get_float_exception_flags(&env->active_fpu.fp_status);
3327b77f048SAleksandar Markovic     if (excp & (float_flag_overflow | float_flag_invalid)) {
3337b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
3347b77f048SAleksandar Markovic     }
3357b77f048SAleksandar Markovic 
3367b77f048SAleksandar Markovic     set_float_exception_flags(0, &env->active_fpu.fp_status);
3377b77f048SAleksandar Markovic     wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
3387b77f048SAleksandar Markovic     excph = get_float_exception_flags(&env->active_fpu.fp_status);
3397b77f048SAleksandar Markovic     if (excph & (float_flag_overflow | float_flag_invalid)) {
3407b77f048SAleksandar Markovic         wth2 = FP_TO_INT32_OVERFLOW;
3417b77f048SAleksandar Markovic     }
3427b77f048SAleksandar Markovic 
3437b77f048SAleksandar Markovic     set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
3447b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3457b77f048SAleksandar Markovic 
3467b77f048SAleksandar Markovic     return ((uint64_t)wth2 << 32) | wt2;
3477b77f048SAleksandar Markovic }
3487b77f048SAleksandar Markovic 
3497b77f048SAleksandar Markovic uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
3507b77f048SAleksandar Markovic {
3517b77f048SAleksandar Markovic     uint32_t fst2;
3527b77f048SAleksandar Markovic 
3537b77f048SAleksandar Markovic     fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
3547b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3557b77f048SAleksandar Markovic     return fst2;
3567b77f048SAleksandar Markovic }
3577b77f048SAleksandar Markovic 
3587b77f048SAleksandar Markovic uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
3597b77f048SAleksandar Markovic {
3607b77f048SAleksandar Markovic     uint32_t fst2;
3617b77f048SAleksandar Markovic 
3627b77f048SAleksandar Markovic     fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
3637b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3647b77f048SAleksandar Markovic     return fst2;
3657b77f048SAleksandar Markovic }
3667b77f048SAleksandar Markovic 
3677b77f048SAleksandar Markovic uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
3687b77f048SAleksandar Markovic {
3697b77f048SAleksandar Markovic     uint32_t fst2;
3707b77f048SAleksandar Markovic 
3717b77f048SAleksandar Markovic     fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
3727b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3737b77f048SAleksandar Markovic     return fst2;
3747b77f048SAleksandar Markovic }
3757b77f048SAleksandar Markovic 
3767b77f048SAleksandar Markovic uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
3777b77f048SAleksandar Markovic {
3787b77f048SAleksandar Markovic     uint32_t wt2;
3797b77f048SAleksandar Markovic 
3807b77f048SAleksandar Markovic     wt2 = wt0;
3817b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3827b77f048SAleksandar Markovic     return wt2;
3837b77f048SAleksandar Markovic }
3847b77f048SAleksandar Markovic 
3857b77f048SAleksandar Markovic uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
3867b77f048SAleksandar Markovic {
3877b77f048SAleksandar Markovic     uint32_t wt2;
3887b77f048SAleksandar Markovic 
3897b77f048SAleksandar Markovic     wt2 = wth0;
3907b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
3917b77f048SAleksandar Markovic     return wt2;
3927b77f048SAleksandar Markovic }
3937b77f048SAleksandar Markovic 
3947b77f048SAleksandar Markovic uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
3957b77f048SAleksandar Markovic {
3967b77f048SAleksandar Markovic     uint32_t wt2;
3977b77f048SAleksandar Markovic 
3987b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
3997b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4007b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4017b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4027b77f048SAleksandar Markovic     }
4037b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4047b77f048SAleksandar Markovic     return wt2;
4057b77f048SAleksandar Markovic }
4067b77f048SAleksandar Markovic 
4077b77f048SAleksandar Markovic uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
4087b77f048SAleksandar Markovic {
4097b77f048SAleksandar Markovic     uint32_t wt2;
4107b77f048SAleksandar Markovic 
4117b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
4127b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4137b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4147b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4157b77f048SAleksandar Markovic     }
4167b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4177b77f048SAleksandar Markovic     return wt2;
4187b77f048SAleksandar Markovic }
4197b77f048SAleksandar Markovic 
4207b77f048SAleksandar Markovic uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
4217b77f048SAleksandar Markovic {
4227b77f048SAleksandar Markovic     uint64_t dt2;
4237b77f048SAleksandar Markovic 
4247b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4257b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4267b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
4277b77f048SAleksandar Markovic     restore_rounding_mode(env);
4287b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4297b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4307b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
4317b77f048SAleksandar Markovic     }
4327b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4337b77f048SAleksandar Markovic     return dt2;
4347b77f048SAleksandar Markovic }
4357b77f048SAleksandar Markovic 
4367b77f048SAleksandar Markovic uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
4377b77f048SAleksandar Markovic {
4387b77f048SAleksandar Markovic     uint64_t dt2;
4397b77f048SAleksandar Markovic 
4407b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4417b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4427b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
4437b77f048SAleksandar Markovic     restore_rounding_mode(env);
4447b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4457b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4467b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
4477b77f048SAleksandar Markovic     }
4487b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4497b77f048SAleksandar Markovic     return dt2;
4507b77f048SAleksandar Markovic }
4517b77f048SAleksandar Markovic 
4527b77f048SAleksandar Markovic uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
4537b77f048SAleksandar Markovic {
4547b77f048SAleksandar Markovic     uint32_t wt2;
4557b77f048SAleksandar Markovic 
4567b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4577b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4587b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
4597b77f048SAleksandar Markovic     restore_rounding_mode(env);
4607b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4617b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4627b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4637b77f048SAleksandar Markovic     }
4647b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4657b77f048SAleksandar Markovic     return wt2;
4667b77f048SAleksandar Markovic }
4677b77f048SAleksandar Markovic 
4687b77f048SAleksandar Markovic uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
4697b77f048SAleksandar Markovic {
4707b77f048SAleksandar Markovic     uint32_t wt2;
4717b77f048SAleksandar Markovic 
4727b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
4737b77f048SAleksandar Markovic                             &env->active_fpu.fp_status);
4747b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
4757b77f048SAleksandar Markovic     restore_rounding_mode(env);
4767b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4777b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4787b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
4797b77f048SAleksandar Markovic     }
4807b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4817b77f048SAleksandar Markovic     return wt2;
4827b77f048SAleksandar Markovic }
4837b77f048SAleksandar Markovic 
4847b77f048SAleksandar Markovic uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
4857b77f048SAleksandar Markovic {
4867b77f048SAleksandar Markovic     uint64_t dt2;
4877b77f048SAleksandar Markovic 
4887b77f048SAleksandar Markovic     dt2 = float64_to_int64_round_to_zero(fdt0,
4897b77f048SAleksandar Markovic                                          &env->active_fpu.fp_status);
4907b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
4917b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
4927b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
4937b77f048SAleksandar Markovic     }
4947b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
4957b77f048SAleksandar Markovic     return dt2;
4967b77f048SAleksandar Markovic }
4977b77f048SAleksandar Markovic 
4987b77f048SAleksandar Markovic uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
4997b77f048SAleksandar Markovic {
5007b77f048SAleksandar Markovic     uint64_t dt2;
5017b77f048SAleksandar Markovic 
5027b77f048SAleksandar Markovic     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
5037b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5047b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5057b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
5067b77f048SAleksandar Markovic     }
5077b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5087b77f048SAleksandar Markovic     return dt2;
5097b77f048SAleksandar Markovic }
5107b77f048SAleksandar Markovic 
5117b77f048SAleksandar Markovic uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
5127b77f048SAleksandar Markovic {
5137b77f048SAleksandar Markovic     uint32_t wt2;
5147b77f048SAleksandar Markovic 
5157b77f048SAleksandar Markovic     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
5167b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5177b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5187b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5197b77f048SAleksandar Markovic     }
5207b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5217b77f048SAleksandar Markovic     return wt2;
5227b77f048SAleksandar Markovic }
5237b77f048SAleksandar Markovic 
5247b77f048SAleksandar Markovic uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
5257b77f048SAleksandar Markovic {
5267b77f048SAleksandar Markovic     uint32_t wt2;
5277b77f048SAleksandar Markovic 
5287b77f048SAleksandar Markovic     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
5297b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5307b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5317b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5327b77f048SAleksandar Markovic     }
5337b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5347b77f048SAleksandar Markovic     return wt2;
5357b77f048SAleksandar Markovic }
5367b77f048SAleksandar Markovic 
5377b77f048SAleksandar Markovic uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
5387b77f048SAleksandar Markovic {
5397b77f048SAleksandar Markovic     uint64_t dt2;
5407b77f048SAleksandar Markovic 
5417b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5427b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
5437b77f048SAleksandar Markovic     restore_rounding_mode(env);
5447b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5457b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5467b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
5477b77f048SAleksandar Markovic     }
5487b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5497b77f048SAleksandar Markovic     return dt2;
5507b77f048SAleksandar Markovic }
5517b77f048SAleksandar Markovic 
5527b77f048SAleksandar Markovic uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
5537b77f048SAleksandar Markovic {
5547b77f048SAleksandar Markovic     uint64_t dt2;
5557b77f048SAleksandar Markovic 
5567b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5577b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
5587b77f048SAleksandar Markovic     restore_rounding_mode(env);
5597b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5607b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5617b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
5627b77f048SAleksandar Markovic     }
5637b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5647b77f048SAleksandar Markovic     return dt2;
5657b77f048SAleksandar Markovic }
5667b77f048SAleksandar Markovic 
5677b77f048SAleksandar Markovic uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
5687b77f048SAleksandar Markovic {
5697b77f048SAleksandar Markovic     uint32_t wt2;
5707b77f048SAleksandar Markovic 
5717b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5727b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
5737b77f048SAleksandar Markovic     restore_rounding_mode(env);
5747b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5757b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5767b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5777b77f048SAleksandar Markovic     }
5787b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5797b77f048SAleksandar Markovic     return wt2;
5807b77f048SAleksandar Markovic }
5817b77f048SAleksandar Markovic 
5827b77f048SAleksandar Markovic uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
5837b77f048SAleksandar Markovic {
5847b77f048SAleksandar Markovic     uint32_t wt2;
5857b77f048SAleksandar Markovic 
5867b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
5877b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
5887b77f048SAleksandar Markovic     restore_rounding_mode(env);
5897b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
5907b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
5917b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
5927b77f048SAleksandar Markovic     }
5937b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
5947b77f048SAleksandar Markovic     return wt2;
5957b77f048SAleksandar Markovic }
5967b77f048SAleksandar Markovic 
5977b77f048SAleksandar Markovic uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
5987b77f048SAleksandar Markovic {
5997b77f048SAleksandar Markovic     uint64_t dt2;
6007b77f048SAleksandar Markovic 
6017b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6027b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
6037b77f048SAleksandar Markovic     restore_rounding_mode(env);
6047b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6057b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6067b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
6077b77f048SAleksandar Markovic     }
6087b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6097b77f048SAleksandar Markovic     return dt2;
6107b77f048SAleksandar Markovic }
6117b77f048SAleksandar Markovic 
6127b77f048SAleksandar Markovic uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
6137b77f048SAleksandar Markovic {
6147b77f048SAleksandar Markovic     uint64_t dt2;
6157b77f048SAleksandar Markovic 
6167b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6177b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
6187b77f048SAleksandar Markovic     restore_rounding_mode(env);
6197b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6207b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6217b77f048SAleksandar Markovic         dt2 = FP_TO_INT64_OVERFLOW;
6227b77f048SAleksandar Markovic     }
6237b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6247b77f048SAleksandar Markovic     return dt2;
6257b77f048SAleksandar Markovic }
6267b77f048SAleksandar Markovic 
6277b77f048SAleksandar Markovic uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
6287b77f048SAleksandar Markovic {
6297b77f048SAleksandar Markovic     uint32_t wt2;
6307b77f048SAleksandar Markovic 
6317b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6327b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
6337b77f048SAleksandar Markovic     restore_rounding_mode(env);
6347b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6357b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6367b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
6377b77f048SAleksandar Markovic     }
6387b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6397b77f048SAleksandar Markovic     return wt2;
6407b77f048SAleksandar Markovic }
6417b77f048SAleksandar Markovic 
6427b77f048SAleksandar Markovic uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
6437b77f048SAleksandar Markovic {
6447b77f048SAleksandar Markovic     uint32_t wt2;
6457b77f048SAleksandar Markovic 
6467b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
6477b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
6487b77f048SAleksandar Markovic     restore_rounding_mode(env);
6497b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6507b77f048SAleksandar Markovic         & (float_flag_invalid | float_flag_overflow)) {
6517b77f048SAleksandar Markovic         wt2 = FP_TO_INT32_OVERFLOW;
6527b77f048SAleksandar Markovic     }
6537b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6547b77f048SAleksandar Markovic     return wt2;
6557b77f048SAleksandar Markovic }
6567b77f048SAleksandar Markovic 
6577b77f048SAleksandar Markovic uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
6587b77f048SAleksandar Markovic {
6597b77f048SAleksandar Markovic     uint64_t dt2;
6607b77f048SAleksandar Markovic 
6617b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
6627b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6637b77f048SAleksandar Markovic             & float_flag_invalid) {
6647b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
6657b77f048SAleksandar Markovic             dt2 = 0;
6667b77f048SAleksandar Markovic         }
6677b77f048SAleksandar Markovic     }
6687b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6697b77f048SAleksandar Markovic     return dt2;
6707b77f048SAleksandar Markovic }
6717b77f048SAleksandar Markovic 
6727b77f048SAleksandar Markovic uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
6737b77f048SAleksandar Markovic {
6747b77f048SAleksandar Markovic     uint64_t dt2;
6757b77f048SAleksandar Markovic 
6767b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
6777b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6787b77f048SAleksandar Markovic             & float_flag_invalid) {
6797b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
6807b77f048SAleksandar Markovic             dt2 = 0;
6817b77f048SAleksandar Markovic         }
6827b77f048SAleksandar Markovic     }
6837b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6847b77f048SAleksandar Markovic     return dt2;
6857b77f048SAleksandar Markovic }
6867b77f048SAleksandar Markovic 
6877b77f048SAleksandar Markovic uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
6887b77f048SAleksandar Markovic {
6897b77f048SAleksandar Markovic     uint32_t wt2;
6907b77f048SAleksandar Markovic 
6917b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
6927b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
6937b77f048SAleksandar Markovic             & float_flag_invalid) {
6947b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
6957b77f048SAleksandar Markovic             wt2 = 0;
6967b77f048SAleksandar Markovic         }
6977b77f048SAleksandar Markovic     }
6987b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
6997b77f048SAleksandar Markovic     return wt2;
7007b77f048SAleksandar Markovic }
7017b77f048SAleksandar Markovic 
7027b77f048SAleksandar Markovic uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
7037b77f048SAleksandar Markovic {
7047b77f048SAleksandar Markovic     uint32_t wt2;
7057b77f048SAleksandar Markovic 
7067b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
7077b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7087b77f048SAleksandar Markovic             & float_flag_invalid) {
7097b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
7107b77f048SAleksandar Markovic             wt2 = 0;
7117b77f048SAleksandar Markovic         }
7127b77f048SAleksandar Markovic     }
7137b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7147b77f048SAleksandar Markovic     return wt2;
7157b77f048SAleksandar Markovic }
7167b77f048SAleksandar Markovic 
7177b77f048SAleksandar Markovic uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
7187b77f048SAleksandar Markovic {
7197b77f048SAleksandar Markovic     uint64_t dt2;
7207b77f048SAleksandar Markovic 
7217b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7227b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7237b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
7247b77f048SAleksandar Markovic     restore_rounding_mode(env);
7257b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7267b77f048SAleksandar Markovic             & float_flag_invalid) {
7277b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
7287b77f048SAleksandar Markovic             dt2 = 0;
7297b77f048SAleksandar Markovic         }
7307b77f048SAleksandar Markovic     }
7317b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7327b77f048SAleksandar Markovic     return dt2;
7337b77f048SAleksandar Markovic }
7347b77f048SAleksandar Markovic 
7357b77f048SAleksandar Markovic uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
7367b77f048SAleksandar Markovic {
7377b77f048SAleksandar Markovic     uint64_t dt2;
7387b77f048SAleksandar Markovic 
7397b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7407b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7417b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
7427b77f048SAleksandar Markovic     restore_rounding_mode(env);
7437b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7447b77f048SAleksandar Markovic             & float_flag_invalid) {
7457b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
7467b77f048SAleksandar Markovic             dt2 = 0;
7477b77f048SAleksandar Markovic         }
7487b77f048SAleksandar Markovic     }
7497b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7507b77f048SAleksandar Markovic     return dt2;
7517b77f048SAleksandar Markovic }
7527b77f048SAleksandar Markovic 
7537b77f048SAleksandar Markovic uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
7547b77f048SAleksandar Markovic {
7557b77f048SAleksandar Markovic     uint32_t wt2;
7567b77f048SAleksandar Markovic 
7577b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7587b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7597b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
7607b77f048SAleksandar Markovic     restore_rounding_mode(env);
7617b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7627b77f048SAleksandar Markovic             & float_flag_invalid) {
7637b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
7647b77f048SAleksandar Markovic             wt2 = 0;
7657b77f048SAleksandar Markovic         }
7667b77f048SAleksandar Markovic     }
7677b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7687b77f048SAleksandar Markovic     return wt2;
7697b77f048SAleksandar Markovic }
7707b77f048SAleksandar Markovic 
7717b77f048SAleksandar Markovic uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
7727b77f048SAleksandar Markovic {
7737b77f048SAleksandar Markovic     uint32_t wt2;
7747b77f048SAleksandar Markovic 
7757b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_nearest_even,
7767b77f048SAleksandar Markovic             &env->active_fpu.fp_status);
7777b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
7787b77f048SAleksandar Markovic     restore_rounding_mode(env);
7797b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7807b77f048SAleksandar Markovic             & float_flag_invalid) {
7817b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
7827b77f048SAleksandar Markovic             wt2 = 0;
7837b77f048SAleksandar Markovic         }
7847b77f048SAleksandar Markovic     }
7857b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
7867b77f048SAleksandar Markovic     return wt2;
7877b77f048SAleksandar Markovic }
7887b77f048SAleksandar Markovic 
7897b77f048SAleksandar Markovic uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
7907b77f048SAleksandar Markovic {
7917b77f048SAleksandar Markovic     uint64_t dt2;
7927b77f048SAleksandar Markovic 
7937b77f048SAleksandar Markovic     dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
7947b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
7957b77f048SAleksandar Markovic             & float_flag_invalid) {
7967b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
7977b77f048SAleksandar Markovic             dt2 = 0;
7987b77f048SAleksandar Markovic         }
7997b77f048SAleksandar Markovic     }
8007b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8017b77f048SAleksandar Markovic     return dt2;
8027b77f048SAleksandar Markovic }
8037b77f048SAleksandar Markovic 
8047b77f048SAleksandar Markovic uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
8057b77f048SAleksandar Markovic {
8067b77f048SAleksandar Markovic     uint64_t dt2;
8077b77f048SAleksandar Markovic 
8087b77f048SAleksandar Markovic     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
8097b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8107b77f048SAleksandar Markovic             & float_flag_invalid) {
8117b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
8127b77f048SAleksandar Markovic             dt2 = 0;
8137b77f048SAleksandar Markovic         }
8147b77f048SAleksandar Markovic     }
8157b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8167b77f048SAleksandar Markovic     return dt2;
8177b77f048SAleksandar Markovic }
8187b77f048SAleksandar Markovic 
8197b77f048SAleksandar Markovic uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
8207b77f048SAleksandar Markovic {
8217b77f048SAleksandar Markovic     uint32_t wt2;
8227b77f048SAleksandar Markovic 
8237b77f048SAleksandar Markovic     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
8247b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8257b77f048SAleksandar Markovic             & float_flag_invalid) {
8267b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
8277b77f048SAleksandar Markovic             wt2 = 0;
8287b77f048SAleksandar Markovic         }
8297b77f048SAleksandar Markovic     }
8307b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8317b77f048SAleksandar Markovic     return wt2;
8327b77f048SAleksandar Markovic }
8337b77f048SAleksandar Markovic 
8347b77f048SAleksandar Markovic uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
8357b77f048SAleksandar Markovic {
8367b77f048SAleksandar Markovic     uint32_t wt2;
8377b77f048SAleksandar Markovic 
8387b77f048SAleksandar Markovic     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
8397b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8407b77f048SAleksandar Markovic             & float_flag_invalid) {
8417b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
8427b77f048SAleksandar Markovic             wt2 = 0;
8437b77f048SAleksandar Markovic         }
8447b77f048SAleksandar Markovic     }
8457b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8467b77f048SAleksandar Markovic     return wt2;
8477b77f048SAleksandar Markovic }
8487b77f048SAleksandar Markovic 
8497b77f048SAleksandar Markovic uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
8507b77f048SAleksandar Markovic {
8517b77f048SAleksandar Markovic     uint64_t dt2;
8527b77f048SAleksandar Markovic 
8537b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
8547b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
8557b77f048SAleksandar Markovic     restore_rounding_mode(env);
8567b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8577b77f048SAleksandar Markovic             & float_flag_invalid) {
8587b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
8597b77f048SAleksandar Markovic             dt2 = 0;
8607b77f048SAleksandar Markovic         }
8617b77f048SAleksandar Markovic     }
8627b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8637b77f048SAleksandar Markovic     return dt2;
8647b77f048SAleksandar Markovic }
8657b77f048SAleksandar Markovic 
8667b77f048SAleksandar Markovic uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
8677b77f048SAleksandar Markovic {
8687b77f048SAleksandar Markovic     uint64_t dt2;
8697b77f048SAleksandar Markovic 
8707b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
8717b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
8727b77f048SAleksandar Markovic     restore_rounding_mode(env);
8737b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8747b77f048SAleksandar Markovic             & float_flag_invalid) {
8757b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
8767b77f048SAleksandar Markovic             dt2 = 0;
8777b77f048SAleksandar Markovic         }
8787b77f048SAleksandar Markovic     }
8797b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8807b77f048SAleksandar Markovic     return dt2;
8817b77f048SAleksandar Markovic }
8827b77f048SAleksandar Markovic 
8837b77f048SAleksandar Markovic uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
8847b77f048SAleksandar Markovic {
8857b77f048SAleksandar Markovic     uint32_t wt2;
8867b77f048SAleksandar Markovic 
8877b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
8887b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
8897b77f048SAleksandar Markovic     restore_rounding_mode(env);
8907b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
8917b77f048SAleksandar Markovic             & float_flag_invalid) {
8927b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
8937b77f048SAleksandar Markovic             wt2 = 0;
8947b77f048SAleksandar Markovic         }
8957b77f048SAleksandar Markovic     }
8967b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
8977b77f048SAleksandar Markovic     return wt2;
8987b77f048SAleksandar Markovic }
8997b77f048SAleksandar Markovic 
9007b77f048SAleksandar Markovic uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
9017b77f048SAleksandar Markovic {
9027b77f048SAleksandar Markovic     uint32_t wt2;
9037b77f048SAleksandar Markovic 
9047b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
9057b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
9067b77f048SAleksandar Markovic     restore_rounding_mode(env);
9077b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9087b77f048SAleksandar Markovic             & float_flag_invalid) {
9097b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
9107b77f048SAleksandar Markovic             wt2 = 0;
9117b77f048SAleksandar Markovic         }
9127b77f048SAleksandar Markovic     }
9137b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9147b77f048SAleksandar Markovic     return wt2;
9157b77f048SAleksandar Markovic }
9167b77f048SAleksandar Markovic 
9177b77f048SAleksandar Markovic uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
9187b77f048SAleksandar Markovic {
9197b77f048SAleksandar Markovic     uint64_t dt2;
9207b77f048SAleksandar Markovic 
9217b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9227b77f048SAleksandar Markovic     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
9237b77f048SAleksandar Markovic     restore_rounding_mode(env);
9247b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9257b77f048SAleksandar Markovic             & float_flag_invalid) {
9267b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
9277b77f048SAleksandar Markovic             dt2 = 0;
9287b77f048SAleksandar Markovic         }
9297b77f048SAleksandar Markovic     }
9307b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9317b77f048SAleksandar Markovic     return dt2;
9327b77f048SAleksandar Markovic }
9337b77f048SAleksandar Markovic 
9347b77f048SAleksandar Markovic uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
9357b77f048SAleksandar Markovic {
9367b77f048SAleksandar Markovic     uint64_t dt2;
9377b77f048SAleksandar Markovic 
9387b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9397b77f048SAleksandar Markovic     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
9407b77f048SAleksandar Markovic     restore_rounding_mode(env);
9417b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9427b77f048SAleksandar Markovic             & float_flag_invalid) {
9437b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
9447b77f048SAleksandar Markovic             dt2 = 0;
9457b77f048SAleksandar Markovic         }
9467b77f048SAleksandar Markovic     }
9477b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9487b77f048SAleksandar Markovic     return dt2;
9497b77f048SAleksandar Markovic }
9507b77f048SAleksandar Markovic 
9517b77f048SAleksandar Markovic uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
9527b77f048SAleksandar Markovic {
9537b77f048SAleksandar Markovic     uint32_t wt2;
9547b77f048SAleksandar Markovic 
9557b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9567b77f048SAleksandar Markovic     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
9577b77f048SAleksandar Markovic     restore_rounding_mode(env);
9587b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9597b77f048SAleksandar Markovic             & float_flag_invalid) {
9607b77f048SAleksandar Markovic         if (float64_is_any_nan(fdt0)) {
9617b77f048SAleksandar Markovic             wt2 = 0;
9627b77f048SAleksandar Markovic         }
9637b77f048SAleksandar Markovic     }
9647b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9657b77f048SAleksandar Markovic     return wt2;
9667b77f048SAleksandar Markovic }
9677b77f048SAleksandar Markovic 
9687b77f048SAleksandar Markovic uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
9697b77f048SAleksandar Markovic {
9707b77f048SAleksandar Markovic     uint32_t wt2;
9717b77f048SAleksandar Markovic 
9727b77f048SAleksandar Markovic     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
9737b77f048SAleksandar Markovic     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
9747b77f048SAleksandar Markovic     restore_rounding_mode(env);
9757b77f048SAleksandar Markovic     if (get_float_exception_flags(&env->active_fpu.fp_status)
9767b77f048SAleksandar Markovic             & float_flag_invalid) {
9777b77f048SAleksandar Markovic         if (float32_is_any_nan(fst0)) {
9787b77f048SAleksandar Markovic             wt2 = 0;
9797b77f048SAleksandar Markovic         }
9807b77f048SAleksandar Markovic     }
9817b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
9827b77f048SAleksandar Markovic     return wt2;
9837b77f048SAleksandar Markovic }
9847b77f048SAleksandar Markovic 
9857b77f048SAleksandar Markovic /* unary operations, not modifying fp status  */
9867b77f048SAleksandar Markovic #define FLOAT_UNOP(name)                                       \
9877b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _d(uint64_t fdt0)                \
9887b77f048SAleksandar Markovic {                                                              \
9897b77f048SAleksandar Markovic     return float64_ ## name(fdt0);                             \
9907b77f048SAleksandar Markovic }                                                              \
9917b77f048SAleksandar Markovic uint32_t helper_float_ ## name ## _s(uint32_t fst0)                \
9927b77f048SAleksandar Markovic {                                                              \
9937b77f048SAleksandar Markovic     return float32_ ## name(fst0);                             \
9947b77f048SAleksandar Markovic }                                                              \
9957b77f048SAleksandar Markovic uint64_t helper_float_ ## name ## _ps(uint64_t fdt0)               \
9967b77f048SAleksandar Markovic {                                                              \
9977b77f048SAleksandar Markovic     uint32_t wt0;                                              \
9987b77f048SAleksandar Markovic     uint32_t wth0;                                             \
9997b77f048SAleksandar Markovic                                                                \
10007b77f048SAleksandar Markovic     wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF);                 \
10017b77f048SAleksandar Markovic     wth0 = float32_ ## name(fdt0 >> 32);                       \
10027b77f048SAleksandar Markovic     return ((uint64_t)wth0 << 32) | wt0;                       \
10037b77f048SAleksandar Markovic }
10047b77f048SAleksandar Markovic FLOAT_UNOP(abs)
10057b77f048SAleksandar Markovic FLOAT_UNOP(chs)
10067b77f048SAleksandar Markovic #undef FLOAT_UNOP
10077b77f048SAleksandar Markovic 
10087b77f048SAleksandar Markovic /* MIPS specific unary operations */
10097b77f048SAleksandar Markovic uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
10107b77f048SAleksandar Markovic {
10117b77f048SAleksandar Markovic     uint64_t fdt2;
10127b77f048SAleksandar Markovic 
10137b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
10147b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10157b77f048SAleksandar Markovic     return fdt2;
10167b77f048SAleksandar Markovic }
10177b77f048SAleksandar Markovic 
10187b77f048SAleksandar Markovic uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
10197b77f048SAleksandar Markovic {
10207b77f048SAleksandar Markovic     uint32_t fst2;
10217b77f048SAleksandar Markovic 
10227b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
10237b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10247b77f048SAleksandar Markovic     return fst2;
10257b77f048SAleksandar Markovic }
10267b77f048SAleksandar Markovic 
10277b77f048SAleksandar Markovic uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
10287b77f048SAleksandar Markovic {
10297b77f048SAleksandar Markovic     uint64_t fdt2;
10307b77f048SAleksandar Markovic 
10317b77f048SAleksandar Markovic     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
10327b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
10337b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10347b77f048SAleksandar Markovic     return fdt2;
10357b77f048SAleksandar Markovic }
10367b77f048SAleksandar Markovic 
10377b77f048SAleksandar Markovic uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
10387b77f048SAleksandar Markovic {
10397b77f048SAleksandar Markovic     uint32_t fst2;
10407b77f048SAleksandar Markovic 
10417b77f048SAleksandar Markovic     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
10427b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
10437b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10447b77f048SAleksandar Markovic     return fst2;
10457b77f048SAleksandar Markovic }
10467b77f048SAleksandar Markovic 
10477b77f048SAleksandar Markovic uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
10487b77f048SAleksandar Markovic {
10497b77f048SAleksandar Markovic     uint64_t fdt2;
10507b77f048SAleksandar Markovic 
10517b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
10527b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10537b77f048SAleksandar Markovic     return fdt2;
10547b77f048SAleksandar Markovic }
10557b77f048SAleksandar Markovic 
10567b77f048SAleksandar Markovic uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
10577b77f048SAleksandar Markovic {
10587b77f048SAleksandar Markovic     uint32_t fst2;
10597b77f048SAleksandar Markovic 
10607b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
10617b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10627b77f048SAleksandar Markovic     return fst2;
10637b77f048SAleksandar Markovic }
10647b77f048SAleksandar Markovic 
10657b77f048SAleksandar Markovic uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
10667b77f048SAleksandar Markovic {
1067485cd2e4SAleksandar Markovic     uint32_t fstl2;
10687b77f048SAleksandar Markovic     uint32_t fsth2;
10697b77f048SAleksandar Markovic 
1070485cd2e4SAleksandar Markovic     fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
10717b77f048SAleksandar Markovic                         &env->active_fpu.fp_status);
10727b77f048SAleksandar Markovic     fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
10737b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
1074485cd2e4SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fstl2;
10757b77f048SAleksandar Markovic }
10767b77f048SAleksandar Markovic 
10777b77f048SAleksandar Markovic uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
10787b77f048SAleksandar Markovic {
10797b77f048SAleksandar Markovic     uint64_t fdt2;
10807b77f048SAleksandar Markovic 
10817b77f048SAleksandar Markovic     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
10827b77f048SAleksandar Markovic     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
10837b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10847b77f048SAleksandar Markovic     return fdt2;
10857b77f048SAleksandar Markovic }
10867b77f048SAleksandar Markovic 
10877b77f048SAleksandar Markovic uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
10887b77f048SAleksandar Markovic {
10897b77f048SAleksandar Markovic     uint32_t fst2;
10907b77f048SAleksandar Markovic 
10917b77f048SAleksandar Markovic     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
10927b77f048SAleksandar Markovic     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
10937b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
10947b77f048SAleksandar Markovic     return fst2;
10957b77f048SAleksandar Markovic }
10967b77f048SAleksandar Markovic 
10977b77f048SAleksandar Markovic uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
10987b77f048SAleksandar Markovic {
1099485cd2e4SAleksandar Markovic     uint32_t fstl2;
11007b77f048SAleksandar Markovic     uint32_t fsth2;
11017b77f048SAleksandar Markovic 
1102485cd2e4SAleksandar Markovic     fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
11037b77f048SAleksandar Markovic     fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
1104485cd2e4SAleksandar Markovic     fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
11057b77f048SAleksandar Markovic     fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
11067b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
1107485cd2e4SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fstl2;
11087b77f048SAleksandar Markovic }
11097b77f048SAleksandar Markovic 
1110728e4246SAleksandar Markovic uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
1111728e4246SAleksandar Markovic {
1112728e4246SAleksandar Markovic     uint64_t fdret;
1113728e4246SAleksandar Markovic 
1114728e4246SAleksandar Markovic     fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
1115728e4246SAleksandar Markovic     update_fcr31(env, GETPC());
1116728e4246SAleksandar Markovic     return fdret;
1117728e4246SAleksandar Markovic }
1118728e4246SAleksandar Markovic 
1119728e4246SAleksandar Markovic uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
1120728e4246SAleksandar Markovic {
1121728e4246SAleksandar Markovic     uint32_t fdret;
1122728e4246SAleksandar Markovic 
1123728e4246SAleksandar Markovic     fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
1124728e4246SAleksandar Markovic     update_fcr31(env, GETPC());
1125728e4246SAleksandar Markovic     return fdret;
1126728e4246SAleksandar Markovic }
1127728e4246SAleksandar Markovic 
11287b77f048SAleksandar Markovic #define FLOAT_CLASS_SIGNALING_NAN      0x001
11297b77f048SAleksandar Markovic #define FLOAT_CLASS_QUIET_NAN          0x002
11307b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
11317b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_NORMAL    0x008
11327b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
11337b77f048SAleksandar Markovic #define FLOAT_CLASS_NEGATIVE_ZERO      0x020
11347b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_INFINITY  0x040
11357b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_NORMAL    0x080
11367b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
11377b77f048SAleksandar Markovic #define FLOAT_CLASS_POSITIVE_ZERO      0x200
11387b77f048SAleksandar Markovic 
11390bd99ac7SAleksandar Markovic uint64_t float_class_d(uint64_t arg, float_status *status)
11400bd99ac7SAleksandar Markovic {
11410bd99ac7SAleksandar Markovic     if (float64_is_signaling_nan(arg, status)) {
11420bd99ac7SAleksandar Markovic         return FLOAT_CLASS_SIGNALING_NAN;
11430bd99ac7SAleksandar Markovic     } else if (float64_is_quiet_nan(arg, status)) {
11440bd99ac7SAleksandar Markovic         return FLOAT_CLASS_QUIET_NAN;
11450bd99ac7SAleksandar Markovic     } else if (float64_is_neg(arg)) {
11460bd99ac7SAleksandar Markovic         if (float64_is_infinity(arg)) {
11470bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_INFINITY;
11480bd99ac7SAleksandar Markovic         } else if (float64_is_zero(arg)) {
11490bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_ZERO;
11500bd99ac7SAleksandar Markovic         } else if (float64_is_zero_or_denormal(arg)) {
11510bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
11520bd99ac7SAleksandar Markovic         } else {
11530bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_NORMAL;
11540bd99ac7SAleksandar Markovic         }
11550bd99ac7SAleksandar Markovic     } else {
11560bd99ac7SAleksandar Markovic         if (float64_is_infinity(arg)) {
11570bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_INFINITY;
11580bd99ac7SAleksandar Markovic         } else if (float64_is_zero(arg)) {
11590bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_ZERO;
11600bd99ac7SAleksandar Markovic         } else if (float64_is_zero_or_denormal(arg)) {
11610bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_SUBNORMAL;
11620bd99ac7SAleksandar Markovic         } else {
11630bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_NORMAL;
11640bd99ac7SAleksandar Markovic         }
11650bd99ac7SAleksandar Markovic     }
11660bd99ac7SAleksandar Markovic }
11670bd99ac7SAleksandar Markovic 
11680bd99ac7SAleksandar Markovic uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
11690bd99ac7SAleksandar Markovic {
11700bd99ac7SAleksandar Markovic     return float_class_d(arg, &env->active_fpu.fp_status);
11710bd99ac7SAleksandar Markovic }
11720bd99ac7SAleksandar Markovic 
11730bd99ac7SAleksandar Markovic uint32_t float_class_s(uint32_t arg, float_status *status)
11740bd99ac7SAleksandar Markovic {
11750bd99ac7SAleksandar Markovic     if (float32_is_signaling_nan(arg, status)) {
11760bd99ac7SAleksandar Markovic         return FLOAT_CLASS_SIGNALING_NAN;
11770bd99ac7SAleksandar Markovic     } else if (float32_is_quiet_nan(arg, status)) {
11780bd99ac7SAleksandar Markovic         return FLOAT_CLASS_QUIET_NAN;
11790bd99ac7SAleksandar Markovic     } else if (float32_is_neg(arg)) {
11800bd99ac7SAleksandar Markovic         if (float32_is_infinity(arg)) {
11810bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_INFINITY;
11820bd99ac7SAleksandar Markovic         } else if (float32_is_zero(arg)) {
11830bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_ZERO;
11840bd99ac7SAleksandar Markovic         } else if (float32_is_zero_or_denormal(arg)) {
11850bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
11860bd99ac7SAleksandar Markovic         } else {
11870bd99ac7SAleksandar Markovic             return FLOAT_CLASS_NEGATIVE_NORMAL;
11880bd99ac7SAleksandar Markovic         }
11890bd99ac7SAleksandar Markovic     } else {
11900bd99ac7SAleksandar Markovic         if (float32_is_infinity(arg)) {
11910bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_INFINITY;
11920bd99ac7SAleksandar Markovic         } else if (float32_is_zero(arg)) {
11930bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_ZERO;
11940bd99ac7SAleksandar Markovic         } else if (float32_is_zero_or_denormal(arg)) {
11950bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_SUBNORMAL;
11960bd99ac7SAleksandar Markovic         } else {
11970bd99ac7SAleksandar Markovic             return FLOAT_CLASS_POSITIVE_NORMAL;
11980bd99ac7SAleksandar Markovic         }
11990bd99ac7SAleksandar Markovic     }
12000bd99ac7SAleksandar Markovic }
12010bd99ac7SAleksandar Markovic 
12020bd99ac7SAleksandar Markovic uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
12030bd99ac7SAleksandar Markovic {
12040bd99ac7SAleksandar Markovic     return float_class_s(arg, &env->active_fpu.fp_status);
12050bd99ac7SAleksandar Markovic }
12060bd99ac7SAleksandar Markovic 
12077b77f048SAleksandar Markovic /* binary operations */
12087b77f048SAleksandar Markovic 
12091ace099fSAleksandar Markovic uint64_t helper_float_add_d(CPUMIPSState *env,
12101ace099fSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
12111ace099fSAleksandar Markovic {
12121ace099fSAleksandar Markovic     uint64_t dt2;
12131ace099fSAleksandar Markovic 
12141ace099fSAleksandar Markovic     dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
12151ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12161ace099fSAleksandar Markovic     return dt2;
12171ace099fSAleksandar Markovic }
12181ace099fSAleksandar Markovic 
12191ace099fSAleksandar Markovic uint32_t helper_float_add_s(CPUMIPSState *env,
12201ace099fSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
12211ace099fSAleksandar Markovic {
12221ace099fSAleksandar Markovic     uint32_t wt2;
12231ace099fSAleksandar Markovic 
12241ace099fSAleksandar Markovic     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
12251ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12261ace099fSAleksandar Markovic     return wt2;
12271ace099fSAleksandar Markovic }
12281ace099fSAleksandar Markovic 
12291ace099fSAleksandar Markovic uint64_t helper_float_add_ps(CPUMIPSState *env,
12301ace099fSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
12311ace099fSAleksandar Markovic {
12321ace099fSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
12331ace099fSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
12341ace099fSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
12351ace099fSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
12361ace099fSAleksandar Markovic     uint32_t wtl2;
12371ace099fSAleksandar Markovic     uint32_t wth2;
12381ace099fSAleksandar Markovic 
12391ace099fSAleksandar Markovic     wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
12401ace099fSAleksandar Markovic     wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
12411ace099fSAleksandar Markovic     update_fcr31(env, GETPC());
12421ace099fSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
12431ace099fSAleksandar Markovic }
12441ace099fSAleksandar Markovic 
124592ebdd7fSAleksandar Markovic uint64_t helper_float_sub_d(CPUMIPSState *env,
124692ebdd7fSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
124792ebdd7fSAleksandar Markovic {
124892ebdd7fSAleksandar Markovic     uint64_t dt2;
124992ebdd7fSAleksandar Markovic 
125092ebdd7fSAleksandar Markovic     dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
125192ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
125292ebdd7fSAleksandar Markovic     return dt2;
125392ebdd7fSAleksandar Markovic }
125492ebdd7fSAleksandar Markovic 
125592ebdd7fSAleksandar Markovic uint32_t helper_float_sub_s(CPUMIPSState *env,
125692ebdd7fSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
125792ebdd7fSAleksandar Markovic {
125892ebdd7fSAleksandar Markovic     uint32_t wt2;
125992ebdd7fSAleksandar Markovic 
126092ebdd7fSAleksandar Markovic     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
126192ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
126292ebdd7fSAleksandar Markovic     return wt2;
126392ebdd7fSAleksandar Markovic }
126492ebdd7fSAleksandar Markovic 
126592ebdd7fSAleksandar Markovic uint64_t helper_float_sub_ps(CPUMIPSState *env,
126692ebdd7fSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
126792ebdd7fSAleksandar Markovic {
126892ebdd7fSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
126992ebdd7fSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
127092ebdd7fSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
127192ebdd7fSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
127292ebdd7fSAleksandar Markovic     uint32_t wtl2;
127392ebdd7fSAleksandar Markovic     uint32_t wth2;
127492ebdd7fSAleksandar Markovic 
127592ebdd7fSAleksandar Markovic     wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
127692ebdd7fSAleksandar Markovic     wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
127792ebdd7fSAleksandar Markovic     update_fcr31(env, GETPC());
127892ebdd7fSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
127992ebdd7fSAleksandar Markovic }
128092ebdd7fSAleksandar Markovic 
128111811198SAleksandar Markovic uint64_t helper_float_mul_d(CPUMIPSState *env,
128211811198SAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
128311811198SAleksandar Markovic {
128411811198SAleksandar Markovic     uint64_t dt2;
128511811198SAleksandar Markovic 
128611811198SAleksandar Markovic     dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
128711811198SAleksandar Markovic     update_fcr31(env, GETPC());
128811811198SAleksandar Markovic     return dt2;
128911811198SAleksandar Markovic }
129011811198SAleksandar Markovic 
129111811198SAleksandar Markovic uint32_t helper_float_mul_s(CPUMIPSState *env,
129211811198SAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
129311811198SAleksandar Markovic {
129411811198SAleksandar Markovic     uint32_t wt2;
129511811198SAleksandar Markovic 
129611811198SAleksandar Markovic     wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
129711811198SAleksandar Markovic     update_fcr31(env, GETPC());
129811811198SAleksandar Markovic     return wt2;
129911811198SAleksandar Markovic }
130011811198SAleksandar Markovic 
130111811198SAleksandar Markovic uint64_t helper_float_mul_ps(CPUMIPSState *env,
130211811198SAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
130311811198SAleksandar Markovic {
130411811198SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
130511811198SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
130611811198SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
130711811198SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
130811811198SAleksandar Markovic     uint32_t wtl2;
130911811198SAleksandar Markovic     uint32_t wth2;
131011811198SAleksandar Markovic 
131111811198SAleksandar Markovic     wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
131211811198SAleksandar Markovic     wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
131311811198SAleksandar Markovic     update_fcr31(env, GETPC());
131411811198SAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
131511811198SAleksandar Markovic }
131611811198SAleksandar Markovic 
1317bcca8c4bSAleksandar Markovic uint64_t helper_float_div_d(CPUMIPSState *env,
1318bcca8c4bSAleksandar Markovic                             uint64_t fdt0, uint64_t fdt1)
1319bcca8c4bSAleksandar Markovic {
1320bcca8c4bSAleksandar Markovic     uint64_t dt2;
1321bcca8c4bSAleksandar Markovic 
1322bcca8c4bSAleksandar Markovic     dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
1323bcca8c4bSAleksandar Markovic     update_fcr31(env, GETPC());
1324bcca8c4bSAleksandar Markovic     return dt2;
1325bcca8c4bSAleksandar Markovic }
1326bcca8c4bSAleksandar Markovic 
1327bcca8c4bSAleksandar Markovic uint32_t helper_float_div_s(CPUMIPSState *env,
1328bcca8c4bSAleksandar Markovic                             uint32_t fst0, uint32_t fst1)
1329bcca8c4bSAleksandar Markovic {
1330bcca8c4bSAleksandar Markovic     uint32_t wt2;
1331bcca8c4bSAleksandar Markovic 
1332bcca8c4bSAleksandar Markovic     wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
1333bcca8c4bSAleksandar Markovic     update_fcr31(env, GETPC());
1334bcca8c4bSAleksandar Markovic     return wt2;
1335bcca8c4bSAleksandar Markovic }
1336bcca8c4bSAleksandar Markovic 
1337bcca8c4bSAleksandar Markovic uint64_t helper_float_div_ps(CPUMIPSState *env,
1338bcca8c4bSAleksandar Markovic                              uint64_t fdt0, uint64_t fdt1)
1339bcca8c4bSAleksandar Markovic {
1340bcca8c4bSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1341bcca8c4bSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1342bcca8c4bSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1343bcca8c4bSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
1344bcca8c4bSAleksandar Markovic     uint32_t wtl2;
1345bcca8c4bSAleksandar Markovic     uint32_t wth2;
1346bcca8c4bSAleksandar Markovic 
1347bcca8c4bSAleksandar Markovic     wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
1348bcca8c4bSAleksandar Markovic     wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
1349bcca8c4bSAleksandar Markovic     update_fcr31(env, GETPC());
1350bcca8c4bSAleksandar Markovic     return ((uint64_t)wth2 << 32) | wtl2;
1351bcca8c4bSAleksandar Markovic }
1352bcca8c4bSAleksandar Markovic 
13531ace099fSAleksandar Markovic 
13547b77f048SAleksandar Markovic /* MIPS specific binary operations */
13557b77f048SAleksandar Markovic uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13567b77f048SAleksandar Markovic {
13577b77f048SAleksandar Markovic     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
13587b77f048SAleksandar Markovic     fdt2 = float64_chs(float64_sub(fdt2, float64_one,
13597b77f048SAleksandar Markovic                                    &env->active_fpu.fp_status));
13607b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13617b77f048SAleksandar Markovic     return fdt2;
13627b77f048SAleksandar Markovic }
13637b77f048SAleksandar Markovic 
13647b77f048SAleksandar Markovic uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
13657b77f048SAleksandar Markovic {
13667b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
13677b77f048SAleksandar Markovic     fst2 = float32_chs(float32_sub(fst2, float32_one,
13687b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13697b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13707b77f048SAleksandar Markovic     return fst2;
13717b77f048SAleksandar Markovic }
13727b77f048SAleksandar Markovic 
13737b77f048SAleksandar Markovic uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13747b77f048SAleksandar Markovic {
1375485cd2e4SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
13767b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1377485cd2e4SAleksandar Markovic     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
13787b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
13797b77f048SAleksandar Markovic 
1380485cd2e4SAleksandar Markovic     fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
13817b77f048SAleksandar Markovic     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1382485cd2e4SAleksandar Markovic     fstl2 = float32_chs(float32_sub(fstl2, float32_one,
13837b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13847b77f048SAleksandar Markovic     fsth2 = float32_chs(float32_sub(fsth2, float32_one,
13857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13867b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
1387485cd2e4SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fstl2;
13887b77f048SAleksandar Markovic }
13897b77f048SAleksandar Markovic 
13907b77f048SAleksandar Markovic uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
13917b77f048SAleksandar Markovic {
13927b77f048SAleksandar Markovic     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
13937b77f048SAleksandar Markovic     fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
13947b77f048SAleksandar Markovic     fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
13957b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
13967b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
13977b77f048SAleksandar Markovic     return fdt2;
13987b77f048SAleksandar Markovic }
13997b77f048SAleksandar Markovic 
14007b77f048SAleksandar Markovic uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
14017b77f048SAleksandar Markovic {
14027b77f048SAleksandar Markovic     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
14037b77f048SAleksandar Markovic     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
14047b77f048SAleksandar Markovic     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
14057b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14067b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
14077b77f048SAleksandar Markovic     return fst2;
14087b77f048SAleksandar Markovic }
14097b77f048SAleksandar Markovic 
14107b77f048SAleksandar Markovic uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
14117b77f048SAleksandar Markovic {
1412485cd2e4SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
14137b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1414485cd2e4SAleksandar Markovic     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
14157b77f048SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
14167b77f048SAleksandar Markovic 
1417485cd2e4SAleksandar Markovic     fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
14187b77f048SAleksandar Markovic     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
1419485cd2e4SAleksandar Markovic     fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
14207b77f048SAleksandar Markovic     fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
1421485cd2e4SAleksandar Markovic     fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
14227b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14237b77f048SAleksandar Markovic     fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
14247b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status));
14257b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
1426485cd2e4SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fstl2;
14277b77f048SAleksandar Markovic }
14287b77f048SAleksandar Markovic 
14297b77f048SAleksandar Markovic uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
14307b77f048SAleksandar Markovic {
1431485cd2e4SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
14327b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1433485cd2e4SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
14347b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
1435485cd2e4SAleksandar Markovic     uint32_t fstl2;
14367b77f048SAleksandar Markovic     uint32_t fsth2;
14377b77f048SAleksandar Markovic 
1438485cd2e4SAleksandar Markovic     fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
1439485cd2e4SAleksandar Markovic     fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
14407b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
1441485cd2e4SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fstl2;
14427b77f048SAleksandar Markovic }
14437b77f048SAleksandar Markovic 
14447b77f048SAleksandar Markovic uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
14457b77f048SAleksandar Markovic {
1446485cd2e4SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
14477b77f048SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1448485cd2e4SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
14497b77f048SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
1450485cd2e4SAleksandar Markovic     uint32_t fstl2;
14517b77f048SAleksandar Markovic     uint32_t fsth2;
14527b77f048SAleksandar Markovic 
1453485cd2e4SAleksandar Markovic     fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
1454485cd2e4SAleksandar Markovic     fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
14557b77f048SAleksandar Markovic     update_fcr31(env, GETPC());
1456485cd2e4SAleksandar Markovic     return ((uint64_t)fsth2 << 32) | fstl2;
14577b77f048SAleksandar Markovic }
14587b77f048SAleksandar Markovic 
14597b77f048SAleksandar Markovic #define FLOAT_MINMAX(name, bits, minmaxfunc)                            \
14607b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,             \
14617b77f048SAleksandar Markovic                                          uint ## bits ## _t fs,         \
14627b77f048SAleksandar Markovic                                          uint ## bits ## _t ft)         \
14637b77f048SAleksandar Markovic {                                                                       \
14647b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                           \
14657b77f048SAleksandar Markovic                                                                         \
14667b77f048SAleksandar Markovic     fdret = float ## bits ## _ ## minmaxfunc(fs, ft,                    \
14677b77f048SAleksandar Markovic                                            &env->active_fpu.fp_status); \
14687b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                         \
14697b77f048SAleksandar Markovic     return fdret;                                                       \
14707b77f048SAleksandar Markovic }
14717b77f048SAleksandar Markovic 
14727b77f048SAleksandar Markovic FLOAT_MINMAX(max_s, 32, maxnum)
14737b77f048SAleksandar Markovic FLOAT_MINMAX(max_d, 64, maxnum)
14747b77f048SAleksandar Markovic FLOAT_MINMAX(maxa_s, 32, maxnummag)
14757b77f048SAleksandar Markovic FLOAT_MINMAX(maxa_d, 64, maxnummag)
14767b77f048SAleksandar Markovic 
14777b77f048SAleksandar Markovic FLOAT_MINMAX(min_s, 32, minnum)
14787b77f048SAleksandar Markovic FLOAT_MINMAX(min_d, 64, minnum)
14797b77f048SAleksandar Markovic FLOAT_MINMAX(mina_s, 32, minnummag)
14807b77f048SAleksandar Markovic FLOAT_MINMAX(mina_d, 64, minnummag)
14817b77f048SAleksandar Markovic #undef FLOAT_MINMAX
14827b77f048SAleksandar Markovic 
14837b77f048SAleksandar Markovic /* ternary operations */
14847b77f048SAleksandar Markovic 
148516734cc1SAleksandar Markovic uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
148616734cc1SAleksandar Markovic                              uint64_t fst1, uint64_t fst2)
148716734cc1SAleksandar Markovic {
148816734cc1SAleksandar Markovic     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
148916734cc1SAleksandar Markovic     fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
149016734cc1SAleksandar Markovic 
149116734cc1SAleksandar Markovic     update_fcr31(env, GETPC());
149216734cc1SAleksandar Markovic     return fst0;
149316734cc1SAleksandar Markovic }
149416734cc1SAleksandar Markovic 
149516734cc1SAleksandar Markovic uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
149616734cc1SAleksandar Markovic                              uint32_t fst1, uint32_t fst2)
149716734cc1SAleksandar Markovic {
149816734cc1SAleksandar Markovic     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
149916734cc1SAleksandar Markovic     fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
150016734cc1SAleksandar Markovic 
150116734cc1SAleksandar Markovic     update_fcr31(env, GETPC());
150216734cc1SAleksandar Markovic     return fst0;
150316734cc1SAleksandar Markovic }
150416734cc1SAleksandar Markovic 
150516734cc1SAleksandar Markovic uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
150616734cc1SAleksandar Markovic                               uint64_t fdt1, uint64_t fdt2)
150716734cc1SAleksandar Markovic {
150816734cc1SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
150916734cc1SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
151016734cc1SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
151116734cc1SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
151216734cc1SAleksandar Markovic     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
151316734cc1SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
151416734cc1SAleksandar Markovic 
151516734cc1SAleksandar Markovic     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
151616734cc1SAleksandar Markovic     fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
151716734cc1SAleksandar Markovic     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
151816734cc1SAleksandar Markovic     fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
151916734cc1SAleksandar Markovic 
152016734cc1SAleksandar Markovic     update_fcr31(env, GETPC());
152116734cc1SAleksandar Markovic     return ((uint64_t)fsth0 << 32) | fstl0;
152216734cc1SAleksandar Markovic }
152316734cc1SAleksandar Markovic 
1524faec7524SAleksandar Markovic uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
1525faec7524SAleksandar Markovic                              uint64_t fst1, uint64_t fst2)
1526faec7524SAleksandar Markovic {
1527faec7524SAleksandar Markovic     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
1528faec7524SAleksandar Markovic     fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
1529faec7524SAleksandar Markovic 
1530faec7524SAleksandar Markovic     update_fcr31(env, GETPC());
1531faec7524SAleksandar Markovic     return fst0;
1532faec7524SAleksandar Markovic }
1533faec7524SAleksandar Markovic 
1534faec7524SAleksandar Markovic uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
1535faec7524SAleksandar Markovic                              uint32_t fst1, uint32_t fst2)
1536faec7524SAleksandar Markovic {
1537faec7524SAleksandar Markovic     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
1538faec7524SAleksandar Markovic     fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
1539faec7524SAleksandar Markovic 
1540faec7524SAleksandar Markovic     update_fcr31(env, GETPC());
1541faec7524SAleksandar Markovic     return fst0;
1542faec7524SAleksandar Markovic }
1543faec7524SAleksandar Markovic 
1544faec7524SAleksandar Markovic uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
1545faec7524SAleksandar Markovic                               uint64_t fdt1, uint64_t fdt2)
1546faec7524SAleksandar Markovic {
1547faec7524SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
1548faec7524SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
1549faec7524SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
1550faec7524SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
1551faec7524SAleksandar Markovic     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
1552faec7524SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
1553faec7524SAleksandar Markovic 
1554faec7524SAleksandar Markovic     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
1555faec7524SAleksandar Markovic     fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
1556faec7524SAleksandar Markovic     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
1557faec7524SAleksandar Markovic     fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
1558faec7524SAleksandar Markovic 
1559faec7524SAleksandar Markovic     update_fcr31(env, GETPC());
1560faec7524SAleksandar Markovic     return ((uint64_t)fsth0 << 32) | fstl0;
1561faec7524SAleksandar Markovic }
1562faec7524SAleksandar Markovic 
15630278586dSAleksandar Markovic uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
15640278586dSAleksandar Markovic                              uint64_t fst1, uint64_t fst2)
15650278586dSAleksandar Markovic {
15660278586dSAleksandar Markovic     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
15670278586dSAleksandar Markovic     fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
15680278586dSAleksandar Markovic     fst0 = float64_chs(fst0);
15690278586dSAleksandar Markovic 
15700278586dSAleksandar Markovic     update_fcr31(env, GETPC());
15710278586dSAleksandar Markovic     return fst0;
15720278586dSAleksandar Markovic }
15730278586dSAleksandar Markovic 
15740278586dSAleksandar Markovic uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
15750278586dSAleksandar Markovic                              uint32_t fst1, uint32_t fst2)
15760278586dSAleksandar Markovic {
15770278586dSAleksandar Markovic     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
15780278586dSAleksandar Markovic     fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
15790278586dSAleksandar Markovic     fst0 = float32_chs(fst0);
15800278586dSAleksandar Markovic 
15810278586dSAleksandar Markovic     update_fcr31(env, GETPC());
15820278586dSAleksandar Markovic     return fst0;
15830278586dSAleksandar Markovic }
15840278586dSAleksandar Markovic 
15850278586dSAleksandar Markovic uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
15860278586dSAleksandar Markovic                               uint64_t fdt1, uint64_t fdt2)
15870278586dSAleksandar Markovic {
15880278586dSAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
15890278586dSAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
15900278586dSAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
15910278586dSAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
15920278586dSAleksandar Markovic     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
15930278586dSAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
15940278586dSAleksandar Markovic 
15950278586dSAleksandar Markovic     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
15960278586dSAleksandar Markovic     fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
15970278586dSAleksandar Markovic     fstl0 = float32_chs(fstl0);
15980278586dSAleksandar Markovic     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
15990278586dSAleksandar Markovic     fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
16000278586dSAleksandar Markovic     fsth0 = float32_chs(fsth0);
16010278586dSAleksandar Markovic 
16020278586dSAleksandar Markovic     update_fcr31(env, GETPC());
16030278586dSAleksandar Markovic     return ((uint64_t)fsth0 << 32) | fstl0;
16040278586dSAleksandar Markovic }
16050278586dSAleksandar Markovic 
16065c591e22SAleksandar Markovic uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
16075c591e22SAleksandar Markovic                              uint64_t fst1, uint64_t fst2)
16085c591e22SAleksandar Markovic {
16095c591e22SAleksandar Markovic     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
16105c591e22SAleksandar Markovic     fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
16115c591e22SAleksandar Markovic     fst0 = float64_chs(fst0);
16125c591e22SAleksandar Markovic 
16135c591e22SAleksandar Markovic     update_fcr31(env, GETPC());
16145c591e22SAleksandar Markovic     return fst0;
16155c591e22SAleksandar Markovic }
16165c591e22SAleksandar Markovic 
16175c591e22SAleksandar Markovic uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
16185c591e22SAleksandar Markovic                              uint32_t fst1, uint32_t fst2)
16195c591e22SAleksandar Markovic {
16205c591e22SAleksandar Markovic     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
16215c591e22SAleksandar Markovic     fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
16225c591e22SAleksandar Markovic     fst0 = float32_chs(fst0);
16235c591e22SAleksandar Markovic 
16245c591e22SAleksandar Markovic     update_fcr31(env, GETPC());
16255c591e22SAleksandar Markovic     return fst0;
16265c591e22SAleksandar Markovic }
16275c591e22SAleksandar Markovic 
16285c591e22SAleksandar Markovic uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
16295c591e22SAleksandar Markovic                               uint64_t fdt1, uint64_t fdt2)
16305c591e22SAleksandar Markovic {
16315c591e22SAleksandar Markovic     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
16325c591e22SAleksandar Markovic     uint32_t fsth0 = fdt0 >> 32;
16335c591e22SAleksandar Markovic     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
16345c591e22SAleksandar Markovic     uint32_t fsth1 = fdt1 >> 32;
16355c591e22SAleksandar Markovic     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
16365c591e22SAleksandar Markovic     uint32_t fsth2 = fdt2 >> 32;
16375c591e22SAleksandar Markovic 
16385c591e22SAleksandar Markovic     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
16395c591e22SAleksandar Markovic     fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
16405c591e22SAleksandar Markovic     fstl0 = float32_chs(fstl0);
16415c591e22SAleksandar Markovic     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
16425c591e22SAleksandar Markovic     fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
16435c591e22SAleksandar Markovic     fsth0 = float32_chs(fsth0);
16445c591e22SAleksandar Markovic 
16455c591e22SAleksandar Markovic     update_fcr31(env, GETPC());
16465c591e22SAleksandar Markovic     return ((uint64_t)fsth0 << 32) | fstl0;
16475c591e22SAleksandar Markovic }
16485c591e22SAleksandar Markovic 
164916734cc1SAleksandar Markovic 
16507b77f048SAleksandar Markovic #define FLOAT_FMADDSUB(name, bits, muladd_arg)                          \
16517b77f048SAleksandar Markovic uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env,             \
16527b77f048SAleksandar Markovic                                          uint ## bits ## _t fs,         \
16537b77f048SAleksandar Markovic                                          uint ## bits ## _t ft,         \
16547b77f048SAleksandar Markovic                                          uint ## bits ## _t fd)         \
16557b77f048SAleksandar Markovic {                                                                       \
16567b77f048SAleksandar Markovic     uint ## bits ## _t fdret;                                           \
16577b77f048SAleksandar Markovic                                                                         \
16587b77f048SAleksandar Markovic     fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg,            \
16597b77f048SAleksandar Markovic                                      &env->active_fpu.fp_status);       \
16607b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                         \
16617b77f048SAleksandar Markovic     return fdret;                                                       \
16627b77f048SAleksandar Markovic }
16637b77f048SAleksandar Markovic 
16647b77f048SAleksandar Markovic FLOAT_FMADDSUB(maddf_s, 32, 0)
16657b77f048SAleksandar Markovic FLOAT_FMADDSUB(maddf_d, 64, 0)
16667b77f048SAleksandar Markovic FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product)
16677b77f048SAleksandar Markovic FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product)
16687b77f048SAleksandar Markovic #undef FLOAT_FMADDSUB
16697b77f048SAleksandar Markovic 
16707b77f048SAleksandar Markovic /* compare operations */
16717b77f048SAleksandar Markovic #define FOP_COND_D(op, cond)                                   \
16727b77f048SAleksandar Markovic void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
16737b77f048SAleksandar Markovic                          uint64_t fdt1, int cc)                \
16747b77f048SAleksandar Markovic {                                                              \
16757b77f048SAleksandar Markovic     int c;                                                     \
16767b77f048SAleksandar Markovic     c = cond;                                                  \
16777b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
16787b77f048SAleksandar Markovic     if (c)                                                     \
16797b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
16807b77f048SAleksandar Markovic     else                                                       \
16817b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
16827b77f048SAleksandar Markovic }                                                              \
16837b77f048SAleksandar Markovic void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
16847b77f048SAleksandar Markovic                             uint64_t fdt1, int cc)             \
16857b77f048SAleksandar Markovic {                                                              \
16867b77f048SAleksandar Markovic     int c;                                                     \
16877b77f048SAleksandar Markovic     fdt0 = float64_abs(fdt0);                                  \
16887b77f048SAleksandar Markovic     fdt1 = float64_abs(fdt1);                                  \
16897b77f048SAleksandar Markovic     c = cond;                                                  \
16907b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
16917b77f048SAleksandar Markovic     if (c)                                                     \
16927b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
16937b77f048SAleksandar Markovic     else                                                       \
16947b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
16957b77f048SAleksandar Markovic }
16967b77f048SAleksandar Markovic 
16977b77f048SAleksandar Markovic /*
16987b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
16997b77f048SAleksandar Markovic  * but float64_unordered_quiet() is still called.
17007b77f048SAleksandar Markovic  */
17017b77f048SAleksandar Markovic FOP_COND_D(f,    (float64_unordered_quiet(fdt1, fdt0,
17027b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17037b77f048SAleksandar Markovic FOP_COND_D(un,   float64_unordered_quiet(fdt1, fdt0,
17047b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17057b77f048SAleksandar Markovic FOP_COND_D(eq,   float64_eq_quiet(fdt0, fdt1,
17067b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17077b77f048SAleksandar Markovic FOP_COND_D(ueq,  float64_unordered_quiet(fdt1, fdt0,
17087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17097b77f048SAleksandar Markovic                  || float64_eq_quiet(fdt0, fdt1,
17107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17117b77f048SAleksandar Markovic FOP_COND_D(olt,  float64_lt_quiet(fdt0, fdt1,
17127b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17137b77f048SAleksandar Markovic FOP_COND_D(ult,  float64_unordered_quiet(fdt1, fdt0,
17147b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17157b77f048SAleksandar Markovic                  || float64_lt_quiet(fdt0, fdt1,
17167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17177b77f048SAleksandar Markovic FOP_COND_D(ole,  float64_le_quiet(fdt0, fdt1,
17187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17197b77f048SAleksandar Markovic FOP_COND_D(ule,  float64_unordered_quiet(fdt1, fdt0,
17207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17217b77f048SAleksandar Markovic                  || float64_le_quiet(fdt0, fdt1,
17227b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17237b77f048SAleksandar Markovic /*
17247b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
17257b77f048SAleksandar Markovic  * but float64_unordered() is still called.
17267b77f048SAleksandar Markovic  */
17277b77f048SAleksandar Markovic FOP_COND_D(sf,   (float64_unordered(fdt1, fdt0,
17287b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17297b77f048SAleksandar Markovic FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
17307b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17317b77f048SAleksandar Markovic FOP_COND_D(seq,  float64_eq(fdt0, fdt1,
17327b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17337b77f048SAleksandar Markovic FOP_COND_D(ngl,  float64_unordered(fdt1, fdt0,
17347b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17357b77f048SAleksandar Markovic                  || float64_eq(fdt0, fdt1,
17367b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17377b77f048SAleksandar Markovic FOP_COND_D(lt,   float64_lt(fdt0, fdt1,
17387b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17397b77f048SAleksandar Markovic FOP_COND_D(nge,  float64_unordered(fdt1, fdt0,
17407b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17417b77f048SAleksandar Markovic                  || float64_lt(fdt0, fdt1,
17427b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17437b77f048SAleksandar Markovic FOP_COND_D(le,   float64_le(fdt0, fdt1,
17447b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17457b77f048SAleksandar Markovic FOP_COND_D(ngt,  float64_unordered(fdt1, fdt0,
17467b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17477b77f048SAleksandar Markovic                  || float64_le(fdt0, fdt1,
17487b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17497b77f048SAleksandar Markovic 
17507b77f048SAleksandar Markovic #define FOP_COND_S(op, cond)                                   \
17517b77f048SAleksandar Markovic void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
17527b77f048SAleksandar Markovic                          uint32_t fst1, int cc)                \
17537b77f048SAleksandar Markovic {                                                              \
17547b77f048SAleksandar Markovic     int c;                                                     \
17557b77f048SAleksandar Markovic     c = cond;                                                  \
17567b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
17577b77f048SAleksandar Markovic     if (c)                                                     \
17587b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
17597b77f048SAleksandar Markovic     else                                                       \
17607b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
17617b77f048SAleksandar Markovic }                                                              \
17627b77f048SAleksandar Markovic void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
17637b77f048SAleksandar Markovic                             uint32_t fst1, int cc)             \
17647b77f048SAleksandar Markovic {                                                              \
17657b77f048SAleksandar Markovic     int c;                                                     \
17667b77f048SAleksandar Markovic     fst0 = float32_abs(fst0);                                  \
17677b77f048SAleksandar Markovic     fst1 = float32_abs(fst1);                                  \
17687b77f048SAleksandar Markovic     c = cond;                                                  \
17697b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                \
17707b77f048SAleksandar Markovic     if (c)                                                     \
17717b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                      \
17727b77f048SAleksandar Markovic     else                                                       \
17737b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                    \
17747b77f048SAleksandar Markovic }
17757b77f048SAleksandar Markovic 
17767b77f048SAleksandar Markovic /*
17777b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
17787b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
17797b77f048SAleksandar Markovic  */
17807b77f048SAleksandar Markovic FOP_COND_S(f,    (float32_unordered_quiet(fst1, fst0,
17817b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
17827b77f048SAleksandar Markovic FOP_COND_S(un,   float32_unordered_quiet(fst1, fst0,
17837b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17847b77f048SAleksandar Markovic FOP_COND_S(eq,   float32_eq_quiet(fst0, fst1,
17857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17867b77f048SAleksandar Markovic FOP_COND_S(ueq,  float32_unordered_quiet(fst1, fst0,
17877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17887b77f048SAleksandar Markovic                  || float32_eq_quiet(fst0, fst1,
17897b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17907b77f048SAleksandar Markovic FOP_COND_S(olt,  float32_lt_quiet(fst0, fst1,
17917b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17927b77f048SAleksandar Markovic FOP_COND_S(ult,  float32_unordered_quiet(fst1, fst0,
17937b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
17947b77f048SAleksandar Markovic                  || float32_lt_quiet(fst0, fst1,
17957b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17967b77f048SAleksandar Markovic FOP_COND_S(ole,  float32_le_quiet(fst0, fst1,
17977b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
17987b77f048SAleksandar Markovic FOP_COND_S(ule,  float32_unordered_quiet(fst1, fst0,
17997b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18007b77f048SAleksandar Markovic                  || float32_le_quiet(fst0, fst1,
18017b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18027b77f048SAleksandar Markovic /*
18037b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
18047b77f048SAleksandar Markovic  * but float32_unordered() is still called.
18057b77f048SAleksandar Markovic  */
18067b77f048SAleksandar Markovic FOP_COND_S(sf,   (float32_unordered(fst1, fst0,
18077b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
18087b77f048SAleksandar Markovic FOP_COND_S(ngle, float32_unordered(fst1, fst0,
18097b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18107b77f048SAleksandar Markovic FOP_COND_S(seq,  float32_eq(fst0, fst1,
18117b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18127b77f048SAleksandar Markovic FOP_COND_S(ngl,  float32_unordered(fst1, fst0,
18137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18147b77f048SAleksandar Markovic                  || float32_eq(fst0, fst1,
18157b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18167b77f048SAleksandar Markovic FOP_COND_S(lt,   float32_lt(fst0, fst1,
18177b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18187b77f048SAleksandar Markovic FOP_COND_S(nge,  float32_unordered(fst1, fst0,
18197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18207b77f048SAleksandar Markovic                  || float32_lt(fst0, fst1,
18217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18227b77f048SAleksandar Markovic FOP_COND_S(le,   float32_le(fst0, fst1,
18237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18247b77f048SAleksandar Markovic FOP_COND_S(ngt,  float32_unordered(fst1, fst0,
18257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18267b77f048SAleksandar Markovic                  || float32_le(fst0, fst1,
18277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18287b77f048SAleksandar Markovic 
18297b77f048SAleksandar Markovic #define FOP_COND_PS(op, condl, condh)                           \
18307b77f048SAleksandar Markovic void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
18317b77f048SAleksandar Markovic                           uint64_t fdt1, int cc)                \
18327b77f048SAleksandar Markovic {                                                               \
18337b77f048SAleksandar Markovic     uint32_t fst0, fsth0, fst1, fsth1;                          \
18347b77f048SAleksandar Markovic     int ch, cl;                                                 \
18357b77f048SAleksandar Markovic     fst0 = fdt0 & 0XFFFFFFFF;                                   \
18367b77f048SAleksandar Markovic     fsth0 = fdt0 >> 32;                                         \
18377b77f048SAleksandar Markovic     fst1 = fdt1 & 0XFFFFFFFF;                                   \
18387b77f048SAleksandar Markovic     fsth1 = fdt1 >> 32;                                         \
18397b77f048SAleksandar Markovic     cl = condl;                                                 \
18407b77f048SAleksandar Markovic     ch = condh;                                                 \
18417b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                 \
18427b77f048SAleksandar Markovic     if (cl)                                                     \
18437b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                       \
18447b77f048SAleksandar Markovic     else                                                        \
18457b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                     \
18467b77f048SAleksandar Markovic     if (ch)                                                     \
18477b77f048SAleksandar Markovic         SET_FP_COND(cc + 1, env->active_fpu);                   \
18487b77f048SAleksandar Markovic     else                                                        \
18497b77f048SAleksandar Markovic         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
18507b77f048SAleksandar Markovic }                                                               \
18517b77f048SAleksandar Markovic void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
18527b77f048SAleksandar Markovic                              uint64_t fdt1, int cc)             \
18537b77f048SAleksandar Markovic {                                                               \
18547b77f048SAleksandar Markovic     uint32_t fst0, fsth0, fst1, fsth1;                          \
18557b77f048SAleksandar Markovic     int ch, cl;                                                 \
18567b77f048SAleksandar Markovic     fst0 = float32_abs(fdt0 & 0XFFFFFFFF);                      \
18577b77f048SAleksandar Markovic     fsth0 = float32_abs(fdt0 >> 32);                            \
18587b77f048SAleksandar Markovic     fst1 = float32_abs(fdt1 & 0XFFFFFFFF);                      \
18597b77f048SAleksandar Markovic     fsth1 = float32_abs(fdt1 >> 32);                            \
18607b77f048SAleksandar Markovic     cl = condl;                                                 \
18617b77f048SAleksandar Markovic     ch = condh;                                                 \
18627b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                 \
18637b77f048SAleksandar Markovic     if (cl)                                                     \
18647b77f048SAleksandar Markovic         SET_FP_COND(cc, env->active_fpu);                       \
18657b77f048SAleksandar Markovic     else                                                        \
18667b77f048SAleksandar Markovic         CLEAR_FP_COND(cc, env->active_fpu);                     \
18677b77f048SAleksandar Markovic     if (ch)                                                     \
18687b77f048SAleksandar Markovic         SET_FP_COND(cc + 1, env->active_fpu);                   \
18697b77f048SAleksandar Markovic     else                                                        \
18707b77f048SAleksandar Markovic         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
18717b77f048SAleksandar Markovic }
18727b77f048SAleksandar Markovic 
18737b77f048SAleksandar Markovic /*
18747b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
18757b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
18767b77f048SAleksandar Markovic  */
18777b77f048SAleksandar Markovic FOP_COND_PS(f,    (float32_unordered_quiet(fst1, fst0,
18787b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0),
18797b77f048SAleksandar Markovic                   (float32_unordered_quiet(fsth1, fsth0,
18807b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
18817b77f048SAleksandar Markovic FOP_COND_PS(un,   float32_unordered_quiet(fst1, fst0,
18827b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18837b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
18847b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18857b77f048SAleksandar Markovic FOP_COND_PS(eq,   float32_eq_quiet(fst0, fst1,
18867b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18877b77f048SAleksandar Markovic                   float32_eq_quiet(fsth0, fsth1,
18887b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18897b77f048SAleksandar Markovic FOP_COND_PS(ueq,  float32_unordered_quiet(fst1, fst0,
18907b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18917b77f048SAleksandar Markovic                   || float32_eq_quiet(fst0, fst1,
18927b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18937b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
18947b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
18957b77f048SAleksandar Markovic                   || float32_eq_quiet(fsth0, fsth1,
18967b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
18977b77f048SAleksandar Markovic FOP_COND_PS(olt,  float32_lt_quiet(fst0, fst1,
18987b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
18997b77f048SAleksandar Markovic                   float32_lt_quiet(fsth0, fsth1,
19007b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19017b77f048SAleksandar Markovic FOP_COND_PS(ult,  float32_unordered_quiet(fst1, fst0,
19027b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19037b77f048SAleksandar Markovic                   || float32_lt_quiet(fst0, fst1,
19047b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19057b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
19067b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19077b77f048SAleksandar Markovic                   || float32_lt_quiet(fsth0, fsth1,
19087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19097b77f048SAleksandar Markovic FOP_COND_PS(ole,  float32_le_quiet(fst0, fst1,
19107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19117b77f048SAleksandar Markovic                   float32_le_quiet(fsth0, fsth1,
19127b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19137b77f048SAleksandar Markovic FOP_COND_PS(ule,  float32_unordered_quiet(fst1, fst0,
19147b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19157b77f048SAleksandar Markovic                   || float32_le_quiet(fst0, fst1,
19167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19177b77f048SAleksandar Markovic                   float32_unordered_quiet(fsth1, fsth0,
19187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19197b77f048SAleksandar Markovic                   || float32_le_quiet(fsth0, fsth1,
19207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19217b77f048SAleksandar Markovic /*
19227b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
19237b77f048SAleksandar Markovic  * but float32_unordered() is still called.
19247b77f048SAleksandar Markovic  */
19257b77f048SAleksandar Markovic FOP_COND_PS(sf,   (float32_unordered(fst1, fst0,
19267b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0),
19277b77f048SAleksandar Markovic                   (float32_unordered(fsth1, fsth0,
19287b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
19297b77f048SAleksandar Markovic FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
19307b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19317b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
19327b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19337b77f048SAleksandar Markovic FOP_COND_PS(seq,  float32_eq(fst0, fst1,
19347b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19357b77f048SAleksandar Markovic                   float32_eq(fsth0, fsth1,
19367b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19377b77f048SAleksandar Markovic FOP_COND_PS(ngl,  float32_unordered(fst1, fst0,
19387b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19397b77f048SAleksandar Markovic                   || float32_eq(fst0, fst1,
19407b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19417b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
19427b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19437b77f048SAleksandar Markovic                   || float32_eq(fsth0, fsth1,
19447b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19457b77f048SAleksandar Markovic FOP_COND_PS(lt,   float32_lt(fst0, fst1,
19467b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19477b77f048SAleksandar Markovic                   float32_lt(fsth0, fsth1,
19487b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19497b77f048SAleksandar Markovic FOP_COND_PS(nge,  float32_unordered(fst1, fst0,
19507b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19517b77f048SAleksandar Markovic                   || float32_lt(fst0, fst1,
19527b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19537b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
19547b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19557b77f048SAleksandar Markovic                   || float32_lt(fsth0, fsth1,
19567b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19577b77f048SAleksandar Markovic FOP_COND_PS(le,   float32_le(fst0, fst1,
19587b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19597b77f048SAleksandar Markovic                   float32_le(fsth0, fsth1,
19607b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19617b77f048SAleksandar Markovic FOP_COND_PS(ngt,  float32_unordered(fst1, fst0,
19627b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19637b77f048SAleksandar Markovic                   || float32_le(fst0, fst1,
19647b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status),
19657b77f048SAleksandar Markovic                   float32_unordered(fsth1, fsth0,
19667b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19677b77f048SAleksandar Markovic                   || float32_le(fsth0, fsth1,
19687b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status))
19697b77f048SAleksandar Markovic 
19707b77f048SAleksandar Markovic /* R6 compare operations */
19717b77f048SAleksandar Markovic #define FOP_CONDN_D(op, cond)                                       \
19727b77f048SAleksandar Markovic uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,   \
19737b77f048SAleksandar Markovic                                 uint64_t fdt1)                      \
19747b77f048SAleksandar Markovic {                                                                   \
19757b77f048SAleksandar Markovic     uint64_t c;                                                     \
19767b77f048SAleksandar Markovic     c = cond;                                                       \
19777b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                     \
19787b77f048SAleksandar Markovic     if (c) {                                                        \
19797b77f048SAleksandar Markovic         return -1;                                                  \
19807b77f048SAleksandar Markovic     } else {                                                        \
19817b77f048SAleksandar Markovic         return 0;                                                   \
19827b77f048SAleksandar Markovic     }                                                               \
19837b77f048SAleksandar Markovic }
19847b77f048SAleksandar Markovic 
19857b77f048SAleksandar Markovic /*
19867b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
19877b77f048SAleksandar Markovic  * but float64_unordered_quiet() is still called.
19887b77f048SAleksandar Markovic  */
19897b77f048SAleksandar Markovic FOP_CONDN_D(af,  (float64_unordered_quiet(fdt1, fdt0,
19907b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
19917b77f048SAleksandar Markovic FOP_CONDN_D(un,  (float64_unordered_quiet(fdt1, fdt0,
19927b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19937b77f048SAleksandar Markovic FOP_CONDN_D(eq,  (float64_eq_quiet(fdt0, fdt1,
19947b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19957b77f048SAleksandar Markovic FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
19967b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
19977b77f048SAleksandar Markovic                  || float64_eq_quiet(fdt0, fdt1,
19987b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
19997b77f048SAleksandar Markovic FOP_CONDN_D(lt,  (float64_lt_quiet(fdt0, fdt1,
20007b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20017b77f048SAleksandar Markovic FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
20027b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20037b77f048SAleksandar Markovic                  || float64_lt_quiet(fdt0, fdt1,
20047b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20057b77f048SAleksandar Markovic FOP_CONDN_D(le,  (float64_le_quiet(fdt0, fdt1,
20067b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20077b77f048SAleksandar Markovic FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
20087b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20097b77f048SAleksandar Markovic                  || float64_le_quiet(fdt0, fdt1,
20107b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20117b77f048SAleksandar Markovic /*
20127b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
20137b77f048SAleksandar Markovic  * but float64_unordered() is still called.\
20147b77f048SAleksandar Markovic  */
20157b77f048SAleksandar Markovic FOP_CONDN_D(saf,  (float64_unordered(fdt1, fdt0,
20167b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
20177b77f048SAleksandar Markovic FOP_CONDN_D(sun,  (float64_unordered(fdt1, fdt0,
20187b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20197b77f048SAleksandar Markovic FOP_CONDN_D(seq,  (float64_eq(fdt0, fdt1,
20207b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20217b77f048SAleksandar Markovic FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
20227b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20237b77f048SAleksandar Markovic                    || float64_eq(fdt0, fdt1,
20247b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20257b77f048SAleksandar Markovic FOP_CONDN_D(slt,  (float64_lt(fdt0, fdt1,
20267b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20277b77f048SAleksandar Markovic FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
20287b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20297b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
20307b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20317b77f048SAleksandar Markovic FOP_CONDN_D(sle,  (float64_le(fdt0, fdt1,
20327b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20337b77f048SAleksandar Markovic FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
20347b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20357b77f048SAleksandar Markovic                    || float64_le(fdt0, fdt1,
20367b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20377b77f048SAleksandar Markovic FOP_CONDN_D(or,   (float64_le_quiet(fdt1, fdt0,
20387b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20397b77f048SAleksandar Markovic                    || float64_le_quiet(fdt0, fdt1,
20407b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20417b77f048SAleksandar Markovic FOP_CONDN_D(une,  (float64_unordered_quiet(fdt1, fdt0,
20427b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20437b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt1, fdt0,
20447b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20457b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt0, fdt1,
20467b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20477b77f048SAleksandar Markovic FOP_CONDN_D(ne,   (float64_lt_quiet(fdt1, fdt0,
20487b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20497b77f048SAleksandar Markovic                    || float64_lt_quiet(fdt0, fdt1,
20507b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20517b77f048SAleksandar Markovic FOP_CONDN_D(sor,  (float64_le(fdt1, fdt0,
20527b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20537b77f048SAleksandar Markovic                    || float64_le(fdt0, fdt1,
20547b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20557b77f048SAleksandar Markovic FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
20567b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20577b77f048SAleksandar Markovic                    || float64_lt(fdt1, fdt0,
20587b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20597b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
20607b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20617b77f048SAleksandar Markovic FOP_CONDN_D(sne,  (float64_lt(fdt1, fdt0,
20627b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20637b77f048SAleksandar Markovic                    || float64_lt(fdt0, fdt1,
20647b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20657b77f048SAleksandar Markovic 
20667b77f048SAleksandar Markovic #define FOP_CONDN_S(op, cond)                                       \
20677b77f048SAleksandar Markovic uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,   \
20687b77f048SAleksandar Markovic                                 uint32_t fst1)                      \
20697b77f048SAleksandar Markovic {                                                                   \
20707b77f048SAleksandar Markovic     uint64_t c;                                                     \
20717b77f048SAleksandar Markovic     c = cond;                                                       \
20727b77f048SAleksandar Markovic     update_fcr31(env, GETPC());                                     \
20737b77f048SAleksandar Markovic     if (c) {                                                        \
20747b77f048SAleksandar Markovic         return -1;                                                  \
20757b77f048SAleksandar Markovic     } else {                                                        \
20767b77f048SAleksandar Markovic         return 0;                                                   \
20777b77f048SAleksandar Markovic     }                                                               \
20787b77f048SAleksandar Markovic }
20797b77f048SAleksandar Markovic 
20807b77f048SAleksandar Markovic /*
20817b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
20827b77f048SAleksandar Markovic  * but float32_unordered_quiet() is still called.
20837b77f048SAleksandar Markovic  */
20847b77f048SAleksandar Markovic FOP_CONDN_S(af,   (float32_unordered_quiet(fst1, fst0,
20857b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
20867b77f048SAleksandar Markovic FOP_CONDN_S(un,   (float32_unordered_quiet(fst1, fst0,
20877b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20887b77f048SAleksandar Markovic FOP_CONDN_S(eq,   (float32_eq_quiet(fst0, fst1,
20897b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20907b77f048SAleksandar Markovic FOP_CONDN_S(ueq,  (float32_unordered_quiet(fst1, fst0,
20917b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20927b77f048SAleksandar Markovic                    || float32_eq_quiet(fst0, fst1,
20937b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20947b77f048SAleksandar Markovic FOP_CONDN_S(lt,   (float32_lt_quiet(fst0, fst1,
20957b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
20967b77f048SAleksandar Markovic FOP_CONDN_S(ult,  (float32_unordered_quiet(fst1, fst0,
20977b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
20987b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
20997b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21007b77f048SAleksandar Markovic FOP_CONDN_S(le,   (float32_le_quiet(fst0, fst1,
21017b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21027b77f048SAleksandar Markovic FOP_CONDN_S(ule,  (float32_unordered_quiet(fst1, fst0,
21037b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21047b77f048SAleksandar Markovic                    || float32_le_quiet(fst0, fst1,
21057b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21067b77f048SAleksandar Markovic /*
21077b77f048SAleksandar Markovic  * NOTE: the comma operator will make "cond" to eval to false,
21087b77f048SAleksandar Markovic  * but float32_unordered() is still called.
21097b77f048SAleksandar Markovic  */
21107b77f048SAleksandar Markovic FOP_CONDN_S(saf,  (float32_unordered(fst1, fst0,
21117b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status), 0))
21127b77f048SAleksandar Markovic FOP_CONDN_S(sun,  (float32_unordered(fst1, fst0,
21137b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21147b77f048SAleksandar Markovic FOP_CONDN_S(seq,  (float32_eq(fst0, fst1,
21157b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21167b77f048SAleksandar Markovic FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
21177b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21187b77f048SAleksandar Markovic                    || float32_eq(fst0, fst1,
21197b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21207b77f048SAleksandar Markovic FOP_CONDN_S(slt,  (float32_lt(fst0, fst1,
21217b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21227b77f048SAleksandar Markovic FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
21237b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21247b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
21257b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21267b77f048SAleksandar Markovic FOP_CONDN_S(sle,  (float32_le(fst0, fst1,
21277b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21287b77f048SAleksandar Markovic FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
21297b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21307b77f048SAleksandar Markovic                    || float32_le(fst0, fst1,
21317b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21327b77f048SAleksandar Markovic FOP_CONDN_S(or,   (float32_le_quiet(fst1, fst0,
21337b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21347b77f048SAleksandar Markovic                    || float32_le_quiet(fst0, fst1,
21357b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21367b77f048SAleksandar Markovic FOP_CONDN_S(une,  (float32_unordered_quiet(fst1, fst0,
21377b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21387b77f048SAleksandar Markovic                    || float32_lt_quiet(fst1, fst0,
21397b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21407b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
21417b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21427b77f048SAleksandar Markovic FOP_CONDN_S(ne,   (float32_lt_quiet(fst1, fst0,
21437b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21447b77f048SAleksandar Markovic                    || float32_lt_quiet(fst0, fst1,
21457b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21467b77f048SAleksandar Markovic FOP_CONDN_S(sor,  (float32_le(fst1, fst0,
21477b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21487b77f048SAleksandar Markovic                    || float32_le(fst0, fst1,
21497b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21507b77f048SAleksandar Markovic FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
21517b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21527b77f048SAleksandar Markovic                    || float32_lt(fst1, fst0,
21537b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21547b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
21557b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
21567b77f048SAleksandar Markovic FOP_CONDN_S(sne,  (float32_lt(fst1, fst0,
21577b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)
21587b77f048SAleksandar Markovic                    || float32_lt(fst0, fst1,
21597b77f048SAleksandar Markovic                                        &env->active_fpu.fp_status)))
2160