Commit d03ef5116bb436437aef6054a284ebfd922612a2
1 parent
f4b147f6
target-ppc: convert rotation instructions to TCG
Also fix rlwimi and rldimi for corner cases. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5555 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
138 additions
and
159 deletions
target-ppc/op.c
| @@ -752,63 +752,7 @@ void OPPROTO op_subfzeo_64 (void) | @@ -752,63 +752,7 @@ void OPPROTO op_subfzeo_64 (void) | ||
| 752 | } | 752 | } |
| 753 | #endif | 753 | #endif |
| 754 | 754 | ||
| 755 | -/*** Integer logical ***/ | ||
| 756 | -/* or */ | ||
| 757 | -void OPPROTO op_or (void) | ||
| 758 | -{ | ||
| 759 | - T0 |= T1; | ||
| 760 | - RETURN(); | ||
| 761 | -} | ||
| 762 | - | ||
| 763 | -/*** Integer rotate ***/ | ||
| 764 | -void OPPROTO op_rotl32_T0_T1 (void) | ||
| 765 | -{ | ||
| 766 | - T0 = rotl32(T0, T1 & 0x1F); | ||
| 767 | - RETURN(); | ||
| 768 | -} | ||
| 769 | - | ||
| 770 | -void OPPROTO op_rotli32_T0 (void) | ||
| 771 | -{ | ||
| 772 | - T0 = rotl32(T0, PARAM1); | ||
| 773 | - RETURN(); | ||
| 774 | -} | ||
| 775 | - | ||
| 776 | -#if defined(TARGET_PPC64) | ||
| 777 | -void OPPROTO op_rotl64_T0_T1 (void) | ||
| 778 | -{ | ||
| 779 | - T0 = rotl64(T0, T1 & 0x3F); | ||
| 780 | - RETURN(); | ||
| 781 | -} | ||
| 782 | - | ||
| 783 | -void OPPROTO op_rotli64_T0 (void) | ||
| 784 | -{ | ||
| 785 | - T0 = rotl64(T0, PARAM1); | ||
| 786 | - RETURN(); | ||
| 787 | -} | ||
| 788 | -#endif | ||
| 789 | - | ||
| 790 | /*** Integer shift ***/ | 755 | /*** Integer shift ***/ |
| 791 | -/* shift right word */ | ||
| 792 | -void OPPROTO op_sli_T0 (void) | ||
| 793 | -{ | ||
| 794 | - T0 = T0 << PARAM1; | ||
| 795 | - RETURN(); | ||
| 796 | -} | ||
| 797 | - | ||
| 798 | -void OPPROTO op_srli_T0 (void) | ||
| 799 | -{ | ||
| 800 | - T0 = (uint32_t)T0 >> PARAM1; | ||
| 801 | - RETURN(); | ||
| 802 | -} | ||
| 803 | - | ||
| 804 | -#if defined(TARGET_PPC64) | ||
| 805 | -void OPPROTO op_srli_T0_64 (void) | ||
| 806 | -{ | ||
| 807 | - T0 = (uint64_t)T0 >> PARAM1; | ||
| 808 | - RETURN(); | ||
| 809 | -} | ||
| 810 | -#endif | ||
| 811 | - | ||
| 812 | void OPPROTO op_srli_T1 (void) | 756 | void OPPROTO op_srli_T1 (void) |
| 813 | { | 757 | { |
| 814 | T1 = (uint32_t)T1 >> PARAM1; | 758 | T1 = (uint32_t)T1 >> PARAM1; |
target-ppc/translate.c
| @@ -1488,40 +1488,40 @@ GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B) | @@ -1488,40 +1488,40 @@ GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B) | ||
| 1488 | /* rlwimi & rlwimi. */ | 1488 | /* rlwimi & rlwimi. */ |
| 1489 | GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | 1489 | GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
| 1490 | { | 1490 | { |
| 1491 | - target_ulong mask; | ||
| 1492 | uint32_t mb, me, sh; | 1491 | uint32_t mb, me, sh; |
| 1493 | 1492 | ||
| 1494 | mb = MB(ctx->opcode); | 1493 | mb = MB(ctx->opcode); |
| 1495 | me = ME(ctx->opcode); | 1494 | me = ME(ctx->opcode); |
| 1496 | sh = SH(ctx->opcode); | 1495 | sh = SH(ctx->opcode); |
| 1497 | - if (likely(sh == 0)) { | ||
| 1498 | - if (likely(mb == 0 && me == 31)) { | ||
| 1499 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1500 | - goto do_store; | ||
| 1501 | - } else if (likely(mb == 31 && me == 0)) { | ||
| 1502 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | ||
| 1503 | - goto do_store; | 1496 | + if (likely(sh == 0 && mb == 0 && me == 31)) { |
| 1497 | + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); | ||
| 1498 | + } else { | ||
| 1499 | + TCGv t0, t1; | ||
| 1500 | + target_ulong mask; | ||
| 1501 | + | ||
| 1502 | + t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1503 | + t1 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1504 | + if (likely(sh == 0)) { | ||
| 1505 | + tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1506 | + } else { | ||
| 1507 | + tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]); | ||
| 1508 | + tcg_gen_shli_tl(t0, t1, sh); | ||
| 1509 | + tcg_gen_shri_tl(t1, t1, 32 - sh); | ||
| 1510 | + tcg_gen_or_tl(t0, t0, t1); | ||
| 1504 | } | 1511 | } |
| 1505 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1506 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]); | ||
| 1507 | - goto do_mask; | ||
| 1508 | - } | ||
| 1509 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1510 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]); | ||
| 1511 | - gen_op_rotli32_T0(SH(ctx->opcode)); | ||
| 1512 | - do_mask: | ||
| 1513 | #if defined(TARGET_PPC64) | 1512 | #if defined(TARGET_PPC64) |
| 1514 | - mb += 32; | ||
| 1515 | - me += 32; | ||
| 1516 | -#endif | ||
| 1517 | - mask = MASK(mb, me); | ||
| 1518 | - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], mask); | ||
| 1519 | - tcg_gen_andi_tl(cpu_T[1], cpu_T[1], ~mask); | ||
| 1520 | - gen_op_or(); | ||
| 1521 | - do_store: | ||
| 1522 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | 1513 | + mb += 32; |
| 1514 | + me += 32; | ||
| 1515 | +#endif | ||
| 1516 | + mask = MASK(mb, me); | ||
| 1517 | + tcg_gen_andi_tl(t0, t0, mask); | ||
| 1518 | + tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask); | ||
| 1519 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | ||
| 1520 | + tcg_temp_free(t0); | ||
| 1521 | + tcg_temp_free(t1); | ||
| 1522 | + } | ||
| 1523 | if (unlikely(Rc(ctx->opcode) != 0)) | 1523 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 1524 | - gen_set_Rc0(ctx, cpu_T[0]); | 1524 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); |
| 1525 | } | 1525 | } |
| 1526 | /* rlwinm & rlwinm. */ | 1526 | /* rlwinm & rlwinm. */ |
| 1527 | GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | 1527 | GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
| @@ -1531,56 +1531,78 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | @@ -1531,56 +1531,78 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | ||
| 1531 | sh = SH(ctx->opcode); | 1531 | sh = SH(ctx->opcode); |
| 1532 | mb = MB(ctx->opcode); | 1532 | mb = MB(ctx->opcode); |
| 1533 | me = ME(ctx->opcode); | 1533 | me = ME(ctx->opcode); |
| 1534 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1535 | - if (likely(sh == 0)) { | ||
| 1536 | - goto do_mask; | ||
| 1537 | - } | ||
| 1538 | - if (likely(mb == 0)) { | ||
| 1539 | - if (likely(me == 31)) { | ||
| 1540 | - gen_op_rotli32_T0(sh); | ||
| 1541 | - goto do_store; | ||
| 1542 | - } else if (likely(me == (31 - sh))) { | ||
| 1543 | - gen_op_sli_T0(sh); | ||
| 1544 | - goto do_store; | 1534 | + |
| 1535 | + if (likely(mb == 0 && me == (31 - sh))) { | ||
| 1536 | + if (likely(sh == 0)) { | ||
| 1537 | + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); | ||
| 1538 | + } else { | ||
| 1539 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1540 | + tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1541 | + tcg_gen_shli_tl(t0, t0, sh); | ||
| 1542 | + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0); | ||
| 1543 | + tcg_temp_free(t0); | ||
| 1545 | } | 1544 | } |
| 1546 | - } else if (likely(me == 31)) { | ||
| 1547 | - if (likely(sh == (32 - mb))) { | ||
| 1548 | - gen_op_srli_T0(mb); | ||
| 1549 | - goto do_store; | 1545 | + } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) { |
| 1546 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1547 | + tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1548 | + tcg_gen_shri_tl(t0, t0, mb); | ||
| 1549 | + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0); | ||
| 1550 | + tcg_temp_free(t0); | ||
| 1551 | + } else { | ||
| 1552 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1553 | + if (likely(sh != 0)) { | ||
| 1554 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1555 | + tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1556 | + tcg_gen_shli_tl(t1, t0, sh); | ||
| 1557 | + tcg_gen_shri_tl(t0, t0, 32 - sh); | ||
| 1558 | + tcg_gen_or_tl(t0, t0, t1); | ||
| 1559 | + tcg_temp_free(t1); | ||
| 1560 | + } else { | ||
| 1561 | + tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1550 | } | 1562 | } |
| 1551 | - } | ||
| 1552 | - gen_op_rotli32_T0(sh); | ||
| 1553 | - do_mask: | ||
| 1554 | #if defined(TARGET_PPC64) | 1563 | #if defined(TARGET_PPC64) |
| 1555 | - mb += 32; | ||
| 1556 | - me += 32; | 1564 | + mb += 32; |
| 1565 | + me += 32; | ||
| 1557 | #endif | 1566 | #endif |
| 1558 | - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me)); | ||
| 1559 | - do_store: | ||
| 1560 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | 1567 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me)); |
| 1568 | + tcg_temp_free(t0); | ||
| 1569 | + } | ||
| 1561 | if (unlikely(Rc(ctx->opcode) != 0)) | 1570 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 1562 | - gen_set_Rc0(ctx, cpu_T[0]); | 1571 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); |
| 1563 | } | 1572 | } |
| 1564 | /* rlwnm & rlwnm. */ | 1573 | /* rlwnm & rlwnm. */ |
| 1565 | GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) | 1574 | GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
| 1566 | { | 1575 | { |
| 1567 | uint32_t mb, me; | 1576 | uint32_t mb, me; |
| 1577 | + TCGv t0, t1, t2, t3; | ||
| 1568 | 1578 | ||
| 1569 | mb = MB(ctx->opcode); | 1579 | mb = MB(ctx->opcode); |
| 1570 | me = ME(ctx->opcode); | 1580 | me = ME(ctx->opcode); |
| 1571 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1572 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | ||
| 1573 | - gen_op_rotl32_T0_T1(); | 1581 | + t0 = tcg_temp_new(TCG_TYPE_TL); |
| 1582 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f); | ||
| 1583 | + t1 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1584 | + tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]); | ||
| 1585 | + t2 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1586 | + tcg_gen_shl_tl(t2, t1, t0); | ||
| 1587 | + t3 = tcg_const_tl(32); | ||
| 1588 | + tcg_gen_sub_tl(t0, t3, t0); | ||
| 1589 | + tcg_temp_free(t3); | ||
| 1590 | + tcg_gen_shr_tl(t1, t1, t0); | ||
| 1591 | + tcg_temp_free(t0); | ||
| 1592 | + tcg_gen_or_tl(t2, t2, t1); | ||
| 1593 | + tcg_temp_free(t1); | ||
| 1574 | if (unlikely(mb != 0 || me != 31)) { | 1594 | if (unlikely(mb != 0 || me != 31)) { |
| 1575 | #if defined(TARGET_PPC64) | 1595 | #if defined(TARGET_PPC64) |
| 1576 | mb += 32; | 1596 | mb += 32; |
| 1577 | me += 32; | 1597 | me += 32; |
| 1578 | #endif | 1598 | #endif |
| 1579 | - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me)); | 1599 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t2, MASK(mb, me)); |
| 1600 | + } else { | ||
| 1601 | + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t2); | ||
| 1580 | } | 1602 | } |
| 1581 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | 1603 | + tcg_temp_free(t2); |
| 1582 | if (unlikely(Rc(ctx->opcode) != 0)) | 1604 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 1583 | - gen_set_Rc0(ctx, cpu_T[0]); | 1605 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); |
| 1584 | } | 1606 | } |
| 1585 | 1607 | ||
| 1586 | #if defined(TARGET_PPC64) | 1608 | #if defined(TARGET_PPC64) |
| @@ -1618,31 +1640,30 @@ GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \ | @@ -1618,31 +1640,30 @@ GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \ | ||
| 1618 | static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb, | 1640 | static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb, |
| 1619 | uint32_t me, uint32_t sh) | 1641 | uint32_t me, uint32_t sh) |
| 1620 | { | 1642 | { |
| 1621 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1622 | - if (likely(sh == 0)) { | ||
| 1623 | - goto do_mask; | ||
| 1624 | - } | ||
| 1625 | - if (likely(mb == 0)) { | ||
| 1626 | - if (likely(me == 63)) { | ||
| 1627 | - gen_op_rotli64_T0(sh); | ||
| 1628 | - goto do_store; | ||
| 1629 | - } else if (likely(me == (63 - sh))) { | ||
| 1630 | - gen_op_sli_T0(sh); | ||
| 1631 | - goto do_store; | 1643 | + if (likely(sh != 0 && mb == 0 && me == (63 - sh))) { |
| 1644 | + tcg_gen_shli_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh); | ||
| 1645 | + } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) { | ||
| 1646 | + tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb); | ||
| 1647 | + } else { | ||
| 1648 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1649 | + if (likely(sh != 0)) { | ||
| 1650 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1651 | + tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | ||
| 1652 | + tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 64 - sh); | ||
| 1653 | + tcg_gen_or_tl(t0, t0, t1); | ||
| 1654 | + tcg_temp_free(t1); | ||
| 1655 | + } else { | ||
| 1656 | + tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1632 | } | 1657 | } |
| 1633 | - } else if (likely(me == 63)) { | ||
| 1634 | - if (likely(sh == (64 - mb))) { | ||
| 1635 | - gen_op_srli_T0_64(mb); | ||
| 1636 | - goto do_store; | 1658 | + if (likely(mb == 0 && me == 63)) { |
| 1659 | + tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0); | ||
| 1660 | + } else { | ||
| 1661 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t0, MASK(mb, me)); | ||
| 1637 | } | 1662 | } |
| 1663 | + tcg_temp_free(t0); | ||
| 1638 | } | 1664 | } |
| 1639 | - gen_op_rotli64_T0(sh); | ||
| 1640 | - do_mask: | ||
| 1641 | - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me)); | ||
| 1642 | - do_store: | ||
| 1643 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | ||
| 1644 | if (unlikely(Rc(ctx->opcode) != 0)) | 1665 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 1645 | - gen_set_Rc0(ctx, cpu_T[0]); | 1666 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); |
| 1646 | } | 1667 | } |
| 1647 | /* rldicl - rldicl. */ | 1668 | /* rldicl - rldicl. */ |
| 1648 | static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn) | 1669 | static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn) |
| @@ -1678,15 +1699,27 @@ GEN_PPC64_R4(rldic, 0x1E, 0x04); | @@ -1678,15 +1699,27 @@ GEN_PPC64_R4(rldic, 0x1E, 0x04); | ||
| 1678 | static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb, | 1699 | static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb, |
| 1679 | uint32_t me) | 1700 | uint32_t me) |
| 1680 | { | 1701 | { |
| 1681 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1682 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | ||
| 1683 | - gen_op_rotl64_T0_T1(); | 1702 | + TCGv t0, t1, t2; |
| 1703 | + | ||
| 1704 | + mb = MB(ctx->opcode); | ||
| 1705 | + me = ME(ctx->opcode); | ||
| 1706 | + t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1707 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f); | ||
| 1708 | + t1 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1709 | + tcg_gen_shl_tl(t1, cpu_gpr[rS(ctx->opcode)], t0); | ||
| 1710 | + t2 = tcg_const_tl(32); | ||
| 1711 | + tcg_gen_sub_tl(t0, t2, t0); | ||
| 1712 | + tcg_temp_free(t2); | ||
| 1713 | + tcg_gen_shr_tl(t0, cpu_gpr[rS(ctx->opcode)], t0); | ||
| 1714 | + tcg_gen_or_tl(t1, t1, t0); | ||
| 1715 | + tcg_temp_free(t0); | ||
| 1684 | if (unlikely(mb != 0 || me != 63)) { | 1716 | if (unlikely(mb != 0 || me != 63)) { |
| 1685 | - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], MASK(mb, me)); | ||
| 1686 | - } | ||
| 1687 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | 1717 | + tcg_gen_andi_tl(cpu_gpr[rA(ctx->opcode)], t1, MASK(mb, me)); |
| 1718 | + } else | ||
| 1719 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t1); | ||
| 1720 | + tcg_temp_free(t1); | ||
| 1688 | if (unlikely(Rc(ctx->opcode) != 0)) | 1721 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 1689 | - gen_set_Rc0(ctx, cpu_T[0]); | 1722 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); |
| 1690 | } | 1723 | } |
| 1691 | 1724 | ||
| 1692 | /* rldcl - rldcl. */ | 1725 | /* rldcl - rldcl. */ |
| @@ -1710,33 +1743,35 @@ GEN_PPC64_R2(rldcr, 0x1E, 0x09); | @@ -1710,33 +1743,35 @@ GEN_PPC64_R2(rldcr, 0x1E, 0x09); | ||
| 1710 | /* rldimi - rldimi. */ | 1743 | /* rldimi - rldimi. */ |
| 1711 | static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) | 1744 | static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) |
| 1712 | { | 1745 | { |
| 1713 | - uint64_t mask; | ||
| 1714 | uint32_t sh, mb, me; | 1746 | uint32_t sh, mb, me; |
| 1715 | 1747 | ||
| 1716 | sh = SH(ctx->opcode) | (shn << 5); | 1748 | sh = SH(ctx->opcode) | (shn << 5); |
| 1717 | mb = MB(ctx->opcode) | (mbn << 5); | 1749 | mb = MB(ctx->opcode) | (mbn << 5); |
| 1718 | me = 63 - sh; | 1750 | me = 63 - sh; |
| 1719 | - if (likely(sh == 0)) { | ||
| 1720 | - if (likely(mb == 0)) { | ||
| 1721 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1722 | - goto do_store; | 1751 | + if (unlikely(sh == 0 && mb == 0)) { |
| 1752 | + tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]); | ||
| 1753 | + } else { | ||
| 1754 | + TCGv t0, t1; | ||
| 1755 | + target_ulong mask; | ||
| 1756 | + | ||
| 1757 | + t0 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1758 | + t1 = tcg_temp_new(TCG_TYPE_TL); | ||
| 1759 | + if (likely(sh == 0)) { | ||
| 1760 | + tcg_gen_mov_tl(t0, cpu_gpr[rS(ctx->opcode)]); | ||
| 1761 | + } else { | ||
| 1762 | + tcg_gen_shli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh); | ||
| 1763 | + tcg_gen_shri_tl(t1, cpu_gpr[rS(ctx->opcode)], 64 - sh); | ||
| 1764 | + tcg_gen_or_tl(t0, t0, t1); | ||
| 1723 | } | 1765 | } |
| 1724 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1725 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]); | ||
| 1726 | - goto do_mask; | 1766 | + mask = MASK(mb, me); |
| 1767 | + tcg_gen_andi_tl(t0, t0, mask); | ||
| 1768 | + tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask); | ||
| 1769 | + tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1); | ||
| 1770 | + tcg_temp_free(t0); | ||
| 1771 | + tcg_temp_free(t1); | ||
| 1727 | } | 1772 | } |
| 1728 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rS(ctx->opcode)]); | ||
| 1729 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rA(ctx->opcode)]); | ||
| 1730 | - gen_op_rotli64_T0(sh); | ||
| 1731 | - do_mask: | ||
| 1732 | - mask = MASK(mb, me); | ||
| 1733 | - tcg_gen_andi_tl(cpu_T[0], cpu_T[0], mask); | ||
| 1734 | - tcg_gen_andi_tl(cpu_T[1], cpu_T[1], ~mask); | ||
| 1735 | - gen_op_or(); | ||
| 1736 | - do_store: | ||
| 1737 | - tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_T[0]); | ||
| 1738 | if (unlikely(Rc(ctx->opcode) != 0)) | 1773 | if (unlikely(Rc(ctx->opcode) != 0)) |
| 1739 | - gen_set_Rc0(ctx, cpu_T[0]); | 1774 | + gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]); |
| 1740 | } | 1775 | } |
| 1741 | GEN_PPC64_R4(rldimi, 0x1E, 0x06); | 1776 | GEN_PPC64_R4(rldimi, 0x1E, 0x06); |
| 1742 | #endif | 1777 | #endif |