Commit 22e0e173376d702bdd9757d308924b6df7cd6529
1 parent
3b63c04e
target-ppc: convert POWER bridge instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5891 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
219 additions
and
287 deletions
target-ppc/helper.h
| ... | ... | @@ -171,5 +171,13 @@ DEF_HELPER_1(602_mfrom, tl, tl) |
| 171 | 171 | #endif |
| 172 | 172 | |
| 173 | 173 | DEF_HELPER_3(dlmzb, tl, tl, tl, i32) |
| 174 | +DEF_HELPER_1(clcs, tl, i32) | |
| 175 | +#if !defined(CONFIG_USER_ONLY) | |
| 176 | +DEF_HELPER_1(rac, tl, tl) | |
| 177 | +#endif | |
| 178 | +DEF_HELPER_2(div, tl, tl, tl) | |
| 179 | +DEF_HELPER_2(divo, tl, tl, tl) | |
| 180 | +DEF_HELPER_2(divs, tl, tl, tl) | |
| 181 | +DEF_HELPER_2(divso, tl, tl, tl) | |
| 174 | 182 | |
| 175 | 183 | #include "def-helper.h" | ... | ... |
target-ppc/op.c
| ... | ... | @@ -370,112 +370,6 @@ void OPPROTO op_store_601_batu (void) |
| 370 | 370 | } |
| 371 | 371 | #endif /* !defined(CONFIG_USER_ONLY) */ |
| 372 | 372 | |
| 373 | -/* PowerPC 601 specific instructions (POWER bridge) */ | |
| 374 | -/* XXX: those micro-ops need tests ! */ | |
| 375 | -void OPPROTO op_POWER_abs (void) | |
| 376 | -{ | |
| 377 | - if ((int32_t)T0 == INT32_MIN) | |
| 378 | - T0 = INT32_MAX; | |
| 379 | - else if ((int32_t)T0 < 0) | |
| 380 | - T0 = -T0; | |
| 381 | - RETURN(); | |
| 382 | -} | |
| 383 | - | |
| 384 | -void OPPROTO op_POWER_abso (void) | |
| 385 | -{ | |
| 386 | - do_POWER_abso(); | |
| 387 | - RETURN(); | |
| 388 | -} | |
| 389 | - | |
| 390 | -void OPPROTO op_POWER_clcs (void) | |
| 391 | -{ | |
| 392 | - do_POWER_clcs(); | |
| 393 | - RETURN(); | |
| 394 | -} | |
| 395 | - | |
| 396 | -void OPPROTO op_POWER_div (void) | |
| 397 | -{ | |
| 398 | - do_POWER_div(); | |
| 399 | - RETURN(); | |
| 400 | -} | |
| 401 | - | |
| 402 | -void OPPROTO op_POWER_divo (void) | |
| 403 | -{ | |
| 404 | - do_POWER_divo(); | |
| 405 | - RETURN(); | |
| 406 | -} | |
| 407 | - | |
| 408 | -void OPPROTO op_POWER_divs (void) | |
| 409 | -{ | |
| 410 | - do_POWER_divs(); | |
| 411 | - RETURN(); | |
| 412 | -} | |
| 413 | - | |
| 414 | -void OPPROTO op_POWER_divso (void) | |
| 415 | -{ | |
| 416 | - do_POWER_divso(); | |
| 417 | - RETURN(); | |
| 418 | -} | |
| 419 | - | |
| 420 | -void OPPROTO op_POWER_doz (void) | |
| 421 | -{ | |
| 422 | - if ((int32_t)T1 > (int32_t)T0) | |
| 423 | - T0 = T1 - T0; | |
| 424 | - else | |
| 425 | - T0 = 0; | |
| 426 | - RETURN(); | |
| 427 | -} | |
| 428 | - | |
| 429 | -void OPPROTO op_POWER_dozo (void) | |
| 430 | -{ | |
| 431 | - do_POWER_dozo(); | |
| 432 | - RETURN(); | |
| 433 | -} | |
| 434 | - | |
| 435 | -void OPPROTO op_POWER_maskg (void) | |
| 436 | -{ | |
| 437 | - do_POWER_maskg(); | |
| 438 | - RETURN(); | |
| 439 | -} | |
| 440 | - | |
| 441 | -void OPPROTO op_POWER_maskir (void) | |
| 442 | -{ | |
| 443 | - T0 = (T0 & ~T2) | (T1 & T2); | |
| 444 | - RETURN(); | |
| 445 | -} | |
| 446 | - | |
| 447 | -void OPPROTO op_POWER_mul (void) | |
| 448 | -{ | |
| 449 | - uint64_t tmp; | |
| 450 | - | |
| 451 | - tmp = (uint64_t)T0 * (uint64_t)T1; | |
| 452 | - env->spr[SPR_MQ] = tmp >> 32; | |
| 453 | - T0 = tmp; | |
| 454 | - RETURN(); | |
| 455 | -} | |
| 456 | - | |
| 457 | -void OPPROTO op_POWER_mulo (void) | |
| 458 | -{ | |
| 459 | - do_POWER_mulo(); | |
| 460 | - RETURN(); | |
| 461 | -} | |
| 462 | - | |
| 463 | -void OPPROTO op_POWER_nabs (void) | |
| 464 | -{ | |
| 465 | - if (T0 > 0) | |
| 466 | - T0 = -T0; | |
| 467 | - RETURN(); | |
| 468 | -} | |
| 469 | - | |
| 470 | -void OPPROTO op_POWER_nabso (void) | |
| 471 | -{ | |
| 472 | - /* nabs never overflows */ | |
| 473 | - if (T0 > 0) | |
| 474 | - T0 = -T0; | |
| 475 | - env->xer &= ~(1 << XER_OV); | |
| 476 | - RETURN(); | |
| 477 | -} | |
| 478 | - | |
| 479 | 373 | /* POWER instructions not implemented in PowerPC 601 */ |
| 480 | 374 | #if !defined(CONFIG_USER_ONLY) |
| 481 | 375 | void OPPROTO op_POWER_mfsri (void) |
| ... | ... | @@ -484,12 +378,6 @@ void OPPROTO op_POWER_mfsri (void) |
| 484 | 378 | T0 = env->sr[T1]; |
| 485 | 379 | RETURN(); |
| 486 | 380 | } |
| 487 | - | |
| 488 | -void OPPROTO op_POWER_rac (void) | |
| 489 | -{ | |
| 490 | - do_POWER_rac(); | |
| 491 | - RETURN(); | |
| 492 | -} | |
| 493 | 381 | #endif |
| 494 | 382 | |
| 495 | 383 | /* PowerPC 4xx specific micro-ops */ | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -1587,147 +1587,101 @@ void do_POWER_abso (void) |
| 1587 | 1587 | } |
| 1588 | 1588 | } |
| 1589 | 1589 | |
| 1590 | -void do_POWER_clcs (void) | |
| 1590 | +target_ulong helper_clcs (uint32_t arg) | |
| 1591 | 1591 | { |
| 1592 | - switch (T0) { | |
| 1592 | + switch (arg) { | |
| 1593 | 1593 | case 0x0CUL: |
| 1594 | 1594 | /* Instruction cache line size */ |
| 1595 | - T0 = env->icache_line_size; | |
| 1595 | + return env->icache_line_size; | |
| 1596 | 1596 | break; |
| 1597 | 1597 | case 0x0DUL: |
| 1598 | 1598 | /* Data cache line size */ |
| 1599 | - T0 = env->dcache_line_size; | |
| 1599 | + return env->dcache_line_size; | |
| 1600 | 1600 | break; |
| 1601 | 1601 | case 0x0EUL: |
| 1602 | 1602 | /* Minimum cache line size */ |
| 1603 | - T0 = env->icache_line_size < env->dcache_line_size ? | |
| 1604 | - env->icache_line_size : env->dcache_line_size; | |
| 1603 | + return (env->icache_line_size < env->dcache_line_size) ? | |
| 1604 | + env->icache_line_size : env->dcache_line_size; | |
| 1605 | 1605 | break; |
| 1606 | 1606 | case 0x0FUL: |
| 1607 | 1607 | /* Maximum cache line size */ |
| 1608 | - T0 = env->icache_line_size > env->dcache_line_size ? | |
| 1609 | - env->icache_line_size : env->dcache_line_size; | |
| 1608 | + return (env->icache_line_size > env->dcache_line_size) ? | |
| 1609 | + env->icache_line_size : env->dcache_line_size; | |
| 1610 | 1610 | break; |
| 1611 | 1611 | default: |
| 1612 | 1612 | /* Undefined */ |
| 1613 | + return 0; | |
| 1613 | 1614 | break; |
| 1614 | 1615 | } |
| 1615 | 1616 | } |
| 1616 | 1617 | |
| 1617 | -void do_POWER_div (void) | |
| 1618 | +target_ulong helper_div (target_ulong arg1, target_ulong arg2) | |
| 1618 | 1619 | { |
| 1619 | - uint64_t tmp; | |
| 1620 | + uint64_t tmp = (uint64_t)arg1 << 32 | env->spr[SPR_MQ]; | |
| 1620 | 1621 | |
| 1621 | - if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) || | |
| 1622 | - (int32_t)T1 == 0) { | |
| 1623 | - T0 = UINT32_MAX * ((uint32_t)T0 >> 31); | |
| 1622 | + if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) || | |
| 1623 | + (int32_t)arg2 == 0) { | |
| 1624 | 1624 | env->spr[SPR_MQ] = 0; |
| 1625 | + return INT32_MIN; | |
| 1625 | 1626 | } else { |
| 1626 | - tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ]; | |
| 1627 | - env->spr[SPR_MQ] = tmp % T1; | |
| 1628 | - T0 = tmp / (int32_t)T1; | |
| 1627 | + env->spr[SPR_MQ] = tmp % arg2; | |
| 1628 | + return tmp / (int32_t)arg2; | |
| 1629 | 1629 | } |
| 1630 | 1630 | } |
| 1631 | 1631 | |
| 1632 | -void do_POWER_divo (void) | |
| 1632 | +target_ulong helper_divo (target_ulong arg1, target_ulong arg2) | |
| 1633 | 1633 | { |
| 1634 | - int64_t tmp; | |
| 1634 | + uint64_t tmp = (uint64_t)arg1 << 32 | env->spr[SPR_MQ]; | |
| 1635 | 1635 | |
| 1636 | - if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) || | |
| 1637 | - (int32_t)T1 == 0) { | |
| 1638 | - T0 = UINT32_MAX * ((uint32_t)T0 >> 31); | |
| 1639 | - env->spr[SPR_MQ] = 0; | |
| 1636 | + if (((int32_t)tmp == INT32_MIN && (int32_t)arg2 == (int32_t)-1) || | |
| 1637 | + (int32_t)arg2 == 0) { | |
| 1640 | 1638 | env->xer |= (1 << XER_OV) | (1 << XER_SO); |
| 1641 | - } else { | |
| 1642 | - tmp = ((uint64_t)T0 << 32) | env->spr[SPR_MQ]; | |
| 1643 | - env->spr[SPR_MQ] = tmp % T1; | |
| 1644 | - tmp /= (int32_t)T1; | |
| 1645 | - if (tmp > (int64_t)INT32_MAX || tmp < (int64_t)INT32_MIN) { | |
| 1646 | - env->xer |= (1 << XER_OV) | (1 << XER_SO); | |
| 1647 | - } else { | |
| 1648 | - env->xer &= ~(1 << XER_OV); | |
| 1649 | - } | |
| 1650 | - T0 = tmp; | |
| 1651 | - } | |
| 1652 | -} | |
| 1653 | - | |
| 1654 | -void do_POWER_divs (void) | |
| 1655 | -{ | |
| 1656 | - if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) || | |
| 1657 | - (int32_t)T1 == 0) { | |
| 1658 | - T0 = UINT32_MAX * ((uint32_t)T0 >> 31); | |
| 1659 | - env->spr[SPR_MQ] = 0; | |
| 1660 | - } else { | |
| 1661 | - env->spr[SPR_MQ] = T0 % T1; | |
| 1662 | - T0 = (int32_t)T0 / (int32_t)T1; | |
| 1663 | - } | |
| 1664 | -} | |
| 1665 | - | |
| 1666 | -void do_POWER_divso (void) | |
| 1667 | -{ | |
| 1668 | - if (((int32_t)T0 == INT32_MIN && (int32_t)T1 == (int32_t)-1) || | |
| 1669 | - (int32_t)T1 == 0) { | |
| 1670 | - T0 = UINT32_MAX * ((uint32_t)T0 >> 31); | |
| 1671 | 1639 | env->spr[SPR_MQ] = 0; |
| 1672 | - env->xer |= (1 << XER_OV) | (1 << XER_SO); | |
| 1640 | + return INT32_MIN; | |
| 1673 | 1641 | } else { |
| 1674 | - T0 = (int32_t)T0 / (int32_t)T1; | |
| 1675 | - env->spr[SPR_MQ] = (int32_t)T0 % (int32_t)T1; | |
| 1676 | - env->xer &= ~(1 << XER_OV); | |
| 1677 | - } | |
| 1678 | -} | |
| 1679 | - | |
| 1680 | -void do_POWER_dozo (void) | |
| 1681 | -{ | |
| 1682 | - if ((int32_t)T1 > (int32_t)T0) { | |
| 1683 | - T2 = T0; | |
| 1684 | - T0 = T1 - T0; | |
| 1685 | - if (((uint32_t)(~T2) ^ (uint32_t)T1 ^ UINT32_MAX) & | |
| 1686 | - ((uint32_t)(~T2) ^ (uint32_t)T0) & (1UL << 31)) { | |
| 1642 | + env->spr[SPR_MQ] = tmp % arg2; | |
| 1643 | + tmp /= (int32_t)arg2; | |
| 1644 | + if ((int32_t)tmp != tmp) { | |
| 1687 | 1645 | env->xer |= (1 << XER_OV) | (1 << XER_SO); |
| 1688 | 1646 | } else { |
| 1689 | 1647 | env->xer &= ~(1 << XER_OV); |
| 1690 | 1648 | } |
| 1691 | - } else { | |
| 1692 | - T0 = 0; | |
| 1693 | - env->xer &= ~(1 << XER_OV); | |
| 1649 | + return tmp; | |
| 1694 | 1650 | } |
| 1695 | 1651 | } |
| 1696 | 1652 | |
| 1697 | -void do_POWER_maskg (void) | |
| 1653 | +target_ulong helper_divs (target_ulong arg1, target_ulong arg2) | |
| 1698 | 1654 | { |
| 1699 | - uint32_t ret; | |
| 1700 | - | |
| 1701 | - if ((uint32_t)T0 == (uint32_t)(T1 + 1)) { | |
| 1702 | - ret = UINT32_MAX; | |
| 1655 | + if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) || | |
| 1656 | + (int32_t)arg2 == 0) { | |
| 1657 | + env->spr[SPR_MQ] = 0; | |
| 1658 | + return INT32_MIN; | |
| 1703 | 1659 | } else { |
| 1704 | - ret = (UINT32_MAX >> ((uint32_t)T0)) ^ | |
| 1705 | - ((UINT32_MAX >> ((uint32_t)T1)) >> 1); | |
| 1706 | - if ((uint32_t)T0 > (uint32_t)T1) | |
| 1707 | - ret = ~ret; | |
| 1660 | + env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2; | |
| 1661 | + return (int32_t)arg1 / (int32_t)arg2; | |
| 1708 | 1662 | } |
| 1709 | - T0 = ret; | |
| 1710 | 1663 | } |
| 1711 | 1664 | |
| 1712 | -void do_POWER_mulo (void) | |
| 1665 | +target_ulong helper_divso (target_ulong arg1, target_ulong arg2) | |
| 1713 | 1666 | { |
| 1714 | - uint64_t tmp; | |
| 1715 | - | |
| 1716 | - tmp = (uint64_t)T0 * (uint64_t)T1; | |
| 1717 | - env->spr[SPR_MQ] = tmp >> 32; | |
| 1718 | - T0 = tmp; | |
| 1719 | - if (tmp >> 32 != ((uint64_t)T0 >> 16) * ((uint64_t)T1 >> 16)) { | |
| 1667 | + if (((int32_t)arg1 == INT32_MIN && (int32_t)arg2 == (int32_t)-1) || | |
| 1668 | + (int32_t)arg2 == 0) { | |
| 1720 | 1669 | env->xer |= (1 << XER_OV) | (1 << XER_SO); |
| 1670 | + env->spr[SPR_MQ] = 0; | |
| 1671 | + return INT32_MIN; | |
| 1721 | 1672 | } else { |
| 1722 | 1673 | env->xer &= ~(1 << XER_OV); |
| 1674 | + env->spr[SPR_MQ] = (int32_t)arg1 % (int32_t)arg2; | |
| 1675 | + return (int32_t)arg1 / (int32_t)arg2; | |
| 1723 | 1676 | } |
| 1724 | 1677 | } |
| 1725 | 1678 | |
| 1726 | 1679 | #if !defined (CONFIG_USER_ONLY) |
| 1727 | -void do_POWER_rac (void) | |
| 1680 | +target_ulong helper_rac (target_ulong addr) | |
| 1728 | 1681 | { |
| 1729 | 1682 | mmu_ctx_t ctx; |
| 1730 | 1683 | int nb_BATs; |
| 1684 | + target_ulong ret = 0; | |
| 1731 | 1685 | |
| 1732 | 1686 | /* We don't have to generate many instances of this instruction, |
| 1733 | 1687 | * as rac is supervisor only. |
| ... | ... | @@ -1735,9 +1689,10 @@ void do_POWER_rac (void) |
| 1735 | 1689 | /* XXX: FIX THIS: Pretend we have no BAT */ |
| 1736 | 1690 | nb_BATs = env->nb_BATs; |
| 1737 | 1691 | env->nb_BATs = 0; |
| 1738 | - if (get_physical_address(env, &ctx, T0, 0, ACCESS_INT) == 0) | |
| 1739 | - T0 = ctx.raddr; | |
| 1692 | + if (get_physical_address(env, &ctx, addr, 0, ACCESS_INT) == 0) | |
| 1693 | + ret = ctx.raddr; | |
| 1740 | 1694 | env->nb_BATs = nb_BATs; |
| 1695 | + return ret; | |
| 1741 | 1696 | } |
| 1742 | 1697 | |
| 1743 | 1698 | void helper_rfsvc (void) | ... | ... |
target-ppc/op_helper.h
| ... | ... | @@ -33,15 +33,6 @@ void do_store_msr (void); |
| 33 | 33 | #endif |
| 34 | 34 | |
| 35 | 35 | /* POWER / PowerPC 601 specific helpers */ |
| 36 | -void do_POWER_abso (void); | |
| 37 | -void do_POWER_clcs (void); | |
| 38 | -void do_POWER_div (void); | |
| 39 | -void do_POWER_divo (void); | |
| 40 | -void do_POWER_divs (void); | |
| 41 | -void do_POWER_divso (void); | |
| 42 | -void do_POWER_dozo (void); | |
| 43 | -void do_POWER_maskg (void); | |
| 44 | -void do_POWER_mulo (void); | |
| 45 | 36 | #if !defined(CONFIG_USER_ONLY) |
| 46 | 37 | void do_POWER_rac (void); |
| 47 | 38 | void do_store_hid0_601 (void); | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -4435,105 +4435,139 @@ GEN_HANDLER(ecowx, 0x1F, 0x16, 0x09, 0x00000001, PPC_EXTERN) |
| 4435 | 4435 | /* abs - abs. */ |
| 4436 | 4436 | GEN_HANDLER(abs, 0x1F, 0x08, 0x0B, 0x0000F800, PPC_POWER_BR) |
| 4437 | 4437 | { |
| 4438 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4439 | - gen_op_POWER_abs(); | |
| 4440 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4438 | + int l1 = gen_new_label(); | |
| 4439 | + int l2 = gen_new_label(); | |
| 4440 | + tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1); | |
| 4441 | + tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4442 | + tcg_gen_br(l2); | |
| 4443 | + gen_set_label(l1); | |
| 4444 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4445 | + gen_set_label(l2); | |
| 4441 | 4446 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4442 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4447 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4443 | 4448 | } |
| 4444 | 4449 | |
| 4445 | 4450 | /* abso - abso. */ |
| 4446 | 4451 | GEN_HANDLER(abso, 0x1F, 0x08, 0x1B, 0x0000F800, PPC_POWER_BR) |
| 4447 | 4452 | { |
| 4448 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4449 | - gen_op_POWER_abso(); | |
| 4450 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4453 | + int l1 = gen_new_label(); | |
| 4454 | + int l2 = gen_new_label(); | |
| 4455 | + int l3 = gen_new_label(); | |
| 4456 | + /* Start with XER OV disabled, the most likely case */ | |
| 4457 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV)); | |
| 4458 | + tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2); | |
| 4459 | + tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1); | |
| 4460 | + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO)); | |
| 4461 | + tcg_gen_br(l2); | |
| 4462 | + gen_set_label(l1); | |
| 4463 | + tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4464 | + tcg_gen_br(l3); | |
| 4465 | + gen_set_label(l2); | |
| 4466 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4467 | + gen_set_label(l3); | |
| 4451 | 4468 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4452 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4469 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4453 | 4470 | } |
| 4454 | 4471 | |
| 4455 | 4472 | /* clcs */ |
| 4456 | 4473 | GEN_HANDLER(clcs, 0x1F, 0x10, 0x13, 0x0000F800, PPC_POWER_BR) |
| 4457 | 4474 | { |
| 4458 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4459 | - gen_op_POWER_clcs(); | |
| 4475 | + TCGv_i32 t0 = tcg_const_i32(rA(ctx->opcode)); | |
| 4476 | + gen_helper_clcs(cpu_gpr[rD(ctx->opcode)], t0); | |
| 4477 | + tcg_temp_free_i32(t0); | |
| 4460 | 4478 | /* Rc=1 sets CR0 to an undefined state */ |
| 4461 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4462 | 4479 | } |
| 4463 | 4480 | |
| 4464 | 4481 | /* div - div. */ |
| 4465 | 4482 | GEN_HANDLER(div, 0x1F, 0x0B, 0x0A, 0x00000000, PPC_POWER_BR) |
| 4466 | 4483 | { |
| 4467 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4468 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4469 | - gen_op_POWER_div(); | |
| 4470 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4484 | + gen_helper_div(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 4471 | 4485 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4472 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4486 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4473 | 4487 | } |
| 4474 | 4488 | |
| 4475 | 4489 | /* divo - divo. */ |
| 4476 | 4490 | GEN_HANDLER(divo, 0x1F, 0x0B, 0x1A, 0x00000000, PPC_POWER_BR) |
| 4477 | 4491 | { |
| 4478 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4479 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4480 | - gen_op_POWER_divo(); | |
| 4481 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4492 | + gen_helper_divo(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 4482 | 4493 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4483 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4494 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4484 | 4495 | } |
| 4485 | 4496 | |
| 4486 | 4497 | /* divs - divs. */ |
| 4487 | 4498 | GEN_HANDLER(divs, 0x1F, 0x0B, 0x0B, 0x00000000, PPC_POWER_BR) |
| 4488 | 4499 | { |
| 4489 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4490 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4491 | - gen_op_POWER_divs(); | |
| 4492 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4500 | + gen_helper_divs(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 4493 | 4501 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4494 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4502 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4495 | 4503 | } |
| 4496 | 4504 | |
| 4497 | 4505 | /* divso - divso. */ |
| 4498 | 4506 | GEN_HANDLER(divso, 0x1F, 0x0B, 0x1B, 0x00000000, PPC_POWER_BR) |
| 4499 | 4507 | { |
| 4500 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4501 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4502 | - gen_op_POWER_divso(); | |
| 4503 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4508 | + gen_helper_divso(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 4504 | 4509 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4505 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4510 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4506 | 4511 | } |
| 4507 | 4512 | |
| 4508 | 4513 | /* doz - doz. */ |
| 4509 | 4514 | GEN_HANDLER(doz, 0x1F, 0x08, 0x08, 0x00000000, PPC_POWER_BR) |
| 4510 | 4515 | { |
| 4511 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4512 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4513 | - gen_op_POWER_doz(); | |
| 4514 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4516 | + int l1 = gen_new_label(); | |
| 4517 | + int l2 = gen_new_label(); | |
| 4518 | + tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1); | |
| 4519 | + tcg_gen_sub_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4520 | + tcg_gen_br(l2); | |
| 4521 | + gen_set_label(l1); | |
| 4522 | + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); | |
| 4523 | + gen_set_label(l2); | |
| 4515 | 4524 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4516 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4525 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4517 | 4526 | } |
| 4518 | 4527 | |
| 4519 | 4528 | /* dozo - dozo. */ |
| 4520 | 4529 | GEN_HANDLER(dozo, 0x1F, 0x08, 0x18, 0x00000000, PPC_POWER_BR) |
| 4521 | 4530 | { |
| 4522 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4523 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4524 | - gen_op_POWER_dozo(); | |
| 4525 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4531 | + int l1 = gen_new_label(); | |
| 4532 | + int l2 = gen_new_label(); | |
| 4533 | + TCGv t0 = tcg_temp_new(); | |
| 4534 | + TCGv t1 = tcg_temp_new(); | |
| 4535 | + TCGv t2 = tcg_temp_new(); | |
| 4536 | + /* Start with XER OV disabled, the most likely case */ | |
| 4537 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV)); | |
| 4538 | + tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1); | |
| 4539 | + tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4540 | + tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4541 | + tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0); | |
| 4542 | + tcg_gen_andc_tl(t1, t1, t2); | |
| 4543 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0); | |
| 4544 | + tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2); | |
| 4545 | + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO)); | |
| 4546 | + tcg_gen_br(l2); | |
| 4547 | + gen_set_label(l1); | |
| 4548 | + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); | |
| 4549 | + gen_set_label(l2); | |
| 4550 | + tcg_temp_free(t0); | |
| 4551 | + tcg_temp_free(t1); | |
| 4552 | + tcg_temp_free(t2); | |
| 4526 | 4553 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4527 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4554 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4528 | 4555 | } |
| 4529 | 4556 | |
| 4530 | 4557 | /* dozi */ |
| 4531 | 4558 | GEN_HANDLER(dozi, 0x09, 0xFF, 0xFF, 0x00000000, PPC_POWER_BR) |
| 4532 | 4559 | { |
| 4533 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4534 | - tcg_gen_movi_tl(cpu_T[1], SIMM(ctx->opcode)); | |
| 4535 | - gen_op_POWER_doz(); | |
| 4536 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4560 | + target_long simm = SIMM(ctx->opcode); | |
| 4561 | + int l1 = gen_new_label(); | |
| 4562 | + int l2 = gen_new_label(); | |
| 4563 | + tcg_gen_brcondi_tl(TCG_COND_LT, cpu_gpr[rA(ctx->opcode)], simm, l1); | |
| 4564 | + tcg_gen_subfi_tl(cpu_gpr[rD(ctx->opcode)], simm, cpu_gpr[rA(ctx->opcode)]); | |
| 4565 | + tcg_gen_br(l2); | |
| 4566 | + gen_set_label(l1); | |
| 4567 | + tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0); | |
| 4568 | + gen_set_label(l2); | |
| 4569 | + if (unlikely(Rc(ctx->opcode) != 0)) | |
| 4570 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4537 | 4571 | } |
| 4538 | 4572 | |
| 4539 | 4573 | /* lscbx - lscbx. */ |
| ... | ... | @@ -4561,66 +4595,120 @@ GEN_HANDLER(lscbx, 0x1F, 0x15, 0x08, 0x00000000, PPC_POWER_BR) |
| 4561 | 4595 | /* maskg - maskg. */ |
| 4562 | 4596 | GEN_HANDLER(maskg, 0x1F, 0x1D, 0x00, 0x00000000, PPC_POWER_BR) |
| 4563 | 4597 | { |
| 4564 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | |
| 4565 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4566 | - gen_op_POWER_maskg(); | |
| 4567 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4598 | + int l1 = gen_new_label(); | |
| 4599 | + TCGv t0 = tcg_temp_new(); | |
| 4600 | + TCGv t1 = tcg_temp_new(); | |
| 4601 | + TCGv t2 = tcg_temp_new(); | |
| 4602 | + TCGv t3 = tcg_temp_new(); | |
| 4603 | + tcg_gen_movi_tl(t3, 0xFFFFFFFF); | |
| 4604 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1F); | |
| 4605 | + tcg_gen_andi_tl(t1, cpu_gpr[rS(ctx->opcode)], 0x1F); | |
| 4606 | + tcg_gen_addi_tl(t2, t0, 1); | |
| 4607 | + tcg_gen_shr_tl(t2, t3, t2); | |
| 4608 | + tcg_gen_shr_tl(t3, t3, t1); | |
| 4609 | + tcg_gen_xor_tl(cpu_gpr[rA(ctx->opcode)], t2, t3); | |
| 4610 | + tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1); | |
| 4611 | + tcg_gen_neg_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4612 | + gen_set_label(l1); | |
| 4613 | + tcg_temp_free(t0); | |
| 4614 | + tcg_temp_free(t1); | |
| 4615 | + tcg_temp_free(t2); | |
| 4616 | + tcg_temp_free(t3); | |
| 4568 | 4617 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4569 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4618 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4570 | 4619 | } |
| 4571 | 4620 | |
| 4572 | 4621 | /* maskir - maskir. */ |
| 4573 | 4622 | GEN_HANDLER(maskir, 0x1F, 0x1D, 0x10, 0x00000000, PPC_POWER_BR) |
| 4574 | 4623 | { |
| 4575 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4576 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rS(ctx->opcode)]); | |
| 4577 | - tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rB(ctx->opcode)]); | |
| 4578 | - gen_op_POWER_maskir(); | |
| 4579 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | |
| 4624 | + TCGv t0 = tcg_temp_new(); | |
| 4625 | + TCGv t1 = tcg_temp_new(); | |
| 4626 | + tcg_gen_and_tl(t0, cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 4627 | + tcg_gen_andc_tl(t1, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 4628 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | |
| 4629 | + tcg_temp_free(t0); | |
| 4630 | + tcg_temp_free(t1); | |
| 4580 | 4631 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4581 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4632 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); | |
| 4582 | 4633 | } |
| 4583 | 4634 | |
| 4584 | 4635 | /* mul - mul. */ |
| 4585 | 4636 | GEN_HANDLER(mul, 0x1F, 0x0B, 0x03, 0x00000000, PPC_POWER_BR) |
| 4586 | 4637 | { |
| 4587 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4588 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4589 | - gen_op_POWER_mul(); | |
| 4590 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4638 | + TCGv_i64 t0 = tcg_temp_new_i64(); | |
| 4639 | + TCGv_i64 t1 = tcg_temp_new_i64(); | |
| 4640 | + TCGv t2 = tcg_temp_new(); | |
| 4641 | + tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); | |
| 4642 | + tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); | |
| 4643 | + tcg_gen_mul_i64(t0, t0, t1); | |
| 4644 | + tcg_gen_trunc_i64_tl(t2, t0); | |
| 4645 | + gen_store_spr(SPR_MQ, t2); | |
| 4646 | + tcg_gen_shri_i64(t1, t0, 32); | |
| 4647 | + tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1); | |
| 4648 | + tcg_temp_free_i64(t0); | |
| 4649 | + tcg_temp_free_i64(t1); | |
| 4650 | + tcg_temp_free(t2); | |
| 4591 | 4651 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4592 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4652 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4593 | 4653 | } |
| 4594 | 4654 | |
| 4595 | 4655 | /* mulo - mulo. */ |
| 4596 | 4656 | GEN_HANDLER(mulo, 0x1F, 0x0B, 0x13, 0x00000000, PPC_POWER_BR) |
| 4597 | 4657 | { |
| 4598 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4599 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 4600 | - gen_op_POWER_mulo(); | |
| 4601 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4658 | + int l1 = gen_new_label(); | |
| 4659 | + TCGv_i64 t0 = tcg_temp_new_i64(); | |
| 4660 | + TCGv_i64 t1 = tcg_temp_new_i64(); | |
| 4661 | + TCGv t2 = tcg_temp_new(); | |
| 4662 | + /* Start with XER OV disabled, the most likely case */ | |
| 4663 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV)); | |
| 4664 | + tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]); | |
| 4665 | + tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]); | |
| 4666 | + tcg_gen_mul_i64(t0, t0, t1); | |
| 4667 | + tcg_gen_trunc_i64_tl(t2, t0); | |
| 4668 | + gen_store_spr(SPR_MQ, t2); | |
| 4669 | + tcg_gen_shri_i64(t1, t0, 32); | |
| 4670 | + tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t1); | |
| 4671 | + tcg_gen_ext32s_i64(t1, t0); | |
| 4672 | + tcg_gen_brcond_i64(TCG_COND_EQ, t0, t1, l1); | |
| 4673 | + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO)); | |
| 4674 | + gen_set_label(l1); | |
| 4675 | + tcg_temp_free_i64(t0); | |
| 4676 | + tcg_temp_free_i64(t1); | |
| 4677 | + tcg_temp_free(t2); | |
| 4602 | 4678 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4603 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4679 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4604 | 4680 | } |
| 4605 | 4681 | |
| 4606 | 4682 | /* nabs - nabs. */ |
| 4607 | 4683 | GEN_HANDLER(nabs, 0x1F, 0x08, 0x0F, 0x00000000, PPC_POWER_BR) |
| 4608 | 4684 | { |
| 4609 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4610 | - gen_op_POWER_nabs(); | |
| 4611 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4685 | + int l1 = gen_new_label(); | |
| 4686 | + int l2 = gen_new_label(); | |
| 4687 | + tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1); | |
| 4688 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4689 | + tcg_gen_br(l2); | |
| 4690 | + gen_set_label(l1); | |
| 4691 | + tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4692 | + gen_set_label(l2); | |
| 4612 | 4693 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4613 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4694 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4614 | 4695 | } |
| 4615 | 4696 | |
| 4616 | 4697 | /* nabso - nabso. */ |
| 4617 | 4698 | GEN_HANDLER(nabso, 0x1F, 0x08, 0x1F, 0x00000000, PPC_POWER_BR) |
| 4618 | 4699 | { |
| 4619 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 4620 | - gen_op_POWER_nabso(); | |
| 4621 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 4700 | + int l1 = gen_new_label(); | |
| 4701 | + int l2 = gen_new_label(); | |
| 4702 | + tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1); | |
| 4703 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4704 | + tcg_gen_br(l2); | |
| 4705 | + gen_set_label(l1); | |
| 4706 | + tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 4707 | + gen_set_label(l2); | |
| 4708 | + /* nabs never overflows */ | |
| 4709 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV)); | |
| 4622 | 4710 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 4623 | - gen_set_Rc0(ctx, cpu_T[0]); | |
| 4711 | + gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]); | |
| 4624 | 4712 | } |
| 4625 | 4713 | |
| 4626 | 4714 | /* rlmi - rlmi. */ |
| ... | ... | @@ -5122,13 +5210,15 @@ GEN_HANDLER(rac, 0x1F, 0x12, 0x19, 0x00000001, PPC_POWER) |
| 5122 | 5210 | #if defined(CONFIG_USER_ONLY) |
| 5123 | 5211 | GEN_EXCP_PRIVOPC(ctx); |
| 5124 | 5212 | #else |
| 5213 | + TCGv t0; | |
| 5125 | 5214 | if (unlikely(!ctx->supervisor)) { |
| 5126 | 5215 | GEN_EXCP_PRIVOPC(ctx); |
| 5127 | 5216 | return; |
| 5128 | 5217 | } |
| 5129 | - gen_addr_reg_index(cpu_T[0], ctx); | |
| 5130 | - gen_op_POWER_rac(); | |
| 5131 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 5218 | + t0 = tcg_temp_new(); | |
| 5219 | + gen_addr_reg_index(t0, ctx); | |
| 5220 | + gen_helper_rac(cpu_gpr[rD(ctx->opcode)], t0); | |
| 5221 | + tcg_temp_free(t0); | |
| 5132 | 5222 | #endif |
| 5133 | 5223 | } |
| 5134 | 5224 | ... | ... |