qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

fpu_helper.c (78493B)


      1 /*
      2  *  Helpers for emulation of FPU-related MIPS instructions.
      3  *
      4  *  Copyright (C) 2004-2005  Jocelyn Mayer
      5  *  Copyright (C) 2020  Wave Computing, Inc.
      6  *  Copyright (C) 2020  Aleksandar Markovic <amarkovic@wavecomp.com>
      7  *
      8  * This library is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU Lesser General Public
     10  * License as published by the Free Software Foundation; either
     11  * version 2.1 of the License, or (at your option) any later version.
     12  *
     13  * This library is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     16  * Lesser General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU Lesser General Public
     19  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     20  *
     21  */
     22 
     23 #include "qemu/osdep.h"
     24 #include "cpu.h"
     25 #include "internal.h"
     26 #include "exec/helper-proto.h"
     27 #include "exec/exec-all.h"
     28 #include "exec/cpu_ldst.h"
     29 #include "fpu/softfloat.h"
     30 #include "fpu_helper.h"
     31 
     32 
     33 /* Complex FPU operations which may need stack space. */
     34 
     35 #define FLOAT_TWO32 make_float32(1 << 30)
     36 #define FLOAT_TWO64 make_float64(1ULL << 62)
     37 
     38 #define FP_TO_INT32_OVERFLOW 0x7fffffff
     39 #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL
     40 
     41 target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg)
     42 {
     43     target_ulong arg1 = 0;
     44 
     45     switch (reg) {
     46     case 0:
     47         arg1 = (int32_t)env->active_fpu.fcr0;
     48         break;
     49     case 1:
     50         /* UFR Support - Read Status FR */
     51         if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) {
     52             if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
     53                 arg1 = (int32_t)
     54                        ((env->CP0_Status & (1  << CP0St_FR)) >> CP0St_FR);
     55             } else {
     56                 do_raise_exception(env, EXCP_RI, GETPC());
     57             }
     58         }
     59         break;
     60     case 5:
     61         /* FRE Support - read Config5.FRE bit */
     62         if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) {
     63             if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
     64                 arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1;
     65             } else {
     66                 helper_raise_exception(env, EXCP_RI);
     67             }
     68         }
     69         break;
     70     case 25:
     71         arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) |
     72                ((env->active_fpu.fcr31 >> 23) & 0x1);
     73         break;
     74     case 26:
     75         arg1 = env->active_fpu.fcr31 & 0x0003f07c;
     76         break;
     77     case 28:
     78         arg1 = (env->active_fpu.fcr31 & 0x00000f83) |
     79                ((env->active_fpu.fcr31 >> 22) & 0x4);
     80         break;
     81     default:
     82         arg1 = (int32_t)env->active_fpu.fcr31;
     83         break;
     84     }
     85 
     86     return arg1;
     87 }
     88 
     89 void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt)
     90 {
     91     switch (fs) {
     92     case 1:
     93         /* UFR Alias - Reset Status FR */
     94         if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
     95             return;
     96         }
     97         if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
     98             env->CP0_Status &= ~(1 << CP0St_FR);
     99             compute_hflags(env);
    100         } else {
    101             do_raise_exception(env, EXCP_RI, GETPC());
    102         }
    103         break;
    104     case 4:
    105         /* UNFR Alias - Set Status FR */
    106         if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) {
    107             return;
    108         }
    109         if (env->CP0_Config5 & (1 << CP0C5_UFR)) {
    110             env->CP0_Status |= (1 << CP0St_FR);
    111             compute_hflags(env);
    112         } else {
    113             do_raise_exception(env, EXCP_RI, GETPC());
    114         }
    115         break;
    116     case 5:
    117         /* FRE Support - clear Config5.FRE bit */
    118         if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
    119             return;
    120         }
    121         if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
    122             env->CP0_Config5 &= ~(1 << CP0C5_FRE);
    123             compute_hflags(env);
    124         } else {
    125             helper_raise_exception(env, EXCP_RI);
    126         }
    127         break;
    128     case 6:
    129         /* FRE Support - set Config5.FRE bit */
    130         if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) {
    131             return;
    132         }
    133         if (env->CP0_Config5 & (1 << CP0C5_UFE)) {
    134             env->CP0_Config5 |= (1 << CP0C5_FRE);
    135             compute_hflags(env);
    136         } else {
    137             helper_raise_exception(env, EXCP_RI);
    138         }
    139         break;
    140     case 25:
    141         if ((env->insn_flags & ISA_MIPS_R6) || (arg1 & 0xffffff00)) {
    142             return;
    143         }
    144         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) |
    145                                 ((arg1 & 0xfe) << 24) |
    146                                 ((arg1 & 0x1) << 23);
    147         break;
    148     case 26:
    149         if (arg1 & 0x007c0000) {
    150             return;
    151         }
    152         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) |
    153                                 (arg1 & 0x0003f07c);
    154         break;
    155     case 28:
    156         if (arg1 & 0x007c0000) {
    157             return;
    158         }
    159         env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) |
    160                                 (arg1 & 0x00000f83) |
    161                                 ((arg1 & 0x4) << 22);
    162         break;
    163     case 31:
    164         env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) |
    165                (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask));
    166         break;
    167     default:
    168         if (env->insn_flags & ISA_MIPS_R6) {
    169             do_raise_exception(env, EXCP_RI, GETPC());
    170         }
    171         return;
    172     }
    173     restore_fp_status(env);
    174     set_float_exception_flags(0, &env->active_fpu.fp_status);
    175     if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) &
    176         GET_FP_CAUSE(env->active_fpu.fcr31)) {
    177         do_raise_exception(env, EXCP_FPE, GETPC());
    178     }
    179 }
    180 
    181 static inline int ieee_to_mips_xcpt(int ieee_xcpt)
    182 {
    183     int mips_xcpt = 0;
    184 
    185     if (ieee_xcpt & float_flag_invalid) {
    186         mips_xcpt |= FP_INVALID;
    187     }
    188     if (ieee_xcpt & float_flag_overflow) {
    189         mips_xcpt |= FP_OVERFLOW;
    190     }
    191     if (ieee_xcpt & float_flag_underflow) {
    192         mips_xcpt |= FP_UNDERFLOW;
    193     }
    194     if (ieee_xcpt & float_flag_divbyzero) {
    195         mips_xcpt |= FP_DIV0;
    196     }
    197     if (ieee_xcpt & float_flag_inexact) {
    198         mips_xcpt |= FP_INEXACT;
    199     }
    200 
    201     return mips_xcpt;
    202 }
    203 
    204 static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
    205 {
    206     int ieee_exception_flags = get_float_exception_flags(
    207                                    &env->active_fpu.fp_status);
    208     int mips_exception_flags = 0;
    209 
    210     if (ieee_exception_flags) {
    211         mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
    212     }
    213 
    214     SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
    215 
    216     if (mips_exception_flags)  {
    217         set_float_exception_flags(0, &env->active_fpu.fp_status);
    218 
    219         if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
    220             do_raise_exception(env, EXCP_FPE, pc);
    221         } else {
    222             UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
    223         }
    224     }
    225 }
    226 
    227 /*
    228  * Float support.
    229  * Single precition routines have a "s" suffix, double precision a
    230  * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps",
    231  * paired single lower "pl", paired single upper "pu".
    232  */
    233 
    234 /* unary operations, modifying fp status  */
    235 uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0)
    236 {
    237     fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
    238     update_fcr31(env, GETPC());
    239     return fdt0;
    240 }
    241 
    242 uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0)
    243 {
    244     fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status);
    245     update_fcr31(env, GETPC());
    246     return fst0;
    247 }
    248 
    249 uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0)
    250 {
    251     uint64_t fdt2;
    252 
    253     fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status);
    254     update_fcr31(env, GETPC());
    255     return fdt2;
    256 }
    257 
    258 uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0)
    259 {
    260     uint64_t fdt2;
    261 
    262     fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status);
    263     update_fcr31(env, GETPC());
    264     return fdt2;
    265 }
    266 
    267 uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0)
    268 {
    269     uint64_t fdt2;
    270 
    271     fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status);
    272     update_fcr31(env, GETPC());
    273     return fdt2;
    274 }
    275 
    276 uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0)
    277 {
    278     uint64_t dt2;
    279 
    280     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    281     if (get_float_exception_flags(&env->active_fpu.fp_status)
    282         & (float_flag_invalid | float_flag_overflow)) {
    283         dt2 = FP_TO_INT64_OVERFLOW;
    284     }
    285     update_fcr31(env, GETPC());
    286     return dt2;
    287 }
    288 
    289 uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0)
    290 {
    291     uint64_t dt2;
    292 
    293     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    294     if (get_float_exception_flags(&env->active_fpu.fp_status)
    295         & (float_flag_invalid | float_flag_overflow)) {
    296         dt2 = FP_TO_INT64_OVERFLOW;
    297     }
    298     update_fcr31(env, GETPC());
    299     return dt2;
    300 }
    301 
    302 uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0)
    303 {
    304     uint32_t fst2;
    305     uint32_t fsth2;
    306 
    307     fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
    308     fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status);
    309     update_fcr31(env, GETPC());
    310     return ((uint64_t)fsth2 << 32) | fst2;
    311 }
    312 
    313 uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0)
    314 {
    315     uint32_t wt2;
    316     uint32_t wth2;
    317     int excp, excph;
    318 
    319     wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
    320     excp = get_float_exception_flags(&env->active_fpu.fp_status);
    321     if (excp & (float_flag_overflow | float_flag_invalid)) {
    322         wt2 = FP_TO_INT32_OVERFLOW;
    323     }
    324 
    325     set_float_exception_flags(0, &env->active_fpu.fp_status);
    326     wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status);
    327     excph = get_float_exception_flags(&env->active_fpu.fp_status);
    328     if (excph & (float_flag_overflow | float_flag_invalid)) {
    329         wth2 = FP_TO_INT32_OVERFLOW;
    330     }
    331 
    332     set_float_exception_flags(excp | excph, &env->active_fpu.fp_status);
    333     update_fcr31(env, GETPC());
    334 
    335     return ((uint64_t)wth2 << 32) | wt2;
    336 }
    337 
    338 uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0)
    339 {
    340     uint32_t fst2;
    341 
    342     fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status);
    343     update_fcr31(env, GETPC());
    344     return fst2;
    345 }
    346 
    347 uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0)
    348 {
    349     uint32_t fst2;
    350 
    351     fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status);
    352     update_fcr31(env, GETPC());
    353     return fst2;
    354 }
    355 
    356 uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0)
    357 {
    358     uint32_t fst2;
    359 
    360     fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status);
    361     update_fcr31(env, GETPC());
    362     return fst2;
    363 }
    364 
    365 uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0)
    366 {
    367     uint32_t wt2;
    368 
    369     wt2 = wt0;
    370     update_fcr31(env, GETPC());
    371     return wt2;
    372 }
    373 
    374 uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0)
    375 {
    376     uint32_t wt2;
    377 
    378     wt2 = wth0;
    379     update_fcr31(env, GETPC());
    380     return wt2;
    381 }
    382 
    383 uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0)
    384 {
    385     uint32_t wt2;
    386 
    387     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    388     if (get_float_exception_flags(&env->active_fpu.fp_status)
    389         & (float_flag_invalid | float_flag_overflow)) {
    390         wt2 = FP_TO_INT32_OVERFLOW;
    391     }
    392     update_fcr31(env, GETPC());
    393     return wt2;
    394 }
    395 
    396 uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0)
    397 {
    398     uint32_t wt2;
    399 
    400     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    401     if (get_float_exception_flags(&env->active_fpu.fp_status)
    402         & (float_flag_invalid | float_flag_overflow)) {
    403         wt2 = FP_TO_INT32_OVERFLOW;
    404     }
    405     update_fcr31(env, GETPC());
    406     return wt2;
    407 }
    408 
    409 uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0)
    410 {
    411     uint64_t dt2;
    412 
    413     set_float_rounding_mode(float_round_nearest_even,
    414                             &env->active_fpu.fp_status);
    415     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    416     restore_rounding_mode(env);
    417     if (get_float_exception_flags(&env->active_fpu.fp_status)
    418         & (float_flag_invalid | float_flag_overflow)) {
    419         dt2 = FP_TO_INT64_OVERFLOW;
    420     }
    421     update_fcr31(env, GETPC());
    422     return dt2;
    423 }
    424 
    425 uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0)
    426 {
    427     uint64_t dt2;
    428 
    429     set_float_rounding_mode(float_round_nearest_even,
    430                             &env->active_fpu.fp_status);
    431     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    432     restore_rounding_mode(env);
    433     if (get_float_exception_flags(&env->active_fpu.fp_status)
    434         & (float_flag_invalid | float_flag_overflow)) {
    435         dt2 = FP_TO_INT64_OVERFLOW;
    436     }
    437     update_fcr31(env, GETPC());
    438     return dt2;
    439 }
    440 
    441 uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0)
    442 {
    443     uint32_t wt2;
    444 
    445     set_float_rounding_mode(float_round_nearest_even,
    446                             &env->active_fpu.fp_status);
    447     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    448     restore_rounding_mode(env);
    449     if (get_float_exception_flags(&env->active_fpu.fp_status)
    450         & (float_flag_invalid | float_flag_overflow)) {
    451         wt2 = FP_TO_INT32_OVERFLOW;
    452     }
    453     update_fcr31(env, GETPC());
    454     return wt2;
    455 }
    456 
    457 uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0)
    458 {
    459     uint32_t wt2;
    460 
    461     set_float_rounding_mode(float_round_nearest_even,
    462                             &env->active_fpu.fp_status);
    463     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    464     restore_rounding_mode(env);
    465     if (get_float_exception_flags(&env->active_fpu.fp_status)
    466         & (float_flag_invalid | float_flag_overflow)) {
    467         wt2 = FP_TO_INT32_OVERFLOW;
    468     }
    469     update_fcr31(env, GETPC());
    470     return wt2;
    471 }
    472 
    473 uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0)
    474 {
    475     uint64_t dt2;
    476 
    477     dt2 = float64_to_int64_round_to_zero(fdt0,
    478                                          &env->active_fpu.fp_status);
    479     if (get_float_exception_flags(&env->active_fpu.fp_status)
    480         & (float_flag_invalid | float_flag_overflow)) {
    481         dt2 = FP_TO_INT64_OVERFLOW;
    482     }
    483     update_fcr31(env, GETPC());
    484     return dt2;
    485 }
    486 
    487 uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0)
    488 {
    489     uint64_t dt2;
    490 
    491     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
    492     if (get_float_exception_flags(&env->active_fpu.fp_status)
    493         & (float_flag_invalid | float_flag_overflow)) {
    494         dt2 = FP_TO_INT64_OVERFLOW;
    495     }
    496     update_fcr31(env, GETPC());
    497     return dt2;
    498 }
    499 
    500 uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0)
    501 {
    502     uint32_t wt2;
    503 
    504     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
    505     if (get_float_exception_flags(&env->active_fpu.fp_status)
    506         & (float_flag_invalid | float_flag_overflow)) {
    507         wt2 = FP_TO_INT32_OVERFLOW;
    508     }
    509     update_fcr31(env, GETPC());
    510     return wt2;
    511 }
    512 
    513 uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0)
    514 {
    515     uint32_t wt2;
    516 
    517     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
    518     if (get_float_exception_flags(&env->active_fpu.fp_status)
    519         & (float_flag_invalid | float_flag_overflow)) {
    520         wt2 = FP_TO_INT32_OVERFLOW;
    521     }
    522     update_fcr31(env, GETPC());
    523     return wt2;
    524 }
    525 
    526 uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0)
    527 {
    528     uint64_t dt2;
    529 
    530     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    531     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    532     restore_rounding_mode(env);
    533     if (get_float_exception_flags(&env->active_fpu.fp_status)
    534         & (float_flag_invalid | float_flag_overflow)) {
    535         dt2 = FP_TO_INT64_OVERFLOW;
    536     }
    537     update_fcr31(env, GETPC());
    538     return dt2;
    539 }
    540 
    541 uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0)
    542 {
    543     uint64_t dt2;
    544 
    545     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    546     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    547     restore_rounding_mode(env);
    548     if (get_float_exception_flags(&env->active_fpu.fp_status)
    549         & (float_flag_invalid | float_flag_overflow)) {
    550         dt2 = FP_TO_INT64_OVERFLOW;
    551     }
    552     update_fcr31(env, GETPC());
    553     return dt2;
    554 }
    555 
    556 uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0)
    557 {
    558     uint32_t wt2;
    559 
    560     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    561     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    562     restore_rounding_mode(env);
    563     if (get_float_exception_flags(&env->active_fpu.fp_status)
    564         & (float_flag_invalid | float_flag_overflow)) {
    565         wt2 = FP_TO_INT32_OVERFLOW;
    566     }
    567     update_fcr31(env, GETPC());
    568     return wt2;
    569 }
    570 
    571 uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0)
    572 {
    573     uint32_t wt2;
    574 
    575     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    576     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    577     restore_rounding_mode(env);
    578     if (get_float_exception_flags(&env->active_fpu.fp_status)
    579         & (float_flag_invalid | float_flag_overflow)) {
    580         wt2 = FP_TO_INT32_OVERFLOW;
    581     }
    582     update_fcr31(env, GETPC());
    583     return wt2;
    584 }
    585 
    586 uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0)
    587 {
    588     uint64_t dt2;
    589 
    590     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    591     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    592     restore_rounding_mode(env);
    593     if (get_float_exception_flags(&env->active_fpu.fp_status)
    594         & (float_flag_invalid | float_flag_overflow)) {
    595         dt2 = FP_TO_INT64_OVERFLOW;
    596     }
    597     update_fcr31(env, GETPC());
    598     return dt2;
    599 }
    600 
    601 uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0)
    602 {
    603     uint64_t dt2;
    604 
    605     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    606     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    607     restore_rounding_mode(env);
    608     if (get_float_exception_flags(&env->active_fpu.fp_status)
    609         & (float_flag_invalid | float_flag_overflow)) {
    610         dt2 = FP_TO_INT64_OVERFLOW;
    611     }
    612     update_fcr31(env, GETPC());
    613     return dt2;
    614 }
    615 
    616 uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0)
    617 {
    618     uint32_t wt2;
    619 
    620     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    621     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    622     restore_rounding_mode(env);
    623     if (get_float_exception_flags(&env->active_fpu.fp_status)
    624         & (float_flag_invalid | float_flag_overflow)) {
    625         wt2 = FP_TO_INT32_OVERFLOW;
    626     }
    627     update_fcr31(env, GETPC());
    628     return wt2;
    629 }
    630 
    631 uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0)
    632 {
    633     uint32_t wt2;
    634 
    635     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    636     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    637     restore_rounding_mode(env);
    638     if (get_float_exception_flags(&env->active_fpu.fp_status)
    639         & (float_flag_invalid | float_flag_overflow)) {
    640         wt2 = FP_TO_INT32_OVERFLOW;
    641     }
    642     update_fcr31(env, GETPC());
    643     return wt2;
    644 }
    645 
    646 uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
    647 {
    648     uint64_t dt2;
    649 
    650     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    651     if (get_float_exception_flags(&env->active_fpu.fp_status)
    652             & float_flag_invalid) {
    653         if (float64_is_any_nan(fdt0)) {
    654             dt2 = 0;
    655         }
    656     }
    657     update_fcr31(env, GETPC());
    658     return dt2;
    659 }
    660 
    661 uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0)
    662 {
    663     uint64_t dt2;
    664 
    665     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    666     if (get_float_exception_flags(&env->active_fpu.fp_status)
    667             & float_flag_invalid) {
    668         if (float32_is_any_nan(fst0)) {
    669             dt2 = 0;
    670         }
    671     }
    672     update_fcr31(env, GETPC());
    673     return dt2;
    674 }
    675 
    676 uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
    677 {
    678     uint32_t wt2;
    679 
    680     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    681     if (get_float_exception_flags(&env->active_fpu.fp_status)
    682             & float_flag_invalid) {
    683         if (float64_is_any_nan(fdt0)) {
    684             wt2 = 0;
    685         }
    686     }
    687     update_fcr31(env, GETPC());
    688     return wt2;
    689 }
    690 
    691 uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0)
    692 {
    693     uint32_t wt2;
    694 
    695     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    696     if (get_float_exception_flags(&env->active_fpu.fp_status)
    697             & float_flag_invalid) {
    698         if (float32_is_any_nan(fst0)) {
    699             wt2 = 0;
    700         }
    701     }
    702     update_fcr31(env, GETPC());
    703     return wt2;
    704 }
    705 
    706 uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
    707 {
    708     uint64_t dt2;
    709 
    710     set_float_rounding_mode(float_round_nearest_even,
    711             &env->active_fpu.fp_status);
    712     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    713     restore_rounding_mode(env);
    714     if (get_float_exception_flags(&env->active_fpu.fp_status)
    715             & float_flag_invalid) {
    716         if (float64_is_any_nan(fdt0)) {
    717             dt2 = 0;
    718         }
    719     }
    720     update_fcr31(env, GETPC());
    721     return dt2;
    722 }
    723 
    724 uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0)
    725 {
    726     uint64_t dt2;
    727 
    728     set_float_rounding_mode(float_round_nearest_even,
    729             &env->active_fpu.fp_status);
    730     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    731     restore_rounding_mode(env);
    732     if (get_float_exception_flags(&env->active_fpu.fp_status)
    733             & float_flag_invalid) {
    734         if (float32_is_any_nan(fst0)) {
    735             dt2 = 0;
    736         }
    737     }
    738     update_fcr31(env, GETPC());
    739     return dt2;
    740 }
    741 
    742 uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
    743 {
    744     uint32_t wt2;
    745 
    746     set_float_rounding_mode(float_round_nearest_even,
    747             &env->active_fpu.fp_status);
    748     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    749     restore_rounding_mode(env);
    750     if (get_float_exception_flags(&env->active_fpu.fp_status)
    751             & float_flag_invalid) {
    752         if (float64_is_any_nan(fdt0)) {
    753             wt2 = 0;
    754         }
    755     }
    756     update_fcr31(env, GETPC());
    757     return wt2;
    758 }
    759 
    760 uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0)
    761 {
    762     uint32_t wt2;
    763 
    764     set_float_rounding_mode(float_round_nearest_even,
    765             &env->active_fpu.fp_status);
    766     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    767     restore_rounding_mode(env);
    768     if (get_float_exception_flags(&env->active_fpu.fp_status)
    769             & float_flag_invalid) {
    770         if (float32_is_any_nan(fst0)) {
    771             wt2 = 0;
    772         }
    773     }
    774     update_fcr31(env, GETPC());
    775     return wt2;
    776 }
    777 
    778 uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
    779 {
    780     uint64_t dt2;
    781 
    782     dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status);
    783     if (get_float_exception_flags(&env->active_fpu.fp_status)
    784             & float_flag_invalid) {
    785         if (float64_is_any_nan(fdt0)) {
    786             dt2 = 0;
    787         }
    788     }
    789     update_fcr31(env, GETPC());
    790     return dt2;
    791 }
    792 
    793 uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0)
    794 {
    795     uint64_t dt2;
    796 
    797     dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status);
    798     if (get_float_exception_flags(&env->active_fpu.fp_status)
    799             & float_flag_invalid) {
    800         if (float32_is_any_nan(fst0)) {
    801             dt2 = 0;
    802         }
    803     }
    804     update_fcr31(env, GETPC());
    805     return dt2;
    806 }
    807 
    808 uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
    809 {
    810     uint32_t wt2;
    811 
    812     wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status);
    813     if (get_float_exception_flags(&env->active_fpu.fp_status)
    814             & float_flag_invalid) {
    815         if (float64_is_any_nan(fdt0)) {
    816             wt2 = 0;
    817         }
    818     }
    819     update_fcr31(env, GETPC());
    820     return wt2;
    821 }
    822 
    823 uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0)
    824 {
    825     uint32_t wt2;
    826 
    827     wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status);
    828     if (get_float_exception_flags(&env->active_fpu.fp_status)
    829             & float_flag_invalid) {
    830         if (float32_is_any_nan(fst0)) {
    831             wt2 = 0;
    832         }
    833     }
    834     update_fcr31(env, GETPC());
    835     return wt2;
    836 }
    837 
    838 uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
    839 {
    840     uint64_t dt2;
    841 
    842     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    843     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    844     restore_rounding_mode(env);
    845     if (get_float_exception_flags(&env->active_fpu.fp_status)
    846             & float_flag_invalid) {
    847         if (float64_is_any_nan(fdt0)) {
    848             dt2 = 0;
    849         }
    850     }
    851     update_fcr31(env, GETPC());
    852     return dt2;
    853 }
    854 
    855 uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0)
    856 {
    857     uint64_t dt2;
    858 
    859     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    860     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    861     restore_rounding_mode(env);
    862     if (get_float_exception_flags(&env->active_fpu.fp_status)
    863             & float_flag_invalid) {
    864         if (float32_is_any_nan(fst0)) {
    865             dt2 = 0;
    866         }
    867     }
    868     update_fcr31(env, GETPC());
    869     return dt2;
    870 }
    871 
    872 uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
    873 {
    874     uint32_t wt2;
    875 
    876     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    877     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    878     restore_rounding_mode(env);
    879     if (get_float_exception_flags(&env->active_fpu.fp_status)
    880             & float_flag_invalid) {
    881         if (float64_is_any_nan(fdt0)) {
    882             wt2 = 0;
    883         }
    884     }
    885     update_fcr31(env, GETPC());
    886     return wt2;
    887 }
    888 
    889 uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0)
    890 {
    891     uint32_t wt2;
    892 
    893     set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status);
    894     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    895     restore_rounding_mode(env);
    896     if (get_float_exception_flags(&env->active_fpu.fp_status)
    897             & float_flag_invalid) {
    898         if (float32_is_any_nan(fst0)) {
    899             wt2 = 0;
    900         }
    901     }
    902     update_fcr31(env, GETPC());
    903     return wt2;
    904 }
    905 
    906 uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0)
    907 {
    908     uint64_t dt2;
    909 
    910     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    911     dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status);
    912     restore_rounding_mode(env);
    913     if (get_float_exception_flags(&env->active_fpu.fp_status)
    914             & float_flag_invalid) {
    915         if (float64_is_any_nan(fdt0)) {
    916             dt2 = 0;
    917         }
    918     }
    919     update_fcr31(env, GETPC());
    920     return dt2;
    921 }
    922 
    923 uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0)
    924 {
    925     uint64_t dt2;
    926 
    927     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    928     dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status);
    929     restore_rounding_mode(env);
    930     if (get_float_exception_flags(&env->active_fpu.fp_status)
    931             & float_flag_invalid) {
    932         if (float32_is_any_nan(fst0)) {
    933             dt2 = 0;
    934         }
    935     }
    936     update_fcr31(env, GETPC());
    937     return dt2;
    938 }
    939 
    940 uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0)
    941 {
    942     uint32_t wt2;
    943 
    944     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    945     wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status);
    946     restore_rounding_mode(env);
    947     if (get_float_exception_flags(&env->active_fpu.fp_status)
    948             & float_flag_invalid) {
    949         if (float64_is_any_nan(fdt0)) {
    950             wt2 = 0;
    951         }
    952     }
    953     update_fcr31(env, GETPC());
    954     return wt2;
    955 }
    956 
    957 uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0)
    958 {
    959     uint32_t wt2;
    960 
    961     set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status);
    962     wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status);
    963     restore_rounding_mode(env);
    964     if (get_float_exception_flags(&env->active_fpu.fp_status)
    965             & float_flag_invalid) {
    966         if (float32_is_any_nan(fst0)) {
    967             wt2 = 0;
    968         }
    969     }
    970     update_fcr31(env, GETPC());
    971     return wt2;
    972 }
    973 
    974 /* unary operations, not modifying fp status  */
    975 
    976 uint64_t helper_float_abs_d(uint64_t fdt0)
    977 {
    978    return float64_abs(fdt0);
    979 }
    980 
    981 uint32_t helper_float_abs_s(uint32_t fst0)
    982 {
    983     return float32_abs(fst0);
    984 }
    985 
    986 uint64_t helper_float_abs_ps(uint64_t fdt0)
    987 {
    988     uint32_t wt0;
    989     uint32_t wth0;
    990 
    991     wt0 = float32_abs(fdt0 & 0XFFFFFFFF);
    992     wth0 = float32_abs(fdt0 >> 32);
    993     return ((uint64_t)wth0 << 32) | wt0;
    994 }
    995 
    996 uint64_t helper_float_chs_d(uint64_t fdt0)
    997 {
    998    return float64_chs(fdt0);
    999 }
   1000 
   1001 uint32_t helper_float_chs_s(uint32_t fst0)
   1002 {
   1003     return float32_chs(fst0);
   1004 }
   1005 
   1006 uint64_t helper_float_chs_ps(uint64_t fdt0)
   1007 {
   1008     uint32_t wt0;
   1009     uint32_t wth0;
   1010 
   1011     wt0 = float32_chs(fdt0 & 0XFFFFFFFF);
   1012     wth0 = float32_chs(fdt0 >> 32);
   1013     return ((uint64_t)wth0 << 32) | wt0;
   1014 }
   1015 
   1016 /* MIPS specific unary operations */
   1017 uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0)
   1018 {
   1019     uint64_t fdt2;
   1020 
   1021     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
   1022     update_fcr31(env, GETPC());
   1023     return fdt2;
   1024 }
   1025 
   1026 uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0)
   1027 {
   1028     uint32_t fst2;
   1029 
   1030     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
   1031     update_fcr31(env, GETPC());
   1032     return fst2;
   1033 }
   1034 
   1035 uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0)
   1036 {
   1037     uint64_t fdt2;
   1038 
   1039     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
   1040     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
   1041     update_fcr31(env, GETPC());
   1042     return fdt2;
   1043 }
   1044 
   1045 uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0)
   1046 {
   1047     uint32_t fst2;
   1048 
   1049     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
   1050     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
   1051     update_fcr31(env, GETPC());
   1052     return fst2;
   1053 }
   1054 
   1055 uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0)
   1056 {
   1057     uint64_t fdt2;
   1058 
   1059     fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status);
   1060     update_fcr31(env, GETPC());
   1061     return fdt2;
   1062 }
   1063 
   1064 uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0)
   1065 {
   1066     uint32_t fst2;
   1067 
   1068     fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status);
   1069     update_fcr31(env, GETPC());
   1070     return fst2;
   1071 }
   1072 
   1073 uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0)
   1074 {
   1075     uint32_t fstl2;
   1076     uint32_t fsth2;
   1077 
   1078     fstl2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF,
   1079                         &env->active_fpu.fp_status);
   1080     fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status);
   1081     update_fcr31(env, GETPC());
   1082     return ((uint64_t)fsth2 << 32) | fstl2;
   1083 }
   1084 
   1085 uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0)
   1086 {
   1087     uint64_t fdt2;
   1088 
   1089     fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status);
   1090     fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status);
   1091     update_fcr31(env, GETPC());
   1092     return fdt2;
   1093 }
   1094 
   1095 uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0)
   1096 {
   1097     uint32_t fst2;
   1098 
   1099     fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status);
   1100     fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status);
   1101     update_fcr31(env, GETPC());
   1102     return fst2;
   1103 }
   1104 
   1105 uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0)
   1106 {
   1107     uint32_t fstl2;
   1108     uint32_t fsth2;
   1109 
   1110     fstl2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status);
   1111     fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status);
   1112     fstl2 = float32_div(float32_one, fstl2, &env->active_fpu.fp_status);
   1113     fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status);
   1114     update_fcr31(env, GETPC());
   1115     return ((uint64_t)fsth2 << 32) | fstl2;
   1116 }
   1117 
   1118 uint64_t helper_float_rint_d(CPUMIPSState *env, uint64_t fs)
   1119 {
   1120     uint64_t fdret;
   1121 
   1122     fdret = float64_round_to_int(fs, &env->active_fpu.fp_status);
   1123     update_fcr31(env, GETPC());
   1124     return fdret;
   1125 }
   1126 
   1127 uint32_t helper_float_rint_s(CPUMIPSState *env, uint32_t fs)
   1128 {
   1129     uint32_t fdret;
   1130 
   1131     fdret = float32_round_to_int(fs, &env->active_fpu.fp_status);
   1132     update_fcr31(env, GETPC());
   1133     return fdret;
   1134 }
   1135 
   1136 #define FLOAT_CLASS_SIGNALING_NAN      0x001
   1137 #define FLOAT_CLASS_QUIET_NAN          0x002
   1138 #define FLOAT_CLASS_NEGATIVE_INFINITY  0x004
   1139 #define FLOAT_CLASS_NEGATIVE_NORMAL    0x008
   1140 #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010
   1141 #define FLOAT_CLASS_NEGATIVE_ZERO      0x020
   1142 #define FLOAT_CLASS_POSITIVE_INFINITY  0x040
   1143 #define FLOAT_CLASS_POSITIVE_NORMAL    0x080
   1144 #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100
   1145 #define FLOAT_CLASS_POSITIVE_ZERO      0x200
   1146 
   1147 uint64_t float_class_d(uint64_t arg, float_status *status)
   1148 {
   1149     if (float64_is_signaling_nan(arg, status)) {
   1150         return FLOAT_CLASS_SIGNALING_NAN;
   1151     } else if (float64_is_quiet_nan(arg, status)) {
   1152         return FLOAT_CLASS_QUIET_NAN;
   1153     } else if (float64_is_neg(arg)) {
   1154         if (float64_is_infinity(arg)) {
   1155             return FLOAT_CLASS_NEGATIVE_INFINITY;
   1156         } else if (float64_is_zero(arg)) {
   1157             return FLOAT_CLASS_NEGATIVE_ZERO;
   1158         } else if (float64_is_zero_or_denormal(arg)) {
   1159             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
   1160         } else {
   1161             return FLOAT_CLASS_NEGATIVE_NORMAL;
   1162         }
   1163     } else {
   1164         if (float64_is_infinity(arg)) {
   1165             return FLOAT_CLASS_POSITIVE_INFINITY;
   1166         } else if (float64_is_zero(arg)) {
   1167             return FLOAT_CLASS_POSITIVE_ZERO;
   1168         } else if (float64_is_zero_or_denormal(arg)) {
   1169             return FLOAT_CLASS_POSITIVE_SUBNORMAL;
   1170         } else {
   1171             return FLOAT_CLASS_POSITIVE_NORMAL;
   1172         }
   1173     }
   1174 }
   1175 
   1176 uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
   1177 {
   1178     return float_class_d(arg, &env->active_fpu.fp_status);
   1179 }
   1180 
   1181 uint32_t float_class_s(uint32_t arg, float_status *status)
   1182 {
   1183     if (float32_is_signaling_nan(arg, status)) {
   1184         return FLOAT_CLASS_SIGNALING_NAN;
   1185     } else if (float32_is_quiet_nan(arg, status)) {
   1186         return FLOAT_CLASS_QUIET_NAN;
   1187     } else if (float32_is_neg(arg)) {
   1188         if (float32_is_infinity(arg)) {
   1189             return FLOAT_CLASS_NEGATIVE_INFINITY;
   1190         } else if (float32_is_zero(arg)) {
   1191             return FLOAT_CLASS_NEGATIVE_ZERO;
   1192         } else if (float32_is_zero_or_denormal(arg)) {
   1193             return FLOAT_CLASS_NEGATIVE_SUBNORMAL;
   1194         } else {
   1195             return FLOAT_CLASS_NEGATIVE_NORMAL;
   1196         }
   1197     } else {
   1198         if (float32_is_infinity(arg)) {
   1199             return FLOAT_CLASS_POSITIVE_INFINITY;
   1200         } else if (float32_is_zero(arg)) {
   1201             return FLOAT_CLASS_POSITIVE_ZERO;
   1202         } else if (float32_is_zero_or_denormal(arg)) {
   1203             return FLOAT_CLASS_POSITIVE_SUBNORMAL;
   1204         } else {
   1205             return FLOAT_CLASS_POSITIVE_NORMAL;
   1206         }
   1207     }
   1208 }
   1209 
   1210 uint32_t helper_float_class_s(CPUMIPSState *env, uint32_t arg)
   1211 {
   1212     return float_class_s(arg, &env->active_fpu.fp_status);
   1213 }
   1214 
   1215 /* binary operations */
   1216 
   1217 uint64_t helper_float_add_d(CPUMIPSState *env,
   1218                             uint64_t fdt0, uint64_t fdt1)
   1219 {
   1220     uint64_t dt2;
   1221 
   1222     dt2 = float64_add(fdt0, fdt1, &env->active_fpu.fp_status);
   1223     update_fcr31(env, GETPC());
   1224     return dt2;
   1225 }
   1226 
   1227 uint32_t helper_float_add_s(CPUMIPSState *env,
   1228                             uint32_t fst0, uint32_t fst1)
   1229 {
   1230     uint32_t wt2;
   1231 
   1232     wt2 = float32_add(fst0, fst1, &env->active_fpu.fp_status);
   1233     update_fcr31(env, GETPC());
   1234     return wt2;
   1235 }
   1236 
   1237 uint64_t helper_float_add_ps(CPUMIPSState *env,
   1238                              uint64_t fdt0, uint64_t fdt1)
   1239 {
   1240     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1241     uint32_t fsth0 = fdt0 >> 32;
   1242     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1243     uint32_t fsth1 = fdt1 >> 32;
   1244     uint32_t wtl2;
   1245     uint32_t wth2;
   1246 
   1247     wtl2 = float32_add(fstl0, fstl1, &env->active_fpu.fp_status);
   1248     wth2 = float32_add(fsth0, fsth1, &env->active_fpu.fp_status);
   1249     update_fcr31(env, GETPC());
   1250     return ((uint64_t)wth2 << 32) | wtl2;
   1251 }
   1252 
   1253 uint64_t helper_float_sub_d(CPUMIPSState *env,
   1254                             uint64_t fdt0, uint64_t fdt1)
   1255 {
   1256     uint64_t dt2;
   1257 
   1258     dt2 = float64_sub(fdt0, fdt1, &env->active_fpu.fp_status);
   1259     update_fcr31(env, GETPC());
   1260     return dt2;
   1261 }
   1262 
   1263 uint32_t helper_float_sub_s(CPUMIPSState *env,
   1264                             uint32_t fst0, uint32_t fst1)
   1265 {
   1266     uint32_t wt2;
   1267 
   1268     wt2 = float32_sub(fst0, fst1, &env->active_fpu.fp_status);
   1269     update_fcr31(env, GETPC());
   1270     return wt2;
   1271 }
   1272 
   1273 uint64_t helper_float_sub_ps(CPUMIPSState *env,
   1274                              uint64_t fdt0, uint64_t fdt1)
   1275 {
   1276     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1277     uint32_t fsth0 = fdt0 >> 32;
   1278     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1279     uint32_t fsth1 = fdt1 >> 32;
   1280     uint32_t wtl2;
   1281     uint32_t wth2;
   1282 
   1283     wtl2 = float32_sub(fstl0, fstl1, &env->active_fpu.fp_status);
   1284     wth2 = float32_sub(fsth0, fsth1, &env->active_fpu.fp_status);
   1285     update_fcr31(env, GETPC());
   1286     return ((uint64_t)wth2 << 32) | wtl2;
   1287 }
   1288 
   1289 uint64_t helper_float_mul_d(CPUMIPSState *env,
   1290                             uint64_t fdt0, uint64_t fdt1)
   1291 {
   1292     uint64_t dt2;
   1293 
   1294     dt2 = float64_mul(fdt0, fdt1, &env->active_fpu.fp_status);
   1295     update_fcr31(env, GETPC());
   1296     return dt2;
   1297 }
   1298 
   1299 uint32_t helper_float_mul_s(CPUMIPSState *env,
   1300                             uint32_t fst0, uint32_t fst1)
   1301 {
   1302     uint32_t wt2;
   1303 
   1304     wt2 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
   1305     update_fcr31(env, GETPC());
   1306     return wt2;
   1307 }
   1308 
   1309 uint64_t helper_float_mul_ps(CPUMIPSState *env,
   1310                              uint64_t fdt0, uint64_t fdt1)
   1311 {
   1312     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1313     uint32_t fsth0 = fdt0 >> 32;
   1314     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1315     uint32_t fsth1 = fdt1 >> 32;
   1316     uint32_t wtl2;
   1317     uint32_t wth2;
   1318 
   1319     wtl2 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
   1320     wth2 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
   1321     update_fcr31(env, GETPC());
   1322     return ((uint64_t)wth2 << 32) | wtl2;
   1323 }
   1324 
   1325 uint64_t helper_float_div_d(CPUMIPSState *env,
   1326                             uint64_t fdt0, uint64_t fdt1)
   1327 {
   1328     uint64_t dt2;
   1329 
   1330     dt2 = float64_div(fdt0, fdt1, &env->active_fpu.fp_status);
   1331     update_fcr31(env, GETPC());
   1332     return dt2;
   1333 }
   1334 
   1335 uint32_t helper_float_div_s(CPUMIPSState *env,
   1336                             uint32_t fst0, uint32_t fst1)
   1337 {
   1338     uint32_t wt2;
   1339 
   1340     wt2 = float32_div(fst0, fst1, &env->active_fpu.fp_status);
   1341     update_fcr31(env, GETPC());
   1342     return wt2;
   1343 }
   1344 
   1345 uint64_t helper_float_div_ps(CPUMIPSState *env,
   1346                              uint64_t fdt0, uint64_t fdt1)
   1347 {
   1348     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1349     uint32_t fsth0 = fdt0 >> 32;
   1350     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1351     uint32_t fsth1 = fdt1 >> 32;
   1352     uint32_t wtl2;
   1353     uint32_t wth2;
   1354 
   1355     wtl2 = float32_div(fstl0, fstl1, &env->active_fpu.fp_status);
   1356     wth2 = float32_div(fsth0, fsth1, &env->active_fpu.fp_status);
   1357     update_fcr31(env, GETPC());
   1358     return ((uint64_t)wth2 << 32) | wtl2;
   1359 }
   1360 
   1361 
   1362 /* MIPS specific binary operations */
   1363 uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
   1364 {
   1365     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
   1366     fdt2 = float64_chs(float64_sub(fdt2, float64_one,
   1367                                    &env->active_fpu.fp_status));
   1368     update_fcr31(env, GETPC());
   1369     return fdt2;
   1370 }
   1371 
   1372 uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
   1373 {
   1374     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
   1375     fst2 = float32_chs(float32_sub(fst2, float32_one,
   1376                                        &env->active_fpu.fp_status));
   1377     update_fcr31(env, GETPC());
   1378     return fst2;
   1379 }
   1380 
   1381 uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
   1382 {
   1383     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1384     uint32_t fsth0 = fdt0 >> 32;
   1385     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
   1386     uint32_t fsth2 = fdt2 >> 32;
   1387 
   1388     fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
   1389     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
   1390     fstl2 = float32_chs(float32_sub(fstl2, float32_one,
   1391                                        &env->active_fpu.fp_status));
   1392     fsth2 = float32_chs(float32_sub(fsth2, float32_one,
   1393                                        &env->active_fpu.fp_status));
   1394     update_fcr31(env, GETPC());
   1395     return ((uint64_t)fsth2 << 32) | fstl2;
   1396 }
   1397 
   1398 uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
   1399 {
   1400     fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status);
   1401     fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status);
   1402     fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64,
   1403                                        &env->active_fpu.fp_status));
   1404     update_fcr31(env, GETPC());
   1405     return fdt2;
   1406 }
   1407 
   1408 uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2)
   1409 {
   1410     fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status);
   1411     fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status);
   1412     fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32,
   1413                                        &env->active_fpu.fp_status));
   1414     update_fcr31(env, GETPC());
   1415     return fst2;
   1416 }
   1417 
   1418 uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2)
   1419 {
   1420     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1421     uint32_t fsth0 = fdt0 >> 32;
   1422     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
   1423     uint32_t fsth2 = fdt2 >> 32;
   1424 
   1425     fstl2 = float32_mul(fstl0, fstl2, &env->active_fpu.fp_status);
   1426     fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status);
   1427     fstl2 = float32_sub(fstl2, float32_one, &env->active_fpu.fp_status);
   1428     fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status);
   1429     fstl2 = float32_chs(float32_div(fstl2, FLOAT_TWO32,
   1430                                        &env->active_fpu.fp_status));
   1431     fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32,
   1432                                        &env->active_fpu.fp_status));
   1433     update_fcr31(env, GETPC());
   1434     return ((uint64_t)fsth2 << 32) | fstl2;
   1435 }
   1436 
   1437 uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
   1438 {
   1439     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1440     uint32_t fsth0 = fdt0 >> 32;
   1441     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1442     uint32_t fsth1 = fdt1 >> 32;
   1443     uint32_t fstl2;
   1444     uint32_t fsth2;
   1445 
   1446     fstl2 = float32_add(fstl0, fsth0, &env->active_fpu.fp_status);
   1447     fsth2 = float32_add(fstl1, fsth1, &env->active_fpu.fp_status);
   1448     update_fcr31(env, GETPC());
   1449     return ((uint64_t)fsth2 << 32) | fstl2;
   1450 }
   1451 
   1452 uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1)
   1453 {
   1454     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1455     uint32_t fsth0 = fdt0 >> 32;
   1456     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1457     uint32_t fsth1 = fdt1 >> 32;
   1458     uint32_t fstl2;
   1459     uint32_t fsth2;
   1460 
   1461     fstl2 = float32_mul(fstl0, fsth0, &env->active_fpu.fp_status);
   1462     fsth2 = float32_mul(fstl1, fsth1, &env->active_fpu.fp_status);
   1463     update_fcr31(env, GETPC());
   1464     return ((uint64_t)fsth2 << 32) | fstl2;
   1465 }
   1466 
   1467 
   1468 uint32_t helper_float_max_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
   1469 {
   1470     uint32_t fdret;
   1471 
   1472     fdret = float32_maxnum(fs, ft, &env->active_fpu.fp_status);
   1473 
   1474     update_fcr31(env, GETPC());
   1475     return fdret;
   1476 }
   1477 
   1478 uint64_t helper_float_max_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
   1479 {
   1480     uint64_t fdret;
   1481 
   1482     fdret = float64_maxnum(fs, ft, &env->active_fpu.fp_status);
   1483 
   1484     update_fcr31(env, GETPC());
   1485     return fdret;
   1486 }
   1487 
   1488 uint32_t helper_float_maxa_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
   1489 {
   1490     uint32_t fdret;
   1491 
   1492     fdret = float32_maxnummag(fs, ft, &env->active_fpu.fp_status);
   1493 
   1494     update_fcr31(env, GETPC());
   1495     return fdret;
   1496 }
   1497 
   1498 uint64_t helper_float_maxa_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
   1499 {
   1500     uint64_t fdret;
   1501 
   1502     fdret = float64_maxnummag(fs, ft, &env->active_fpu.fp_status);
   1503 
   1504     update_fcr31(env, GETPC());
   1505     return fdret;
   1506 }
   1507 
   1508 uint32_t helper_float_min_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
   1509 {
   1510     uint32_t fdret;
   1511 
   1512     fdret = float32_minnum(fs, ft, &env->active_fpu.fp_status);
   1513 
   1514     update_fcr31(env, GETPC());
   1515     return fdret;
   1516 }
   1517 
   1518 uint64_t helper_float_min_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
   1519 {
   1520     uint64_t fdret;
   1521 
   1522     fdret = float64_minnum(fs, ft, &env->active_fpu.fp_status);
   1523 
   1524     update_fcr31(env, GETPC());
   1525     return fdret;
   1526 }
   1527 
   1528 uint32_t helper_float_mina_s(CPUMIPSState *env, uint32_t fs, uint32_t ft)
   1529 {
   1530     uint32_t fdret;
   1531 
   1532     fdret = float32_minnummag(fs, ft, &env->active_fpu.fp_status);
   1533 
   1534     update_fcr31(env, GETPC());
   1535     return fdret;
   1536 }
   1537 
   1538 uint64_t helper_float_mina_d(CPUMIPSState *env, uint64_t fs, uint64_t ft)
   1539 {
   1540     uint64_t fdret;
   1541 
   1542     fdret = float64_minnummag(fs, ft, &env->active_fpu.fp_status);
   1543 
   1544     update_fcr31(env, GETPC());
   1545     return fdret;
   1546 }
   1547 
   1548 
   1549 /* ternary operations */
   1550 
   1551 uint64_t helper_float_madd_d(CPUMIPSState *env, uint64_t fst0,
   1552                              uint64_t fst1, uint64_t fst2)
   1553 {
   1554     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
   1555     fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
   1556 
   1557     update_fcr31(env, GETPC());
   1558     return fst0;
   1559 }
   1560 
   1561 uint32_t helper_float_madd_s(CPUMIPSState *env, uint32_t fst0,
   1562                              uint32_t fst1, uint32_t fst2)
   1563 {
   1564     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
   1565     fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
   1566 
   1567     update_fcr31(env, GETPC());
   1568     return fst0;
   1569 }
   1570 
   1571 uint64_t helper_float_madd_ps(CPUMIPSState *env, uint64_t fdt0,
   1572                               uint64_t fdt1, uint64_t fdt2)
   1573 {
   1574     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1575     uint32_t fsth0 = fdt0 >> 32;
   1576     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1577     uint32_t fsth1 = fdt1 >> 32;
   1578     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
   1579     uint32_t fsth2 = fdt2 >> 32;
   1580 
   1581     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
   1582     fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
   1583     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
   1584     fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
   1585 
   1586     update_fcr31(env, GETPC());
   1587     return ((uint64_t)fsth0 << 32) | fstl0;
   1588 }
   1589 
   1590 uint64_t helper_float_msub_d(CPUMIPSState *env, uint64_t fst0,
   1591                              uint64_t fst1, uint64_t fst2)
   1592 {
   1593     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
   1594     fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
   1595 
   1596     update_fcr31(env, GETPC());
   1597     return fst0;
   1598 }
   1599 
   1600 uint32_t helper_float_msub_s(CPUMIPSState *env, uint32_t fst0,
   1601                              uint32_t fst1, uint32_t fst2)
   1602 {
   1603     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
   1604     fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
   1605 
   1606     update_fcr31(env, GETPC());
   1607     return fst0;
   1608 }
   1609 
   1610 uint64_t helper_float_msub_ps(CPUMIPSState *env, uint64_t fdt0,
   1611                               uint64_t fdt1, uint64_t fdt2)
   1612 {
   1613     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1614     uint32_t fsth0 = fdt0 >> 32;
   1615     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1616     uint32_t fsth1 = fdt1 >> 32;
   1617     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
   1618     uint32_t fsth2 = fdt2 >> 32;
   1619 
   1620     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
   1621     fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
   1622     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
   1623     fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
   1624 
   1625     update_fcr31(env, GETPC());
   1626     return ((uint64_t)fsth0 << 32) | fstl0;
   1627 }
   1628 
   1629 uint64_t helper_float_nmadd_d(CPUMIPSState *env, uint64_t fst0,
   1630                              uint64_t fst1, uint64_t fst2)
   1631 {
   1632     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
   1633     fst0 = float64_add(fst0, fst2, &env->active_fpu.fp_status);
   1634     fst0 = float64_chs(fst0);
   1635 
   1636     update_fcr31(env, GETPC());
   1637     return fst0;
   1638 }
   1639 
   1640 uint32_t helper_float_nmadd_s(CPUMIPSState *env, uint32_t fst0,
   1641                              uint32_t fst1, uint32_t fst2)
   1642 {
   1643     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
   1644     fst0 = float32_add(fst0, fst2, &env->active_fpu.fp_status);
   1645     fst0 = float32_chs(fst0);
   1646 
   1647     update_fcr31(env, GETPC());
   1648     return fst0;
   1649 }
   1650 
   1651 uint64_t helper_float_nmadd_ps(CPUMIPSState *env, uint64_t fdt0,
   1652                               uint64_t fdt1, uint64_t fdt2)
   1653 {
   1654     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1655     uint32_t fsth0 = fdt0 >> 32;
   1656     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1657     uint32_t fsth1 = fdt1 >> 32;
   1658     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
   1659     uint32_t fsth2 = fdt2 >> 32;
   1660 
   1661     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
   1662     fstl0 = float32_add(fstl0, fstl2, &env->active_fpu.fp_status);
   1663     fstl0 = float32_chs(fstl0);
   1664     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
   1665     fsth0 = float32_add(fsth0, fsth2, &env->active_fpu.fp_status);
   1666     fsth0 = float32_chs(fsth0);
   1667 
   1668     update_fcr31(env, GETPC());
   1669     return ((uint64_t)fsth0 << 32) | fstl0;
   1670 }
   1671 
   1672 uint64_t helper_float_nmsub_d(CPUMIPSState *env, uint64_t fst0,
   1673                              uint64_t fst1, uint64_t fst2)
   1674 {
   1675     fst0 = float64_mul(fst0, fst1, &env->active_fpu.fp_status);
   1676     fst0 = float64_sub(fst0, fst2, &env->active_fpu.fp_status);
   1677     fst0 = float64_chs(fst0);
   1678 
   1679     update_fcr31(env, GETPC());
   1680     return fst0;
   1681 }
   1682 
   1683 uint32_t helper_float_nmsub_s(CPUMIPSState *env, uint32_t fst0,
   1684                              uint32_t fst1, uint32_t fst2)
   1685 {
   1686     fst0 = float32_mul(fst0, fst1, &env->active_fpu.fp_status);
   1687     fst0 = float32_sub(fst0, fst2, &env->active_fpu.fp_status);
   1688     fst0 = float32_chs(fst0);
   1689 
   1690     update_fcr31(env, GETPC());
   1691     return fst0;
   1692 }
   1693 
   1694 uint64_t helper_float_nmsub_ps(CPUMIPSState *env, uint64_t fdt0,
   1695                               uint64_t fdt1, uint64_t fdt2)
   1696 {
   1697     uint32_t fstl0 = fdt0 & 0XFFFFFFFF;
   1698     uint32_t fsth0 = fdt0 >> 32;
   1699     uint32_t fstl1 = fdt1 & 0XFFFFFFFF;
   1700     uint32_t fsth1 = fdt1 >> 32;
   1701     uint32_t fstl2 = fdt2 & 0XFFFFFFFF;
   1702     uint32_t fsth2 = fdt2 >> 32;
   1703 
   1704     fstl0 = float32_mul(fstl0, fstl1, &env->active_fpu.fp_status);
   1705     fstl0 = float32_sub(fstl0, fstl2, &env->active_fpu.fp_status);
   1706     fstl0 = float32_chs(fstl0);
   1707     fsth0 = float32_mul(fsth0, fsth1, &env->active_fpu.fp_status);
   1708     fsth0 = float32_sub(fsth0, fsth2, &env->active_fpu.fp_status);
   1709     fsth0 = float32_chs(fsth0);
   1710 
   1711     update_fcr31(env, GETPC());
   1712     return ((uint64_t)fsth0 << 32) | fstl0;
   1713 }
   1714 
   1715 
   1716 uint32_t helper_float_maddf_s(CPUMIPSState *env, uint32_t fs,
   1717                               uint32_t ft, uint32_t fd)
   1718 {
   1719     uint32_t fdret;
   1720 
   1721     fdret = float32_muladd(fs, ft, fd, 0,
   1722                            &env->active_fpu.fp_status);
   1723 
   1724     update_fcr31(env, GETPC());
   1725     return fdret;
   1726 }
   1727 
   1728 uint64_t helper_float_maddf_d(CPUMIPSState *env, uint64_t fs,
   1729                               uint64_t ft, uint64_t fd)
   1730 {
   1731     uint64_t fdret;
   1732 
   1733     fdret = float64_muladd(fs, ft, fd, 0,
   1734                            &env->active_fpu.fp_status);
   1735 
   1736     update_fcr31(env, GETPC());
   1737     return fdret;
   1738 }
   1739 
   1740 uint32_t helper_float_msubf_s(CPUMIPSState *env, uint32_t fs,
   1741                               uint32_t ft, uint32_t fd)
   1742 {
   1743     uint32_t fdret;
   1744 
   1745     fdret = float32_muladd(fs, ft, fd, float_muladd_negate_product,
   1746                            &env->active_fpu.fp_status);
   1747 
   1748     update_fcr31(env, GETPC());
   1749     return fdret;
   1750 }
   1751 
   1752 uint64_t helper_float_msubf_d(CPUMIPSState *env, uint64_t fs,
   1753                               uint64_t ft, uint64_t fd)
   1754 {
   1755     uint64_t fdret;
   1756 
   1757     fdret = float64_muladd(fs, ft, fd, float_muladd_negate_product,
   1758                            &env->active_fpu.fp_status);
   1759 
   1760     update_fcr31(env, GETPC());
   1761     return fdret;
   1762 }
   1763 
   1764 
   1765 /* compare operations */
   1766 #define FOP_COND_D(op, cond)                                   \
   1767 void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
   1768                          uint64_t fdt1, int cc)                \
   1769 {                                                              \
   1770     int c;                                                     \
   1771     c = cond;                                                  \
   1772     update_fcr31(env, GETPC());                                \
   1773     if (c)                                                     \
   1774         SET_FP_COND(cc, env->active_fpu);                      \
   1775     else                                                       \
   1776         CLEAR_FP_COND(cc, env->active_fpu);                    \
   1777 }                                                              \
   1778 void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
   1779                             uint64_t fdt1, int cc)             \
   1780 {                                                              \
   1781     int c;                                                     \
   1782     fdt0 = float64_abs(fdt0);                                  \
   1783     fdt1 = float64_abs(fdt1);                                  \
   1784     c = cond;                                                  \
   1785     update_fcr31(env, GETPC());                                \
   1786     if (c)                                                     \
   1787         SET_FP_COND(cc, env->active_fpu);                      \
   1788     else                                                       \
   1789         CLEAR_FP_COND(cc, env->active_fpu);                    \
   1790 }
   1791 
   1792 /*
   1793  * NOTE: the comma operator will make "cond" to eval to false,
   1794  * but float64_unordered_quiet() is still called.
   1795  */
   1796 FOP_COND_D(f,    (float64_unordered_quiet(fdt1, fdt0,
   1797                                        &env->active_fpu.fp_status), 0))
   1798 FOP_COND_D(un,   float64_unordered_quiet(fdt1, fdt0,
   1799                                        &env->active_fpu.fp_status))
   1800 FOP_COND_D(eq,   float64_eq_quiet(fdt0, fdt1,
   1801                                        &env->active_fpu.fp_status))
   1802 FOP_COND_D(ueq,  float64_unordered_quiet(fdt1, fdt0,
   1803                                        &env->active_fpu.fp_status)
   1804                  || float64_eq_quiet(fdt0, fdt1,
   1805                                        &env->active_fpu.fp_status))
   1806 FOP_COND_D(olt,  float64_lt_quiet(fdt0, fdt1,
   1807                                        &env->active_fpu.fp_status))
   1808 FOP_COND_D(ult,  float64_unordered_quiet(fdt1, fdt0,
   1809                                        &env->active_fpu.fp_status)
   1810                  || float64_lt_quiet(fdt0, fdt1,
   1811                                        &env->active_fpu.fp_status))
   1812 FOP_COND_D(ole,  float64_le_quiet(fdt0, fdt1,
   1813                                        &env->active_fpu.fp_status))
   1814 FOP_COND_D(ule,  float64_unordered_quiet(fdt1, fdt0,
   1815                                        &env->active_fpu.fp_status)
   1816                  || float64_le_quiet(fdt0, fdt1,
   1817                                        &env->active_fpu.fp_status))
   1818 /*
   1819  * NOTE: the comma operator will make "cond" to eval to false,
   1820  * but float64_unordered() is still called.
   1821  */
   1822 FOP_COND_D(sf,   (float64_unordered(fdt1, fdt0,
   1823                                        &env->active_fpu.fp_status), 0))
   1824 FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
   1825                                        &env->active_fpu.fp_status))
   1826 FOP_COND_D(seq,  float64_eq(fdt0, fdt1,
   1827                                        &env->active_fpu.fp_status))
   1828 FOP_COND_D(ngl,  float64_unordered(fdt1, fdt0,
   1829                                        &env->active_fpu.fp_status)
   1830                  || float64_eq(fdt0, fdt1,
   1831                                        &env->active_fpu.fp_status))
   1832 FOP_COND_D(lt,   float64_lt(fdt0, fdt1,
   1833                                        &env->active_fpu.fp_status))
   1834 FOP_COND_D(nge,  float64_unordered(fdt1, fdt0,
   1835                                        &env->active_fpu.fp_status)
   1836                  || float64_lt(fdt0, fdt1,
   1837                                        &env->active_fpu.fp_status))
   1838 FOP_COND_D(le,   float64_le(fdt0, fdt1,
   1839                                        &env->active_fpu.fp_status))
   1840 FOP_COND_D(ngt,  float64_unordered(fdt1, fdt0,
   1841                                        &env->active_fpu.fp_status)
   1842                  || float64_le(fdt0, fdt1,
   1843                                        &env->active_fpu.fp_status))
   1844 
   1845 #define FOP_COND_S(op, cond)                                   \
   1846 void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,     \
   1847                          uint32_t fst1, int cc)                \
   1848 {                                                              \
   1849     int c;                                                     \
   1850     c = cond;                                                  \
   1851     update_fcr31(env, GETPC());                                \
   1852     if (c)                                                     \
   1853         SET_FP_COND(cc, env->active_fpu);                      \
   1854     else                                                       \
   1855         CLEAR_FP_COND(cc, env->active_fpu);                    \
   1856 }                                                              \
   1857 void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0,  \
   1858                             uint32_t fst1, int cc)             \
   1859 {                                                              \
   1860     int c;                                                     \
   1861     fst0 = float32_abs(fst0);                                  \
   1862     fst1 = float32_abs(fst1);                                  \
   1863     c = cond;                                                  \
   1864     update_fcr31(env, GETPC());                                \
   1865     if (c)                                                     \
   1866         SET_FP_COND(cc, env->active_fpu);                      \
   1867     else                                                       \
   1868         CLEAR_FP_COND(cc, env->active_fpu);                    \
   1869 }
   1870 
   1871 /*
   1872  * NOTE: the comma operator will make "cond" to eval to false,
   1873  * but float32_unordered_quiet() is still called.
   1874  */
   1875 FOP_COND_S(f,    (float32_unordered_quiet(fst1, fst0,
   1876                                        &env->active_fpu.fp_status), 0))
   1877 FOP_COND_S(un,   float32_unordered_quiet(fst1, fst0,
   1878                                        &env->active_fpu.fp_status))
   1879 FOP_COND_S(eq,   float32_eq_quiet(fst0, fst1,
   1880                                        &env->active_fpu.fp_status))
   1881 FOP_COND_S(ueq,  float32_unordered_quiet(fst1, fst0,
   1882                                        &env->active_fpu.fp_status)
   1883                  || float32_eq_quiet(fst0, fst1,
   1884                                        &env->active_fpu.fp_status))
   1885 FOP_COND_S(olt,  float32_lt_quiet(fst0, fst1,
   1886                                        &env->active_fpu.fp_status))
   1887 FOP_COND_S(ult,  float32_unordered_quiet(fst1, fst0,
   1888                                        &env->active_fpu.fp_status)
   1889                  || float32_lt_quiet(fst0, fst1,
   1890                                        &env->active_fpu.fp_status))
   1891 FOP_COND_S(ole,  float32_le_quiet(fst0, fst1,
   1892                                        &env->active_fpu.fp_status))
   1893 FOP_COND_S(ule,  float32_unordered_quiet(fst1, fst0,
   1894                                        &env->active_fpu.fp_status)
   1895                  || float32_le_quiet(fst0, fst1,
   1896                                        &env->active_fpu.fp_status))
   1897 /*
   1898  * NOTE: the comma operator will make "cond" to eval to false,
   1899  * but float32_unordered() is still called.
   1900  */
   1901 FOP_COND_S(sf,   (float32_unordered(fst1, fst0,
   1902                                        &env->active_fpu.fp_status), 0))
   1903 FOP_COND_S(ngle, float32_unordered(fst1, fst0,
   1904                                        &env->active_fpu.fp_status))
   1905 FOP_COND_S(seq,  float32_eq(fst0, fst1,
   1906                                        &env->active_fpu.fp_status))
   1907 FOP_COND_S(ngl,  float32_unordered(fst1, fst0,
   1908                                        &env->active_fpu.fp_status)
   1909                  || float32_eq(fst0, fst1,
   1910                                        &env->active_fpu.fp_status))
   1911 FOP_COND_S(lt,   float32_lt(fst0, fst1,
   1912                                        &env->active_fpu.fp_status))
   1913 FOP_COND_S(nge,  float32_unordered(fst1, fst0,
   1914                                        &env->active_fpu.fp_status)
   1915                  || float32_lt(fst0, fst1,
   1916                                        &env->active_fpu.fp_status))
   1917 FOP_COND_S(le,   float32_le(fst0, fst1,
   1918                                        &env->active_fpu.fp_status))
   1919 FOP_COND_S(ngt,  float32_unordered(fst1, fst0,
   1920                                        &env->active_fpu.fp_status)
   1921                  || float32_le(fst0, fst1,
   1922                                        &env->active_fpu.fp_status))
   1923 
   1924 #define FOP_COND_PS(op, condl, condh)                           \
   1925 void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,     \
   1926                           uint64_t fdt1, int cc)                \
   1927 {                                                               \
   1928     uint32_t fst0, fsth0, fst1, fsth1;                          \
   1929     int ch, cl;                                                 \
   1930     fst0 = fdt0 & 0XFFFFFFFF;                                   \
   1931     fsth0 = fdt0 >> 32;                                         \
   1932     fst1 = fdt1 & 0XFFFFFFFF;                                   \
   1933     fsth1 = fdt1 >> 32;                                         \
   1934     cl = condl;                                                 \
   1935     ch = condh;                                                 \
   1936     update_fcr31(env, GETPC());                                 \
   1937     if (cl)                                                     \
   1938         SET_FP_COND(cc, env->active_fpu);                       \
   1939     else                                                        \
   1940         CLEAR_FP_COND(cc, env->active_fpu);                     \
   1941     if (ch)                                                     \
   1942         SET_FP_COND(cc + 1, env->active_fpu);                   \
   1943     else                                                        \
   1944         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
   1945 }                                                               \
   1946 void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0,  \
   1947                              uint64_t fdt1, int cc)             \
   1948 {                                                               \
   1949     uint32_t fst0, fsth0, fst1, fsth1;                          \
   1950     int ch, cl;                                                 \
   1951     fst0 = float32_abs(fdt0 & 0XFFFFFFFF);                      \
   1952     fsth0 = float32_abs(fdt0 >> 32);                            \
   1953     fst1 = float32_abs(fdt1 & 0XFFFFFFFF);                      \
   1954     fsth1 = float32_abs(fdt1 >> 32);                            \
   1955     cl = condl;                                                 \
   1956     ch = condh;                                                 \
   1957     update_fcr31(env, GETPC());                                 \
   1958     if (cl)                                                     \
   1959         SET_FP_COND(cc, env->active_fpu);                       \
   1960     else                                                        \
   1961         CLEAR_FP_COND(cc, env->active_fpu);                     \
   1962     if (ch)                                                     \
   1963         SET_FP_COND(cc + 1, env->active_fpu);                   \
   1964     else                                                        \
   1965         CLEAR_FP_COND(cc + 1, env->active_fpu);                 \
   1966 }
   1967 
   1968 /*
   1969  * NOTE: the comma operator will make "cond" to eval to false,
   1970  * but float32_unordered_quiet() is still called.
   1971  */
   1972 FOP_COND_PS(f,    (float32_unordered_quiet(fst1, fst0,
   1973                                        &env->active_fpu.fp_status), 0),
   1974                   (float32_unordered_quiet(fsth1, fsth0,
   1975                                        &env->active_fpu.fp_status), 0))
   1976 FOP_COND_PS(un,   float32_unordered_quiet(fst1, fst0,
   1977                                        &env->active_fpu.fp_status),
   1978                   float32_unordered_quiet(fsth1, fsth0,
   1979                                        &env->active_fpu.fp_status))
   1980 FOP_COND_PS(eq,   float32_eq_quiet(fst0, fst1,
   1981                                        &env->active_fpu.fp_status),
   1982                   float32_eq_quiet(fsth0, fsth1,
   1983                                        &env->active_fpu.fp_status))
   1984 FOP_COND_PS(ueq,  float32_unordered_quiet(fst1, fst0,
   1985                                        &env->active_fpu.fp_status)
   1986                   || float32_eq_quiet(fst0, fst1,
   1987                                        &env->active_fpu.fp_status),
   1988                   float32_unordered_quiet(fsth1, fsth0,
   1989                                        &env->active_fpu.fp_status)
   1990                   || float32_eq_quiet(fsth0, fsth1,
   1991                                        &env->active_fpu.fp_status))
   1992 FOP_COND_PS(olt,  float32_lt_quiet(fst0, fst1,
   1993                                        &env->active_fpu.fp_status),
   1994                   float32_lt_quiet(fsth0, fsth1,
   1995                                        &env->active_fpu.fp_status))
   1996 FOP_COND_PS(ult,  float32_unordered_quiet(fst1, fst0,
   1997                                        &env->active_fpu.fp_status)
   1998                   || float32_lt_quiet(fst0, fst1,
   1999                                        &env->active_fpu.fp_status),
   2000                   float32_unordered_quiet(fsth1, fsth0,
   2001                                        &env->active_fpu.fp_status)
   2002                   || float32_lt_quiet(fsth0, fsth1,
   2003                                        &env->active_fpu.fp_status))
   2004 FOP_COND_PS(ole,  float32_le_quiet(fst0, fst1,
   2005                                        &env->active_fpu.fp_status),
   2006                   float32_le_quiet(fsth0, fsth1,
   2007                                        &env->active_fpu.fp_status))
   2008 FOP_COND_PS(ule,  float32_unordered_quiet(fst1, fst0,
   2009                                        &env->active_fpu.fp_status)
   2010                   || float32_le_quiet(fst0, fst1,
   2011                                        &env->active_fpu.fp_status),
   2012                   float32_unordered_quiet(fsth1, fsth0,
   2013                                        &env->active_fpu.fp_status)
   2014                   || float32_le_quiet(fsth0, fsth1,
   2015                                        &env->active_fpu.fp_status))
   2016 /*
   2017  * NOTE: the comma operator will make "cond" to eval to false,
   2018  * but float32_unordered() is still called.
   2019  */
   2020 FOP_COND_PS(sf,   (float32_unordered(fst1, fst0,
   2021                                        &env->active_fpu.fp_status), 0),
   2022                   (float32_unordered(fsth1, fsth0,
   2023                                        &env->active_fpu.fp_status), 0))
   2024 FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
   2025                                        &env->active_fpu.fp_status),
   2026                   float32_unordered(fsth1, fsth0,
   2027                                        &env->active_fpu.fp_status))
   2028 FOP_COND_PS(seq,  float32_eq(fst0, fst1,
   2029                                        &env->active_fpu.fp_status),
   2030                   float32_eq(fsth0, fsth1,
   2031                                        &env->active_fpu.fp_status))
   2032 FOP_COND_PS(ngl,  float32_unordered(fst1, fst0,
   2033                                        &env->active_fpu.fp_status)
   2034                   || float32_eq(fst0, fst1,
   2035                                        &env->active_fpu.fp_status),
   2036                   float32_unordered(fsth1, fsth0,
   2037                                        &env->active_fpu.fp_status)
   2038                   || float32_eq(fsth0, fsth1,
   2039                                        &env->active_fpu.fp_status))
   2040 FOP_COND_PS(lt,   float32_lt(fst0, fst1,
   2041                                        &env->active_fpu.fp_status),
   2042                   float32_lt(fsth0, fsth1,
   2043                                        &env->active_fpu.fp_status))
   2044 FOP_COND_PS(nge,  float32_unordered(fst1, fst0,
   2045                                        &env->active_fpu.fp_status)
   2046                   || float32_lt(fst0, fst1,
   2047                                        &env->active_fpu.fp_status),
   2048                   float32_unordered(fsth1, fsth0,
   2049                                        &env->active_fpu.fp_status)
   2050                   || float32_lt(fsth0, fsth1,
   2051                                        &env->active_fpu.fp_status))
   2052 FOP_COND_PS(le,   float32_le(fst0, fst1,
   2053                                        &env->active_fpu.fp_status),
   2054                   float32_le(fsth0, fsth1,
   2055                                        &env->active_fpu.fp_status))
   2056 FOP_COND_PS(ngt,  float32_unordered(fst1, fst0,
   2057                                        &env->active_fpu.fp_status)
   2058                   || float32_le(fst0, fst1,
   2059                                        &env->active_fpu.fp_status),
   2060                   float32_unordered(fsth1, fsth0,
   2061                                        &env->active_fpu.fp_status)
   2062                   || float32_le(fsth0, fsth1,
   2063                                        &env->active_fpu.fp_status))
   2064 
   2065 /* R6 compare operations */
   2066 #define FOP_CONDN_D(op, cond)                                       \
   2067 uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0,   \
   2068                                 uint64_t fdt1)                      \
   2069 {                                                                   \
   2070     uint64_t c;                                                     \
   2071     c = cond;                                                       \
   2072     update_fcr31(env, GETPC());                                     \
   2073     if (c) {                                                        \
   2074         return -1;                                                  \
   2075     } else {                                                        \
   2076         return 0;                                                   \
   2077     }                                                               \
   2078 }
   2079 
   2080 /*
   2081  * NOTE: the comma operator will make "cond" to eval to false,
   2082  * but float64_unordered_quiet() is still called.
   2083  */
   2084 FOP_CONDN_D(af,  (float64_unordered_quiet(fdt1, fdt0,
   2085                                        &env->active_fpu.fp_status), 0))
   2086 FOP_CONDN_D(un,  (float64_unordered_quiet(fdt1, fdt0,
   2087                                        &env->active_fpu.fp_status)))
   2088 FOP_CONDN_D(eq,  (float64_eq_quiet(fdt0, fdt1,
   2089                                        &env->active_fpu.fp_status)))
   2090 FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0,
   2091                                        &env->active_fpu.fp_status)
   2092                  || float64_eq_quiet(fdt0, fdt1,
   2093                                        &env->active_fpu.fp_status)))
   2094 FOP_CONDN_D(lt,  (float64_lt_quiet(fdt0, fdt1,
   2095                                        &env->active_fpu.fp_status)))
   2096 FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0,
   2097                                        &env->active_fpu.fp_status)
   2098                  || float64_lt_quiet(fdt0, fdt1,
   2099                                        &env->active_fpu.fp_status)))
   2100 FOP_CONDN_D(le,  (float64_le_quiet(fdt0, fdt1,
   2101                                        &env->active_fpu.fp_status)))
   2102 FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0,
   2103                                        &env->active_fpu.fp_status)
   2104                  || float64_le_quiet(fdt0, fdt1,
   2105                                        &env->active_fpu.fp_status)))
   2106 /*
   2107  * NOTE: the comma operator will make "cond" to eval to false,
   2108  * but float64_unordered() is still called.\
   2109  */
   2110 FOP_CONDN_D(saf,  (float64_unordered(fdt1, fdt0,
   2111                                        &env->active_fpu.fp_status), 0))
   2112 FOP_CONDN_D(sun,  (float64_unordered(fdt1, fdt0,
   2113                                        &env->active_fpu.fp_status)))
   2114 FOP_CONDN_D(seq,  (float64_eq(fdt0, fdt1,
   2115                                        &env->active_fpu.fp_status)))
   2116 FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
   2117                                        &env->active_fpu.fp_status)
   2118                    || float64_eq(fdt0, fdt1,
   2119                                        &env->active_fpu.fp_status)))
   2120 FOP_CONDN_D(slt,  (float64_lt(fdt0, fdt1,
   2121                                        &env->active_fpu.fp_status)))
   2122 FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
   2123                                        &env->active_fpu.fp_status)
   2124                    || float64_lt(fdt0, fdt1,
   2125                                        &env->active_fpu.fp_status)))
   2126 FOP_CONDN_D(sle,  (float64_le(fdt0, fdt1,
   2127                                        &env->active_fpu.fp_status)))
   2128 FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
   2129                                        &env->active_fpu.fp_status)
   2130                    || float64_le(fdt0, fdt1,
   2131                                        &env->active_fpu.fp_status)))
   2132 FOP_CONDN_D(or,   (float64_le_quiet(fdt1, fdt0,
   2133                                        &env->active_fpu.fp_status)
   2134                    || float64_le_quiet(fdt0, fdt1,
   2135                                        &env->active_fpu.fp_status)))
   2136 FOP_CONDN_D(une,  (float64_unordered_quiet(fdt1, fdt0,
   2137                                        &env->active_fpu.fp_status)
   2138                    || float64_lt_quiet(fdt1, fdt0,
   2139                                        &env->active_fpu.fp_status)
   2140                    || float64_lt_quiet(fdt0, fdt1,
   2141                                        &env->active_fpu.fp_status)))
   2142 FOP_CONDN_D(ne,   (float64_lt_quiet(fdt1, fdt0,
   2143                                        &env->active_fpu.fp_status)
   2144                    || float64_lt_quiet(fdt0, fdt1,
   2145                                        &env->active_fpu.fp_status)))
   2146 FOP_CONDN_D(sor,  (float64_le(fdt1, fdt0,
   2147                                        &env->active_fpu.fp_status)
   2148                    || float64_le(fdt0, fdt1,
   2149                                        &env->active_fpu.fp_status)))
   2150 FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0,
   2151                                        &env->active_fpu.fp_status)
   2152                    || float64_lt(fdt1, fdt0,
   2153                                        &env->active_fpu.fp_status)
   2154                    || float64_lt(fdt0, fdt1,
   2155                                        &env->active_fpu.fp_status)))
   2156 FOP_CONDN_D(sne,  (float64_lt(fdt1, fdt0,
   2157                                        &env->active_fpu.fp_status)
   2158                    || float64_lt(fdt0, fdt1,
   2159                                        &env->active_fpu.fp_status)))
   2160 
   2161 #define FOP_CONDN_S(op, cond)                                       \
   2162 uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0,   \
   2163                                 uint32_t fst1)                      \
   2164 {                                                                   \
   2165     uint64_t c;                                                     \
   2166     c = cond;                                                       \
   2167     update_fcr31(env, GETPC());                                     \
   2168     if (c) {                                                        \
   2169         return -1;                                                  \
   2170     } else {                                                        \
   2171         return 0;                                                   \
   2172     }                                                               \
   2173 }
   2174 
   2175 /*
   2176  * NOTE: the comma operator will make "cond" to eval to false,
   2177  * but float32_unordered_quiet() is still called.
   2178  */
   2179 FOP_CONDN_S(af,   (float32_unordered_quiet(fst1, fst0,
   2180                                        &env->active_fpu.fp_status), 0))
   2181 FOP_CONDN_S(un,   (float32_unordered_quiet(fst1, fst0,
   2182                                        &env->active_fpu.fp_status)))
   2183 FOP_CONDN_S(eq,   (float32_eq_quiet(fst0, fst1,
   2184                                        &env->active_fpu.fp_status)))
   2185 FOP_CONDN_S(ueq,  (float32_unordered_quiet(fst1, fst0,
   2186                                        &env->active_fpu.fp_status)
   2187                    || float32_eq_quiet(fst0, fst1,
   2188                                        &env->active_fpu.fp_status)))
   2189 FOP_CONDN_S(lt,   (float32_lt_quiet(fst0, fst1,
   2190                                        &env->active_fpu.fp_status)))
   2191 FOP_CONDN_S(ult,  (float32_unordered_quiet(fst1, fst0,
   2192                                        &env->active_fpu.fp_status)
   2193                    || float32_lt_quiet(fst0, fst1,
   2194                                        &env->active_fpu.fp_status)))
   2195 FOP_CONDN_S(le,   (float32_le_quiet(fst0, fst1,
   2196                                        &env->active_fpu.fp_status)))
   2197 FOP_CONDN_S(ule,  (float32_unordered_quiet(fst1, fst0,
   2198                                        &env->active_fpu.fp_status)
   2199                    || float32_le_quiet(fst0, fst1,
   2200                                        &env->active_fpu.fp_status)))
   2201 /*
   2202  * NOTE: the comma operator will make "cond" to eval to false,
   2203  * but float32_unordered() is still called.
   2204  */
   2205 FOP_CONDN_S(saf,  (float32_unordered(fst1, fst0,
   2206                                        &env->active_fpu.fp_status), 0))
   2207 FOP_CONDN_S(sun,  (float32_unordered(fst1, fst0,
   2208                                        &env->active_fpu.fp_status)))
   2209 FOP_CONDN_S(seq,  (float32_eq(fst0, fst1,
   2210                                        &env->active_fpu.fp_status)))
   2211 FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
   2212                                        &env->active_fpu.fp_status)
   2213                    || float32_eq(fst0, fst1,
   2214                                        &env->active_fpu.fp_status)))
   2215 FOP_CONDN_S(slt,  (float32_lt(fst0, fst1,
   2216                                        &env->active_fpu.fp_status)))
   2217 FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
   2218                                        &env->active_fpu.fp_status)
   2219                    || float32_lt(fst0, fst1,
   2220                                        &env->active_fpu.fp_status)))
   2221 FOP_CONDN_S(sle,  (float32_le(fst0, fst1,
   2222                                        &env->active_fpu.fp_status)))
   2223 FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
   2224                                        &env->active_fpu.fp_status)
   2225                    || float32_le(fst0, fst1,
   2226                                        &env->active_fpu.fp_status)))
   2227 FOP_CONDN_S(or,   (float32_le_quiet(fst1, fst0,
   2228                                        &env->active_fpu.fp_status)
   2229                    || float32_le_quiet(fst0, fst1,
   2230                                        &env->active_fpu.fp_status)))
   2231 FOP_CONDN_S(une,  (float32_unordered_quiet(fst1, fst0,
   2232                                        &env->active_fpu.fp_status)
   2233                    || float32_lt_quiet(fst1, fst0,
   2234                                        &env->active_fpu.fp_status)
   2235                    || float32_lt_quiet(fst0, fst1,
   2236                                        &env->active_fpu.fp_status)))
   2237 FOP_CONDN_S(ne,   (float32_lt_quiet(fst1, fst0,
   2238                                        &env->active_fpu.fp_status)
   2239                    || float32_lt_quiet(fst0, fst1,
   2240                                        &env->active_fpu.fp_status)))
   2241 FOP_CONDN_S(sor,  (float32_le(fst1, fst0,
   2242                                        &env->active_fpu.fp_status)
   2243                    || float32_le(fst0, fst1,
   2244                                        &env->active_fpu.fp_status)))
   2245 FOP_CONDN_S(sune, (float32_unordered(fst1, fst0,
   2246                                        &env->active_fpu.fp_status)
   2247                    || float32_lt(fst1, fst0,
   2248                                        &env->active_fpu.fp_status)
   2249                    || float32_lt(fst0, fst1,
   2250                                        &env->active_fpu.fp_status)))
   2251 FOP_CONDN_S(sne,  (float32_lt(fst1, fst0,
   2252                                        &env->active_fpu.fp_status)
   2253                    || float32_lt(fst0, fst1,
   2254                                        &env->active_fpu.fp_status)))