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