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