cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

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
     41target_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
     89void 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
    181static 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
    204static 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  */
    235uint64_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
    242uint32_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
    249uint64_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
    258uint64_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
    267uint64_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
    276uint64_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
    289uint64_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
    302uint64_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
    313uint64_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
    338uint32_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
    347uint32_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
    356uint32_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
    365uint32_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
    374uint32_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
    383uint32_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
    396uint32_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
    409uint64_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
    425uint64_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
    441uint32_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
    457uint32_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
    473uint64_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
    487uint64_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
    500uint32_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
    513uint32_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
    526uint64_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
    541uint64_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
    556uint32_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
    571uint32_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
    586uint64_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
    601uint64_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
    616uint32_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
    631uint32_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
    646uint64_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
    661uint64_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
    676uint32_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
    691uint32_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
    706uint64_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
    724uint64_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
    742uint32_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
    760uint32_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
    778uint64_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
    793uint64_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
    808uint32_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
    823uint32_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
    838uint64_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
    855uint64_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
    872uint32_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
    889uint32_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
    906uint64_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
    923uint64_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
    940uint32_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
    957uint32_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
    976uint64_t helper_float_abs_d(uint64_t fdt0)
    977{
    978   return float64_abs(fdt0);
    979}
    980
    981uint32_t helper_float_abs_s(uint32_t fst0)
    982{
    983    return float32_abs(fst0);
    984}
    985
    986uint64_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
    996uint64_t helper_float_chs_d(uint64_t fdt0)
    997{
    998   return float64_chs(fdt0);
    999}
   1000
   1001uint32_t helper_float_chs_s(uint32_t fst0)
   1002{
   1003    return float32_chs(fst0);
   1004}
   1005
   1006uint64_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 */
   1017uint64_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
   1026uint32_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
   1035uint64_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
   1045uint32_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
   1055uint64_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
   1064uint32_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
   1073uint64_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
   1085uint64_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
   1095uint32_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
   1105uint64_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
   1118uint64_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
   1127uint32_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
   1147uint64_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
   1176uint64_t helper_float_class_d(CPUMIPSState *env, uint64_t arg)
   1177{
   1178    return float_class_d(arg, &env->active_fpu.fp_status);
   1179}
   1180
   1181uint32_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
   1210uint32_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
   1217uint64_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
   1227uint32_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
   1237uint64_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
   1253uint64_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
   1263uint32_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
   1273uint64_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
   1289uint64_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
   1299uint32_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
   1309uint64_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
   1325uint64_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
   1335uint32_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
   1345uint64_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 */
   1363uint64_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
   1372uint32_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
   1381uint64_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
   1398uint64_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
   1408uint32_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
   1418uint64_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
   1437uint64_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
   1452uint64_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
   1468uint32_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
   1478uint64_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
   1488uint32_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
   1498uint64_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
   1508uint32_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
   1518uint64_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
   1528uint32_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
   1538uint64_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
   1551uint64_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
   1561uint32_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
   1571uint64_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
   1590uint64_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
   1600uint32_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
   1610uint64_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
   1629uint64_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
   1640uint32_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
   1651uint64_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
   1672uint64_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
   1683uint32_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
   1694uint64_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
   1716uint32_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
   1728uint64_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
   1740uint32_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
   1752uint64_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)                                   \
   1767void 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}                                                              \
   1778void 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 */
   1796FOP_COND_D(f,    (float64_unordered_quiet(fdt1, fdt0,
   1797                                       &env->active_fpu.fp_status), 0))
   1798FOP_COND_D(un,   float64_unordered_quiet(fdt1, fdt0,
   1799                                       &env->active_fpu.fp_status))
   1800FOP_COND_D(eq,   float64_eq_quiet(fdt0, fdt1,
   1801                                       &env->active_fpu.fp_status))
   1802FOP_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))
   1806FOP_COND_D(olt,  float64_lt_quiet(fdt0, fdt1,
   1807                                       &env->active_fpu.fp_status))
   1808FOP_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))
   1812FOP_COND_D(ole,  float64_le_quiet(fdt0, fdt1,
   1813                                       &env->active_fpu.fp_status))
   1814FOP_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 */
   1822FOP_COND_D(sf,   (float64_unordered(fdt1, fdt0,
   1823                                       &env->active_fpu.fp_status), 0))
   1824FOP_COND_D(ngle, float64_unordered(fdt1, fdt0,
   1825                                       &env->active_fpu.fp_status))
   1826FOP_COND_D(seq,  float64_eq(fdt0, fdt1,
   1827                                       &env->active_fpu.fp_status))
   1828FOP_COND_D(ngl,  float64_unordered(fdt1, fdt0,
   1829                                       &env->active_fpu.fp_status)
   1830                 || float64_eq(fdt0, fdt1,
   1831                                       &env->active_fpu.fp_status))
   1832FOP_COND_D(lt,   float64_lt(fdt0, fdt1,
   1833                                       &env->active_fpu.fp_status))
   1834FOP_COND_D(nge,  float64_unordered(fdt1, fdt0,
   1835                                       &env->active_fpu.fp_status)
   1836                 || float64_lt(fdt0, fdt1,
   1837                                       &env->active_fpu.fp_status))
   1838FOP_COND_D(le,   float64_le(fdt0, fdt1,
   1839                                       &env->active_fpu.fp_status))
   1840FOP_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)                                   \
   1846void 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}                                                              \
   1857void 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 */
   1875FOP_COND_S(f,    (float32_unordered_quiet(fst1, fst0,
   1876                                       &env->active_fpu.fp_status), 0))
   1877FOP_COND_S(un,   float32_unordered_quiet(fst1, fst0,
   1878                                       &env->active_fpu.fp_status))
   1879FOP_COND_S(eq,   float32_eq_quiet(fst0, fst1,
   1880                                       &env->active_fpu.fp_status))
   1881FOP_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))
   1885FOP_COND_S(olt,  float32_lt_quiet(fst0, fst1,
   1886                                       &env->active_fpu.fp_status))
   1887FOP_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))
   1891FOP_COND_S(ole,  float32_le_quiet(fst0, fst1,
   1892                                       &env->active_fpu.fp_status))
   1893FOP_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 */
   1901FOP_COND_S(sf,   (float32_unordered(fst1, fst0,
   1902                                       &env->active_fpu.fp_status), 0))
   1903FOP_COND_S(ngle, float32_unordered(fst1, fst0,
   1904                                       &env->active_fpu.fp_status))
   1905FOP_COND_S(seq,  float32_eq(fst0, fst1,
   1906                                       &env->active_fpu.fp_status))
   1907FOP_COND_S(ngl,  float32_unordered(fst1, fst0,
   1908                                       &env->active_fpu.fp_status)
   1909                 || float32_eq(fst0, fst1,
   1910                                       &env->active_fpu.fp_status))
   1911FOP_COND_S(lt,   float32_lt(fst0, fst1,
   1912                                       &env->active_fpu.fp_status))
   1913FOP_COND_S(nge,  float32_unordered(fst1, fst0,
   1914                                       &env->active_fpu.fp_status)
   1915                 || float32_lt(fst0, fst1,
   1916                                       &env->active_fpu.fp_status))
   1917FOP_COND_S(le,   float32_le(fst0, fst1,
   1918                                       &env->active_fpu.fp_status))
   1919FOP_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)                           \
   1925void 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}                                                               \
   1946void 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 */
   1972FOP_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))
   1976FOP_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))
   1980FOP_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))
   1984FOP_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))
   1992FOP_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))
   1996FOP_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))
   2004FOP_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))
   2008FOP_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 */
   2020FOP_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))
   2024FOP_COND_PS(ngle, float32_unordered(fst1, fst0,
   2025                                       &env->active_fpu.fp_status),
   2026                  float32_unordered(fsth1, fsth0,
   2027                                       &env->active_fpu.fp_status))
   2028FOP_COND_PS(seq,  float32_eq(fst0, fst1,
   2029                                       &env->active_fpu.fp_status),
   2030                  float32_eq(fsth0, fsth1,
   2031                                       &env->active_fpu.fp_status))
   2032FOP_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))
   2040FOP_COND_PS(lt,   float32_lt(fst0, fst1,
   2041                                       &env->active_fpu.fp_status),
   2042                  float32_lt(fsth0, fsth1,
   2043                                       &env->active_fpu.fp_status))
   2044FOP_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))
   2052FOP_COND_PS(le,   float32_le(fst0, fst1,
   2053                                       &env->active_fpu.fp_status),
   2054                  float32_le(fsth0, fsth1,
   2055                                       &env->active_fpu.fp_status))
   2056FOP_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)                                       \
   2067uint64_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 */
   2084FOP_CONDN_D(af,  (float64_unordered_quiet(fdt1, fdt0,
   2085                                       &env->active_fpu.fp_status), 0))
   2086FOP_CONDN_D(un,  (float64_unordered_quiet(fdt1, fdt0,
   2087                                       &env->active_fpu.fp_status)))
   2088FOP_CONDN_D(eq,  (float64_eq_quiet(fdt0, fdt1,
   2089                                       &env->active_fpu.fp_status)))
   2090FOP_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)))
   2094FOP_CONDN_D(lt,  (float64_lt_quiet(fdt0, fdt1,
   2095                                       &env->active_fpu.fp_status)))
   2096FOP_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)))
   2100FOP_CONDN_D(le,  (float64_le_quiet(fdt0, fdt1,
   2101                                       &env->active_fpu.fp_status)))
   2102FOP_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 */
   2110FOP_CONDN_D(saf,  (float64_unordered(fdt1, fdt0,
   2111                                       &env->active_fpu.fp_status), 0))
   2112FOP_CONDN_D(sun,  (float64_unordered(fdt1, fdt0,
   2113                                       &env->active_fpu.fp_status)))
   2114FOP_CONDN_D(seq,  (float64_eq(fdt0, fdt1,
   2115                                       &env->active_fpu.fp_status)))
   2116FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0,
   2117                                       &env->active_fpu.fp_status)
   2118                   || float64_eq(fdt0, fdt1,
   2119                                       &env->active_fpu.fp_status)))
   2120FOP_CONDN_D(slt,  (float64_lt(fdt0, fdt1,
   2121                                       &env->active_fpu.fp_status)))
   2122FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0,
   2123                                       &env->active_fpu.fp_status)
   2124                   || float64_lt(fdt0, fdt1,
   2125                                       &env->active_fpu.fp_status)))
   2126FOP_CONDN_D(sle,  (float64_le(fdt0, fdt1,
   2127                                       &env->active_fpu.fp_status)))
   2128FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0,
   2129                                       &env->active_fpu.fp_status)
   2130                   || float64_le(fdt0, fdt1,
   2131                                       &env->active_fpu.fp_status)))
   2132FOP_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)))
   2136FOP_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)))
   2142FOP_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)))
   2146FOP_CONDN_D(sor,  (float64_le(fdt1, fdt0,
   2147                                       &env->active_fpu.fp_status)
   2148                   || float64_le(fdt0, fdt1,
   2149                                       &env->active_fpu.fp_status)))
   2150FOP_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)))
   2156FOP_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)                                       \
   2162uint32_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 */
   2179FOP_CONDN_S(af,   (float32_unordered_quiet(fst1, fst0,
   2180                                       &env->active_fpu.fp_status), 0))
   2181FOP_CONDN_S(un,   (float32_unordered_quiet(fst1, fst0,
   2182                                       &env->active_fpu.fp_status)))
   2183FOP_CONDN_S(eq,   (float32_eq_quiet(fst0, fst1,
   2184                                       &env->active_fpu.fp_status)))
   2185FOP_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)))
   2189FOP_CONDN_S(lt,   (float32_lt_quiet(fst0, fst1,
   2190                                       &env->active_fpu.fp_status)))
   2191FOP_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)))
   2195FOP_CONDN_S(le,   (float32_le_quiet(fst0, fst1,
   2196                                       &env->active_fpu.fp_status)))
   2197FOP_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 */
   2205FOP_CONDN_S(saf,  (float32_unordered(fst1, fst0,
   2206                                       &env->active_fpu.fp_status), 0))
   2207FOP_CONDN_S(sun,  (float32_unordered(fst1, fst0,
   2208                                       &env->active_fpu.fp_status)))
   2209FOP_CONDN_S(seq,  (float32_eq(fst0, fst1,
   2210                                       &env->active_fpu.fp_status)))
   2211FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0,
   2212                                       &env->active_fpu.fp_status)
   2213                   || float32_eq(fst0, fst1,
   2214                                       &env->active_fpu.fp_status)))
   2215FOP_CONDN_S(slt,  (float32_lt(fst0, fst1,
   2216                                       &env->active_fpu.fp_status)))
   2217FOP_CONDN_S(sult, (float32_unordered(fst1, fst0,
   2218                                       &env->active_fpu.fp_status)
   2219                   || float32_lt(fst0, fst1,
   2220                                       &env->active_fpu.fp_status)))
   2221FOP_CONDN_S(sle,  (float32_le(fst0, fst1,
   2222                                       &env->active_fpu.fp_status)))
   2223FOP_CONDN_S(sule, (float32_unordered(fst1, fst0,
   2224                                       &env->active_fpu.fp_status)
   2225                   || float32_le(fst0, fst1,
   2226                                       &env->active_fpu.fp_status)))
   2227FOP_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)))
   2231FOP_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)))
   2237FOP_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)))
   2241FOP_CONDN_S(sor,  (float32_le(fst1, fst0,
   2242                                       &env->active_fpu.fp_status)
   2243                   || float32_le(fst0, fst1,
   2244                                       &env->active_fpu.fp_status)))
   2245FOP_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)))
   2251FOP_CONDN_S(sne,  (float32_lt(fst1, fst0,
   2252                                       &env->active_fpu.fp_status)
   2253                   || float32_lt(fst0, fst1,
   2254                                       &env->active_fpu.fp_status)))