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