Commit a16336e4792c4f092bd2fdcd20c9d70c979b2b22
1 parent
8f2ad0a3
Convert remaining MIPS FP instructions to TCG.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4753 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
426 additions
and
363 deletions
target-mips/helper.h
| ... | ... | @@ -154,6 +154,7 @@ DEF_HELPER(void, do_float_mulr_ps, (void)) |
| 154 | 154 | #define FOP_PROTO(op) \ |
| 155 | 155 | DEF_HELPER(void, do_float_ ## op ## _s, (void)) \ |
| 156 | 156 | DEF_HELPER(void, do_float_ ## op ## _d, (void)) |
| 157 | +FOP_PROTO(sqrt) | |
| 157 | 158 | FOP_PROTO(roundl) |
| 158 | 159 | FOP_PROTO(roundw) |
| 159 | 160 | FOP_PROTO(truncl) |
| ... | ... | @@ -174,6 +175,12 @@ FOP_PROTO(add) |
| 174 | 175 | FOP_PROTO(sub) |
| 175 | 176 | FOP_PROTO(mul) |
| 176 | 177 | FOP_PROTO(div) |
| 178 | +FOP_PROTO(abs) | |
| 179 | +FOP_PROTO(chs) | |
| 180 | +FOP_PROTO(muladd) | |
| 181 | +FOP_PROTO(mulsub) | |
| 182 | +FOP_PROTO(nmuladd) | |
| 183 | +FOP_PROTO(nmulsub) | |
| 177 | 184 | FOP_PROTO(recip1) |
| 178 | 185 | FOP_PROTO(recip2) |
| 179 | 186 | FOP_PROTO(rsqrt1) | ... | ... |
target-mips/op.c
| ... | ... | @@ -295,295 +295,3 @@ void op_mulshiu (void) |
| 295 | 295 | #else |
| 296 | 296 | # define DEBUG_FPU_STATE() do { } while(0) |
| 297 | 297 | #endif |
| 298 | - | |
| 299 | -/* Float support. | |
| 300 | - Single precition routines have a "s" suffix, double precision a | |
| 301 | - "d" suffix, 32bit integer "w", 64bit integer "l", paired singe "ps", | |
| 302 | - paired single lowwer "pl", paired single upper "pu". */ | |
| 303 | - | |
| 304 | -#define FLOAT_OP(name, p) void OPPROTO op_float_##name##_##p(void) | |
| 305 | - | |
| 306 | -FLOAT_OP(pll, ps) | |
| 307 | -{ | |
| 308 | - DT2 = ((uint64_t)WT0 << 32) | WT1; | |
| 309 | - DEBUG_FPU_STATE(); | |
| 310 | - FORCE_RET(); | |
| 311 | -} | |
| 312 | -FLOAT_OP(plu, ps) | |
| 313 | -{ | |
| 314 | - DT2 = ((uint64_t)WT0 << 32) | WTH1; | |
| 315 | - DEBUG_FPU_STATE(); | |
| 316 | - FORCE_RET(); | |
| 317 | -} | |
| 318 | -FLOAT_OP(pul, ps) | |
| 319 | -{ | |
| 320 | - DT2 = ((uint64_t)WTH0 << 32) | WT1; | |
| 321 | - DEBUG_FPU_STATE(); | |
| 322 | - FORCE_RET(); | |
| 323 | -} | |
| 324 | -FLOAT_OP(puu, ps) | |
| 325 | -{ | |
| 326 | - DT2 = ((uint64_t)WTH0 << 32) | WTH1; | |
| 327 | - DEBUG_FPU_STATE(); | |
| 328 | - FORCE_RET(); | |
| 329 | -} | |
| 330 | - | |
| 331 | -FLOAT_OP(movf, d) | |
| 332 | -{ | |
| 333 | - if (!(env->fpu->fcr31 & PARAM1)) | |
| 334 | - DT2 = DT0; | |
| 335 | - DEBUG_FPU_STATE(); | |
| 336 | - FORCE_RET(); | |
| 337 | -} | |
| 338 | -FLOAT_OP(movf, s) | |
| 339 | -{ | |
| 340 | - if (!(env->fpu->fcr31 & PARAM1)) | |
| 341 | - WT2 = WT0; | |
| 342 | - DEBUG_FPU_STATE(); | |
| 343 | - FORCE_RET(); | |
| 344 | -} | |
| 345 | -FLOAT_OP(movf, ps) | |
| 346 | -{ | |
| 347 | - unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1; | |
| 348 | - if (!(mask & 1)) | |
| 349 | - WT2 = WT0; | |
| 350 | - if (!(mask & 2)) | |
| 351 | - WTH2 = WTH0; | |
| 352 | - DEBUG_FPU_STATE(); | |
| 353 | - FORCE_RET(); | |
| 354 | -} | |
| 355 | -FLOAT_OP(movt, d) | |
| 356 | -{ | |
| 357 | - if (env->fpu->fcr31 & PARAM1) | |
| 358 | - DT2 = DT0; | |
| 359 | - DEBUG_FPU_STATE(); | |
| 360 | - FORCE_RET(); | |
| 361 | -} | |
| 362 | -FLOAT_OP(movt, s) | |
| 363 | -{ | |
| 364 | - if (env->fpu->fcr31 & PARAM1) | |
| 365 | - WT2 = WT0; | |
| 366 | - DEBUG_FPU_STATE(); | |
| 367 | - FORCE_RET(); | |
| 368 | -} | |
| 369 | -FLOAT_OP(movt, ps) | |
| 370 | -{ | |
| 371 | - unsigned int mask = GET_FP_COND (env->fpu) >> PARAM1; | |
| 372 | - if (mask & 1) | |
| 373 | - WT2 = WT0; | |
| 374 | - if (mask & 2) | |
| 375 | - WTH2 = WTH0; | |
| 376 | - DEBUG_FPU_STATE(); | |
| 377 | - FORCE_RET(); | |
| 378 | -} | |
| 379 | -FLOAT_OP(movz, d) | |
| 380 | -{ | |
| 381 | - if (!T0) | |
| 382 | - DT2 = DT0; | |
| 383 | - DEBUG_FPU_STATE(); | |
| 384 | - FORCE_RET(); | |
| 385 | -} | |
| 386 | -FLOAT_OP(movz, s) | |
| 387 | -{ | |
| 388 | - if (!T0) | |
| 389 | - WT2 = WT0; | |
| 390 | - DEBUG_FPU_STATE(); | |
| 391 | - FORCE_RET(); | |
| 392 | -} | |
| 393 | -FLOAT_OP(movz, ps) | |
| 394 | -{ | |
| 395 | - if (!T0) { | |
| 396 | - WT2 = WT0; | |
| 397 | - WTH2 = WTH0; | |
| 398 | - } | |
| 399 | - DEBUG_FPU_STATE(); | |
| 400 | - FORCE_RET(); | |
| 401 | -} | |
| 402 | -FLOAT_OP(movn, d) | |
| 403 | -{ | |
| 404 | - if (T0) | |
| 405 | - DT2 = DT0; | |
| 406 | - DEBUG_FPU_STATE(); | |
| 407 | - FORCE_RET(); | |
| 408 | -} | |
| 409 | -FLOAT_OP(movn, s) | |
| 410 | -{ | |
| 411 | - if (T0) | |
| 412 | - WT2 = WT0; | |
| 413 | - DEBUG_FPU_STATE(); | |
| 414 | - FORCE_RET(); | |
| 415 | -} | |
| 416 | -FLOAT_OP(movn, ps) | |
| 417 | -{ | |
| 418 | - if (T0) { | |
| 419 | - WT2 = WT0; | |
| 420 | - WTH2 = WTH0; | |
| 421 | - } | |
| 422 | - DEBUG_FPU_STATE(); | |
| 423 | - FORCE_RET(); | |
| 424 | -} | |
| 425 | - | |
| 426 | -/* ternary operations */ | |
| 427 | -#define FLOAT_TERNOP(name1, name2) \ | |
| 428 | -FLOAT_OP(name1 ## name2, d) \ | |
| 429 | -{ \ | |
| 430 | - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ | |
| 431 | - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ | |
| 432 | - DEBUG_FPU_STATE(); \ | |
| 433 | - FORCE_RET(); \ | |
| 434 | -} \ | |
| 435 | -FLOAT_OP(name1 ## name2, s) \ | |
| 436 | -{ \ | |
| 437 | - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 438 | - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 439 | - DEBUG_FPU_STATE(); \ | |
| 440 | - FORCE_RET(); \ | |
| 441 | -} \ | |
| 442 | -FLOAT_OP(name1 ## name2, ps) \ | |
| 443 | -{ \ | |
| 444 | - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 445 | - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ | |
| 446 | - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 447 | - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ | |
| 448 | - DEBUG_FPU_STATE(); \ | |
| 449 | - FORCE_RET(); \ | |
| 450 | -} | |
| 451 | -FLOAT_TERNOP(mul, add) | |
| 452 | -FLOAT_TERNOP(mul, sub) | |
| 453 | -#undef FLOAT_TERNOP | |
| 454 | - | |
| 455 | -/* negated ternary operations */ | |
| 456 | -#define FLOAT_NTERNOP(name1, name2) \ | |
| 457 | -FLOAT_OP(n ## name1 ## name2, d) \ | |
| 458 | -{ \ | |
| 459 | - FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ | |
| 460 | - FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ | |
| 461 | - FDT2 = float64_chs(FDT2); \ | |
| 462 | - DEBUG_FPU_STATE(); \ | |
| 463 | - FORCE_RET(); \ | |
| 464 | -} \ | |
| 465 | -FLOAT_OP(n ## name1 ## name2, s) \ | |
| 466 | -{ \ | |
| 467 | - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 468 | - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 469 | - FST2 = float32_chs(FST2); \ | |
| 470 | - DEBUG_FPU_STATE(); \ | |
| 471 | - FORCE_RET(); \ | |
| 472 | -} \ | |
| 473 | -FLOAT_OP(n ## name1 ## name2, ps) \ | |
| 474 | -{ \ | |
| 475 | - FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 476 | - FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ | |
| 477 | - FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 478 | - FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ | |
| 479 | - FST2 = float32_chs(FST2); \ | |
| 480 | - FSTH2 = float32_chs(FSTH2); \ | |
| 481 | - DEBUG_FPU_STATE(); \ | |
| 482 | - FORCE_RET(); \ | |
| 483 | -} | |
| 484 | -FLOAT_NTERNOP(mul, add) | |
| 485 | -FLOAT_NTERNOP(mul, sub) | |
| 486 | -#undef FLOAT_NTERNOP | |
| 487 | - | |
| 488 | -/* unary operations, modifying fp status */ | |
| 489 | -#define FLOAT_UNOP(name) \ | |
| 490 | -FLOAT_OP(name, d) \ | |
| 491 | -{ \ | |
| 492 | - FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \ | |
| 493 | - DEBUG_FPU_STATE(); \ | |
| 494 | - FORCE_RET(); \ | |
| 495 | -} \ | |
| 496 | -FLOAT_OP(name, s) \ | |
| 497 | -{ \ | |
| 498 | - FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \ | |
| 499 | - DEBUG_FPU_STATE(); \ | |
| 500 | - FORCE_RET(); \ | |
| 501 | -} | |
| 502 | -FLOAT_UNOP(sqrt) | |
| 503 | -#undef FLOAT_UNOP | |
| 504 | - | |
| 505 | -/* unary operations, not modifying fp status */ | |
| 506 | -#define FLOAT_UNOP(name) \ | |
| 507 | -FLOAT_OP(name, d) \ | |
| 508 | -{ \ | |
| 509 | - FDT2 = float64_ ## name(FDT0); \ | |
| 510 | - DEBUG_FPU_STATE(); \ | |
| 511 | - FORCE_RET(); \ | |
| 512 | -} \ | |
| 513 | -FLOAT_OP(name, s) \ | |
| 514 | -{ \ | |
| 515 | - FST2 = float32_ ## name(FST0); \ | |
| 516 | - DEBUG_FPU_STATE(); \ | |
| 517 | - FORCE_RET(); \ | |
| 518 | -} \ | |
| 519 | -FLOAT_OP(name, ps) \ | |
| 520 | -{ \ | |
| 521 | - FST2 = float32_ ## name(FST0); \ | |
| 522 | - FSTH2 = float32_ ## name(FSTH0); \ | |
| 523 | - DEBUG_FPU_STATE(); \ | |
| 524 | - FORCE_RET(); \ | |
| 525 | -} | |
| 526 | -FLOAT_UNOP(abs) | |
| 527 | -FLOAT_UNOP(chs) | |
| 528 | -#undef FLOAT_UNOP | |
| 529 | - | |
| 530 | -FLOAT_OP(alnv, ps) | |
| 531 | -{ | |
| 532 | - switch (T0 & 0x7) { | |
| 533 | - case 0: | |
| 534 | - FST2 = FST0; | |
| 535 | - FSTH2 = FSTH0; | |
| 536 | - break; | |
| 537 | - case 4: | |
| 538 | -#ifdef TARGET_WORDS_BIGENDIAN | |
| 539 | - FSTH2 = FST0; | |
| 540 | - FST2 = FSTH1; | |
| 541 | -#else | |
| 542 | - FSTH2 = FST1; | |
| 543 | - FST2 = FSTH0; | |
| 544 | -#endif | |
| 545 | - break; | |
| 546 | - default: /* unpredictable */ | |
| 547 | - break; | |
| 548 | - } | |
| 549 | - DEBUG_FPU_STATE(); | |
| 550 | - FORCE_RET(); | |
| 551 | -} | |
| 552 | - | |
| 553 | -void op_bc1f (void) | |
| 554 | -{ | |
| 555 | - T0 = !!(~GET_FP_COND(env->fpu) & (0x1 << PARAM1)); | |
| 556 | - DEBUG_FPU_STATE(); | |
| 557 | - FORCE_RET(); | |
| 558 | -} | |
| 559 | -void op_bc1any2f (void) | |
| 560 | -{ | |
| 561 | - T0 = !!(~GET_FP_COND(env->fpu) & (0x3 << PARAM1)); | |
| 562 | - DEBUG_FPU_STATE(); | |
| 563 | - FORCE_RET(); | |
| 564 | -} | |
| 565 | -void op_bc1any4f (void) | |
| 566 | -{ | |
| 567 | - T0 = !!(~GET_FP_COND(env->fpu) & (0xf << PARAM1)); | |
| 568 | - DEBUG_FPU_STATE(); | |
| 569 | - FORCE_RET(); | |
| 570 | -} | |
| 571 | - | |
| 572 | -void op_bc1t (void) | |
| 573 | -{ | |
| 574 | - T0 = !!(GET_FP_COND(env->fpu) & (0x1 << PARAM1)); | |
| 575 | - DEBUG_FPU_STATE(); | |
| 576 | - FORCE_RET(); | |
| 577 | -} | |
| 578 | -void op_bc1any2t (void) | |
| 579 | -{ | |
| 580 | - T0 = !!(GET_FP_COND(env->fpu) & (0x3 << PARAM1)); | |
| 581 | - DEBUG_FPU_STATE(); | |
| 582 | - FORCE_RET(); | |
| 583 | -} | |
| 584 | -void op_bc1any4t (void) | |
| 585 | -{ | |
| 586 | - T0 = !!(GET_FP_COND(env->fpu) & (0xf << PARAM1)); | |
| 587 | - DEBUG_FPU_STATE(); | |
| 588 | - FORCE_RET(); | |
| 589 | -} | ... | ... |
target-mips/op_helper.c
| ... | ... | @@ -1703,8 +1703,26 @@ static always_inline void update_fcr31(void) |
| 1703 | 1703 | UPDATE_FP_FLAGS(env->fpu->fcr31, tmp); |
| 1704 | 1704 | } |
| 1705 | 1705 | |
| 1706 | +/* Float support. | |
| 1707 | + Single precition routines have a "s" suffix, double precision a | |
| 1708 | + "d" suffix, 32bit integer "w", 64bit integer "l", paired single "ps", | |
| 1709 | + paired single lower "pl", paired single upper "pu". */ | |
| 1710 | + | |
| 1706 | 1711 | #define FLOAT_OP(name, p) void do_float_##name##_##p(void) |
| 1707 | 1712 | |
| 1713 | +/* unary operations, modifying fp status */ | |
| 1714 | +#define FLOAT_UNOP(name) \ | |
| 1715 | +FLOAT_OP(name, d) \ | |
| 1716 | +{ \ | |
| 1717 | + FDT2 = float64_ ## name(FDT0, &env->fpu->fp_status); \ | |
| 1718 | +} \ | |
| 1719 | +FLOAT_OP(name, s) \ | |
| 1720 | +{ \ | |
| 1721 | + FST2 = float32_ ## name(FST0, &env->fpu->fp_status); \ | |
| 1722 | +} | |
| 1723 | +FLOAT_UNOP(sqrt) | |
| 1724 | +#undef FLOAT_UNOP | |
| 1725 | + | |
| 1708 | 1726 | FLOAT_OP(cvtd, s) |
| 1709 | 1727 | { |
| 1710 | 1728 | set_float_exception_flags(0, &env->fpu->fp_status); |
| ... | ... | @@ -1943,6 +1961,25 @@ FLOAT_OP(floorw, s) |
| 1943 | 1961 | WT2 = FLOAT_SNAN32; |
| 1944 | 1962 | } |
| 1945 | 1963 | |
| 1964 | +/* unary operations, not modifying fp status */ | |
| 1965 | +#define FLOAT_UNOP(name) \ | |
| 1966 | +FLOAT_OP(name, d) \ | |
| 1967 | +{ \ | |
| 1968 | + FDT2 = float64_ ## name(FDT0); \ | |
| 1969 | +} \ | |
| 1970 | +FLOAT_OP(name, s) \ | |
| 1971 | +{ \ | |
| 1972 | + FST2 = float32_ ## name(FST0); \ | |
| 1973 | +} \ | |
| 1974 | +FLOAT_OP(name, ps) \ | |
| 1975 | +{ \ | |
| 1976 | + FST2 = float32_ ## name(FST0); \ | |
| 1977 | + FSTH2 = float32_ ## name(FSTH0); \ | |
| 1978 | +} | |
| 1979 | +FLOAT_UNOP(abs) | |
| 1980 | +FLOAT_UNOP(chs) | |
| 1981 | +#undef FLOAT_UNOP | |
| 1982 | + | |
| 1946 | 1983 | /* MIPS specific unary operations */ |
| 1947 | 1984 | FLOAT_OP(recip, d) |
| 1948 | 1985 | { |
| ... | ... | @@ -2051,6 +2088,56 @@ FLOAT_BINOP(mul) |
| 2051 | 2088 | FLOAT_BINOP(div) |
| 2052 | 2089 | #undef FLOAT_BINOP |
| 2053 | 2090 | |
| 2091 | +/* ternary operations */ | |
| 2092 | +#define FLOAT_TERNOP(name1, name2) \ | |
| 2093 | +FLOAT_OP(name1 ## name2, d) \ | |
| 2094 | +{ \ | |
| 2095 | + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ | |
| 2096 | + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ | |
| 2097 | +} \ | |
| 2098 | +FLOAT_OP(name1 ## name2, s) \ | |
| 2099 | +{ \ | |
| 2100 | + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 2101 | + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 2102 | +} \ | |
| 2103 | +FLOAT_OP(name1 ## name2, ps) \ | |
| 2104 | +{ \ | |
| 2105 | + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 2106 | + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ | |
| 2107 | + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 2108 | + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ | |
| 2109 | +} | |
| 2110 | +FLOAT_TERNOP(mul, add) | |
| 2111 | +FLOAT_TERNOP(mul, sub) | |
| 2112 | +#undef FLOAT_TERNOP | |
| 2113 | + | |
| 2114 | +/* negated ternary operations */ | |
| 2115 | +#define FLOAT_NTERNOP(name1, name2) \ | |
| 2116 | +FLOAT_OP(n ## name1 ## name2, d) \ | |
| 2117 | +{ \ | |
| 2118 | + FDT0 = float64_ ## name1 (FDT0, FDT1, &env->fpu->fp_status); \ | |
| 2119 | + FDT2 = float64_ ## name2 (FDT0, FDT2, &env->fpu->fp_status); \ | |
| 2120 | + FDT2 = float64_chs(FDT2); \ | |
| 2121 | +} \ | |
| 2122 | +FLOAT_OP(n ## name1 ## name2, s) \ | |
| 2123 | +{ \ | |
| 2124 | + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 2125 | + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 2126 | + FST2 = float32_chs(FST2); \ | |
| 2127 | +} \ | |
| 2128 | +FLOAT_OP(n ## name1 ## name2, ps) \ | |
| 2129 | +{ \ | |
| 2130 | + FST0 = float32_ ## name1 (FST0, FST1, &env->fpu->fp_status); \ | |
| 2131 | + FSTH0 = float32_ ## name1 (FSTH0, FSTH1, &env->fpu->fp_status); \ | |
| 2132 | + FST2 = float32_ ## name2 (FST0, FST2, &env->fpu->fp_status); \ | |
| 2133 | + FSTH2 = float32_ ## name2 (FSTH0, FSTH2, &env->fpu->fp_status); \ | |
| 2134 | + FST2 = float32_chs(FST2); \ | |
| 2135 | + FSTH2 = float32_chs(FSTH2); \ | |
| 2136 | +} | |
| 2137 | +FLOAT_NTERNOP(mul, add) | |
| 2138 | +FLOAT_NTERNOP(mul, sub) | |
| 2139 | +#undef FLOAT_NTERNOP | |
| 2140 | + | |
| 2054 | 2141 | /* MIPS specific binary operations */ |
| 2055 | 2142 | FLOAT_OP(recip2, d) |
| 2056 | 2143 | { | ... | ... |
target-mips/translate.c
| ... | ... | @@ -630,6 +630,21 @@ static inline void gen_store_fpr32h (TCGv t, int reg) |
| 630 | 630 | tcg_gen_st_i32(t, current_fpu, 8 * reg + 4 * !FP_ENDIAN_IDX); |
| 631 | 631 | } |
| 632 | 632 | |
| 633 | +static inline void get_fp_cond (TCGv t) | |
| 634 | +{ | |
| 635 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 636 | + TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_I32); | |
| 637 | + | |
| 638 | + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); | |
| 639 | + tcg_gen_shri_i32(r_tmp2, r_tmp1, 24); | |
| 640 | + tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe); | |
| 641 | + tcg_gen_shri_i32(r_tmp1, r_tmp1, 23); | |
| 642 | + tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1); | |
| 643 | + tcg_gen_or_i32(t, r_tmp1, r_tmp2); | |
| 644 | + tcg_temp_free(r_tmp1); | |
| 645 | + tcg_temp_free(r_tmp2); | |
| 646 | +} | |
| 647 | + | |
| 633 | 648 | #define FOP_CONDS(type, fmt) \ |
| 634 | 649 | static GenOpFunc1 * fcmp ## type ## _ ## fmt ## _table[16] = { \ |
| 635 | 650 | do_cmp ## type ## _ ## fmt ## _f, \ |
| ... | ... | @@ -5541,38 +5556,170 @@ static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op, |
| 5541 | 5556 | |
| 5542 | 5557 | switch (op) { |
| 5543 | 5558 | case OPC_BC1F: |
| 5544 | - gen_op_bc1f(cc); | |
| 5559 | + { | |
| 5560 | + int l1 = gen_new_label(); | |
| 5561 | + int l2 = gen_new_label(); | |
| 5562 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5563 | + | |
| 5564 | + get_fp_cond(r_tmp1); | |
| 5565 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5566 | + tcg_temp_free(r_tmp1); | |
| 5567 | + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); | |
| 5568 | + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); | |
| 5569 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5570 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5571 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5572 | + tcg_gen_br(l2); | |
| 5573 | + gen_set_label(l1); | |
| 5574 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5575 | + gen_set_label(l2); | |
| 5576 | + } | |
| 5545 | 5577 | opn = "bc1f"; |
| 5546 | 5578 | goto not_likely; |
| 5547 | 5579 | case OPC_BC1FL: |
| 5548 | - gen_op_bc1f(cc); | |
| 5580 | + { | |
| 5581 | + int l1 = gen_new_label(); | |
| 5582 | + int l2 = gen_new_label(); | |
| 5583 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5584 | + | |
| 5585 | + get_fp_cond(r_tmp1); | |
| 5586 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5587 | + tcg_temp_free(r_tmp1); | |
| 5588 | + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); | |
| 5589 | + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); | |
| 5590 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5591 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5592 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5593 | + tcg_gen_br(l2); | |
| 5594 | + gen_set_label(l1); | |
| 5595 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5596 | + gen_set_label(l2); | |
| 5597 | + } | |
| 5549 | 5598 | opn = "bc1fl"; |
| 5550 | 5599 | goto likely; |
| 5551 | 5600 | case OPC_BC1T: |
| 5552 | - gen_op_bc1t(cc); | |
| 5601 | + { | |
| 5602 | + int l1 = gen_new_label(); | |
| 5603 | + int l2 = gen_new_label(); | |
| 5604 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5605 | + | |
| 5606 | + get_fp_cond(r_tmp1); | |
| 5607 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5608 | + tcg_temp_free(r_tmp1); | |
| 5609 | + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); | |
| 5610 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5611 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5612 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5613 | + tcg_gen_br(l2); | |
| 5614 | + gen_set_label(l1); | |
| 5615 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5616 | + gen_set_label(l2); | |
| 5617 | + } | |
| 5553 | 5618 | opn = "bc1t"; |
| 5554 | 5619 | goto not_likely; |
| 5555 | 5620 | case OPC_BC1TL: |
| 5556 | - gen_op_bc1t(cc); | |
| 5621 | + { | |
| 5622 | + int l1 = gen_new_label(); | |
| 5623 | + int l2 = gen_new_label(); | |
| 5624 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5625 | + | |
| 5626 | + get_fp_cond(r_tmp1); | |
| 5627 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5628 | + tcg_temp_free(r_tmp1); | |
| 5629 | + tcg_gen_movi_tl(cpu_T[1], 0x1 << cc); | |
| 5630 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5631 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5632 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5633 | + tcg_gen_br(l2); | |
| 5634 | + gen_set_label(l1); | |
| 5635 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5636 | + gen_set_label(l2); | |
| 5637 | + } | |
| 5557 | 5638 | opn = "bc1tl"; |
| 5558 | 5639 | likely: |
| 5559 | 5640 | ctx->hflags |= MIPS_HFLAG_BL; |
| 5560 | 5641 | tcg_gen_st_tl(cpu_T[0], cpu_env, offsetof(CPUState, bcond)); |
| 5561 | 5642 | break; |
| 5562 | 5643 | case OPC_BC1FANY2: |
| 5563 | - gen_op_bc1any2f(cc); | |
| 5644 | + { | |
| 5645 | + int l1 = gen_new_label(); | |
| 5646 | + int l2 = gen_new_label(); | |
| 5647 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5648 | + | |
| 5649 | + get_fp_cond(r_tmp1); | |
| 5650 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5651 | + tcg_temp_free(r_tmp1); | |
| 5652 | + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); | |
| 5653 | + tcg_gen_movi_tl(cpu_T[1], 0x3 << cc); | |
| 5654 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5655 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5656 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5657 | + tcg_gen_br(l2); | |
| 5658 | + gen_set_label(l1); | |
| 5659 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5660 | + gen_set_label(l2); | |
| 5661 | + } | |
| 5564 | 5662 | opn = "bc1any2f"; |
| 5565 | 5663 | goto not_likely; |
| 5566 | 5664 | case OPC_BC1TANY2: |
| 5567 | - gen_op_bc1any2t(cc); | |
| 5665 | + { | |
| 5666 | + int l1 = gen_new_label(); | |
| 5667 | + int l2 = gen_new_label(); | |
| 5668 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5669 | + | |
| 5670 | + get_fp_cond(r_tmp1); | |
| 5671 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5672 | + tcg_temp_free(r_tmp1); | |
| 5673 | + tcg_gen_movi_tl(cpu_T[1], 0x3 << cc); | |
| 5674 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5675 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5676 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5677 | + tcg_gen_br(l2); | |
| 5678 | + gen_set_label(l1); | |
| 5679 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5680 | + gen_set_label(l2); | |
| 5681 | + } | |
| 5568 | 5682 | opn = "bc1any2t"; |
| 5569 | 5683 | goto not_likely; |
| 5570 | 5684 | case OPC_BC1FANY4: |
| 5571 | - gen_op_bc1any4f(cc); | |
| 5685 | + { | |
| 5686 | + int l1 = gen_new_label(); | |
| 5687 | + int l2 = gen_new_label(); | |
| 5688 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5689 | + | |
| 5690 | + get_fp_cond(r_tmp1); | |
| 5691 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5692 | + tcg_temp_free(r_tmp1); | |
| 5693 | + tcg_gen_not_tl(cpu_T[0], cpu_T[0]); | |
| 5694 | + tcg_gen_movi_tl(cpu_T[1], 0xf << cc); | |
| 5695 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5696 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5697 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5698 | + tcg_gen_br(l2); | |
| 5699 | + gen_set_label(l1); | |
| 5700 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5701 | + gen_set_label(l2); | |
| 5702 | + } | |
| 5572 | 5703 | opn = "bc1any4f"; |
| 5573 | 5704 | goto not_likely; |
| 5574 | 5705 | case OPC_BC1TANY4: |
| 5575 | - gen_op_bc1any4t(cc); | |
| 5706 | + { | |
| 5707 | + int l1 = gen_new_label(); | |
| 5708 | + int l2 = gen_new_label(); | |
| 5709 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5710 | + | |
| 5711 | + get_fp_cond(r_tmp1); | |
| 5712 | + tcg_gen_ext_i32_tl(cpu_T[0], r_tmp1); | |
| 5713 | + tcg_temp_free(r_tmp1); | |
| 5714 | + tcg_gen_movi_tl(cpu_T[1], 0xf << cc); | |
| 5715 | + tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_T[1]); | |
| 5716 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 5717 | + tcg_gen_movi_tl(cpu_T[0], 0); | |
| 5718 | + tcg_gen_br(l2); | |
| 5719 | + gen_set_label(l1); | |
| 5720 | + tcg_gen_movi_tl(cpu_T[0], 1); | |
| 5721 | + gen_set_label(l2); | |
| 5722 | + } | |
| 5576 | 5723 | opn = "bc1any4t"; |
| 5577 | 5724 | not_likely: |
| 5578 | 5725 | ctx->hflags |= MIPS_HFLAG_BC; |
| ... | ... | @@ -5685,23 +5832,83 @@ static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf) |
| 5685 | 5832 | gen_store_gpr(cpu_T[0], rd); |
| 5686 | 5833 | } |
| 5687 | 5834 | |
| 5688 | -#define GEN_MOVCF(fmt) \ | |
| 5689 | -static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \ | |
| 5690 | -{ \ | |
| 5691 | - uint32_t ccbit; \ | |
| 5692 | - \ | |
| 5693 | - if (cc) { \ | |
| 5694 | - ccbit = 1 << (24 + cc); \ | |
| 5695 | - } else \ | |
| 5696 | - ccbit = 1 << 23; \ | |
| 5697 | - if (!tf) \ | |
| 5698 | - glue(gen_op_float_movf_, fmt)(ccbit); \ | |
| 5699 | - else \ | |
| 5700 | - glue(gen_op_float_movt_, fmt)(ccbit); \ | |
| 5835 | +static inline void gen_movcf_s (int cc, int tf) | |
| 5836 | +{ | |
| 5837 | + uint32_t ccbit; | |
| 5838 | + int cond; | |
| 5839 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5840 | + int l1 = gen_new_label(); | |
| 5841 | + | |
| 5842 | + if (cc) | |
| 5843 | + ccbit = 1 << (24 + cc); | |
| 5844 | + else | |
| 5845 | + ccbit = 1 << 23; | |
| 5846 | + | |
| 5847 | + if (tf) | |
| 5848 | + cond = TCG_COND_EQ; | |
| 5849 | + else | |
| 5850 | + cond = TCG_COND_NE; | |
| 5851 | + | |
| 5852 | + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); | |
| 5853 | + tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit); | |
| 5854 | + tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); | |
| 5855 | + tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]); | |
| 5856 | + gen_set_label(l1); | |
| 5857 | + tcg_temp_free(r_tmp1); | |
| 5701 | 5858 | } |
| 5702 | -GEN_MOVCF(d); | |
| 5703 | -GEN_MOVCF(s); | |
| 5704 | -#undef GEN_MOVCF | |
| 5859 | + | |
| 5860 | +static inline void gen_movcf_d (int cc, int tf) | |
| 5861 | +{ | |
| 5862 | + uint32_t ccbit; | |
| 5863 | + int cond; | |
| 5864 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32); | |
| 5865 | + int l1 = gen_new_label(); | |
| 5866 | + | |
| 5867 | + if (cc) | |
| 5868 | + ccbit = 1 << (24 + cc); | |
| 5869 | + else | |
| 5870 | + ccbit = 1 << 23; | |
| 5871 | + | |
| 5872 | + if (tf) | |
| 5873 | + cond = TCG_COND_EQ; | |
| 5874 | + else | |
| 5875 | + cond = TCG_COND_NE; | |
| 5876 | + | |
| 5877 | + tcg_gen_ld_i32(r_tmp1, current_fpu, offsetof(CPUMIPSFPUContext, fcr31)); | |
| 5878 | + tcg_gen_andi_i32(r_tmp1, r_tmp1, ccbit); | |
| 5879 | + tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1); | |
| 5880 | + tcg_gen_movi_i64(fpu64_T[2], fpu64_T[0]); | |
| 5881 | + gen_set_label(l1); | |
| 5882 | + tcg_temp_free(r_tmp1); | |
| 5883 | +} | |
| 5884 | + | |
| 5885 | +static inline void gen_movcf_ps (int cc, int tf) | |
| 5886 | +{ | |
| 5887 | + int cond; | |
| 5888 | + TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32); | |
| 5889 | + TCGv r_tmp2 = tcg_temp_local_new(TCG_TYPE_I32); | |
| 5890 | + int l1 = gen_new_label(); | |
| 5891 | + int l2 = gen_new_label(); | |
| 5892 | + | |
| 5893 | + if (tf) | |
| 5894 | + cond = TCG_COND_EQ; | |
| 5895 | + else | |
| 5896 | + cond = TCG_COND_NE; | |
| 5897 | + | |
| 5898 | + get_fp_cond(r_tmp1); | |
| 5899 | + tcg_gen_shri_i32(r_tmp1, r_tmp1, cc); | |
| 5900 | + tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x1); | |
| 5901 | + tcg_gen_brcondi_i32(cond, r_tmp2, 0, l1); | |
| 5902 | + tcg_gen_movi_i32(fpu32_T[2], fpu32_T[0]); | |
| 5903 | + gen_set_label(l1); | |
| 5904 | + tcg_gen_andi_i32(r_tmp2, r_tmp1, 0x2); | |
| 5905 | + tcg_gen_brcondi_i32(cond, r_tmp2, 0, l2); | |
| 5906 | + tcg_gen_movi_i32(fpu32h_T[2], fpu32h_T[0]); | |
| 5907 | + gen_set_label(l2); | |
| 5908 | + tcg_temp_free(r_tmp1); | |
| 5909 | + tcg_temp_free(r_tmp2); | |
| 5910 | +} | |
| 5911 | + | |
| 5705 | 5912 | |
| 5706 | 5913 | static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 5707 | 5914 | int ft, int fs, int fd, int cc) |
| ... | ... | @@ -5781,13 +5988,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 5781 | 5988 | break; |
| 5782 | 5989 | case FOP(4, 16): |
| 5783 | 5990 | gen_load_fpr32(fpu32_T[0], fs); |
| 5784 | - gen_op_float_sqrt_s(); | |
| 5991 | + tcg_gen_helper_0_0(do_float_sqrt_s); | |
| 5785 | 5992 | gen_store_fpr32(fpu32_T[2], fd); |
| 5786 | 5993 | opn = "sqrt.s"; |
| 5787 | 5994 | break; |
| 5788 | 5995 | case FOP(5, 16): |
| 5789 | 5996 | gen_load_fpr32(fpu32_T[0], fs); |
| 5790 | - gen_op_float_abs_s(); | |
| 5997 | + tcg_gen_helper_0_0(do_float_abs_s); | |
| 5791 | 5998 | gen_store_fpr32(fpu32_T[2], fd); |
| 5792 | 5999 | opn = "abs.s"; |
| 5793 | 6000 | break; |
| ... | ... | @@ -5798,7 +6005,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 5798 | 6005 | break; |
| 5799 | 6006 | case FOP(7, 16): |
| 5800 | 6007 | gen_load_fpr32(fpu32_T[0], fs); |
| 5801 | - gen_op_float_chs_s(); | |
| 6008 | + tcg_gen_helper_0_0(do_float_chs_s); | |
| 5802 | 6009 | gen_store_fpr32(fpu32_T[2], fd); |
| 5803 | 6010 | opn = "neg.s"; |
| 5804 | 6011 | break; |
| ... | ... | @@ -5855,10 +6062,9 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 5855 | 6062 | opn = "floor.w.s"; |
| 5856 | 6063 | break; |
| 5857 | 6064 | case FOP(17, 16): |
| 5858 | - gen_load_gpr(cpu_T[0], ft); | |
| 5859 | 6065 | gen_load_fpr32(fpu32_T[0], fs); |
| 5860 | 6066 | gen_load_fpr32(fpu32_T[2], fd); |
| 5861 | - gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1); | |
| 6067 | + gen_movcf_s((ft >> 2) & 0x7, ft & 0x1); | |
| 5862 | 6068 | gen_store_fpr32(fpu32_T[2], fd); |
| 5863 | 6069 | opn = "movcf.s"; |
| 5864 | 6070 | break; |
| ... | ... | @@ -5866,7 +6072,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 5866 | 6072 | gen_load_gpr(cpu_T[0], ft); |
| 5867 | 6073 | gen_load_fpr32(fpu32_T[0], fs); |
| 5868 | 6074 | gen_load_fpr32(fpu32_T[2], fd); |
| 5869 | - gen_op_float_movz_s(); | |
| 6075 | + { | |
| 6076 | + int l1 = gen_new_label(); | |
| 6077 | + | |
| 6078 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 6079 | + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); | |
| 6080 | + gen_set_label(l1); | |
| 6081 | + } | |
| 5870 | 6082 | gen_store_fpr32(fpu32_T[2], fd); |
| 5871 | 6083 | opn = "movz.s"; |
| 5872 | 6084 | break; |
| ... | ... | @@ -5874,7 +6086,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 5874 | 6086 | gen_load_gpr(cpu_T[0], ft); |
| 5875 | 6087 | gen_load_fpr32(fpu32_T[0], fs); |
| 5876 | 6088 | gen_load_fpr32(fpu32_T[2], fd); |
| 5877 | - gen_op_float_movn_s(); | |
| 6089 | + { | |
| 6090 | + int l1 = gen_new_label(); | |
| 6091 | + | |
| 6092 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); | |
| 6093 | + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); | |
| 6094 | + gen_set_label(l1); | |
| 6095 | + } | |
| 5878 | 6096 | gen_store_fpr32(fpu32_T[2], fd); |
| 5879 | 6097 | opn = "movn.s"; |
| 5880 | 6098 | break; |
| ... | ... | @@ -6019,14 +6237,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6019 | 6237 | case FOP(4, 17): |
| 6020 | 6238 | check_cp1_registers(ctx, fs | fd); |
| 6021 | 6239 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6022 | - gen_op_float_sqrt_d(); | |
| 6240 | + tcg_gen_helper_0_0(do_float_sqrt_d); | |
| 6023 | 6241 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6024 | 6242 | opn = "sqrt.d"; |
| 6025 | 6243 | break; |
| 6026 | 6244 | case FOP(5, 17): |
| 6027 | 6245 | check_cp1_registers(ctx, fs | fd); |
| 6028 | 6246 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6029 | - gen_op_float_abs_d(); | |
| 6247 | + tcg_gen_helper_0_0(do_float_abs_d); | |
| 6030 | 6248 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6031 | 6249 | opn = "abs.d"; |
| 6032 | 6250 | break; |
| ... | ... | @@ -6039,7 +6257,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6039 | 6257 | case FOP(7, 17): |
| 6040 | 6258 | check_cp1_registers(ctx, fs | fd); |
| 6041 | 6259 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6042 | - gen_op_float_chs_d(); | |
| 6260 | + tcg_gen_helper_0_0(do_float_chs_d); | |
| 6043 | 6261 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6044 | 6262 | opn = "neg.d"; |
| 6045 | 6263 | break; |
| ... | ... | @@ -6100,10 +6318,9 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6100 | 6318 | opn = "floor.w.d"; |
| 6101 | 6319 | break; |
| 6102 | 6320 | case FOP(17, 17): |
| 6103 | - gen_load_gpr(cpu_T[0], ft); | |
| 6104 | 6321 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6105 | 6322 | gen_load_fpr64(ctx, fpu64_T[2], fd); |
| 6106 | - gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1); | |
| 6323 | + gen_movcf_d((ft >> 2) & 0x7, ft & 0x1); | |
| 6107 | 6324 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6108 | 6325 | opn = "movcf.d"; |
| 6109 | 6326 | break; |
| ... | ... | @@ -6111,7 +6328,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6111 | 6328 | gen_load_gpr(cpu_T[0], ft); |
| 6112 | 6329 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6113 | 6330 | gen_load_fpr64(ctx, fpu64_T[2], fd); |
| 6114 | - gen_op_float_movz_d(); | |
| 6331 | + { | |
| 6332 | + int l1 = gen_new_label(); | |
| 6333 | + | |
| 6334 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 6335 | + tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); | |
| 6336 | + gen_set_label(l1); | |
| 6337 | + } | |
| 6115 | 6338 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6116 | 6339 | opn = "movz.d"; |
| 6117 | 6340 | break; |
| ... | ... | @@ -6119,7 +6342,13 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6119 | 6342 | gen_load_gpr(cpu_T[0], ft); |
| 6120 | 6343 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6121 | 6344 | gen_load_fpr64(ctx, fpu64_T[2], fd); |
| 6122 | - gen_op_float_movn_d(); | |
| 6345 | + { | |
| 6346 | + int l1 = gen_new_label(); | |
| 6347 | + | |
| 6348 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); | |
| 6349 | + tcg_gen_mov_i64(fpu64_T[2], fpu64_T[0]); | |
| 6350 | + gen_set_label(l1); | |
| 6351 | + } | |
| 6123 | 6352 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6124 | 6353 | opn = "movn.d"; |
| 6125 | 6354 | break; |
| ... | ... | @@ -6290,7 +6519,7 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6290 | 6519 | check_cp1_64bitmode(ctx); |
| 6291 | 6520 | gen_load_fpr32(fpu32_T[0], fs); |
| 6292 | 6521 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6293 | - gen_op_float_abs_ps(); | |
| 6522 | + tcg_gen_helper_0_0(do_float_abs_ps); | |
| 6294 | 6523 | gen_store_fpr32(fpu32_T[2], fd); |
| 6295 | 6524 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6296 | 6525 | opn = "abs.ps"; |
| ... | ... | @@ -6307,22 +6536,18 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6307 | 6536 | check_cp1_64bitmode(ctx); |
| 6308 | 6537 | gen_load_fpr32(fpu32_T[0], fs); |
| 6309 | 6538 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6310 | - gen_op_float_chs_ps(); | |
| 6539 | + tcg_gen_helper_0_0(do_float_chs_ps); | |
| 6311 | 6540 | gen_store_fpr32(fpu32_T[2], fd); |
| 6312 | 6541 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6313 | 6542 | opn = "neg.ps"; |
| 6314 | 6543 | break; |
| 6315 | 6544 | case FOP(17, 22): |
| 6316 | 6545 | check_cp1_64bitmode(ctx); |
| 6317 | - gen_load_gpr(cpu_T[0], ft); | |
| 6318 | 6546 | gen_load_fpr32(fpu32_T[0], fs); |
| 6319 | 6547 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6320 | 6548 | gen_load_fpr32(fpu32_T[2], fd); |
| 6321 | 6549 | gen_load_fpr32h(fpu32h_T[2], fd); |
| 6322 | - if (ft & 0x1) | |
| 6323 | - gen_op_float_movt_ps ((ft >> 2) & 0x7); | |
| 6324 | - else | |
| 6325 | - gen_op_float_movf_ps ((ft >> 2) & 0x7); | |
| 6550 | + gen_movcf_ps((ft >> 2) & 0x7, ft & 0x1); | |
| 6326 | 6551 | gen_store_fpr32(fpu32_T[2], fd); |
| 6327 | 6552 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6328 | 6553 | opn = "movcf.ps"; |
| ... | ... | @@ -6334,7 +6559,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6334 | 6559 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6335 | 6560 | gen_load_fpr32(fpu32_T[2], fd); |
| 6336 | 6561 | gen_load_fpr32h(fpu32h_T[2], fd); |
| 6337 | - gen_op_float_movz_ps(); | |
| 6562 | + { | |
| 6563 | + int l1 = gen_new_label(); | |
| 6564 | + | |
| 6565 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 6566 | + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); | |
| 6567 | + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); | |
| 6568 | + gen_set_label(l1); | |
| 6569 | + } | |
| 6338 | 6570 | gen_store_fpr32(fpu32_T[2], fd); |
| 6339 | 6571 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6340 | 6572 | opn = "movz.ps"; |
| ... | ... | @@ -6346,7 +6578,14 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6346 | 6578 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6347 | 6579 | gen_load_fpr32(fpu32_T[2], fd); |
| 6348 | 6580 | gen_load_fpr32h(fpu32h_T[2], fd); |
| 6349 | - gen_op_float_movn_ps(); | |
| 6581 | + { | |
| 6582 | + int l1 = gen_new_label(); | |
| 6583 | + | |
| 6584 | + tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_T[0], 0, l1); | |
| 6585 | + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); | |
| 6586 | + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); | |
| 6587 | + gen_set_label(l1); | |
| 6588 | + } | |
| 6350 | 6589 | gen_store_fpr32(fpu32_T[2], fd); |
| 6351 | 6590 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6352 | 6591 | opn = "movn.ps"; |
| ... | ... | @@ -6440,32 +6679,32 @@ static void gen_farith (DisasContext *ctx, uint32_t op1, |
| 6440 | 6679 | check_cp1_64bitmode(ctx); |
| 6441 | 6680 | gen_load_fpr32(fpu32_T[0], fs); |
| 6442 | 6681 | gen_load_fpr32(fpu32_T[1], ft); |
| 6443 | - gen_op_float_pll_ps(); | |
| 6444 | - gen_store_fpr64(ctx, fpu64_T[2], fd); | |
| 6682 | + gen_store_fpr32h(fpu32_T[0], fd); | |
| 6683 | + gen_store_fpr32(fpu32_T[1], fd); | |
| 6445 | 6684 | opn = "pll.ps"; |
| 6446 | 6685 | break; |
| 6447 | 6686 | case FOP(45, 22): |
| 6448 | 6687 | check_cp1_64bitmode(ctx); |
| 6449 | 6688 | gen_load_fpr32(fpu32_T[0], fs); |
| 6450 | 6689 | gen_load_fpr32h(fpu32h_T[1], ft); |
| 6451 | - gen_op_float_plu_ps(); | |
| 6452 | - gen_store_fpr64(ctx, fpu64_T[2], fd); | |
| 6690 | + gen_store_fpr32(fpu32h_T[1], fd); | |
| 6691 | + gen_store_fpr32h(fpu32_T[0], fd); | |
| 6453 | 6692 | opn = "plu.ps"; |
| 6454 | 6693 | break; |
| 6455 | 6694 | case FOP(46, 22): |
| 6456 | 6695 | check_cp1_64bitmode(ctx); |
| 6457 | 6696 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6458 | 6697 | gen_load_fpr32(fpu32_T[1], ft); |
| 6459 | - gen_op_float_pul_ps(); | |
| 6460 | - gen_store_fpr64(ctx, fpu64_T[2], fd); | |
| 6698 | + gen_store_fpr32(fpu32_T[1], fd); | |
| 6699 | + gen_store_fpr32h(fpu32h_T[0], fd); | |
| 6461 | 6700 | opn = "pul.ps"; |
| 6462 | 6701 | break; |
| 6463 | 6702 | case FOP(47, 22): |
| 6464 | 6703 | check_cp1_64bitmode(ctx); |
| 6465 | 6704 | gen_load_fpr32h(fpu32h_T[0], fs); |
| 6466 | 6705 | gen_load_fpr32h(fpu32h_T[1], ft); |
| 6467 | - gen_op_float_puu_ps(); | |
| 6468 | - gen_store_fpr64(ctx, fpu64_T[2], fd); | |
| 6706 | + gen_store_fpr32(fpu32h_T[1], fd); | |
| 6707 | + gen_store_fpr32h(fpu32h_T[0], fd); | |
| 6469 | 6708 | opn = "puu.ps"; |
| 6470 | 6709 | break; |
| 6471 | 6710 | case FOP(48, 22): |
| ... | ... | @@ -6595,10 +6834,32 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6595 | 6834 | case OPC_ALNV_PS: |
| 6596 | 6835 | check_cp1_64bitmode(ctx); |
| 6597 | 6836 | gen_load_gpr(cpu_T[0], fr); |
| 6598 | - gen_load_fpr64(ctx, fpu64_T[0], fs); | |
| 6599 | - gen_load_fpr64(ctx, fpu64_T[1], ft); | |
| 6600 | - gen_op_float_alnv_ps(); | |
| 6601 | - gen_store_fpr64(ctx, fpu64_T[2], fd); | |
| 6837 | + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], 0x7); | |
| 6838 | + gen_load_fpr32(fpu32_T[0], fs); | |
| 6839 | + gen_load_fpr32h(fpu32h_T[0], fs); | |
| 6840 | + gen_load_fpr32(fpu32_T[1], ft); | |
| 6841 | + gen_load_fpr32h(fpu32h_T[1], ft); | |
| 6842 | + { | |
| 6843 | + int l1 = gen_new_label(); | |
| 6844 | + int l2 = gen_new_label(); | |
| 6845 | + | |
| 6846 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 0, l1); | |
| 6847 | + tcg_gen_mov_i32(fpu32_T[2], fpu32_T[0]); | |
| 6848 | + tcg_gen_mov_i32(fpu32h_T[2], fpu32h_T[0]); | |
| 6849 | + tcg_gen_br(l2); | |
| 6850 | + gen_set_label(l1); | |
| 6851 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_T[0], 4, l2); | |
| 6852 | +#ifdef TARGET_WORDS_BIGENDIAN | |
| 6853 | + tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[0]); | |
| 6854 | + tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[1]); | |
| 6855 | +#else | |
| 6856 | + tcg_gen_mov_i32(fpu32h_T[2], fpu32_T[1]); | |
| 6857 | + tcg_gen_mov_i32(fpu32_T[2], fpu32h_T[0]); | |
| 6858 | +#endif | |
| 6859 | + gen_set_label(l2); | |
| 6860 | + } | |
| 6861 | + gen_store_fpr32(fpu32_T[2], fd); | |
| 6862 | + gen_store_fpr32h(fpu32h_T[2], fd); | |
| 6602 | 6863 | opn = "alnv.ps"; |
| 6603 | 6864 | break; |
| 6604 | 6865 | case OPC_MADD_S: |
| ... | ... | @@ -6606,7 +6867,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6606 | 6867 | gen_load_fpr32(fpu32_T[0], fs); |
| 6607 | 6868 | gen_load_fpr32(fpu32_T[1], ft); |
| 6608 | 6869 | gen_load_fpr32(fpu32_T[2], fr); |
| 6609 | - gen_op_float_muladd_s(); | |
| 6870 | + tcg_gen_helper_0_0(do_float_muladd_s); | |
| 6610 | 6871 | gen_store_fpr32(fpu32_T[2], fd); |
| 6611 | 6872 | opn = "madd.s"; |
| 6612 | 6873 | break; |
| ... | ... | @@ -6616,7 +6877,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6616 | 6877 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6617 | 6878 | gen_load_fpr64(ctx, fpu64_T[1], ft); |
| 6618 | 6879 | gen_load_fpr64(ctx, fpu64_T[2], fr); |
| 6619 | - gen_op_float_muladd_d(); | |
| 6880 | + tcg_gen_helper_0_0(do_float_muladd_d); | |
| 6620 | 6881 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6621 | 6882 | opn = "madd.d"; |
| 6622 | 6883 | break; |
| ... | ... | @@ -6628,7 +6889,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6628 | 6889 | gen_load_fpr32h(fpu32h_T[1], ft); |
| 6629 | 6890 | gen_load_fpr32(fpu32_T[2], fr); |
| 6630 | 6891 | gen_load_fpr32h(fpu32h_T[2], fr); |
| 6631 | - gen_op_float_muladd_ps(); | |
| 6892 | + tcg_gen_helper_0_0(do_float_muladd_ps); | |
| 6632 | 6893 | gen_store_fpr32(fpu32_T[2], fd); |
| 6633 | 6894 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6634 | 6895 | opn = "madd.ps"; |
| ... | ... | @@ -6638,7 +6899,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6638 | 6899 | gen_load_fpr32(fpu32_T[0], fs); |
| 6639 | 6900 | gen_load_fpr32(fpu32_T[1], ft); |
| 6640 | 6901 | gen_load_fpr32(fpu32_T[2], fr); |
| 6641 | - gen_op_float_mulsub_s(); | |
| 6902 | + tcg_gen_helper_0_0(do_float_mulsub_s); | |
| 6642 | 6903 | gen_store_fpr32(fpu32_T[2], fd); |
| 6643 | 6904 | opn = "msub.s"; |
| 6644 | 6905 | break; |
| ... | ... | @@ -6648,7 +6909,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6648 | 6909 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6649 | 6910 | gen_load_fpr64(ctx, fpu64_T[1], ft); |
| 6650 | 6911 | gen_load_fpr64(ctx, fpu64_T[2], fr); |
| 6651 | - gen_op_float_mulsub_d(); | |
| 6912 | + tcg_gen_helper_0_0(do_float_mulsub_d); | |
| 6652 | 6913 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6653 | 6914 | opn = "msub.d"; |
| 6654 | 6915 | break; |
| ... | ... | @@ -6660,7 +6921,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6660 | 6921 | gen_load_fpr32h(fpu32h_T[1], ft); |
| 6661 | 6922 | gen_load_fpr32(fpu32_T[2], fr); |
| 6662 | 6923 | gen_load_fpr32h(fpu32h_T[2], fr); |
| 6663 | - gen_op_float_mulsub_ps(); | |
| 6924 | + tcg_gen_helper_0_0(do_float_mulsub_ps); | |
| 6664 | 6925 | gen_store_fpr32(fpu32_T[2], fd); |
| 6665 | 6926 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6666 | 6927 | opn = "msub.ps"; |
| ... | ... | @@ -6670,7 +6931,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6670 | 6931 | gen_load_fpr32(fpu32_T[0], fs); |
| 6671 | 6932 | gen_load_fpr32(fpu32_T[1], ft); |
| 6672 | 6933 | gen_load_fpr32(fpu32_T[2], fr); |
| 6673 | - gen_op_float_nmuladd_s(); | |
| 6934 | + tcg_gen_helper_0_0(do_float_nmuladd_s); | |
| 6674 | 6935 | gen_store_fpr32(fpu32_T[2], fd); |
| 6675 | 6936 | opn = "nmadd.s"; |
| 6676 | 6937 | break; |
| ... | ... | @@ -6680,7 +6941,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6680 | 6941 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6681 | 6942 | gen_load_fpr64(ctx, fpu64_T[1], ft); |
| 6682 | 6943 | gen_load_fpr64(ctx, fpu64_T[2], fr); |
| 6683 | - gen_op_float_nmuladd_d(); | |
| 6944 | + tcg_gen_helper_0_0(do_float_nmuladd_d); | |
| 6684 | 6945 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6685 | 6946 | opn = "nmadd.d"; |
| 6686 | 6947 | break; |
| ... | ... | @@ -6692,7 +6953,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6692 | 6953 | gen_load_fpr32h(fpu32h_T[1], ft); |
| 6693 | 6954 | gen_load_fpr32(fpu32_T[2], fr); |
| 6694 | 6955 | gen_load_fpr32h(fpu32h_T[2], fr); |
| 6695 | - gen_op_float_nmuladd_ps(); | |
| 6956 | + tcg_gen_helper_0_0(do_float_nmuladd_ps); | |
| 6696 | 6957 | gen_store_fpr32(fpu32_T[2], fd); |
| 6697 | 6958 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6698 | 6959 | opn = "nmadd.ps"; |
| ... | ... | @@ -6702,7 +6963,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6702 | 6963 | gen_load_fpr32(fpu32_T[0], fs); |
| 6703 | 6964 | gen_load_fpr32(fpu32_T[1], ft); |
| 6704 | 6965 | gen_load_fpr32(fpu32_T[2], fr); |
| 6705 | - gen_op_float_nmulsub_s(); | |
| 6966 | + tcg_gen_helper_0_0(do_float_nmulsub_s); | |
| 6706 | 6967 | gen_store_fpr32(fpu32_T[2], fd); |
| 6707 | 6968 | opn = "nmsub.s"; |
| 6708 | 6969 | break; |
| ... | ... | @@ -6712,7 +6973,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6712 | 6973 | gen_load_fpr64(ctx, fpu64_T[0], fs); |
| 6713 | 6974 | gen_load_fpr64(ctx, fpu64_T[1], ft); |
| 6714 | 6975 | gen_load_fpr64(ctx, fpu64_T[2], fr); |
| 6715 | - gen_op_float_nmulsub_d(); | |
| 6976 | + tcg_gen_helper_0_0(do_float_nmulsub_d); | |
| 6716 | 6977 | gen_store_fpr64(ctx, fpu64_T[2], fd); |
| 6717 | 6978 | opn = "nmsub.d"; |
| 6718 | 6979 | break; |
| ... | ... | @@ -6724,7 +6985,7 @@ static void gen_flt3_arith (DisasContext *ctx, uint32_t opc, |
| 6724 | 6985 | gen_load_fpr32h(fpu32h_T[1], ft); |
| 6725 | 6986 | gen_load_fpr32(fpu32_T[2], fr); |
| 6726 | 6987 | gen_load_fpr32h(fpu32h_T[2], fr); |
| 6727 | - gen_op_float_nmulsub_ps(); | |
| 6988 | + tcg_gen_helper_0_0(do_float_nmulsub_ps); | |
| 6728 | 6989 | gen_store_fpr32(fpu32_T[2], fd); |
| 6729 | 6990 | gen_store_fpr32h(fpu32h_T[2], fd); |
| 6730 | 6991 | opn = "nmsub.ps"; | ... | ... |