qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

target/mips: Separate FPU-related helpers into their own file

For clarity and easier maintenence, create target/mips/fpu_helper.c, and
move all FPU-related content form target/mips/op_helper.c to that file.

Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com>
Reviewed-by: Aleksandar Rikalo <aleksandar.rikalo@rt-rk.com>
Message-Id: <1580745443-24650-3-git-send-email-aleksandar.markovic@rt-rk.com>

+1912 -1878
+1 -1
target/mips/Makefile.objs
··· 1 1 obj-y += translate.o cpu.o gdbstub.o helper.o 2 - obj-y += op_helper.o cp0_helper.o 2 + obj-y += op_helper.o cp0_helper.o fpu_helper.o 3 3 obj-y += dsp_helper.o lmi_helper.o msa_helper.o 4 4 obj-$(CONFIG_SOFTMMU) += mips-semi.o 5 5 obj-$(CONFIG_SOFTMMU) += machine.o cp0_timer.o
+1911
target/mips/fpu_helper.c
··· 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 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 */ 45 + unsigned int ieee_rm[] = { 46 + float_round_nearest_even, 47 + float_round_to_zero, 48 + float_round_up, 49 + float_round_down 50 + }; 51 + 52 + target_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 + 100 + void 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 + 192 + int ieee_ex_to_mips(int xcpt) 193 + { 194 + int ret = 0; 195 + if (xcpt) { 196 + if (xcpt & float_flag_invalid) { 197 + ret |= FP_INVALID; 198 + } 199 + if (xcpt & float_flag_overflow) { 200 + ret |= FP_OVERFLOW; 201 + } 202 + if (xcpt & float_flag_underflow) { 203 + ret |= FP_UNDERFLOW; 204 + } 205 + if (xcpt & float_flag_divbyzero) { 206 + ret |= FP_DIV0; 207 + } 208 + if (xcpt & float_flag_inexact) { 209 + ret |= FP_INEXACT; 210 + } 211 + } 212 + return ret; 213 + } 214 + 215 + static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc) 216 + { 217 + int tmp = ieee_ex_to_mips(get_float_exception_flags( 218 + &env->active_fpu.fp_status)); 219 + 220 + SET_FP_CAUSE(env->active_fpu.fcr31, tmp); 221 + 222 + if (tmp) { 223 + set_float_exception_flags(0, &env->active_fpu.fp_status); 224 + 225 + if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp) { 226 + do_raise_exception(env, EXCP_FPE, pc); 227 + } else { 228 + UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp); 229 + } 230 + } 231 + } 232 + 233 + /* 234 + * Float support. 235 + * Single precition routines have a "s" suffix, double precision a 236 + * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps", 237 + * paired single lower "pl", paired single upper "pu". 238 + */ 239 + 240 + /* unary operations, modifying fp status */ 241 + uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0) 242 + { 243 + fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status); 244 + update_fcr31(env, GETPC()); 245 + return fdt0; 246 + } 247 + 248 + uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0) 249 + { 250 + fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status); 251 + update_fcr31(env, GETPC()); 252 + return fst0; 253 + } 254 + 255 + uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0) 256 + { 257 + uint64_t fdt2; 258 + 259 + fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status); 260 + update_fcr31(env, GETPC()); 261 + return fdt2; 262 + } 263 + 264 + uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0) 265 + { 266 + uint64_t fdt2; 267 + 268 + fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status); 269 + update_fcr31(env, GETPC()); 270 + return fdt2; 271 + } 272 + 273 + uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0) 274 + { 275 + uint64_t fdt2; 276 + 277 + fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status); 278 + update_fcr31(env, GETPC()); 279 + return fdt2; 280 + } 281 + 282 + uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0) 283 + { 284 + uint64_t dt2; 285 + 286 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 287 + if (get_float_exception_flags(&env->active_fpu.fp_status) 288 + & (float_flag_invalid | float_flag_overflow)) { 289 + dt2 = FP_TO_INT64_OVERFLOW; 290 + } 291 + update_fcr31(env, GETPC()); 292 + return dt2; 293 + } 294 + 295 + uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0) 296 + { 297 + uint64_t dt2; 298 + 299 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 300 + if (get_float_exception_flags(&env->active_fpu.fp_status) 301 + & (float_flag_invalid | float_flag_overflow)) { 302 + dt2 = FP_TO_INT64_OVERFLOW; 303 + } 304 + update_fcr31(env, GETPC()); 305 + return dt2; 306 + } 307 + 308 + uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0) 309 + { 310 + uint32_t fst2; 311 + uint32_t fsth2; 312 + 313 + fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status); 314 + fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status); 315 + update_fcr31(env, GETPC()); 316 + return ((uint64_t)fsth2 << 32) | fst2; 317 + } 318 + 319 + uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0) 320 + { 321 + uint32_t wt2; 322 + uint32_t wth2; 323 + int excp, excph; 324 + 325 + wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status); 326 + excp = get_float_exception_flags(&env->active_fpu.fp_status); 327 + if (excp & (float_flag_overflow | float_flag_invalid)) { 328 + wt2 = FP_TO_INT32_OVERFLOW; 329 + } 330 + 331 + set_float_exception_flags(0, &env->active_fpu.fp_status); 332 + wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status); 333 + excph = get_float_exception_flags(&env->active_fpu.fp_status); 334 + if (excph & (float_flag_overflow | float_flag_invalid)) { 335 + wth2 = FP_TO_INT32_OVERFLOW; 336 + } 337 + 338 + set_float_exception_flags(excp | excph, &env->active_fpu.fp_status); 339 + update_fcr31(env, GETPC()); 340 + 341 + return ((uint64_t)wth2 << 32) | wt2; 342 + } 343 + 344 + uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0) 345 + { 346 + uint32_t fst2; 347 + 348 + fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status); 349 + update_fcr31(env, GETPC()); 350 + return fst2; 351 + } 352 + 353 + uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0) 354 + { 355 + uint32_t fst2; 356 + 357 + fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status); 358 + update_fcr31(env, GETPC()); 359 + return fst2; 360 + } 361 + 362 + uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0) 363 + { 364 + uint32_t fst2; 365 + 366 + fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status); 367 + update_fcr31(env, GETPC()); 368 + return fst2; 369 + } 370 + 371 + uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0) 372 + { 373 + uint32_t wt2; 374 + 375 + wt2 = wt0; 376 + update_fcr31(env, GETPC()); 377 + return wt2; 378 + } 379 + 380 + uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0) 381 + { 382 + uint32_t wt2; 383 + 384 + wt2 = wth0; 385 + update_fcr31(env, GETPC()); 386 + return wt2; 387 + } 388 + 389 + uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0) 390 + { 391 + uint32_t wt2; 392 + 393 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 394 + if (get_float_exception_flags(&env->active_fpu.fp_status) 395 + & (float_flag_invalid | float_flag_overflow)) { 396 + wt2 = FP_TO_INT32_OVERFLOW; 397 + } 398 + update_fcr31(env, GETPC()); 399 + return wt2; 400 + } 401 + 402 + uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0) 403 + { 404 + uint32_t wt2; 405 + 406 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 407 + if (get_float_exception_flags(&env->active_fpu.fp_status) 408 + & (float_flag_invalid | float_flag_overflow)) { 409 + wt2 = FP_TO_INT32_OVERFLOW; 410 + } 411 + update_fcr31(env, GETPC()); 412 + return wt2; 413 + } 414 + 415 + uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0) 416 + { 417 + uint64_t dt2; 418 + 419 + set_float_rounding_mode(float_round_nearest_even, 420 + &env->active_fpu.fp_status); 421 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 422 + restore_rounding_mode(env); 423 + if (get_float_exception_flags(&env->active_fpu.fp_status) 424 + & (float_flag_invalid | float_flag_overflow)) { 425 + dt2 = FP_TO_INT64_OVERFLOW; 426 + } 427 + update_fcr31(env, GETPC()); 428 + return dt2; 429 + } 430 + 431 + uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0) 432 + { 433 + uint64_t dt2; 434 + 435 + set_float_rounding_mode(float_round_nearest_even, 436 + &env->active_fpu.fp_status); 437 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 438 + restore_rounding_mode(env); 439 + if (get_float_exception_flags(&env->active_fpu.fp_status) 440 + & (float_flag_invalid | float_flag_overflow)) { 441 + dt2 = FP_TO_INT64_OVERFLOW; 442 + } 443 + update_fcr31(env, GETPC()); 444 + return dt2; 445 + } 446 + 447 + uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0) 448 + { 449 + uint32_t wt2; 450 + 451 + set_float_rounding_mode(float_round_nearest_even, 452 + &env->active_fpu.fp_status); 453 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 454 + restore_rounding_mode(env); 455 + if (get_float_exception_flags(&env->active_fpu.fp_status) 456 + & (float_flag_invalid | float_flag_overflow)) { 457 + wt2 = FP_TO_INT32_OVERFLOW; 458 + } 459 + update_fcr31(env, GETPC()); 460 + return wt2; 461 + } 462 + 463 + uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0) 464 + { 465 + uint32_t wt2; 466 + 467 + set_float_rounding_mode(float_round_nearest_even, 468 + &env->active_fpu.fp_status); 469 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 470 + restore_rounding_mode(env); 471 + if (get_float_exception_flags(&env->active_fpu.fp_status) 472 + & (float_flag_invalid | float_flag_overflow)) { 473 + wt2 = FP_TO_INT32_OVERFLOW; 474 + } 475 + update_fcr31(env, GETPC()); 476 + return wt2; 477 + } 478 + 479 + uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0) 480 + { 481 + uint64_t dt2; 482 + 483 + dt2 = float64_to_int64_round_to_zero(fdt0, 484 + &env->active_fpu.fp_status); 485 + if (get_float_exception_flags(&env->active_fpu.fp_status) 486 + & (float_flag_invalid | float_flag_overflow)) { 487 + dt2 = FP_TO_INT64_OVERFLOW; 488 + } 489 + update_fcr31(env, GETPC()); 490 + return dt2; 491 + } 492 + 493 + uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0) 494 + { 495 + uint64_t dt2; 496 + 497 + dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); 498 + if (get_float_exception_flags(&env->active_fpu.fp_status) 499 + & (float_flag_invalid | float_flag_overflow)) { 500 + dt2 = FP_TO_INT64_OVERFLOW; 501 + } 502 + update_fcr31(env, GETPC()); 503 + return dt2; 504 + } 505 + 506 + uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0) 507 + { 508 + uint32_t wt2; 509 + 510 + wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); 511 + if (get_float_exception_flags(&env->active_fpu.fp_status) 512 + & (float_flag_invalid | float_flag_overflow)) { 513 + wt2 = FP_TO_INT32_OVERFLOW; 514 + } 515 + update_fcr31(env, GETPC()); 516 + return wt2; 517 + } 518 + 519 + uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0) 520 + { 521 + uint32_t wt2; 522 + 523 + wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); 524 + if (get_float_exception_flags(&env->active_fpu.fp_status) 525 + & (float_flag_invalid | float_flag_overflow)) { 526 + wt2 = FP_TO_INT32_OVERFLOW; 527 + } 528 + update_fcr31(env, GETPC()); 529 + return wt2; 530 + } 531 + 532 + uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0) 533 + { 534 + uint64_t dt2; 535 + 536 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 537 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 538 + restore_rounding_mode(env); 539 + if (get_float_exception_flags(&env->active_fpu.fp_status) 540 + & (float_flag_invalid | float_flag_overflow)) { 541 + dt2 = FP_TO_INT64_OVERFLOW; 542 + } 543 + update_fcr31(env, GETPC()); 544 + return dt2; 545 + } 546 + 547 + uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0) 548 + { 549 + uint64_t dt2; 550 + 551 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 552 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 553 + restore_rounding_mode(env); 554 + if (get_float_exception_flags(&env->active_fpu.fp_status) 555 + & (float_flag_invalid | float_flag_overflow)) { 556 + dt2 = FP_TO_INT64_OVERFLOW; 557 + } 558 + update_fcr31(env, GETPC()); 559 + return dt2; 560 + } 561 + 562 + uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0) 563 + { 564 + uint32_t wt2; 565 + 566 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 567 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 568 + restore_rounding_mode(env); 569 + if (get_float_exception_flags(&env->active_fpu.fp_status) 570 + & (float_flag_invalid | float_flag_overflow)) { 571 + wt2 = FP_TO_INT32_OVERFLOW; 572 + } 573 + update_fcr31(env, GETPC()); 574 + return wt2; 575 + } 576 + 577 + uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0) 578 + { 579 + uint32_t wt2; 580 + 581 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 582 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 583 + restore_rounding_mode(env); 584 + if (get_float_exception_flags(&env->active_fpu.fp_status) 585 + & (float_flag_invalid | float_flag_overflow)) { 586 + wt2 = FP_TO_INT32_OVERFLOW; 587 + } 588 + update_fcr31(env, GETPC()); 589 + return wt2; 590 + } 591 + 592 + uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0) 593 + { 594 + uint64_t dt2; 595 + 596 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 597 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 598 + restore_rounding_mode(env); 599 + if (get_float_exception_flags(&env->active_fpu.fp_status) 600 + & (float_flag_invalid | float_flag_overflow)) { 601 + dt2 = FP_TO_INT64_OVERFLOW; 602 + } 603 + update_fcr31(env, GETPC()); 604 + return dt2; 605 + } 606 + 607 + uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0) 608 + { 609 + uint64_t dt2; 610 + 611 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 612 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 613 + restore_rounding_mode(env); 614 + if (get_float_exception_flags(&env->active_fpu.fp_status) 615 + & (float_flag_invalid | float_flag_overflow)) { 616 + dt2 = FP_TO_INT64_OVERFLOW; 617 + } 618 + update_fcr31(env, GETPC()); 619 + return dt2; 620 + } 621 + 622 + uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0) 623 + { 624 + uint32_t wt2; 625 + 626 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 627 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 628 + restore_rounding_mode(env); 629 + if (get_float_exception_flags(&env->active_fpu.fp_status) 630 + & (float_flag_invalid | float_flag_overflow)) { 631 + wt2 = FP_TO_INT32_OVERFLOW; 632 + } 633 + update_fcr31(env, GETPC()); 634 + return wt2; 635 + } 636 + 637 + uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0) 638 + { 639 + uint32_t wt2; 640 + 641 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 642 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 643 + restore_rounding_mode(env); 644 + if (get_float_exception_flags(&env->active_fpu.fp_status) 645 + & (float_flag_invalid | float_flag_overflow)) { 646 + wt2 = FP_TO_INT32_OVERFLOW; 647 + } 648 + update_fcr31(env, GETPC()); 649 + return wt2; 650 + } 651 + 652 + uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 653 + { 654 + uint64_t dt2; 655 + 656 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 657 + if (get_float_exception_flags(&env->active_fpu.fp_status) 658 + & float_flag_invalid) { 659 + if (float64_is_any_nan(fdt0)) { 660 + dt2 = 0; 661 + } 662 + } 663 + update_fcr31(env, GETPC()); 664 + return dt2; 665 + } 666 + 667 + uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0) 668 + { 669 + uint64_t dt2; 670 + 671 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 672 + if (get_float_exception_flags(&env->active_fpu.fp_status) 673 + & float_flag_invalid) { 674 + if (float32_is_any_nan(fst0)) { 675 + dt2 = 0; 676 + } 677 + } 678 + update_fcr31(env, GETPC()); 679 + return dt2; 680 + } 681 + 682 + uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 683 + { 684 + uint32_t wt2; 685 + 686 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 687 + if (get_float_exception_flags(&env->active_fpu.fp_status) 688 + & float_flag_invalid) { 689 + if (float64_is_any_nan(fdt0)) { 690 + wt2 = 0; 691 + } 692 + } 693 + update_fcr31(env, GETPC()); 694 + return wt2; 695 + } 696 + 697 + uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0) 698 + { 699 + uint32_t wt2; 700 + 701 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 702 + if (get_float_exception_flags(&env->active_fpu.fp_status) 703 + & float_flag_invalid) { 704 + if (float32_is_any_nan(fst0)) { 705 + wt2 = 0; 706 + } 707 + } 708 + update_fcr31(env, GETPC()); 709 + return wt2; 710 + } 711 + 712 + uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 713 + { 714 + uint64_t dt2; 715 + 716 + set_float_rounding_mode(float_round_nearest_even, 717 + &env->active_fpu.fp_status); 718 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 719 + restore_rounding_mode(env); 720 + if (get_float_exception_flags(&env->active_fpu.fp_status) 721 + & float_flag_invalid) { 722 + if (float64_is_any_nan(fdt0)) { 723 + dt2 = 0; 724 + } 725 + } 726 + update_fcr31(env, GETPC()); 727 + return dt2; 728 + } 729 + 730 + uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0) 731 + { 732 + uint64_t dt2; 733 + 734 + set_float_rounding_mode(float_round_nearest_even, 735 + &env->active_fpu.fp_status); 736 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 737 + restore_rounding_mode(env); 738 + if (get_float_exception_flags(&env->active_fpu.fp_status) 739 + & float_flag_invalid) { 740 + if (float32_is_any_nan(fst0)) { 741 + dt2 = 0; 742 + } 743 + } 744 + update_fcr31(env, GETPC()); 745 + return dt2; 746 + } 747 + 748 + uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 749 + { 750 + uint32_t wt2; 751 + 752 + set_float_rounding_mode(float_round_nearest_even, 753 + &env->active_fpu.fp_status); 754 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 755 + restore_rounding_mode(env); 756 + if (get_float_exception_flags(&env->active_fpu.fp_status) 757 + & float_flag_invalid) { 758 + if (float64_is_any_nan(fdt0)) { 759 + wt2 = 0; 760 + } 761 + } 762 + update_fcr31(env, GETPC()); 763 + return wt2; 764 + } 765 + 766 + uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0) 767 + { 768 + uint32_t wt2; 769 + 770 + set_float_rounding_mode(float_round_nearest_even, 771 + &env->active_fpu.fp_status); 772 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 773 + restore_rounding_mode(env); 774 + if (get_float_exception_flags(&env->active_fpu.fp_status) 775 + & float_flag_invalid) { 776 + if (float32_is_any_nan(fst0)) { 777 + wt2 = 0; 778 + } 779 + } 780 + update_fcr31(env, GETPC()); 781 + return wt2; 782 + } 783 + 784 + uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 785 + { 786 + uint64_t dt2; 787 + 788 + dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status); 789 + if (get_float_exception_flags(&env->active_fpu.fp_status) 790 + & float_flag_invalid) { 791 + if (float64_is_any_nan(fdt0)) { 792 + dt2 = 0; 793 + } 794 + } 795 + update_fcr31(env, GETPC()); 796 + return dt2; 797 + } 798 + 799 + uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0) 800 + { 801 + uint64_t dt2; 802 + 803 + dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); 804 + if (get_float_exception_flags(&env->active_fpu.fp_status) 805 + & float_flag_invalid) { 806 + if (float32_is_any_nan(fst0)) { 807 + dt2 = 0; 808 + } 809 + } 810 + update_fcr31(env, GETPC()); 811 + return dt2; 812 + } 813 + 814 + uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 815 + { 816 + uint32_t wt2; 817 + 818 + wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); 819 + if (get_float_exception_flags(&env->active_fpu.fp_status) 820 + & float_flag_invalid) { 821 + if (float64_is_any_nan(fdt0)) { 822 + wt2 = 0; 823 + } 824 + } 825 + update_fcr31(env, GETPC()); 826 + return wt2; 827 + } 828 + 829 + uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0) 830 + { 831 + uint32_t wt2; 832 + 833 + wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); 834 + if (get_float_exception_flags(&env->active_fpu.fp_status) 835 + & float_flag_invalid) { 836 + if (float32_is_any_nan(fst0)) { 837 + wt2 = 0; 838 + } 839 + } 840 + update_fcr31(env, GETPC()); 841 + return wt2; 842 + } 843 + 844 + uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 845 + { 846 + uint64_t dt2; 847 + 848 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 849 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 850 + restore_rounding_mode(env); 851 + if (get_float_exception_flags(&env->active_fpu.fp_status) 852 + & float_flag_invalid) { 853 + if (float64_is_any_nan(fdt0)) { 854 + dt2 = 0; 855 + } 856 + } 857 + update_fcr31(env, GETPC()); 858 + return dt2; 859 + } 860 + 861 + uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0) 862 + { 863 + uint64_t dt2; 864 + 865 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 866 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 867 + restore_rounding_mode(env); 868 + if (get_float_exception_flags(&env->active_fpu.fp_status) 869 + & float_flag_invalid) { 870 + if (float32_is_any_nan(fst0)) { 871 + dt2 = 0; 872 + } 873 + } 874 + update_fcr31(env, GETPC()); 875 + return dt2; 876 + } 877 + 878 + uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 879 + { 880 + uint32_t wt2; 881 + 882 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 883 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 884 + restore_rounding_mode(env); 885 + if (get_float_exception_flags(&env->active_fpu.fp_status) 886 + & float_flag_invalid) { 887 + if (float64_is_any_nan(fdt0)) { 888 + wt2 = 0; 889 + } 890 + } 891 + update_fcr31(env, GETPC()); 892 + return wt2; 893 + } 894 + 895 + uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0) 896 + { 897 + uint32_t wt2; 898 + 899 + set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 900 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 901 + restore_rounding_mode(env); 902 + if (get_float_exception_flags(&env->active_fpu.fp_status) 903 + & float_flag_invalid) { 904 + if (float32_is_any_nan(fst0)) { 905 + wt2 = 0; 906 + } 907 + } 908 + update_fcr31(env, GETPC()); 909 + return wt2; 910 + } 911 + 912 + uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 913 + { 914 + uint64_t dt2; 915 + 916 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 917 + dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 918 + restore_rounding_mode(env); 919 + if (get_float_exception_flags(&env->active_fpu.fp_status) 920 + & float_flag_invalid) { 921 + if (float64_is_any_nan(fdt0)) { 922 + dt2 = 0; 923 + } 924 + } 925 + update_fcr31(env, GETPC()); 926 + return dt2; 927 + } 928 + 929 + uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0) 930 + { 931 + uint64_t dt2; 932 + 933 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 934 + dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 935 + restore_rounding_mode(env); 936 + if (get_float_exception_flags(&env->active_fpu.fp_status) 937 + & float_flag_invalid) { 938 + if (float32_is_any_nan(fst0)) { 939 + dt2 = 0; 940 + } 941 + } 942 + update_fcr31(env, GETPC()); 943 + return dt2; 944 + } 945 + 946 + uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 947 + { 948 + uint32_t wt2; 949 + 950 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 951 + wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 952 + restore_rounding_mode(env); 953 + if (get_float_exception_flags(&env->active_fpu.fp_status) 954 + & float_flag_invalid) { 955 + if (float64_is_any_nan(fdt0)) { 956 + wt2 = 0; 957 + } 958 + } 959 + update_fcr31(env, GETPC()); 960 + return wt2; 961 + } 962 + 963 + uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0) 964 + { 965 + uint32_t wt2; 966 + 967 + set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 968 + wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 969 + restore_rounding_mode(env); 970 + if (get_float_exception_flags(&env->active_fpu.fp_status) 971 + & float_flag_invalid) { 972 + if (float32_is_any_nan(fst0)) { 973 + wt2 = 0; 974 + } 975 + } 976 + update_fcr31(env, GETPC()); 977 + return wt2; 978 + } 979 + 980 + /* unary operations, not modifying fp status */ 981 + #define FLOAT_UNOP(name) \ 982 + uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \ 983 + { \ 984 + return float64_ ## name(fdt0); \ 985 + } \ 986 + uint32_t helper_float_ ## name ## _s(uint32_t fst0) \ 987 + { \ 988 + return float32_ ## name(fst0); \ 989 + } \ 990 + uint64_t helper_float_ ## name ## _ps(uint64_t fdt0) \ 991 + { \ 992 + uint32_t wt0; \ 993 + uint32_t wth0; \ 994 + \ 995 + wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF); \ 996 + wth0 = float32_ ## name(fdt0 >> 32); \ 997 + return ((uint64_t)wth0 << 32) | wt0; \ 998 + } 999 + FLOAT_UNOP(abs) 1000 + FLOAT_UNOP(chs) 1001 + #undef FLOAT_UNOP 1002 + 1003 + /* MIPS specific unary operations */ 1004 + uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0) 1005 + { 1006 + uint64_t fdt2; 1007 + 1008 + fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); 1009 + update_fcr31(env, GETPC()); 1010 + return fdt2; 1011 + } 1012 + 1013 + uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0) 1014 + { 1015 + uint32_t fst2; 1016 + 1017 + fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); 1018 + update_fcr31(env, GETPC()); 1019 + return fst2; 1020 + } 1021 + 1022 + uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0) 1023 + { 1024 + uint64_t fdt2; 1025 + 1026 + fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); 1027 + fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); 1028 + update_fcr31(env, GETPC()); 1029 + return fdt2; 1030 + } 1031 + 1032 + uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0) 1033 + { 1034 + uint32_t fst2; 1035 + 1036 + fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); 1037 + fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); 1038 + update_fcr31(env, GETPC()); 1039 + return fst2; 1040 + } 1041 + 1042 + uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0) 1043 + { 1044 + uint64_t fdt2; 1045 + 1046 + fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); 1047 + update_fcr31(env, GETPC()); 1048 + return fdt2; 1049 + } 1050 + 1051 + uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0) 1052 + { 1053 + uint32_t fst2; 1054 + 1055 + fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); 1056 + update_fcr31(env, GETPC()); 1057 + return fst2; 1058 + } 1059 + 1060 + uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0) 1061 + { 1062 + uint32_t fst2; 1063 + uint32_t fsth2; 1064 + 1065 + fst2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF, 1066 + &env->active_fpu.fp_status); 1067 + fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status); 1068 + update_fcr31(env, GETPC()); 1069 + return ((uint64_t)fsth2 << 32) | fst2; 1070 + } 1071 + 1072 + uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0) 1073 + { 1074 + uint64_t fdt2; 1075 + 1076 + fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); 1077 + fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); 1078 + update_fcr31(env, GETPC()); 1079 + return fdt2; 1080 + } 1081 + 1082 + uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0) 1083 + { 1084 + uint32_t fst2; 1085 + 1086 + fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); 1087 + fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); 1088 + update_fcr31(env, GETPC()); 1089 + return fst2; 1090 + } 1091 + 1092 + uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0) 1093 + { 1094 + uint32_t fst2; 1095 + uint32_t fsth2; 1096 + 1097 + fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status); 1098 + fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status); 1099 + fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); 1100 + fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status); 1101 + update_fcr31(env, GETPC()); 1102 + return ((uint64_t)fsth2 << 32) | fst2; 1103 + } 1104 + 1105 + #define FLOAT_RINT(name, bits) \ 1106 + uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 1107 + uint ## bits ## _t fs) \ 1108 + { \ 1109 + uint ## bits ## _t fdret; \ 1110 + \ 1111 + fdret = float ## bits ## _round_to_int(fs, &env->active_fpu.fp_status); \ 1112 + update_fcr31(env, GETPC()); \ 1113 + return fdret; \ 1114 + } 1115 + 1116 + FLOAT_RINT(rint_s, 32) 1117 + FLOAT_RINT(rint_d, 64) 1118 + #undef FLOAT_RINT 1119 + 1120 + #define FLOAT_CLASS_SIGNALING_NAN 0x001 1121 + #define FLOAT_CLASS_QUIET_NAN 0x002 1122 + #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004 1123 + #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008 1124 + #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010 1125 + #define FLOAT_CLASS_NEGATIVE_ZERO 0x020 1126 + #define FLOAT_CLASS_POSITIVE_INFINITY 0x040 1127 + #define FLOAT_CLASS_POSITIVE_NORMAL 0x080 1128 + #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100 1129 + #define FLOAT_CLASS_POSITIVE_ZERO 0x200 1130 + 1131 + #define FLOAT_CLASS(name, bits) \ 1132 + uint ## bits ## _t float_ ## name(uint ## bits ## _t arg, \ 1133 + float_status *status) \ 1134 + { \ 1135 + if (float ## bits ## _is_signaling_nan(arg, status)) { \ 1136 + return FLOAT_CLASS_SIGNALING_NAN; \ 1137 + } else if (float ## bits ## _is_quiet_nan(arg, status)) { \ 1138 + return FLOAT_CLASS_QUIET_NAN; \ 1139 + } else if (float ## bits ## _is_neg(arg)) { \ 1140 + if (float ## bits ## _is_infinity(arg)) { \ 1141 + return FLOAT_CLASS_NEGATIVE_INFINITY; \ 1142 + } else if (float ## bits ## _is_zero(arg)) { \ 1143 + return FLOAT_CLASS_NEGATIVE_ZERO; \ 1144 + } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ 1145 + return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \ 1146 + } else { \ 1147 + return FLOAT_CLASS_NEGATIVE_NORMAL; \ 1148 + } \ 1149 + } else { \ 1150 + if (float ## bits ## _is_infinity(arg)) { \ 1151 + return FLOAT_CLASS_POSITIVE_INFINITY; \ 1152 + } else if (float ## bits ## _is_zero(arg)) { \ 1153 + return FLOAT_CLASS_POSITIVE_ZERO; \ 1154 + } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ 1155 + return FLOAT_CLASS_POSITIVE_SUBNORMAL; \ 1156 + } else { \ 1157 + return FLOAT_CLASS_POSITIVE_NORMAL; \ 1158 + } \ 1159 + } \ 1160 + } \ 1161 + \ 1162 + uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 1163 + uint ## bits ## _t arg) \ 1164 + { \ 1165 + return float_ ## name(arg, &env->active_fpu.fp_status); \ 1166 + } 1167 + 1168 + FLOAT_CLASS(class_s, 32) 1169 + FLOAT_CLASS(class_d, 64) 1170 + #undef FLOAT_CLASS 1171 + 1172 + /* binary operations */ 1173 + #define FLOAT_BINOP(name) \ 1174 + uint64_t helper_float_ ## name ## _d(CPUMIPSState *env, \ 1175 + uint64_t fdt0, uint64_t fdt1) \ 1176 + { \ 1177 + uint64_t dt2; \ 1178 + \ 1179 + dt2 = float64_ ## name(fdt0, fdt1, &env->active_fpu.fp_status);\ 1180 + update_fcr31(env, GETPC()); \ 1181 + return dt2; \ 1182 + } \ 1183 + \ 1184 + uint32_t helper_float_ ## name ## _s(CPUMIPSState *env, \ 1185 + uint32_t fst0, uint32_t fst1) \ 1186 + { \ 1187 + uint32_t wt2; \ 1188 + \ 1189 + wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);\ 1190 + update_fcr31(env, GETPC()); \ 1191 + return wt2; \ 1192 + } \ 1193 + \ 1194 + uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \ 1195 + uint64_t fdt0, \ 1196 + uint64_t fdt1) \ 1197 + { \ 1198 + uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ 1199 + uint32_t fsth0 = fdt0 >> 32; \ 1200 + uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ 1201 + uint32_t fsth1 = fdt1 >> 32; \ 1202 + uint32_t wt2; \ 1203 + uint32_t wth2; \ 1204 + \ 1205 + wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status); \ 1206 + wth2 = float32_ ## name(fsth0, fsth1, &env->active_fpu.fp_status); \ 1207 + update_fcr31(env, GETPC()); \ 1208 + return ((uint64_t)wth2 << 32) | wt2; \ 1209 + } 1210 + 1211 + FLOAT_BINOP(add) 1212 + FLOAT_BINOP(sub) 1213 + FLOAT_BINOP(mul) 1214 + FLOAT_BINOP(div) 1215 + #undef FLOAT_BINOP 1216 + 1217 + /* MIPS specific binary operations */ 1218 + uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 1219 + { 1220 + fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status); 1221 + fdt2 = float64_chs(float64_sub(fdt2, float64_one, 1222 + &env->active_fpu.fp_status)); 1223 + update_fcr31(env, GETPC()); 1224 + return fdt2; 1225 + } 1226 + 1227 + uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2) 1228 + { 1229 + fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 1230 + fst2 = float32_chs(float32_sub(fst2, float32_one, 1231 + &env->active_fpu.fp_status)); 1232 + update_fcr31(env, GETPC()); 1233 + return fst2; 1234 + } 1235 + 1236 + uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 1237 + { 1238 + uint32_t fst0 = fdt0 & 0XFFFFFFFF; 1239 + uint32_t fsth0 = fdt0 >> 32; 1240 + uint32_t fst2 = fdt2 & 0XFFFFFFFF; 1241 + uint32_t fsth2 = fdt2 >> 32; 1242 + 1243 + fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 1244 + fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status); 1245 + fst2 = float32_chs(float32_sub(fst2, float32_one, 1246 + &env->active_fpu.fp_status)); 1247 + fsth2 = float32_chs(float32_sub(fsth2, float32_one, 1248 + &env->active_fpu.fp_status)); 1249 + update_fcr31(env, GETPC()); 1250 + return ((uint64_t)fsth2 << 32) | fst2; 1251 + } 1252 + 1253 + uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 1254 + { 1255 + fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status); 1256 + fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status); 1257 + fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, 1258 + &env->active_fpu.fp_status)); 1259 + update_fcr31(env, GETPC()); 1260 + return fdt2; 1261 + } 1262 + 1263 + uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2) 1264 + { 1265 + fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 1266 + fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status); 1267 + fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, 1268 + &env->active_fpu.fp_status)); 1269 + update_fcr31(env, GETPC()); 1270 + return fst2; 1271 + } 1272 + 1273 + uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 1274 + { 1275 + uint32_t fst0 = fdt0 & 0XFFFFFFFF; 1276 + uint32_t fsth0 = fdt0 >> 32; 1277 + uint32_t fst2 = fdt2 & 0XFFFFFFFF; 1278 + uint32_t fsth2 = fdt2 >> 32; 1279 + 1280 + fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 1281 + fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status); 1282 + fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status); 1283 + fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status); 1284 + fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, 1285 + &env->active_fpu.fp_status)); 1286 + fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, 1287 + &env->active_fpu.fp_status)); 1288 + update_fcr31(env, GETPC()); 1289 + return ((uint64_t)fsth2 << 32) | fst2; 1290 + } 1291 + 1292 + uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1) 1293 + { 1294 + uint32_t fst0 = fdt0 & 0XFFFFFFFF; 1295 + uint32_t fsth0 = fdt0 >> 32; 1296 + uint32_t fst1 = fdt1 & 0XFFFFFFFF; 1297 + uint32_t fsth1 = fdt1 >> 32; 1298 + uint32_t fst2; 1299 + uint32_t fsth2; 1300 + 1301 + fst2 = float32_add(fst0, fsth0, &env->active_fpu.fp_status); 1302 + fsth2 = float32_add(fst1, fsth1, &env->active_fpu.fp_status); 1303 + update_fcr31(env, GETPC()); 1304 + return ((uint64_t)fsth2 << 32) | fst2; 1305 + } 1306 + 1307 + uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1) 1308 + { 1309 + uint32_t fst0 = fdt0 & 0XFFFFFFFF; 1310 + uint32_t fsth0 = fdt0 >> 32; 1311 + uint32_t fst1 = fdt1 & 0XFFFFFFFF; 1312 + uint32_t fsth1 = fdt1 >> 32; 1313 + uint32_t fst2; 1314 + uint32_t fsth2; 1315 + 1316 + fst2 = float32_mul(fst0, fsth0, &env->active_fpu.fp_status); 1317 + fsth2 = float32_mul(fst1, fsth1, &env->active_fpu.fp_status); 1318 + update_fcr31(env, GETPC()); 1319 + return ((uint64_t)fsth2 << 32) | fst2; 1320 + } 1321 + 1322 + #define FLOAT_MINMAX(name, bits, minmaxfunc) \ 1323 + uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 1324 + uint ## bits ## _t fs, \ 1325 + uint ## bits ## _t ft) \ 1326 + { \ 1327 + uint ## bits ## _t fdret; \ 1328 + \ 1329 + fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \ 1330 + &env->active_fpu.fp_status); \ 1331 + update_fcr31(env, GETPC()); \ 1332 + return fdret; \ 1333 + } 1334 + 1335 + FLOAT_MINMAX(max_s, 32, maxnum) 1336 + FLOAT_MINMAX(max_d, 64, maxnum) 1337 + FLOAT_MINMAX(maxa_s, 32, maxnummag) 1338 + FLOAT_MINMAX(maxa_d, 64, maxnummag) 1339 + 1340 + FLOAT_MINMAX(min_s, 32, minnum) 1341 + FLOAT_MINMAX(min_d, 64, minnum) 1342 + FLOAT_MINMAX(mina_s, 32, minnummag) 1343 + FLOAT_MINMAX(mina_d, 64, minnummag) 1344 + #undef FLOAT_MINMAX 1345 + 1346 + /* ternary operations */ 1347 + #define UNFUSED_FMA(prefix, a, b, c, flags) \ 1348 + { \ 1349 + a = prefix##_mul(a, b, &env->active_fpu.fp_status); \ 1350 + if ((flags) & float_muladd_negate_c) { \ 1351 + a = prefix##_sub(a, c, &env->active_fpu.fp_status); \ 1352 + } else { \ 1353 + a = prefix##_add(a, c, &env->active_fpu.fp_status); \ 1354 + } \ 1355 + if ((flags) & float_muladd_negate_result) { \ 1356 + a = prefix##_chs(a); \ 1357 + } \ 1358 + } 1359 + 1360 + /* FMA based operations */ 1361 + #define FLOAT_FMA(name, type) \ 1362 + uint64_t helper_float_ ## name ## _d(CPUMIPSState *env, \ 1363 + uint64_t fdt0, uint64_t fdt1, \ 1364 + uint64_t fdt2) \ 1365 + { \ 1366 + UNFUSED_FMA(float64, fdt0, fdt1, fdt2, type); \ 1367 + update_fcr31(env, GETPC()); \ 1368 + return fdt0; \ 1369 + } \ 1370 + \ 1371 + uint32_t helper_float_ ## name ## _s(CPUMIPSState *env, \ 1372 + uint32_t fst0, uint32_t fst1, \ 1373 + uint32_t fst2) \ 1374 + { \ 1375 + UNFUSED_FMA(float32, fst0, fst1, fst2, type); \ 1376 + update_fcr31(env, GETPC()); \ 1377 + return fst0; \ 1378 + } \ 1379 + \ 1380 + uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \ 1381 + uint64_t fdt0, uint64_t fdt1, \ 1382 + uint64_t fdt2) \ 1383 + { \ 1384 + uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ 1385 + uint32_t fsth0 = fdt0 >> 32; \ 1386 + uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ 1387 + uint32_t fsth1 = fdt1 >> 32; \ 1388 + uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ 1389 + uint32_t fsth2 = fdt2 >> 32; \ 1390 + \ 1391 + UNFUSED_FMA(float32, fst0, fst1, fst2, type); \ 1392 + UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type); \ 1393 + update_fcr31(env, GETPC()); \ 1394 + return ((uint64_t)fsth0 << 32) | fst0; \ 1395 + } 1396 + FLOAT_FMA(madd, 0) 1397 + FLOAT_FMA(msub, float_muladd_negate_c) 1398 + FLOAT_FMA(nmadd, float_muladd_negate_result) 1399 + FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c) 1400 + #undef FLOAT_FMA 1401 + 1402 + #define FLOAT_FMADDSUB(name, bits, muladd_arg) \ 1403 + uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 1404 + uint ## bits ## _t fs, \ 1405 + uint ## bits ## _t ft, \ 1406 + uint ## bits ## _t fd) \ 1407 + { \ 1408 + uint ## bits ## _t fdret; \ 1409 + \ 1410 + fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \ 1411 + &env->active_fpu.fp_status); \ 1412 + update_fcr31(env, GETPC()); \ 1413 + return fdret; \ 1414 + } 1415 + 1416 + FLOAT_FMADDSUB(maddf_s, 32, 0) 1417 + FLOAT_FMADDSUB(maddf_d, 64, 0) 1418 + FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product) 1419 + FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product) 1420 + #undef FLOAT_FMADDSUB 1421 + 1422 + /* compare operations */ 1423 + #define FOP_COND_D(op, cond) \ 1424 + void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 1425 + uint64_t fdt1, int cc) \ 1426 + { \ 1427 + int c; \ 1428 + c = cond; \ 1429 + update_fcr31(env, GETPC()); \ 1430 + if (c) \ 1431 + SET_FP_COND(cc, env->active_fpu); \ 1432 + else \ 1433 + CLEAR_FP_COND(cc, env->active_fpu); \ 1434 + } \ 1435 + void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 1436 + uint64_t fdt1, int cc) \ 1437 + { \ 1438 + int c; \ 1439 + fdt0 = float64_abs(fdt0); \ 1440 + fdt1 = float64_abs(fdt1); \ 1441 + c = cond; \ 1442 + update_fcr31(env, GETPC()); \ 1443 + if (c) \ 1444 + SET_FP_COND(cc, env->active_fpu); \ 1445 + else \ 1446 + CLEAR_FP_COND(cc, env->active_fpu); \ 1447 + } 1448 + 1449 + /* 1450 + * NOTE: the comma operator will make "cond" to eval to false, 1451 + * but float64_unordered_quiet() is still called. 1452 + */ 1453 + FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0, 1454 + &env->active_fpu.fp_status), 0)) 1455 + FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0, 1456 + &env->active_fpu.fp_status)) 1457 + FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1, 1458 + &env->active_fpu.fp_status)) 1459 + FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, 1460 + &env->active_fpu.fp_status) 1461 + || float64_eq_quiet(fdt0, fdt1, 1462 + &env->active_fpu.fp_status)) 1463 + FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1, 1464 + &env->active_fpu.fp_status)) 1465 + FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, 1466 + &env->active_fpu.fp_status) 1467 + || float64_lt_quiet(fdt0, fdt1, 1468 + &env->active_fpu.fp_status)) 1469 + FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1, 1470 + &env->active_fpu.fp_status)) 1471 + FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, 1472 + &env->active_fpu.fp_status) 1473 + || float64_le_quiet(fdt0, fdt1, 1474 + &env->active_fpu.fp_status)) 1475 + /* 1476 + * NOTE: the comma operator will make "cond" to eval to false, 1477 + * but float64_unordered() is still called. 1478 + */ 1479 + FOP_COND_D(sf, (float64_unordered(fdt1, fdt0, 1480 + &env->active_fpu.fp_status), 0)) 1481 + FOP_COND_D(ngle, float64_unordered(fdt1, fdt0, 1482 + &env->active_fpu.fp_status)) 1483 + FOP_COND_D(seq, float64_eq(fdt0, fdt1, 1484 + &env->active_fpu.fp_status)) 1485 + FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, 1486 + &env->active_fpu.fp_status) 1487 + || float64_eq(fdt0, fdt1, 1488 + &env->active_fpu.fp_status)) 1489 + FOP_COND_D(lt, float64_lt(fdt0, fdt1, 1490 + &env->active_fpu.fp_status)) 1491 + FOP_COND_D(nge, float64_unordered(fdt1, fdt0, 1492 + &env->active_fpu.fp_status) 1493 + || float64_lt(fdt0, fdt1, 1494 + &env->active_fpu.fp_status)) 1495 + FOP_COND_D(le, float64_le(fdt0, fdt1, 1496 + &env->active_fpu.fp_status)) 1497 + FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, 1498 + &env->active_fpu.fp_status) 1499 + || float64_le(fdt0, fdt1, 1500 + &env->active_fpu.fp_status)) 1501 + 1502 + #define FOP_COND_S(op, cond) \ 1503 + void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \ 1504 + uint32_t fst1, int cc) \ 1505 + { \ 1506 + int c; \ 1507 + c = cond; \ 1508 + update_fcr31(env, GETPC()); \ 1509 + if (c) \ 1510 + SET_FP_COND(cc, env->active_fpu); \ 1511 + else \ 1512 + CLEAR_FP_COND(cc, env->active_fpu); \ 1513 + } \ 1514 + void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \ 1515 + uint32_t fst1, int cc) \ 1516 + { \ 1517 + int c; \ 1518 + fst0 = float32_abs(fst0); \ 1519 + fst1 = float32_abs(fst1); \ 1520 + c = cond; \ 1521 + update_fcr31(env, GETPC()); \ 1522 + if (c) \ 1523 + SET_FP_COND(cc, env->active_fpu); \ 1524 + else \ 1525 + CLEAR_FP_COND(cc, env->active_fpu); \ 1526 + } 1527 + 1528 + /* 1529 + * NOTE: the comma operator will make "cond" to eval to false, 1530 + * but float32_unordered_quiet() is still called. 1531 + */ 1532 + FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0, 1533 + &env->active_fpu.fp_status), 0)) 1534 + FOP_COND_S(un, float32_unordered_quiet(fst1, fst0, 1535 + &env->active_fpu.fp_status)) 1536 + FOP_COND_S(eq, float32_eq_quiet(fst0, fst1, 1537 + &env->active_fpu.fp_status)) 1538 + FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, 1539 + &env->active_fpu.fp_status) 1540 + || float32_eq_quiet(fst0, fst1, 1541 + &env->active_fpu.fp_status)) 1542 + FOP_COND_S(olt, float32_lt_quiet(fst0, fst1, 1543 + &env->active_fpu.fp_status)) 1544 + FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, 1545 + &env->active_fpu.fp_status) 1546 + || float32_lt_quiet(fst0, fst1, 1547 + &env->active_fpu.fp_status)) 1548 + FOP_COND_S(ole, float32_le_quiet(fst0, fst1, 1549 + &env->active_fpu.fp_status)) 1550 + FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, 1551 + &env->active_fpu.fp_status) 1552 + || float32_le_quiet(fst0, fst1, 1553 + &env->active_fpu.fp_status)) 1554 + /* 1555 + * NOTE: the comma operator will make "cond" to eval to false, 1556 + * but float32_unordered() is still called. 1557 + */ 1558 + FOP_COND_S(sf, (float32_unordered(fst1, fst0, 1559 + &env->active_fpu.fp_status), 0)) 1560 + FOP_COND_S(ngle, float32_unordered(fst1, fst0, 1561 + &env->active_fpu.fp_status)) 1562 + FOP_COND_S(seq, float32_eq(fst0, fst1, 1563 + &env->active_fpu.fp_status)) 1564 + FOP_COND_S(ngl, float32_unordered(fst1, fst0, 1565 + &env->active_fpu.fp_status) 1566 + || float32_eq(fst0, fst1, 1567 + &env->active_fpu.fp_status)) 1568 + FOP_COND_S(lt, float32_lt(fst0, fst1, 1569 + &env->active_fpu.fp_status)) 1570 + FOP_COND_S(nge, float32_unordered(fst1, fst0, 1571 + &env->active_fpu.fp_status) 1572 + || float32_lt(fst0, fst1, 1573 + &env->active_fpu.fp_status)) 1574 + FOP_COND_S(le, float32_le(fst0, fst1, 1575 + &env->active_fpu.fp_status)) 1576 + FOP_COND_S(ngt, float32_unordered(fst1, fst0, 1577 + &env->active_fpu.fp_status) 1578 + || float32_le(fst0, fst1, 1579 + &env->active_fpu.fp_status)) 1580 + 1581 + #define FOP_COND_PS(op, condl, condh) \ 1582 + void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 1583 + uint64_t fdt1, int cc) \ 1584 + { \ 1585 + uint32_t fst0, fsth0, fst1, fsth1; \ 1586 + int ch, cl; \ 1587 + fst0 = fdt0 & 0XFFFFFFFF; \ 1588 + fsth0 = fdt0 >> 32; \ 1589 + fst1 = fdt1 & 0XFFFFFFFF; \ 1590 + fsth1 = fdt1 >> 32; \ 1591 + cl = condl; \ 1592 + ch = condh; \ 1593 + update_fcr31(env, GETPC()); \ 1594 + if (cl) \ 1595 + SET_FP_COND(cc, env->active_fpu); \ 1596 + else \ 1597 + CLEAR_FP_COND(cc, env->active_fpu); \ 1598 + if (ch) \ 1599 + SET_FP_COND(cc + 1, env->active_fpu); \ 1600 + else \ 1601 + CLEAR_FP_COND(cc + 1, env->active_fpu); \ 1602 + } \ 1603 + void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 1604 + uint64_t fdt1, int cc) \ 1605 + { \ 1606 + uint32_t fst0, fsth0, fst1, fsth1; \ 1607 + int ch, cl; \ 1608 + fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ 1609 + fsth0 = float32_abs(fdt0 >> 32); \ 1610 + fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ 1611 + fsth1 = float32_abs(fdt1 >> 32); \ 1612 + cl = condl; \ 1613 + ch = condh; \ 1614 + update_fcr31(env, GETPC()); \ 1615 + if (cl) \ 1616 + SET_FP_COND(cc, env->active_fpu); \ 1617 + else \ 1618 + CLEAR_FP_COND(cc, env->active_fpu); \ 1619 + if (ch) \ 1620 + SET_FP_COND(cc + 1, env->active_fpu); \ 1621 + else \ 1622 + CLEAR_FP_COND(cc + 1, env->active_fpu); \ 1623 + } 1624 + 1625 + /* 1626 + * NOTE: the comma operator will make "cond" to eval to false, 1627 + * but float32_unordered_quiet() is still called. 1628 + */ 1629 + FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0, 1630 + &env->active_fpu.fp_status), 0), 1631 + (float32_unordered_quiet(fsth1, fsth0, 1632 + &env->active_fpu.fp_status), 0)) 1633 + FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0, 1634 + &env->active_fpu.fp_status), 1635 + float32_unordered_quiet(fsth1, fsth0, 1636 + &env->active_fpu.fp_status)) 1637 + FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1, 1638 + &env->active_fpu.fp_status), 1639 + float32_eq_quiet(fsth0, fsth1, 1640 + &env->active_fpu.fp_status)) 1641 + FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, 1642 + &env->active_fpu.fp_status) 1643 + || float32_eq_quiet(fst0, fst1, 1644 + &env->active_fpu.fp_status), 1645 + float32_unordered_quiet(fsth1, fsth0, 1646 + &env->active_fpu.fp_status) 1647 + || float32_eq_quiet(fsth0, fsth1, 1648 + &env->active_fpu.fp_status)) 1649 + FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1, 1650 + &env->active_fpu.fp_status), 1651 + float32_lt_quiet(fsth0, fsth1, 1652 + &env->active_fpu.fp_status)) 1653 + FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, 1654 + &env->active_fpu.fp_status) 1655 + || float32_lt_quiet(fst0, fst1, 1656 + &env->active_fpu.fp_status), 1657 + float32_unordered_quiet(fsth1, fsth0, 1658 + &env->active_fpu.fp_status) 1659 + || float32_lt_quiet(fsth0, fsth1, 1660 + &env->active_fpu.fp_status)) 1661 + FOP_COND_PS(ole, float32_le_quiet(fst0, fst1, 1662 + &env->active_fpu.fp_status), 1663 + float32_le_quiet(fsth0, fsth1, 1664 + &env->active_fpu.fp_status)) 1665 + FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, 1666 + &env->active_fpu.fp_status) 1667 + || float32_le_quiet(fst0, fst1, 1668 + &env->active_fpu.fp_status), 1669 + float32_unordered_quiet(fsth1, fsth0, 1670 + &env->active_fpu.fp_status) 1671 + || float32_le_quiet(fsth0, fsth1, 1672 + &env->active_fpu.fp_status)) 1673 + /* 1674 + * NOTE: the comma operator will make "cond" to eval to false, 1675 + * but float32_unordered() is still called. 1676 + */ 1677 + FOP_COND_PS(sf, (float32_unordered(fst1, fst0, 1678 + &env->active_fpu.fp_status), 0), 1679 + (float32_unordered(fsth1, fsth0, 1680 + &env->active_fpu.fp_status), 0)) 1681 + FOP_COND_PS(ngle, float32_unordered(fst1, fst0, 1682 + &env->active_fpu.fp_status), 1683 + float32_unordered(fsth1, fsth0, 1684 + &env->active_fpu.fp_status)) 1685 + FOP_COND_PS(seq, float32_eq(fst0, fst1, 1686 + &env->active_fpu.fp_status), 1687 + float32_eq(fsth0, fsth1, 1688 + &env->active_fpu.fp_status)) 1689 + FOP_COND_PS(ngl, float32_unordered(fst1, fst0, 1690 + &env->active_fpu.fp_status) 1691 + || float32_eq(fst0, fst1, 1692 + &env->active_fpu.fp_status), 1693 + float32_unordered(fsth1, fsth0, 1694 + &env->active_fpu.fp_status) 1695 + || float32_eq(fsth0, fsth1, 1696 + &env->active_fpu.fp_status)) 1697 + FOP_COND_PS(lt, float32_lt(fst0, fst1, 1698 + &env->active_fpu.fp_status), 1699 + float32_lt(fsth0, fsth1, 1700 + &env->active_fpu.fp_status)) 1701 + FOP_COND_PS(nge, float32_unordered(fst1, fst0, 1702 + &env->active_fpu.fp_status) 1703 + || float32_lt(fst0, fst1, 1704 + &env->active_fpu.fp_status), 1705 + float32_unordered(fsth1, fsth0, 1706 + &env->active_fpu.fp_status) 1707 + || float32_lt(fsth0, fsth1, 1708 + &env->active_fpu.fp_status)) 1709 + FOP_COND_PS(le, float32_le(fst0, fst1, 1710 + &env->active_fpu.fp_status), 1711 + float32_le(fsth0, fsth1, 1712 + &env->active_fpu.fp_status)) 1713 + FOP_COND_PS(ngt, float32_unordered(fst1, fst0, 1714 + &env->active_fpu.fp_status) 1715 + || float32_le(fst0, fst1, 1716 + &env->active_fpu.fp_status), 1717 + float32_unordered(fsth1, fsth0, 1718 + &env->active_fpu.fp_status) 1719 + || float32_le(fsth0, fsth1, 1720 + &env->active_fpu.fp_status)) 1721 + 1722 + /* R6 compare operations */ 1723 + #define FOP_CONDN_D(op, cond) \ 1724 + uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 1725 + uint64_t fdt1) \ 1726 + { \ 1727 + uint64_t c; \ 1728 + c = cond; \ 1729 + update_fcr31(env, GETPC()); \ 1730 + if (c) { \ 1731 + return -1; \ 1732 + } else { \ 1733 + return 0; \ 1734 + } \ 1735 + } 1736 + 1737 + /* 1738 + * NOTE: the comma operator will make "cond" to eval to false, 1739 + * but float64_unordered_quiet() is still called. 1740 + */ 1741 + FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, 1742 + &env->active_fpu.fp_status), 0)) 1743 + FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, 1744 + &env->active_fpu.fp_status))) 1745 + FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, 1746 + &env->active_fpu.fp_status))) 1747 + FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, 1748 + &env->active_fpu.fp_status) 1749 + || float64_eq_quiet(fdt0, fdt1, 1750 + &env->active_fpu.fp_status))) 1751 + FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, 1752 + &env->active_fpu.fp_status))) 1753 + FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, 1754 + &env->active_fpu.fp_status) 1755 + || float64_lt_quiet(fdt0, fdt1, 1756 + &env->active_fpu.fp_status))) 1757 + FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, 1758 + &env->active_fpu.fp_status))) 1759 + FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, 1760 + &env->active_fpu.fp_status) 1761 + || float64_le_quiet(fdt0, fdt1, 1762 + &env->active_fpu.fp_status))) 1763 + /* 1764 + * NOTE: the comma operator will make "cond" to eval to false, 1765 + * but float64_unordered() is still called.\ 1766 + */ 1767 + FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, 1768 + &env->active_fpu.fp_status), 0)) 1769 + FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, 1770 + &env->active_fpu.fp_status))) 1771 + FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, 1772 + &env->active_fpu.fp_status))) 1773 + FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, 1774 + &env->active_fpu.fp_status) 1775 + || float64_eq(fdt0, fdt1, 1776 + &env->active_fpu.fp_status))) 1777 + FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, 1778 + &env->active_fpu.fp_status))) 1779 + FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, 1780 + &env->active_fpu.fp_status) 1781 + || float64_lt(fdt0, fdt1, 1782 + &env->active_fpu.fp_status))) 1783 + FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, 1784 + &env->active_fpu.fp_status))) 1785 + FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, 1786 + &env->active_fpu.fp_status) 1787 + || float64_le(fdt0, fdt1, 1788 + &env->active_fpu.fp_status))) 1789 + FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, 1790 + &env->active_fpu.fp_status) 1791 + || float64_le_quiet(fdt0, fdt1, 1792 + &env->active_fpu.fp_status))) 1793 + FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, 1794 + &env->active_fpu.fp_status) 1795 + || float64_lt_quiet(fdt1, fdt0, 1796 + &env->active_fpu.fp_status) 1797 + || float64_lt_quiet(fdt0, fdt1, 1798 + &env->active_fpu.fp_status))) 1799 + FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, 1800 + &env->active_fpu.fp_status) 1801 + || float64_lt_quiet(fdt0, fdt1, 1802 + &env->active_fpu.fp_status))) 1803 + FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, 1804 + &env->active_fpu.fp_status) 1805 + || float64_le(fdt0, fdt1, 1806 + &env->active_fpu.fp_status))) 1807 + FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, 1808 + &env->active_fpu.fp_status) 1809 + || float64_lt(fdt1, fdt0, 1810 + &env->active_fpu.fp_status) 1811 + || float64_lt(fdt0, fdt1, 1812 + &env->active_fpu.fp_status))) 1813 + FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, 1814 + &env->active_fpu.fp_status) 1815 + || float64_lt(fdt0, fdt1, 1816 + &env->active_fpu.fp_status))) 1817 + 1818 + #define FOP_CONDN_S(op, cond) \ 1819 + uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \ 1820 + uint32_t fst1) \ 1821 + { \ 1822 + uint64_t c; \ 1823 + c = cond; \ 1824 + update_fcr31(env, GETPC()); \ 1825 + if (c) { \ 1826 + return -1; \ 1827 + } else { \ 1828 + return 0; \ 1829 + } \ 1830 + } 1831 + 1832 + /* 1833 + * NOTE: the comma operator will make "cond" to eval to false, 1834 + * but float32_unordered_quiet() is still called. 1835 + */ 1836 + FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, 1837 + &env->active_fpu.fp_status), 0)) 1838 + FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, 1839 + &env->active_fpu.fp_status))) 1840 + FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, 1841 + &env->active_fpu.fp_status))) 1842 + FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, 1843 + &env->active_fpu.fp_status) 1844 + || float32_eq_quiet(fst0, fst1, 1845 + &env->active_fpu.fp_status))) 1846 + FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, 1847 + &env->active_fpu.fp_status))) 1848 + FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, 1849 + &env->active_fpu.fp_status) 1850 + || float32_lt_quiet(fst0, fst1, 1851 + &env->active_fpu.fp_status))) 1852 + FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, 1853 + &env->active_fpu.fp_status))) 1854 + FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, 1855 + &env->active_fpu.fp_status) 1856 + || float32_le_quiet(fst0, fst1, 1857 + &env->active_fpu.fp_status))) 1858 + /* 1859 + * NOTE: the comma operator will make "cond" to eval to false, 1860 + * but float32_unordered() is still called. 1861 + */ 1862 + FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, 1863 + &env->active_fpu.fp_status), 0)) 1864 + FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, 1865 + &env->active_fpu.fp_status))) 1866 + FOP_CONDN_S(seq, (float32_eq(fst0, fst1, 1867 + &env->active_fpu.fp_status))) 1868 + FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, 1869 + &env->active_fpu.fp_status) 1870 + || float32_eq(fst0, fst1, 1871 + &env->active_fpu.fp_status))) 1872 + FOP_CONDN_S(slt, (float32_lt(fst0, fst1, 1873 + &env->active_fpu.fp_status))) 1874 + FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, 1875 + &env->active_fpu.fp_status) 1876 + || float32_lt(fst0, fst1, 1877 + &env->active_fpu.fp_status))) 1878 + FOP_CONDN_S(sle, (float32_le(fst0, fst1, 1879 + &env->active_fpu.fp_status))) 1880 + FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, 1881 + &env->active_fpu.fp_status) 1882 + || float32_le(fst0, fst1, 1883 + &env->active_fpu.fp_status))) 1884 + FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, 1885 + &env->active_fpu.fp_status) 1886 + || float32_le_quiet(fst0, fst1, 1887 + &env->active_fpu.fp_status))) 1888 + FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, 1889 + &env->active_fpu.fp_status) 1890 + || float32_lt_quiet(fst1, fst0, 1891 + &env->active_fpu.fp_status) 1892 + || float32_lt_quiet(fst0, fst1, 1893 + &env->active_fpu.fp_status))) 1894 + FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, 1895 + &env->active_fpu.fp_status) 1896 + || float32_lt_quiet(fst0, fst1, 1897 + &env->active_fpu.fp_status))) 1898 + FOP_CONDN_S(sor, (float32_le(fst1, fst0, 1899 + &env->active_fpu.fp_status) 1900 + || float32_le(fst0, fst1, 1901 + &env->active_fpu.fp_status))) 1902 + FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, 1903 + &env->active_fpu.fp_status) 1904 + || float32_lt(fst1, fst0, 1905 + &env->active_fpu.fp_status) 1906 + || float32_lt(fst0, fst1, 1907 + &env->active_fpu.fp_status))) 1908 + FOP_CONDN_S(sne, (float32_lt(fst1, fst0, 1909 + &env->active_fpu.fp_status) 1910 + || float32_lt(fst0, fst1, 1911 + &env->active_fpu.fp_status)))
-1877
target/mips/op_helper.c
··· 28 28 #include "exec/cpu_ldst.h" 29 29 #include "exec/memop.h" 30 30 #include "sysemu/kvm.h" 31 - #include "fpu/softfloat.h" 32 31 33 32 34 33 /*****************************************************************************/ ··· 1178 1177 } 1179 1178 #endif /* !CONFIG_USER_ONLY */ 1180 1179 1181 - /* Complex FPU operations which may need stack space. */ 1182 - 1183 - #define FLOAT_TWO32 make_float32(1 << 30) 1184 - #define FLOAT_TWO64 make_float64(1ULL << 62) 1185 - 1186 - #define FP_TO_INT32_OVERFLOW 0x7fffffff 1187 - #define FP_TO_INT64_OVERFLOW 0x7fffffffffffffffULL 1188 - 1189 - /* convert MIPS rounding mode in FCR31 to IEEE library */ 1190 - unsigned int ieee_rm[] = { 1191 - float_round_nearest_even, 1192 - float_round_to_zero, 1193 - float_round_up, 1194 - float_round_down 1195 - }; 1196 - 1197 - target_ulong helper_cfc1(CPUMIPSState *env, uint32_t reg) 1198 - { 1199 - target_ulong arg1 = 0; 1200 - 1201 - switch (reg) { 1202 - case 0: 1203 - arg1 = (int32_t)env->active_fpu.fcr0; 1204 - break; 1205 - case 1: 1206 - /* UFR Support - Read Status FR */ 1207 - if (env->active_fpu.fcr0 & (1 << FCR0_UFRP)) { 1208 - if (env->CP0_Config5 & (1 << CP0C5_UFR)) { 1209 - arg1 = (int32_t) 1210 - ((env->CP0_Status & (1 << CP0St_FR)) >> CP0St_FR); 1211 - } else { 1212 - do_raise_exception(env, EXCP_RI, GETPC()); 1213 - } 1214 - } 1215 - break; 1216 - case 5: 1217 - /* FRE Support - read Config5.FRE bit */ 1218 - if (env->active_fpu.fcr0 & (1 << FCR0_FREP)) { 1219 - if (env->CP0_Config5 & (1 << CP0C5_UFE)) { 1220 - arg1 = (env->CP0_Config5 >> CP0C5_FRE) & 1; 1221 - } else { 1222 - helper_raise_exception(env, EXCP_RI); 1223 - } 1224 - } 1225 - break; 1226 - case 25: 1227 - arg1 = ((env->active_fpu.fcr31 >> 24) & 0xfe) | 1228 - ((env->active_fpu.fcr31 >> 23) & 0x1); 1229 - break; 1230 - case 26: 1231 - arg1 = env->active_fpu.fcr31 & 0x0003f07c; 1232 - break; 1233 - case 28: 1234 - arg1 = (env->active_fpu.fcr31 & 0x00000f83) | 1235 - ((env->active_fpu.fcr31 >> 22) & 0x4); 1236 - break; 1237 - default: 1238 - arg1 = (int32_t)env->active_fpu.fcr31; 1239 - break; 1240 - } 1241 - 1242 - return arg1; 1243 - } 1244 - 1245 - void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t fs, uint32_t rt) 1246 - { 1247 - switch (fs) { 1248 - case 1: 1249 - /* UFR Alias - Reset Status FR */ 1250 - if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) { 1251 - return; 1252 - } 1253 - if (env->CP0_Config5 & (1 << CP0C5_UFR)) { 1254 - env->CP0_Status &= ~(1 << CP0St_FR); 1255 - compute_hflags(env); 1256 - } else { 1257 - do_raise_exception(env, EXCP_RI, GETPC()); 1258 - } 1259 - break; 1260 - case 4: 1261 - /* UNFR Alias - Set Status FR */ 1262 - if (!((env->active_fpu.fcr0 & (1 << FCR0_UFRP)) && (rt == 0))) { 1263 - return; 1264 - } 1265 - if (env->CP0_Config5 & (1 << CP0C5_UFR)) { 1266 - env->CP0_Status |= (1 << CP0St_FR); 1267 - compute_hflags(env); 1268 - } else { 1269 - do_raise_exception(env, EXCP_RI, GETPC()); 1270 - } 1271 - break; 1272 - case 5: 1273 - /* FRE Support - clear Config5.FRE bit */ 1274 - if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) { 1275 - return; 1276 - } 1277 - if (env->CP0_Config5 & (1 << CP0C5_UFE)) { 1278 - env->CP0_Config5 &= ~(1 << CP0C5_FRE); 1279 - compute_hflags(env); 1280 - } else { 1281 - helper_raise_exception(env, EXCP_RI); 1282 - } 1283 - break; 1284 - case 6: 1285 - /* FRE Support - set Config5.FRE bit */ 1286 - if (!((env->active_fpu.fcr0 & (1 << FCR0_FREP)) && (rt == 0))) { 1287 - return; 1288 - } 1289 - if (env->CP0_Config5 & (1 << CP0C5_UFE)) { 1290 - env->CP0_Config5 |= (1 << CP0C5_FRE); 1291 - compute_hflags(env); 1292 - } else { 1293 - helper_raise_exception(env, EXCP_RI); 1294 - } 1295 - break; 1296 - case 25: 1297 - if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) { 1298 - return; 1299 - } 1300 - env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) | 1301 - ((arg1 & 0xfe) << 24) | 1302 - ((arg1 & 0x1) << 23); 1303 - break; 1304 - case 26: 1305 - if (arg1 & 0x007c0000) { 1306 - return; 1307 - } 1308 - env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) | 1309 - (arg1 & 0x0003f07c); 1310 - break; 1311 - case 28: 1312 - if (arg1 & 0x007c0000) { 1313 - return; 1314 - } 1315 - env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) | 1316 - (arg1 & 0x00000f83) | 1317 - ((arg1 & 0x4) << 22); 1318 - break; 1319 - case 31: 1320 - env->active_fpu.fcr31 = (arg1 & env->active_fpu.fcr31_rw_bitmask) | 1321 - (env->active_fpu.fcr31 & ~(env->active_fpu.fcr31_rw_bitmask)); 1322 - break; 1323 - default: 1324 - if (env->insn_flags & ISA_MIPS32R6) { 1325 - do_raise_exception(env, EXCP_RI, GETPC()); 1326 - } 1327 - return; 1328 - } 1329 - restore_fp_status(env); 1330 - set_float_exception_flags(0, &env->active_fpu.fp_status); 1331 - if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & 1332 - GET_FP_CAUSE(env->active_fpu.fcr31)) { 1333 - do_raise_exception(env, EXCP_FPE, GETPC()); 1334 - } 1335 - } 1336 - 1337 - int ieee_ex_to_mips(int xcpt) 1338 - { 1339 - int ret = 0; 1340 - if (xcpt) { 1341 - if (xcpt & float_flag_invalid) { 1342 - ret |= FP_INVALID; 1343 - } 1344 - if (xcpt & float_flag_overflow) { 1345 - ret |= FP_OVERFLOW; 1346 - } 1347 - if (xcpt & float_flag_underflow) { 1348 - ret |= FP_UNDERFLOW; 1349 - } 1350 - if (xcpt & float_flag_divbyzero) { 1351 - ret |= FP_DIV0; 1352 - } 1353 - if (xcpt & float_flag_inexact) { 1354 - ret |= FP_INEXACT; 1355 - } 1356 - } 1357 - return ret; 1358 - } 1359 - 1360 - static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc) 1361 - { 1362 - int tmp = ieee_ex_to_mips(get_float_exception_flags( 1363 - &env->active_fpu.fp_status)); 1364 - 1365 - SET_FP_CAUSE(env->active_fpu.fcr31, tmp); 1366 - 1367 - if (tmp) { 1368 - set_float_exception_flags(0, &env->active_fpu.fp_status); 1369 - 1370 - if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp) { 1371 - do_raise_exception(env, EXCP_FPE, pc); 1372 - } else { 1373 - UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp); 1374 - } 1375 - } 1376 - } 1377 - 1378 - /* 1379 - * Float support. 1380 - * Single precition routines have a "s" suffix, double precision a 1381 - * "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps", 1382 - * paired single lower "pl", paired single upper "pu". 1383 - */ 1384 - 1385 - /* unary operations, modifying fp status */ 1386 - uint64_t helper_float_sqrt_d(CPUMIPSState *env, uint64_t fdt0) 1387 - { 1388 - fdt0 = float64_sqrt(fdt0, &env->active_fpu.fp_status); 1389 - update_fcr31(env, GETPC()); 1390 - return fdt0; 1391 - } 1392 - 1393 - uint32_t helper_float_sqrt_s(CPUMIPSState *env, uint32_t fst0) 1394 - { 1395 - fst0 = float32_sqrt(fst0, &env->active_fpu.fp_status); 1396 - update_fcr31(env, GETPC()); 1397 - return fst0; 1398 - } 1399 - 1400 - uint64_t helper_float_cvtd_s(CPUMIPSState *env, uint32_t fst0) 1401 - { 1402 - uint64_t fdt2; 1403 - 1404 - fdt2 = float32_to_float64(fst0, &env->active_fpu.fp_status); 1405 - update_fcr31(env, GETPC()); 1406 - return fdt2; 1407 - } 1408 - 1409 - uint64_t helper_float_cvtd_w(CPUMIPSState *env, uint32_t wt0) 1410 - { 1411 - uint64_t fdt2; 1412 - 1413 - fdt2 = int32_to_float64(wt0, &env->active_fpu.fp_status); 1414 - update_fcr31(env, GETPC()); 1415 - return fdt2; 1416 - } 1417 - 1418 - uint64_t helper_float_cvtd_l(CPUMIPSState *env, uint64_t dt0) 1419 - { 1420 - uint64_t fdt2; 1421 - 1422 - fdt2 = int64_to_float64(dt0, &env->active_fpu.fp_status); 1423 - update_fcr31(env, GETPC()); 1424 - return fdt2; 1425 - } 1426 - 1427 - uint64_t helper_float_cvt_l_d(CPUMIPSState *env, uint64_t fdt0) 1428 - { 1429 - uint64_t dt2; 1430 - 1431 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1432 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1433 - & (float_flag_invalid | float_flag_overflow)) { 1434 - dt2 = FP_TO_INT64_OVERFLOW; 1435 - } 1436 - update_fcr31(env, GETPC()); 1437 - return dt2; 1438 - } 1439 - 1440 - uint64_t helper_float_cvt_l_s(CPUMIPSState *env, uint32_t fst0) 1441 - { 1442 - uint64_t dt2; 1443 - 1444 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 1445 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1446 - & (float_flag_invalid | float_flag_overflow)) { 1447 - dt2 = FP_TO_INT64_OVERFLOW; 1448 - } 1449 - update_fcr31(env, GETPC()); 1450 - return dt2; 1451 - } 1452 - 1453 - uint64_t helper_float_cvtps_pw(CPUMIPSState *env, uint64_t dt0) 1454 - { 1455 - uint32_t fst2; 1456 - uint32_t fsth2; 1457 - 1458 - fst2 = int32_to_float32(dt0 & 0XFFFFFFFF, &env->active_fpu.fp_status); 1459 - fsth2 = int32_to_float32(dt0 >> 32, &env->active_fpu.fp_status); 1460 - update_fcr31(env, GETPC()); 1461 - return ((uint64_t)fsth2 << 32) | fst2; 1462 - } 1463 - 1464 - uint64_t helper_float_cvtpw_ps(CPUMIPSState *env, uint64_t fdt0) 1465 - { 1466 - uint32_t wt2; 1467 - uint32_t wth2; 1468 - int excp, excph; 1469 - 1470 - wt2 = float32_to_int32(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status); 1471 - excp = get_float_exception_flags(&env->active_fpu.fp_status); 1472 - if (excp & (float_flag_overflow | float_flag_invalid)) { 1473 - wt2 = FP_TO_INT32_OVERFLOW; 1474 - } 1475 - 1476 - set_float_exception_flags(0, &env->active_fpu.fp_status); 1477 - wth2 = float32_to_int32(fdt0 >> 32, &env->active_fpu.fp_status); 1478 - excph = get_float_exception_flags(&env->active_fpu.fp_status); 1479 - if (excph & (float_flag_overflow | float_flag_invalid)) { 1480 - wth2 = FP_TO_INT32_OVERFLOW; 1481 - } 1482 - 1483 - set_float_exception_flags(excp | excph, &env->active_fpu.fp_status); 1484 - update_fcr31(env, GETPC()); 1485 - 1486 - return ((uint64_t)wth2 << 32) | wt2; 1487 - } 1488 - 1489 - uint32_t helper_float_cvts_d(CPUMIPSState *env, uint64_t fdt0) 1490 - { 1491 - uint32_t fst2; 1492 - 1493 - fst2 = float64_to_float32(fdt0, &env->active_fpu.fp_status); 1494 - update_fcr31(env, GETPC()); 1495 - return fst2; 1496 - } 1497 - 1498 - uint32_t helper_float_cvts_w(CPUMIPSState *env, uint32_t wt0) 1499 - { 1500 - uint32_t fst2; 1501 - 1502 - fst2 = int32_to_float32(wt0, &env->active_fpu.fp_status); 1503 - update_fcr31(env, GETPC()); 1504 - return fst2; 1505 - } 1506 - 1507 - uint32_t helper_float_cvts_l(CPUMIPSState *env, uint64_t dt0) 1508 - { 1509 - uint32_t fst2; 1510 - 1511 - fst2 = int64_to_float32(dt0, &env->active_fpu.fp_status); 1512 - update_fcr31(env, GETPC()); 1513 - return fst2; 1514 - } 1515 - 1516 - uint32_t helper_float_cvts_pl(CPUMIPSState *env, uint32_t wt0) 1517 - { 1518 - uint32_t wt2; 1519 - 1520 - wt2 = wt0; 1521 - update_fcr31(env, GETPC()); 1522 - return wt2; 1523 - } 1524 - 1525 - uint32_t helper_float_cvts_pu(CPUMIPSState *env, uint32_t wth0) 1526 - { 1527 - uint32_t wt2; 1528 - 1529 - wt2 = wth0; 1530 - update_fcr31(env, GETPC()); 1531 - return wt2; 1532 - } 1533 - 1534 - uint32_t helper_float_cvt_w_s(CPUMIPSState *env, uint32_t fst0) 1535 - { 1536 - uint32_t wt2; 1537 - 1538 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 1539 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1540 - & (float_flag_invalid | float_flag_overflow)) { 1541 - wt2 = FP_TO_INT32_OVERFLOW; 1542 - } 1543 - update_fcr31(env, GETPC()); 1544 - return wt2; 1545 - } 1546 - 1547 - uint32_t helper_float_cvt_w_d(CPUMIPSState *env, uint64_t fdt0) 1548 - { 1549 - uint32_t wt2; 1550 - 1551 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 1552 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1553 - & (float_flag_invalid | float_flag_overflow)) { 1554 - wt2 = FP_TO_INT32_OVERFLOW; 1555 - } 1556 - update_fcr31(env, GETPC()); 1557 - return wt2; 1558 - } 1559 - 1560 - uint64_t helper_float_round_l_d(CPUMIPSState *env, uint64_t fdt0) 1561 - { 1562 - uint64_t dt2; 1563 - 1564 - set_float_rounding_mode(float_round_nearest_even, 1565 - &env->active_fpu.fp_status); 1566 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1567 - restore_rounding_mode(env); 1568 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1569 - & (float_flag_invalid | float_flag_overflow)) { 1570 - dt2 = FP_TO_INT64_OVERFLOW; 1571 - } 1572 - update_fcr31(env, GETPC()); 1573 - return dt2; 1574 - } 1575 - 1576 - uint64_t helper_float_round_l_s(CPUMIPSState *env, uint32_t fst0) 1577 - { 1578 - uint64_t dt2; 1579 - 1580 - set_float_rounding_mode(float_round_nearest_even, 1581 - &env->active_fpu.fp_status); 1582 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 1583 - restore_rounding_mode(env); 1584 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1585 - & (float_flag_invalid | float_flag_overflow)) { 1586 - dt2 = FP_TO_INT64_OVERFLOW; 1587 - } 1588 - update_fcr31(env, GETPC()); 1589 - return dt2; 1590 - } 1591 - 1592 - uint32_t helper_float_round_w_d(CPUMIPSState *env, uint64_t fdt0) 1593 - { 1594 - uint32_t wt2; 1595 - 1596 - set_float_rounding_mode(float_round_nearest_even, 1597 - &env->active_fpu.fp_status); 1598 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 1599 - restore_rounding_mode(env); 1600 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1601 - & (float_flag_invalid | float_flag_overflow)) { 1602 - wt2 = FP_TO_INT32_OVERFLOW; 1603 - } 1604 - update_fcr31(env, GETPC()); 1605 - return wt2; 1606 - } 1607 - 1608 - uint32_t helper_float_round_w_s(CPUMIPSState *env, uint32_t fst0) 1609 - { 1610 - uint32_t wt2; 1611 - 1612 - set_float_rounding_mode(float_round_nearest_even, 1613 - &env->active_fpu.fp_status); 1614 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 1615 - restore_rounding_mode(env); 1616 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1617 - & (float_flag_invalid | float_flag_overflow)) { 1618 - wt2 = FP_TO_INT32_OVERFLOW; 1619 - } 1620 - update_fcr31(env, GETPC()); 1621 - return wt2; 1622 - } 1623 - 1624 - uint64_t helper_float_trunc_l_d(CPUMIPSState *env, uint64_t fdt0) 1625 - { 1626 - uint64_t dt2; 1627 - 1628 - dt2 = float64_to_int64_round_to_zero(fdt0, 1629 - &env->active_fpu.fp_status); 1630 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1631 - & (float_flag_invalid | float_flag_overflow)) { 1632 - dt2 = FP_TO_INT64_OVERFLOW; 1633 - } 1634 - update_fcr31(env, GETPC()); 1635 - return dt2; 1636 - } 1637 - 1638 - uint64_t helper_float_trunc_l_s(CPUMIPSState *env, uint32_t fst0) 1639 - { 1640 - uint64_t dt2; 1641 - 1642 - dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); 1643 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1644 - & (float_flag_invalid | float_flag_overflow)) { 1645 - dt2 = FP_TO_INT64_OVERFLOW; 1646 - } 1647 - update_fcr31(env, GETPC()); 1648 - return dt2; 1649 - } 1650 - 1651 - uint32_t helper_float_trunc_w_d(CPUMIPSState *env, uint64_t fdt0) 1652 - { 1653 - uint32_t wt2; 1654 - 1655 - wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); 1656 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1657 - & (float_flag_invalid | float_flag_overflow)) { 1658 - wt2 = FP_TO_INT32_OVERFLOW; 1659 - } 1660 - update_fcr31(env, GETPC()); 1661 - return wt2; 1662 - } 1663 - 1664 - uint32_t helper_float_trunc_w_s(CPUMIPSState *env, uint32_t fst0) 1665 - { 1666 - uint32_t wt2; 1667 - 1668 - wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); 1669 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1670 - & (float_flag_invalid | float_flag_overflow)) { 1671 - wt2 = FP_TO_INT32_OVERFLOW; 1672 - } 1673 - update_fcr31(env, GETPC()); 1674 - return wt2; 1675 - } 1676 - 1677 - uint64_t helper_float_ceil_l_d(CPUMIPSState *env, uint64_t fdt0) 1678 - { 1679 - uint64_t dt2; 1680 - 1681 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 1682 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1683 - restore_rounding_mode(env); 1684 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1685 - & (float_flag_invalid | float_flag_overflow)) { 1686 - dt2 = FP_TO_INT64_OVERFLOW; 1687 - } 1688 - update_fcr31(env, GETPC()); 1689 - return dt2; 1690 - } 1691 - 1692 - uint64_t helper_float_ceil_l_s(CPUMIPSState *env, uint32_t fst0) 1693 - { 1694 - uint64_t dt2; 1695 - 1696 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 1697 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 1698 - restore_rounding_mode(env); 1699 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1700 - & (float_flag_invalid | float_flag_overflow)) { 1701 - dt2 = FP_TO_INT64_OVERFLOW; 1702 - } 1703 - update_fcr31(env, GETPC()); 1704 - return dt2; 1705 - } 1706 - 1707 - uint32_t helper_float_ceil_w_d(CPUMIPSState *env, uint64_t fdt0) 1708 - { 1709 - uint32_t wt2; 1710 - 1711 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 1712 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 1713 - restore_rounding_mode(env); 1714 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1715 - & (float_flag_invalid | float_flag_overflow)) { 1716 - wt2 = FP_TO_INT32_OVERFLOW; 1717 - } 1718 - update_fcr31(env, GETPC()); 1719 - return wt2; 1720 - } 1721 - 1722 - uint32_t helper_float_ceil_w_s(CPUMIPSState *env, uint32_t fst0) 1723 - { 1724 - uint32_t wt2; 1725 - 1726 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 1727 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 1728 - restore_rounding_mode(env); 1729 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1730 - & (float_flag_invalid | float_flag_overflow)) { 1731 - wt2 = FP_TO_INT32_OVERFLOW; 1732 - } 1733 - update_fcr31(env, GETPC()); 1734 - return wt2; 1735 - } 1736 - 1737 - uint64_t helper_float_floor_l_d(CPUMIPSState *env, uint64_t fdt0) 1738 - { 1739 - uint64_t dt2; 1740 - 1741 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 1742 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1743 - restore_rounding_mode(env); 1744 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1745 - & (float_flag_invalid | float_flag_overflow)) { 1746 - dt2 = FP_TO_INT64_OVERFLOW; 1747 - } 1748 - update_fcr31(env, GETPC()); 1749 - return dt2; 1750 - } 1751 - 1752 - uint64_t helper_float_floor_l_s(CPUMIPSState *env, uint32_t fst0) 1753 - { 1754 - uint64_t dt2; 1755 - 1756 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 1757 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 1758 - restore_rounding_mode(env); 1759 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1760 - & (float_flag_invalid | float_flag_overflow)) { 1761 - dt2 = FP_TO_INT64_OVERFLOW; 1762 - } 1763 - update_fcr31(env, GETPC()); 1764 - return dt2; 1765 - } 1766 - 1767 - uint32_t helper_float_floor_w_d(CPUMIPSState *env, uint64_t fdt0) 1768 - { 1769 - uint32_t wt2; 1770 - 1771 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 1772 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 1773 - restore_rounding_mode(env); 1774 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1775 - & (float_flag_invalid | float_flag_overflow)) { 1776 - wt2 = FP_TO_INT32_OVERFLOW; 1777 - } 1778 - update_fcr31(env, GETPC()); 1779 - return wt2; 1780 - } 1781 - 1782 - uint32_t helper_float_floor_w_s(CPUMIPSState *env, uint32_t fst0) 1783 - { 1784 - uint32_t wt2; 1785 - 1786 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 1787 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 1788 - restore_rounding_mode(env); 1789 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1790 - & (float_flag_invalid | float_flag_overflow)) { 1791 - wt2 = FP_TO_INT32_OVERFLOW; 1792 - } 1793 - update_fcr31(env, GETPC()); 1794 - return wt2; 1795 - } 1796 - 1797 - uint64_t helper_float_cvt_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 1798 - { 1799 - uint64_t dt2; 1800 - 1801 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1802 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1803 - & float_flag_invalid) { 1804 - if (float64_is_any_nan(fdt0)) { 1805 - dt2 = 0; 1806 - } 1807 - } 1808 - update_fcr31(env, GETPC()); 1809 - return dt2; 1810 - } 1811 - 1812 - uint64_t helper_float_cvt_2008_l_s(CPUMIPSState *env, uint32_t fst0) 1813 - { 1814 - uint64_t dt2; 1815 - 1816 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 1817 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1818 - & float_flag_invalid) { 1819 - if (float32_is_any_nan(fst0)) { 1820 - dt2 = 0; 1821 - } 1822 - } 1823 - update_fcr31(env, GETPC()); 1824 - return dt2; 1825 - } 1826 - 1827 - uint32_t helper_float_cvt_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 1828 - { 1829 - uint32_t wt2; 1830 - 1831 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 1832 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1833 - & float_flag_invalid) { 1834 - if (float64_is_any_nan(fdt0)) { 1835 - wt2 = 0; 1836 - } 1837 - } 1838 - update_fcr31(env, GETPC()); 1839 - return wt2; 1840 - } 1841 - 1842 - uint32_t helper_float_cvt_2008_w_s(CPUMIPSState *env, uint32_t fst0) 1843 - { 1844 - uint32_t wt2; 1845 - 1846 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 1847 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1848 - & float_flag_invalid) { 1849 - if (float32_is_any_nan(fst0)) { 1850 - wt2 = 0; 1851 - } 1852 - } 1853 - update_fcr31(env, GETPC()); 1854 - return wt2; 1855 - } 1856 - 1857 - uint64_t helper_float_round_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 1858 - { 1859 - uint64_t dt2; 1860 - 1861 - set_float_rounding_mode(float_round_nearest_even, 1862 - &env->active_fpu.fp_status); 1863 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1864 - restore_rounding_mode(env); 1865 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1866 - & float_flag_invalid) { 1867 - if (float64_is_any_nan(fdt0)) { 1868 - dt2 = 0; 1869 - } 1870 - } 1871 - update_fcr31(env, GETPC()); 1872 - return dt2; 1873 - } 1874 - 1875 - uint64_t helper_float_round_2008_l_s(CPUMIPSState *env, uint32_t fst0) 1876 - { 1877 - uint64_t dt2; 1878 - 1879 - set_float_rounding_mode(float_round_nearest_even, 1880 - &env->active_fpu.fp_status); 1881 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 1882 - restore_rounding_mode(env); 1883 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1884 - & float_flag_invalid) { 1885 - if (float32_is_any_nan(fst0)) { 1886 - dt2 = 0; 1887 - } 1888 - } 1889 - update_fcr31(env, GETPC()); 1890 - return dt2; 1891 - } 1892 - 1893 - uint32_t helper_float_round_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 1894 - { 1895 - uint32_t wt2; 1896 - 1897 - set_float_rounding_mode(float_round_nearest_even, 1898 - &env->active_fpu.fp_status); 1899 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 1900 - restore_rounding_mode(env); 1901 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1902 - & float_flag_invalid) { 1903 - if (float64_is_any_nan(fdt0)) { 1904 - wt2 = 0; 1905 - } 1906 - } 1907 - update_fcr31(env, GETPC()); 1908 - return wt2; 1909 - } 1910 - 1911 - uint32_t helper_float_round_2008_w_s(CPUMIPSState *env, uint32_t fst0) 1912 - { 1913 - uint32_t wt2; 1914 - 1915 - set_float_rounding_mode(float_round_nearest_even, 1916 - &env->active_fpu.fp_status); 1917 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 1918 - restore_rounding_mode(env); 1919 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1920 - & float_flag_invalid) { 1921 - if (float32_is_any_nan(fst0)) { 1922 - wt2 = 0; 1923 - } 1924 - } 1925 - update_fcr31(env, GETPC()); 1926 - return wt2; 1927 - } 1928 - 1929 - uint64_t helper_float_trunc_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 1930 - { 1931 - uint64_t dt2; 1932 - 1933 - dt2 = float64_to_int64_round_to_zero(fdt0, &env->active_fpu.fp_status); 1934 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1935 - & float_flag_invalid) { 1936 - if (float64_is_any_nan(fdt0)) { 1937 - dt2 = 0; 1938 - } 1939 - } 1940 - update_fcr31(env, GETPC()); 1941 - return dt2; 1942 - } 1943 - 1944 - uint64_t helper_float_trunc_2008_l_s(CPUMIPSState *env, uint32_t fst0) 1945 - { 1946 - uint64_t dt2; 1947 - 1948 - dt2 = float32_to_int64_round_to_zero(fst0, &env->active_fpu.fp_status); 1949 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1950 - & float_flag_invalid) { 1951 - if (float32_is_any_nan(fst0)) { 1952 - dt2 = 0; 1953 - } 1954 - } 1955 - update_fcr31(env, GETPC()); 1956 - return dt2; 1957 - } 1958 - 1959 - uint32_t helper_float_trunc_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 1960 - { 1961 - uint32_t wt2; 1962 - 1963 - wt2 = float64_to_int32_round_to_zero(fdt0, &env->active_fpu.fp_status); 1964 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1965 - & float_flag_invalid) { 1966 - if (float64_is_any_nan(fdt0)) { 1967 - wt2 = 0; 1968 - } 1969 - } 1970 - update_fcr31(env, GETPC()); 1971 - return wt2; 1972 - } 1973 - 1974 - uint32_t helper_float_trunc_2008_w_s(CPUMIPSState *env, uint32_t fst0) 1975 - { 1976 - uint32_t wt2; 1977 - 1978 - wt2 = float32_to_int32_round_to_zero(fst0, &env->active_fpu.fp_status); 1979 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1980 - & float_flag_invalid) { 1981 - if (float32_is_any_nan(fst0)) { 1982 - wt2 = 0; 1983 - } 1984 - } 1985 - update_fcr31(env, GETPC()); 1986 - return wt2; 1987 - } 1988 - 1989 - uint64_t helper_float_ceil_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 1990 - { 1991 - uint64_t dt2; 1992 - 1993 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 1994 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 1995 - restore_rounding_mode(env); 1996 - if (get_float_exception_flags(&env->active_fpu.fp_status) 1997 - & float_flag_invalid) { 1998 - if (float64_is_any_nan(fdt0)) { 1999 - dt2 = 0; 2000 - } 2001 - } 2002 - update_fcr31(env, GETPC()); 2003 - return dt2; 2004 - } 2005 - 2006 - uint64_t helper_float_ceil_2008_l_s(CPUMIPSState *env, uint32_t fst0) 2007 - { 2008 - uint64_t dt2; 2009 - 2010 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 2011 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 2012 - restore_rounding_mode(env); 2013 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2014 - & float_flag_invalid) { 2015 - if (float32_is_any_nan(fst0)) { 2016 - dt2 = 0; 2017 - } 2018 - } 2019 - update_fcr31(env, GETPC()); 2020 - return dt2; 2021 - } 2022 - 2023 - uint32_t helper_float_ceil_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 2024 - { 2025 - uint32_t wt2; 2026 - 2027 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 2028 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 2029 - restore_rounding_mode(env); 2030 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2031 - & float_flag_invalid) { 2032 - if (float64_is_any_nan(fdt0)) { 2033 - wt2 = 0; 2034 - } 2035 - } 2036 - update_fcr31(env, GETPC()); 2037 - return wt2; 2038 - } 2039 - 2040 - uint32_t helper_float_ceil_2008_w_s(CPUMIPSState *env, uint32_t fst0) 2041 - { 2042 - uint32_t wt2; 2043 - 2044 - set_float_rounding_mode(float_round_up, &env->active_fpu.fp_status); 2045 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 2046 - restore_rounding_mode(env); 2047 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2048 - & float_flag_invalid) { 2049 - if (float32_is_any_nan(fst0)) { 2050 - wt2 = 0; 2051 - } 2052 - } 2053 - update_fcr31(env, GETPC()); 2054 - return wt2; 2055 - } 2056 - 2057 - uint64_t helper_float_floor_2008_l_d(CPUMIPSState *env, uint64_t fdt0) 2058 - { 2059 - uint64_t dt2; 2060 - 2061 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 2062 - dt2 = float64_to_int64(fdt0, &env->active_fpu.fp_status); 2063 - restore_rounding_mode(env); 2064 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2065 - & float_flag_invalid) { 2066 - if (float64_is_any_nan(fdt0)) { 2067 - dt2 = 0; 2068 - } 2069 - } 2070 - update_fcr31(env, GETPC()); 2071 - return dt2; 2072 - } 2073 - 2074 - uint64_t helper_float_floor_2008_l_s(CPUMIPSState *env, uint32_t fst0) 2075 - { 2076 - uint64_t dt2; 2077 - 2078 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 2079 - dt2 = float32_to_int64(fst0, &env->active_fpu.fp_status); 2080 - restore_rounding_mode(env); 2081 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2082 - & float_flag_invalid) { 2083 - if (float32_is_any_nan(fst0)) { 2084 - dt2 = 0; 2085 - } 2086 - } 2087 - update_fcr31(env, GETPC()); 2088 - return dt2; 2089 - } 2090 - 2091 - uint32_t helper_float_floor_2008_w_d(CPUMIPSState *env, uint64_t fdt0) 2092 - { 2093 - uint32_t wt2; 2094 - 2095 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 2096 - wt2 = float64_to_int32(fdt0, &env->active_fpu.fp_status); 2097 - restore_rounding_mode(env); 2098 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2099 - & float_flag_invalid) { 2100 - if (float64_is_any_nan(fdt0)) { 2101 - wt2 = 0; 2102 - } 2103 - } 2104 - update_fcr31(env, GETPC()); 2105 - return wt2; 2106 - } 2107 - 2108 - uint32_t helper_float_floor_2008_w_s(CPUMIPSState *env, uint32_t fst0) 2109 - { 2110 - uint32_t wt2; 2111 - 2112 - set_float_rounding_mode(float_round_down, &env->active_fpu.fp_status); 2113 - wt2 = float32_to_int32(fst0, &env->active_fpu.fp_status); 2114 - restore_rounding_mode(env); 2115 - if (get_float_exception_flags(&env->active_fpu.fp_status) 2116 - & float_flag_invalid) { 2117 - if (float32_is_any_nan(fst0)) { 2118 - wt2 = 0; 2119 - } 2120 - } 2121 - update_fcr31(env, GETPC()); 2122 - return wt2; 2123 - } 2124 - 2125 - /* unary operations, not modifying fp status */ 2126 - #define FLOAT_UNOP(name) \ 2127 - uint64_t helper_float_ ## name ## _d(uint64_t fdt0) \ 2128 - { \ 2129 - return float64_ ## name(fdt0); \ 2130 - } \ 2131 - uint32_t helper_float_ ## name ## _s(uint32_t fst0) \ 2132 - { \ 2133 - return float32_ ## name(fst0); \ 2134 - } \ 2135 - uint64_t helper_float_ ## name ## _ps(uint64_t fdt0) \ 2136 - { \ 2137 - uint32_t wt0; \ 2138 - uint32_t wth0; \ 2139 - \ 2140 - wt0 = float32_ ## name(fdt0 & 0XFFFFFFFF); \ 2141 - wth0 = float32_ ## name(fdt0 >> 32); \ 2142 - return ((uint64_t)wth0 << 32) | wt0; \ 2143 - } 2144 - FLOAT_UNOP(abs) 2145 - FLOAT_UNOP(chs) 2146 - #undef FLOAT_UNOP 2147 - 2148 - /* MIPS specific unary operations */ 2149 - uint64_t helper_float_recip_d(CPUMIPSState *env, uint64_t fdt0) 2150 - { 2151 - uint64_t fdt2; 2152 - 2153 - fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); 2154 - update_fcr31(env, GETPC()); 2155 - return fdt2; 2156 - } 2157 - 2158 - uint32_t helper_float_recip_s(CPUMIPSState *env, uint32_t fst0) 2159 - { 2160 - uint32_t fst2; 2161 - 2162 - fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); 2163 - update_fcr31(env, GETPC()); 2164 - return fst2; 2165 - } 2166 - 2167 - uint64_t helper_float_rsqrt_d(CPUMIPSState *env, uint64_t fdt0) 2168 - { 2169 - uint64_t fdt2; 2170 - 2171 - fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); 2172 - fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); 2173 - update_fcr31(env, GETPC()); 2174 - return fdt2; 2175 - } 2176 - 2177 - uint32_t helper_float_rsqrt_s(CPUMIPSState *env, uint32_t fst0) 2178 - { 2179 - uint32_t fst2; 2180 - 2181 - fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); 2182 - fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); 2183 - update_fcr31(env, GETPC()); 2184 - return fst2; 2185 - } 2186 - 2187 - uint64_t helper_float_recip1_d(CPUMIPSState *env, uint64_t fdt0) 2188 - { 2189 - uint64_t fdt2; 2190 - 2191 - fdt2 = float64_div(float64_one, fdt0, &env->active_fpu.fp_status); 2192 - update_fcr31(env, GETPC()); 2193 - return fdt2; 2194 - } 2195 - 2196 - uint32_t helper_float_recip1_s(CPUMIPSState *env, uint32_t fst0) 2197 - { 2198 - uint32_t fst2; 2199 - 2200 - fst2 = float32_div(float32_one, fst0, &env->active_fpu.fp_status); 2201 - update_fcr31(env, GETPC()); 2202 - return fst2; 2203 - } 2204 - 2205 - uint64_t helper_float_recip1_ps(CPUMIPSState *env, uint64_t fdt0) 2206 - { 2207 - uint32_t fst2; 2208 - uint32_t fsth2; 2209 - 2210 - fst2 = float32_div(float32_one, fdt0 & 0XFFFFFFFF, 2211 - &env->active_fpu.fp_status); 2212 - fsth2 = float32_div(float32_one, fdt0 >> 32, &env->active_fpu.fp_status); 2213 - update_fcr31(env, GETPC()); 2214 - return ((uint64_t)fsth2 << 32) | fst2; 2215 - } 2216 - 2217 - uint64_t helper_float_rsqrt1_d(CPUMIPSState *env, uint64_t fdt0) 2218 - { 2219 - uint64_t fdt2; 2220 - 2221 - fdt2 = float64_sqrt(fdt0, &env->active_fpu.fp_status); 2222 - fdt2 = float64_div(float64_one, fdt2, &env->active_fpu.fp_status); 2223 - update_fcr31(env, GETPC()); 2224 - return fdt2; 2225 - } 2226 - 2227 - uint32_t helper_float_rsqrt1_s(CPUMIPSState *env, uint32_t fst0) 2228 - { 2229 - uint32_t fst2; 2230 - 2231 - fst2 = float32_sqrt(fst0, &env->active_fpu.fp_status); 2232 - fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); 2233 - update_fcr31(env, GETPC()); 2234 - return fst2; 2235 - } 2236 - 2237 - uint64_t helper_float_rsqrt1_ps(CPUMIPSState *env, uint64_t fdt0) 2238 - { 2239 - uint32_t fst2; 2240 - uint32_t fsth2; 2241 - 2242 - fst2 = float32_sqrt(fdt0 & 0XFFFFFFFF, &env->active_fpu.fp_status); 2243 - fsth2 = float32_sqrt(fdt0 >> 32, &env->active_fpu.fp_status); 2244 - fst2 = float32_div(float32_one, fst2, &env->active_fpu.fp_status); 2245 - fsth2 = float32_div(float32_one, fsth2, &env->active_fpu.fp_status); 2246 - update_fcr31(env, GETPC()); 2247 - return ((uint64_t)fsth2 << 32) | fst2; 2248 - } 2249 - 2250 - #define FLOAT_RINT(name, bits) \ 2251 - uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 2252 - uint ## bits ## _t fs) \ 2253 - { \ 2254 - uint ## bits ## _t fdret; \ 2255 - \ 2256 - fdret = float ## bits ## _round_to_int(fs, &env->active_fpu.fp_status); \ 2257 - update_fcr31(env, GETPC()); \ 2258 - return fdret; \ 2259 - } 2260 - 2261 - FLOAT_RINT(rint_s, 32) 2262 - FLOAT_RINT(rint_d, 64) 2263 - #undef FLOAT_RINT 2264 - 2265 - #define FLOAT_CLASS_SIGNALING_NAN 0x001 2266 - #define FLOAT_CLASS_QUIET_NAN 0x002 2267 - #define FLOAT_CLASS_NEGATIVE_INFINITY 0x004 2268 - #define FLOAT_CLASS_NEGATIVE_NORMAL 0x008 2269 - #define FLOAT_CLASS_NEGATIVE_SUBNORMAL 0x010 2270 - #define FLOAT_CLASS_NEGATIVE_ZERO 0x020 2271 - #define FLOAT_CLASS_POSITIVE_INFINITY 0x040 2272 - #define FLOAT_CLASS_POSITIVE_NORMAL 0x080 2273 - #define FLOAT_CLASS_POSITIVE_SUBNORMAL 0x100 2274 - #define FLOAT_CLASS_POSITIVE_ZERO 0x200 2275 - 2276 - #define FLOAT_CLASS(name, bits) \ 2277 - uint ## bits ## _t float_ ## name(uint ## bits ## _t arg, \ 2278 - float_status *status) \ 2279 - { \ 2280 - if (float ## bits ## _is_signaling_nan(arg, status)) { \ 2281 - return FLOAT_CLASS_SIGNALING_NAN; \ 2282 - } else if (float ## bits ## _is_quiet_nan(arg, status)) { \ 2283 - return FLOAT_CLASS_QUIET_NAN; \ 2284 - } else if (float ## bits ## _is_neg(arg)) { \ 2285 - if (float ## bits ## _is_infinity(arg)) { \ 2286 - return FLOAT_CLASS_NEGATIVE_INFINITY; \ 2287 - } else if (float ## bits ## _is_zero(arg)) { \ 2288 - return FLOAT_CLASS_NEGATIVE_ZERO; \ 2289 - } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ 2290 - return FLOAT_CLASS_NEGATIVE_SUBNORMAL; \ 2291 - } else { \ 2292 - return FLOAT_CLASS_NEGATIVE_NORMAL; \ 2293 - } \ 2294 - } else { \ 2295 - if (float ## bits ## _is_infinity(arg)) { \ 2296 - return FLOAT_CLASS_POSITIVE_INFINITY; \ 2297 - } else if (float ## bits ## _is_zero(arg)) { \ 2298 - return FLOAT_CLASS_POSITIVE_ZERO; \ 2299 - } else if (float ## bits ## _is_zero_or_denormal(arg)) { \ 2300 - return FLOAT_CLASS_POSITIVE_SUBNORMAL; \ 2301 - } else { \ 2302 - return FLOAT_CLASS_POSITIVE_NORMAL; \ 2303 - } \ 2304 - } \ 2305 - } \ 2306 - \ 2307 - uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 2308 - uint ## bits ## _t arg) \ 2309 - { \ 2310 - return float_ ## name(arg, &env->active_fpu.fp_status); \ 2311 - } 2312 - 2313 - FLOAT_CLASS(class_s, 32) 2314 - FLOAT_CLASS(class_d, 64) 2315 - #undef FLOAT_CLASS 2316 - 2317 - /* binary operations */ 2318 - #define FLOAT_BINOP(name) \ 2319 - uint64_t helper_float_ ## name ## _d(CPUMIPSState *env, \ 2320 - uint64_t fdt0, uint64_t fdt1) \ 2321 - { \ 2322 - uint64_t dt2; \ 2323 - \ 2324 - dt2 = float64_ ## name(fdt0, fdt1, &env->active_fpu.fp_status);\ 2325 - update_fcr31(env, GETPC()); \ 2326 - return dt2; \ 2327 - } \ 2328 - \ 2329 - uint32_t helper_float_ ## name ## _s(CPUMIPSState *env, \ 2330 - uint32_t fst0, uint32_t fst1) \ 2331 - { \ 2332 - uint32_t wt2; \ 2333 - \ 2334 - wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status);\ 2335 - update_fcr31(env, GETPC()); \ 2336 - return wt2; \ 2337 - } \ 2338 - \ 2339 - uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \ 2340 - uint64_t fdt0, \ 2341 - uint64_t fdt1) \ 2342 - { \ 2343 - uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ 2344 - uint32_t fsth0 = fdt0 >> 32; \ 2345 - uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ 2346 - uint32_t fsth1 = fdt1 >> 32; \ 2347 - uint32_t wt2; \ 2348 - uint32_t wth2; \ 2349 - \ 2350 - wt2 = float32_ ## name(fst0, fst1, &env->active_fpu.fp_status); \ 2351 - wth2 = float32_ ## name(fsth0, fsth1, &env->active_fpu.fp_status); \ 2352 - update_fcr31(env, GETPC()); \ 2353 - return ((uint64_t)wth2 << 32) | wt2; \ 2354 - } 2355 - 2356 - FLOAT_BINOP(add) 2357 - FLOAT_BINOP(sub) 2358 - FLOAT_BINOP(mul) 2359 - FLOAT_BINOP(div) 2360 - #undef FLOAT_BINOP 2361 - 2362 - /* MIPS specific binary operations */ 2363 - uint64_t helper_float_recip2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 2364 - { 2365 - fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status); 2366 - fdt2 = float64_chs(float64_sub(fdt2, float64_one, 2367 - &env->active_fpu.fp_status)); 2368 - update_fcr31(env, GETPC()); 2369 - return fdt2; 2370 - } 2371 - 2372 - uint32_t helper_float_recip2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2) 2373 - { 2374 - fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 2375 - fst2 = float32_chs(float32_sub(fst2, float32_one, 2376 - &env->active_fpu.fp_status)); 2377 - update_fcr31(env, GETPC()); 2378 - return fst2; 2379 - } 2380 - 2381 - uint64_t helper_float_recip2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 2382 - { 2383 - uint32_t fst0 = fdt0 & 0XFFFFFFFF; 2384 - uint32_t fsth0 = fdt0 >> 32; 2385 - uint32_t fst2 = fdt2 & 0XFFFFFFFF; 2386 - uint32_t fsth2 = fdt2 >> 32; 2387 - 2388 - fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 2389 - fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status); 2390 - fst2 = float32_chs(float32_sub(fst2, float32_one, 2391 - &env->active_fpu.fp_status)); 2392 - fsth2 = float32_chs(float32_sub(fsth2, float32_one, 2393 - &env->active_fpu.fp_status)); 2394 - update_fcr31(env, GETPC()); 2395 - return ((uint64_t)fsth2 << 32) | fst2; 2396 - } 2397 - 2398 - uint64_t helper_float_rsqrt2_d(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 2399 - { 2400 - fdt2 = float64_mul(fdt0, fdt2, &env->active_fpu.fp_status); 2401 - fdt2 = float64_sub(fdt2, float64_one, &env->active_fpu.fp_status); 2402 - fdt2 = float64_chs(float64_div(fdt2, FLOAT_TWO64, 2403 - &env->active_fpu.fp_status)); 2404 - update_fcr31(env, GETPC()); 2405 - return fdt2; 2406 - } 2407 - 2408 - uint32_t helper_float_rsqrt2_s(CPUMIPSState *env, uint32_t fst0, uint32_t fst2) 2409 - { 2410 - fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 2411 - fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status); 2412 - fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, 2413 - &env->active_fpu.fp_status)); 2414 - update_fcr31(env, GETPC()); 2415 - return fst2; 2416 - } 2417 - 2418 - uint64_t helper_float_rsqrt2_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt2) 2419 - { 2420 - uint32_t fst0 = fdt0 & 0XFFFFFFFF; 2421 - uint32_t fsth0 = fdt0 >> 32; 2422 - uint32_t fst2 = fdt2 & 0XFFFFFFFF; 2423 - uint32_t fsth2 = fdt2 >> 32; 2424 - 2425 - fst2 = float32_mul(fst0, fst2, &env->active_fpu.fp_status); 2426 - fsth2 = float32_mul(fsth0, fsth2, &env->active_fpu.fp_status); 2427 - fst2 = float32_sub(fst2, float32_one, &env->active_fpu.fp_status); 2428 - fsth2 = float32_sub(fsth2, float32_one, &env->active_fpu.fp_status); 2429 - fst2 = float32_chs(float32_div(fst2, FLOAT_TWO32, 2430 - &env->active_fpu.fp_status)); 2431 - fsth2 = float32_chs(float32_div(fsth2, FLOAT_TWO32, 2432 - &env->active_fpu.fp_status)); 2433 - update_fcr31(env, GETPC()); 2434 - return ((uint64_t)fsth2 << 32) | fst2; 2435 - } 2436 - 2437 - uint64_t helper_float_addr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1) 2438 - { 2439 - uint32_t fst0 = fdt0 & 0XFFFFFFFF; 2440 - uint32_t fsth0 = fdt0 >> 32; 2441 - uint32_t fst1 = fdt1 & 0XFFFFFFFF; 2442 - uint32_t fsth1 = fdt1 >> 32; 2443 - uint32_t fst2; 2444 - uint32_t fsth2; 2445 - 2446 - fst2 = float32_add(fst0, fsth0, &env->active_fpu.fp_status); 2447 - fsth2 = float32_add(fst1, fsth1, &env->active_fpu.fp_status); 2448 - update_fcr31(env, GETPC()); 2449 - return ((uint64_t)fsth2 << 32) | fst2; 2450 - } 2451 - 2452 - uint64_t helper_float_mulr_ps(CPUMIPSState *env, uint64_t fdt0, uint64_t fdt1) 2453 - { 2454 - uint32_t fst0 = fdt0 & 0XFFFFFFFF; 2455 - uint32_t fsth0 = fdt0 >> 32; 2456 - uint32_t fst1 = fdt1 & 0XFFFFFFFF; 2457 - uint32_t fsth1 = fdt1 >> 32; 2458 - uint32_t fst2; 2459 - uint32_t fsth2; 2460 - 2461 - fst2 = float32_mul(fst0, fsth0, &env->active_fpu.fp_status); 2462 - fsth2 = float32_mul(fst1, fsth1, &env->active_fpu.fp_status); 2463 - update_fcr31(env, GETPC()); 2464 - return ((uint64_t)fsth2 << 32) | fst2; 2465 - } 2466 - 2467 - #define FLOAT_MINMAX(name, bits, minmaxfunc) \ 2468 - uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 2469 - uint ## bits ## _t fs, \ 2470 - uint ## bits ## _t ft) \ 2471 - { \ 2472 - uint ## bits ## _t fdret; \ 2473 - \ 2474 - fdret = float ## bits ## _ ## minmaxfunc(fs, ft, \ 2475 - &env->active_fpu.fp_status); \ 2476 - update_fcr31(env, GETPC()); \ 2477 - return fdret; \ 2478 - } 2479 - 2480 - FLOAT_MINMAX(max_s, 32, maxnum) 2481 - FLOAT_MINMAX(max_d, 64, maxnum) 2482 - FLOAT_MINMAX(maxa_s, 32, maxnummag) 2483 - FLOAT_MINMAX(maxa_d, 64, maxnummag) 2484 - 2485 - FLOAT_MINMAX(min_s, 32, minnum) 2486 - FLOAT_MINMAX(min_d, 64, minnum) 2487 - FLOAT_MINMAX(mina_s, 32, minnummag) 2488 - FLOAT_MINMAX(mina_d, 64, minnummag) 2489 - #undef FLOAT_MINMAX 2490 - 2491 - /* ternary operations */ 2492 - #define UNFUSED_FMA(prefix, a, b, c, flags) \ 2493 - { \ 2494 - a = prefix##_mul(a, b, &env->active_fpu.fp_status); \ 2495 - if ((flags) & float_muladd_negate_c) { \ 2496 - a = prefix##_sub(a, c, &env->active_fpu.fp_status); \ 2497 - } else { \ 2498 - a = prefix##_add(a, c, &env->active_fpu.fp_status); \ 2499 - } \ 2500 - if ((flags) & float_muladd_negate_result) { \ 2501 - a = prefix##_chs(a); \ 2502 - } \ 2503 - } 2504 - 2505 - /* FMA based operations */ 2506 - #define FLOAT_FMA(name, type) \ 2507 - uint64_t helper_float_ ## name ## _d(CPUMIPSState *env, \ 2508 - uint64_t fdt0, uint64_t fdt1, \ 2509 - uint64_t fdt2) \ 2510 - { \ 2511 - UNFUSED_FMA(float64, fdt0, fdt1, fdt2, type); \ 2512 - update_fcr31(env, GETPC()); \ 2513 - return fdt0; \ 2514 - } \ 2515 - \ 2516 - uint32_t helper_float_ ## name ## _s(CPUMIPSState *env, \ 2517 - uint32_t fst0, uint32_t fst1, \ 2518 - uint32_t fst2) \ 2519 - { \ 2520 - UNFUSED_FMA(float32, fst0, fst1, fst2, type); \ 2521 - update_fcr31(env, GETPC()); \ 2522 - return fst0; \ 2523 - } \ 2524 - \ 2525 - uint64_t helper_float_ ## name ## _ps(CPUMIPSState *env, \ 2526 - uint64_t fdt0, uint64_t fdt1, \ 2527 - uint64_t fdt2) \ 2528 - { \ 2529 - uint32_t fst0 = fdt0 & 0XFFFFFFFF; \ 2530 - uint32_t fsth0 = fdt0 >> 32; \ 2531 - uint32_t fst1 = fdt1 & 0XFFFFFFFF; \ 2532 - uint32_t fsth1 = fdt1 >> 32; \ 2533 - uint32_t fst2 = fdt2 & 0XFFFFFFFF; \ 2534 - uint32_t fsth2 = fdt2 >> 32; \ 2535 - \ 2536 - UNFUSED_FMA(float32, fst0, fst1, fst2, type); \ 2537 - UNFUSED_FMA(float32, fsth0, fsth1, fsth2, type); \ 2538 - update_fcr31(env, GETPC()); \ 2539 - return ((uint64_t)fsth0 << 32) | fst0; \ 2540 - } 2541 - FLOAT_FMA(madd, 0) 2542 - FLOAT_FMA(msub, float_muladd_negate_c) 2543 - FLOAT_FMA(nmadd, float_muladd_negate_result) 2544 - FLOAT_FMA(nmsub, float_muladd_negate_result | float_muladd_negate_c) 2545 - #undef FLOAT_FMA 2546 - 2547 - #define FLOAT_FMADDSUB(name, bits, muladd_arg) \ 2548 - uint ## bits ## _t helper_float_ ## name(CPUMIPSState *env, \ 2549 - uint ## bits ## _t fs, \ 2550 - uint ## bits ## _t ft, \ 2551 - uint ## bits ## _t fd) \ 2552 - { \ 2553 - uint ## bits ## _t fdret; \ 2554 - \ 2555 - fdret = float ## bits ## _muladd(fs, ft, fd, muladd_arg, \ 2556 - &env->active_fpu.fp_status); \ 2557 - update_fcr31(env, GETPC()); \ 2558 - return fdret; \ 2559 - } 2560 - 2561 - FLOAT_FMADDSUB(maddf_s, 32, 0) 2562 - FLOAT_FMADDSUB(maddf_d, 64, 0) 2563 - FLOAT_FMADDSUB(msubf_s, 32, float_muladd_negate_product) 2564 - FLOAT_FMADDSUB(msubf_d, 64, float_muladd_negate_product) 2565 - #undef FLOAT_FMADDSUB 2566 - 2567 - /* compare operations */ 2568 - #define FOP_COND_D(op, cond) \ 2569 - void helper_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 2570 - uint64_t fdt1, int cc) \ 2571 - { \ 2572 - int c; \ 2573 - c = cond; \ 2574 - update_fcr31(env, GETPC()); \ 2575 - if (c) \ 2576 - SET_FP_COND(cc, env->active_fpu); \ 2577 - else \ 2578 - CLEAR_FP_COND(cc, env->active_fpu); \ 2579 - } \ 2580 - void helper_cmpabs_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 2581 - uint64_t fdt1, int cc) \ 2582 - { \ 2583 - int c; \ 2584 - fdt0 = float64_abs(fdt0); \ 2585 - fdt1 = float64_abs(fdt1); \ 2586 - c = cond; \ 2587 - update_fcr31(env, GETPC()); \ 2588 - if (c) \ 2589 - SET_FP_COND(cc, env->active_fpu); \ 2590 - else \ 2591 - CLEAR_FP_COND(cc, env->active_fpu); \ 2592 - } 2593 - 2594 - /* 2595 - * NOTE: the comma operator will make "cond" to eval to false, 2596 - * but float64_unordered_quiet() is still called. 2597 - */ 2598 - FOP_COND_D(f, (float64_unordered_quiet(fdt1, fdt0, 2599 - &env->active_fpu.fp_status), 0)) 2600 - FOP_COND_D(un, float64_unordered_quiet(fdt1, fdt0, 2601 - &env->active_fpu.fp_status)) 2602 - FOP_COND_D(eq, float64_eq_quiet(fdt0, fdt1, 2603 - &env->active_fpu.fp_status)) 2604 - FOP_COND_D(ueq, float64_unordered_quiet(fdt1, fdt0, 2605 - &env->active_fpu.fp_status) 2606 - || float64_eq_quiet(fdt0, fdt1, 2607 - &env->active_fpu.fp_status)) 2608 - FOP_COND_D(olt, float64_lt_quiet(fdt0, fdt1, 2609 - &env->active_fpu.fp_status)) 2610 - FOP_COND_D(ult, float64_unordered_quiet(fdt1, fdt0, 2611 - &env->active_fpu.fp_status) 2612 - || float64_lt_quiet(fdt0, fdt1, 2613 - &env->active_fpu.fp_status)) 2614 - FOP_COND_D(ole, float64_le_quiet(fdt0, fdt1, 2615 - &env->active_fpu.fp_status)) 2616 - FOP_COND_D(ule, float64_unordered_quiet(fdt1, fdt0, 2617 - &env->active_fpu.fp_status) 2618 - || float64_le_quiet(fdt0, fdt1, 2619 - &env->active_fpu.fp_status)) 2620 - /* 2621 - * NOTE: the comma operator will make "cond" to eval to false, 2622 - * but float64_unordered() is still called. 2623 - */ 2624 - FOP_COND_D(sf, (float64_unordered(fdt1, fdt0, 2625 - &env->active_fpu.fp_status), 0)) 2626 - FOP_COND_D(ngle, float64_unordered(fdt1, fdt0, 2627 - &env->active_fpu.fp_status)) 2628 - FOP_COND_D(seq, float64_eq(fdt0, fdt1, 2629 - &env->active_fpu.fp_status)) 2630 - FOP_COND_D(ngl, float64_unordered(fdt1, fdt0, 2631 - &env->active_fpu.fp_status) 2632 - || float64_eq(fdt0, fdt1, 2633 - &env->active_fpu.fp_status)) 2634 - FOP_COND_D(lt, float64_lt(fdt0, fdt1, 2635 - &env->active_fpu.fp_status)) 2636 - FOP_COND_D(nge, float64_unordered(fdt1, fdt0, 2637 - &env->active_fpu.fp_status) 2638 - || float64_lt(fdt0, fdt1, 2639 - &env->active_fpu.fp_status)) 2640 - FOP_COND_D(le, float64_le(fdt0, fdt1, 2641 - &env->active_fpu.fp_status)) 2642 - FOP_COND_D(ngt, float64_unordered(fdt1, fdt0, 2643 - &env->active_fpu.fp_status) 2644 - || float64_le(fdt0, fdt1, 2645 - &env->active_fpu.fp_status)) 2646 - 2647 - #define FOP_COND_S(op, cond) \ 2648 - void helper_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \ 2649 - uint32_t fst1, int cc) \ 2650 - { \ 2651 - int c; \ 2652 - c = cond; \ 2653 - update_fcr31(env, GETPC()); \ 2654 - if (c) \ 2655 - SET_FP_COND(cc, env->active_fpu); \ 2656 - else \ 2657 - CLEAR_FP_COND(cc, env->active_fpu); \ 2658 - } \ 2659 - void helper_cmpabs_s_ ## op(CPUMIPSState *env, uint32_t fst0, \ 2660 - uint32_t fst1, int cc) \ 2661 - { \ 2662 - int c; \ 2663 - fst0 = float32_abs(fst0); \ 2664 - fst1 = float32_abs(fst1); \ 2665 - c = cond; \ 2666 - update_fcr31(env, GETPC()); \ 2667 - if (c) \ 2668 - SET_FP_COND(cc, env->active_fpu); \ 2669 - else \ 2670 - CLEAR_FP_COND(cc, env->active_fpu); \ 2671 - } 2672 - 2673 - /* 2674 - * NOTE: the comma operator will make "cond" to eval to false, 2675 - * but float32_unordered_quiet() is still called. 2676 - */ 2677 - FOP_COND_S(f, (float32_unordered_quiet(fst1, fst0, 2678 - &env->active_fpu.fp_status), 0)) 2679 - FOP_COND_S(un, float32_unordered_quiet(fst1, fst0, 2680 - &env->active_fpu.fp_status)) 2681 - FOP_COND_S(eq, float32_eq_quiet(fst0, fst1, 2682 - &env->active_fpu.fp_status)) 2683 - FOP_COND_S(ueq, float32_unordered_quiet(fst1, fst0, 2684 - &env->active_fpu.fp_status) 2685 - || float32_eq_quiet(fst0, fst1, 2686 - &env->active_fpu.fp_status)) 2687 - FOP_COND_S(olt, float32_lt_quiet(fst0, fst1, 2688 - &env->active_fpu.fp_status)) 2689 - FOP_COND_S(ult, float32_unordered_quiet(fst1, fst0, 2690 - &env->active_fpu.fp_status) 2691 - || float32_lt_quiet(fst0, fst1, 2692 - &env->active_fpu.fp_status)) 2693 - FOP_COND_S(ole, float32_le_quiet(fst0, fst1, 2694 - &env->active_fpu.fp_status)) 2695 - FOP_COND_S(ule, float32_unordered_quiet(fst1, fst0, 2696 - &env->active_fpu.fp_status) 2697 - || float32_le_quiet(fst0, fst1, 2698 - &env->active_fpu.fp_status)) 2699 - /* 2700 - * NOTE: the comma operator will make "cond" to eval to false, 2701 - * but float32_unordered() is still called. 2702 - */ 2703 - FOP_COND_S(sf, (float32_unordered(fst1, fst0, 2704 - &env->active_fpu.fp_status), 0)) 2705 - FOP_COND_S(ngle, float32_unordered(fst1, fst0, 2706 - &env->active_fpu.fp_status)) 2707 - FOP_COND_S(seq, float32_eq(fst0, fst1, 2708 - &env->active_fpu.fp_status)) 2709 - FOP_COND_S(ngl, float32_unordered(fst1, fst0, 2710 - &env->active_fpu.fp_status) 2711 - || float32_eq(fst0, fst1, 2712 - &env->active_fpu.fp_status)) 2713 - FOP_COND_S(lt, float32_lt(fst0, fst1, 2714 - &env->active_fpu.fp_status)) 2715 - FOP_COND_S(nge, float32_unordered(fst1, fst0, 2716 - &env->active_fpu.fp_status) 2717 - || float32_lt(fst0, fst1, 2718 - &env->active_fpu.fp_status)) 2719 - FOP_COND_S(le, float32_le(fst0, fst1, 2720 - &env->active_fpu.fp_status)) 2721 - FOP_COND_S(ngt, float32_unordered(fst1, fst0, 2722 - &env->active_fpu.fp_status) 2723 - || float32_le(fst0, fst1, 2724 - &env->active_fpu.fp_status)) 2725 - 2726 - #define FOP_COND_PS(op, condl, condh) \ 2727 - void helper_cmp_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 2728 - uint64_t fdt1, int cc) \ 2729 - { \ 2730 - uint32_t fst0, fsth0, fst1, fsth1; \ 2731 - int ch, cl; \ 2732 - fst0 = fdt0 & 0XFFFFFFFF; \ 2733 - fsth0 = fdt0 >> 32; \ 2734 - fst1 = fdt1 & 0XFFFFFFFF; \ 2735 - fsth1 = fdt1 >> 32; \ 2736 - cl = condl; \ 2737 - ch = condh; \ 2738 - update_fcr31(env, GETPC()); \ 2739 - if (cl) \ 2740 - SET_FP_COND(cc, env->active_fpu); \ 2741 - else \ 2742 - CLEAR_FP_COND(cc, env->active_fpu); \ 2743 - if (ch) \ 2744 - SET_FP_COND(cc + 1, env->active_fpu); \ 2745 - else \ 2746 - CLEAR_FP_COND(cc + 1, env->active_fpu); \ 2747 - } \ 2748 - void helper_cmpabs_ps_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 2749 - uint64_t fdt1, int cc) \ 2750 - { \ 2751 - uint32_t fst0, fsth0, fst1, fsth1; \ 2752 - int ch, cl; \ 2753 - fst0 = float32_abs(fdt0 & 0XFFFFFFFF); \ 2754 - fsth0 = float32_abs(fdt0 >> 32); \ 2755 - fst1 = float32_abs(fdt1 & 0XFFFFFFFF); \ 2756 - fsth1 = float32_abs(fdt1 >> 32); \ 2757 - cl = condl; \ 2758 - ch = condh; \ 2759 - update_fcr31(env, GETPC()); \ 2760 - if (cl) \ 2761 - SET_FP_COND(cc, env->active_fpu); \ 2762 - else \ 2763 - CLEAR_FP_COND(cc, env->active_fpu); \ 2764 - if (ch) \ 2765 - SET_FP_COND(cc + 1, env->active_fpu); \ 2766 - else \ 2767 - CLEAR_FP_COND(cc + 1, env->active_fpu); \ 2768 - } 2769 - 2770 - /* 2771 - * NOTE: the comma operator will make "cond" to eval to false, 2772 - * but float32_unordered_quiet() is still called. 2773 - */ 2774 - FOP_COND_PS(f, (float32_unordered_quiet(fst1, fst0, 2775 - &env->active_fpu.fp_status), 0), 2776 - (float32_unordered_quiet(fsth1, fsth0, 2777 - &env->active_fpu.fp_status), 0)) 2778 - FOP_COND_PS(un, float32_unordered_quiet(fst1, fst0, 2779 - &env->active_fpu.fp_status), 2780 - float32_unordered_quiet(fsth1, fsth0, 2781 - &env->active_fpu.fp_status)) 2782 - FOP_COND_PS(eq, float32_eq_quiet(fst0, fst1, 2783 - &env->active_fpu.fp_status), 2784 - float32_eq_quiet(fsth0, fsth1, 2785 - &env->active_fpu.fp_status)) 2786 - FOP_COND_PS(ueq, float32_unordered_quiet(fst1, fst0, 2787 - &env->active_fpu.fp_status) 2788 - || float32_eq_quiet(fst0, fst1, 2789 - &env->active_fpu.fp_status), 2790 - float32_unordered_quiet(fsth1, fsth0, 2791 - &env->active_fpu.fp_status) 2792 - || float32_eq_quiet(fsth0, fsth1, 2793 - &env->active_fpu.fp_status)) 2794 - FOP_COND_PS(olt, float32_lt_quiet(fst0, fst1, 2795 - &env->active_fpu.fp_status), 2796 - float32_lt_quiet(fsth0, fsth1, 2797 - &env->active_fpu.fp_status)) 2798 - FOP_COND_PS(ult, float32_unordered_quiet(fst1, fst0, 2799 - &env->active_fpu.fp_status) 2800 - || float32_lt_quiet(fst0, fst1, 2801 - &env->active_fpu.fp_status), 2802 - float32_unordered_quiet(fsth1, fsth0, 2803 - &env->active_fpu.fp_status) 2804 - || float32_lt_quiet(fsth0, fsth1, 2805 - &env->active_fpu.fp_status)) 2806 - FOP_COND_PS(ole, float32_le_quiet(fst0, fst1, 2807 - &env->active_fpu.fp_status), 2808 - float32_le_quiet(fsth0, fsth1, 2809 - &env->active_fpu.fp_status)) 2810 - FOP_COND_PS(ule, float32_unordered_quiet(fst1, fst0, 2811 - &env->active_fpu.fp_status) 2812 - || float32_le_quiet(fst0, fst1, 2813 - &env->active_fpu.fp_status), 2814 - float32_unordered_quiet(fsth1, fsth0, 2815 - &env->active_fpu.fp_status) 2816 - || float32_le_quiet(fsth0, fsth1, 2817 - &env->active_fpu.fp_status)) 2818 - /* 2819 - * NOTE: the comma operator will make "cond" to eval to false, 2820 - * but float32_unordered() is still called. 2821 - */ 2822 - FOP_COND_PS(sf, (float32_unordered(fst1, fst0, 2823 - &env->active_fpu.fp_status), 0), 2824 - (float32_unordered(fsth1, fsth0, 2825 - &env->active_fpu.fp_status), 0)) 2826 - FOP_COND_PS(ngle, float32_unordered(fst1, fst0, 2827 - &env->active_fpu.fp_status), 2828 - float32_unordered(fsth1, fsth0, 2829 - &env->active_fpu.fp_status)) 2830 - FOP_COND_PS(seq, float32_eq(fst0, fst1, 2831 - &env->active_fpu.fp_status), 2832 - float32_eq(fsth0, fsth1, 2833 - &env->active_fpu.fp_status)) 2834 - FOP_COND_PS(ngl, float32_unordered(fst1, fst0, 2835 - &env->active_fpu.fp_status) 2836 - || float32_eq(fst0, fst1, 2837 - &env->active_fpu.fp_status), 2838 - float32_unordered(fsth1, fsth0, 2839 - &env->active_fpu.fp_status) 2840 - || float32_eq(fsth0, fsth1, 2841 - &env->active_fpu.fp_status)) 2842 - FOP_COND_PS(lt, float32_lt(fst0, fst1, 2843 - &env->active_fpu.fp_status), 2844 - float32_lt(fsth0, fsth1, 2845 - &env->active_fpu.fp_status)) 2846 - FOP_COND_PS(nge, float32_unordered(fst1, fst0, 2847 - &env->active_fpu.fp_status) 2848 - || float32_lt(fst0, fst1, 2849 - &env->active_fpu.fp_status), 2850 - float32_unordered(fsth1, fsth0, 2851 - &env->active_fpu.fp_status) 2852 - || float32_lt(fsth0, fsth1, 2853 - &env->active_fpu.fp_status)) 2854 - FOP_COND_PS(le, float32_le(fst0, fst1, 2855 - &env->active_fpu.fp_status), 2856 - float32_le(fsth0, fsth1, 2857 - &env->active_fpu.fp_status)) 2858 - FOP_COND_PS(ngt, float32_unordered(fst1, fst0, 2859 - &env->active_fpu.fp_status) 2860 - || float32_le(fst0, fst1, 2861 - &env->active_fpu.fp_status), 2862 - float32_unordered(fsth1, fsth0, 2863 - &env->active_fpu.fp_status) 2864 - || float32_le(fsth0, fsth1, 2865 - &env->active_fpu.fp_status)) 2866 - 2867 - /* R6 compare operations */ 2868 - #define FOP_CONDN_D(op, cond) \ 2869 - uint64_t helper_r6_cmp_d_ ## op(CPUMIPSState *env, uint64_t fdt0, \ 2870 - uint64_t fdt1) \ 2871 - { \ 2872 - uint64_t c; \ 2873 - c = cond; \ 2874 - update_fcr31(env, GETPC()); \ 2875 - if (c) { \ 2876 - return -1; \ 2877 - } else { \ 2878 - return 0; \ 2879 - } \ 2880 - } 2881 - 2882 - /* 2883 - * NOTE: the comma operator will make "cond" to eval to false, 2884 - * but float64_unordered_quiet() is still called. 2885 - */ 2886 - FOP_CONDN_D(af, (float64_unordered_quiet(fdt1, fdt0, 2887 - &env->active_fpu.fp_status), 0)) 2888 - FOP_CONDN_D(un, (float64_unordered_quiet(fdt1, fdt0, 2889 - &env->active_fpu.fp_status))) 2890 - FOP_CONDN_D(eq, (float64_eq_quiet(fdt0, fdt1, 2891 - &env->active_fpu.fp_status))) 2892 - FOP_CONDN_D(ueq, (float64_unordered_quiet(fdt1, fdt0, 2893 - &env->active_fpu.fp_status) 2894 - || float64_eq_quiet(fdt0, fdt1, 2895 - &env->active_fpu.fp_status))) 2896 - FOP_CONDN_D(lt, (float64_lt_quiet(fdt0, fdt1, 2897 - &env->active_fpu.fp_status))) 2898 - FOP_CONDN_D(ult, (float64_unordered_quiet(fdt1, fdt0, 2899 - &env->active_fpu.fp_status) 2900 - || float64_lt_quiet(fdt0, fdt1, 2901 - &env->active_fpu.fp_status))) 2902 - FOP_CONDN_D(le, (float64_le_quiet(fdt0, fdt1, 2903 - &env->active_fpu.fp_status))) 2904 - FOP_CONDN_D(ule, (float64_unordered_quiet(fdt1, fdt0, 2905 - &env->active_fpu.fp_status) 2906 - || float64_le_quiet(fdt0, fdt1, 2907 - &env->active_fpu.fp_status))) 2908 - /* 2909 - * NOTE: the comma operator will make "cond" to eval to false, 2910 - * but float64_unordered() is still called.\ 2911 - */ 2912 - FOP_CONDN_D(saf, (float64_unordered(fdt1, fdt0, 2913 - &env->active_fpu.fp_status), 0)) 2914 - FOP_CONDN_D(sun, (float64_unordered(fdt1, fdt0, 2915 - &env->active_fpu.fp_status))) 2916 - FOP_CONDN_D(seq, (float64_eq(fdt0, fdt1, 2917 - &env->active_fpu.fp_status))) 2918 - FOP_CONDN_D(sueq, (float64_unordered(fdt1, fdt0, 2919 - &env->active_fpu.fp_status) 2920 - || float64_eq(fdt0, fdt1, 2921 - &env->active_fpu.fp_status))) 2922 - FOP_CONDN_D(slt, (float64_lt(fdt0, fdt1, 2923 - &env->active_fpu.fp_status))) 2924 - FOP_CONDN_D(sult, (float64_unordered(fdt1, fdt0, 2925 - &env->active_fpu.fp_status) 2926 - || float64_lt(fdt0, fdt1, 2927 - &env->active_fpu.fp_status))) 2928 - FOP_CONDN_D(sle, (float64_le(fdt0, fdt1, 2929 - &env->active_fpu.fp_status))) 2930 - FOP_CONDN_D(sule, (float64_unordered(fdt1, fdt0, 2931 - &env->active_fpu.fp_status) 2932 - || float64_le(fdt0, fdt1, 2933 - &env->active_fpu.fp_status))) 2934 - FOP_CONDN_D(or, (float64_le_quiet(fdt1, fdt0, 2935 - &env->active_fpu.fp_status) 2936 - || float64_le_quiet(fdt0, fdt1, 2937 - &env->active_fpu.fp_status))) 2938 - FOP_CONDN_D(une, (float64_unordered_quiet(fdt1, fdt0, 2939 - &env->active_fpu.fp_status) 2940 - || float64_lt_quiet(fdt1, fdt0, 2941 - &env->active_fpu.fp_status) 2942 - || float64_lt_quiet(fdt0, fdt1, 2943 - &env->active_fpu.fp_status))) 2944 - FOP_CONDN_D(ne, (float64_lt_quiet(fdt1, fdt0, 2945 - &env->active_fpu.fp_status) 2946 - || float64_lt_quiet(fdt0, fdt1, 2947 - &env->active_fpu.fp_status))) 2948 - FOP_CONDN_D(sor, (float64_le(fdt1, fdt0, 2949 - &env->active_fpu.fp_status) 2950 - || float64_le(fdt0, fdt1, 2951 - &env->active_fpu.fp_status))) 2952 - FOP_CONDN_D(sune, (float64_unordered(fdt1, fdt0, 2953 - &env->active_fpu.fp_status) 2954 - || float64_lt(fdt1, fdt0, 2955 - &env->active_fpu.fp_status) 2956 - || float64_lt(fdt0, fdt1, 2957 - &env->active_fpu.fp_status))) 2958 - FOP_CONDN_D(sne, (float64_lt(fdt1, fdt0, 2959 - &env->active_fpu.fp_status) 2960 - || float64_lt(fdt0, fdt1, 2961 - &env->active_fpu.fp_status))) 2962 - 2963 - #define FOP_CONDN_S(op, cond) \ 2964 - uint32_t helper_r6_cmp_s_ ## op(CPUMIPSState *env, uint32_t fst0, \ 2965 - uint32_t fst1) \ 2966 - { \ 2967 - uint64_t c; \ 2968 - c = cond; \ 2969 - update_fcr31(env, GETPC()); \ 2970 - if (c) { \ 2971 - return -1; \ 2972 - } else { \ 2973 - return 0; \ 2974 - } \ 2975 - } 2976 - 2977 - /* 2978 - * NOTE: the comma operator will make "cond" to eval to false, 2979 - * but float32_unordered_quiet() is still called. 2980 - */ 2981 - FOP_CONDN_S(af, (float32_unordered_quiet(fst1, fst0, 2982 - &env->active_fpu.fp_status), 0)) 2983 - FOP_CONDN_S(un, (float32_unordered_quiet(fst1, fst0, 2984 - &env->active_fpu.fp_status))) 2985 - FOP_CONDN_S(eq, (float32_eq_quiet(fst0, fst1, 2986 - &env->active_fpu.fp_status))) 2987 - FOP_CONDN_S(ueq, (float32_unordered_quiet(fst1, fst0, 2988 - &env->active_fpu.fp_status) 2989 - || float32_eq_quiet(fst0, fst1, 2990 - &env->active_fpu.fp_status))) 2991 - FOP_CONDN_S(lt, (float32_lt_quiet(fst0, fst1, 2992 - &env->active_fpu.fp_status))) 2993 - FOP_CONDN_S(ult, (float32_unordered_quiet(fst1, fst0, 2994 - &env->active_fpu.fp_status) 2995 - || float32_lt_quiet(fst0, fst1, 2996 - &env->active_fpu.fp_status))) 2997 - FOP_CONDN_S(le, (float32_le_quiet(fst0, fst1, 2998 - &env->active_fpu.fp_status))) 2999 - FOP_CONDN_S(ule, (float32_unordered_quiet(fst1, fst0, 3000 - &env->active_fpu.fp_status) 3001 - || float32_le_quiet(fst0, fst1, 3002 - &env->active_fpu.fp_status))) 3003 - /* 3004 - * NOTE: the comma operator will make "cond" to eval to false, 3005 - * but float32_unordered() is still called. 3006 - */ 3007 - FOP_CONDN_S(saf, (float32_unordered(fst1, fst0, 3008 - &env->active_fpu.fp_status), 0)) 3009 - FOP_CONDN_S(sun, (float32_unordered(fst1, fst0, 3010 - &env->active_fpu.fp_status))) 3011 - FOP_CONDN_S(seq, (float32_eq(fst0, fst1, 3012 - &env->active_fpu.fp_status))) 3013 - FOP_CONDN_S(sueq, (float32_unordered(fst1, fst0, 3014 - &env->active_fpu.fp_status) 3015 - || float32_eq(fst0, fst1, 3016 - &env->active_fpu.fp_status))) 3017 - FOP_CONDN_S(slt, (float32_lt(fst0, fst1, 3018 - &env->active_fpu.fp_status))) 3019 - FOP_CONDN_S(sult, (float32_unordered(fst1, fst0, 3020 - &env->active_fpu.fp_status) 3021 - || float32_lt(fst0, fst1, 3022 - &env->active_fpu.fp_status))) 3023 - FOP_CONDN_S(sle, (float32_le(fst0, fst1, 3024 - &env->active_fpu.fp_status))) 3025 - FOP_CONDN_S(sule, (float32_unordered(fst1, fst0, 3026 - &env->active_fpu.fp_status) 3027 - || float32_le(fst0, fst1, 3028 - &env->active_fpu.fp_status))) 3029 - FOP_CONDN_S(or, (float32_le_quiet(fst1, fst0, 3030 - &env->active_fpu.fp_status) 3031 - || float32_le_quiet(fst0, fst1, 3032 - &env->active_fpu.fp_status))) 3033 - FOP_CONDN_S(une, (float32_unordered_quiet(fst1, fst0, 3034 - &env->active_fpu.fp_status) 3035 - || float32_lt_quiet(fst1, fst0, 3036 - &env->active_fpu.fp_status) 3037 - || float32_lt_quiet(fst0, fst1, 3038 - &env->active_fpu.fp_status))) 3039 - FOP_CONDN_S(ne, (float32_lt_quiet(fst1, fst0, 3040 - &env->active_fpu.fp_status) 3041 - || float32_lt_quiet(fst0, fst1, 3042 - &env->active_fpu.fp_status))) 3043 - FOP_CONDN_S(sor, (float32_le(fst1, fst0, 3044 - &env->active_fpu.fp_status) 3045 - || float32_le(fst0, fst1, 3046 - &env->active_fpu.fp_status))) 3047 - FOP_CONDN_S(sune, (float32_unordered(fst1, fst0, 3048 - &env->active_fpu.fp_status) 3049 - || float32_lt(fst1, fst0, 3050 - &env->active_fpu.fp_status) 3051 - || float32_lt(fst0, fst1, 3052 - &env->active_fpu.fp_status))) 3053 - FOP_CONDN_S(sne, (float32_lt(fst1, fst0, 3054 - &env->active_fpu.fp_status) 3055 - || float32_lt(fst0, fst1, 3056 - &env->active_fpu.fp_status))) 3057 1180 3058 1181 /* MSA */ 3059 1182 /* Data format min and max values */