Commit d03ef5116bb436437aef6054a284ebfd922612a2

Authored by aurel32
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
target-ppc/op.c
... ... @@ -752,63 +752,7 @@ void OPPROTO op_subfzeo_64 (void)
752 752 }
753 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 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 756 void OPPROTO op_srli_T1 (void)
813 757 {
814 758 T1 = (uint32_t)T1 >> PARAM1;
... ...
target-ppc/translate.c
... ... @@ -1488,40 +1488,40 @@ GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
1488 1488 /* rlwimi & rlwimi. */
1489 1489 GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1490 1490 {
1491   - target_ulong mask;
1492 1491 uint32_t mb, me, sh;
1493 1492  
1494 1493 mb = MB(ctx->opcode);
1495 1494 me = ME(ctx->opcode);
1496 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 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 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 1526 /* rlwinm & rlwinm. */
1527 1527 GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
... ... @@ -1531,56 +1531,78 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1531 1531 sh = SH(ctx->opcode);
1532 1532 mb = MB(ctx->opcode);
1533 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 1563 #if defined(TARGET_PPC64)
1555   - mb += 32;
1556   - me += 32;
  1564 + mb += 32;
  1565 + me += 32;
1557 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 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 1573 /* rlwnm & rlwnm. */
1565 1574 GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1566 1575 {
1567 1576 uint32_t mb, me;
  1577 + TCGv t0, t1, t2, t3;
1568 1578  
1569 1579 mb = MB(ctx->opcode);
1570 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 1594 if (unlikely(mb != 0 || me != 31)) {
1575 1595 #if defined(TARGET_PPC64)
1576 1596 mb += 32;
1577 1597 me += 32;
1578 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 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 1608 #if defined(TARGET_PPC64)
... ... @@ -1618,31 +1640,30 @@ GEN_HANDLER2(name##3, stringify(name), opc1, opc2 | 0x11, 0xFF, 0x00000000, \
1618 1640 static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
1619 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 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 1668 /* rldicl - rldicl. */
1648 1669 static always_inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
... ... @@ -1678,15 +1699,27 @@ GEN_PPC64_R4(rldic, 0x1E, 0x04);
1678 1699 static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
1679 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 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 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 1725 /* rldcl - rldcl. */
... ... @@ -1710,33 +1743,35 @@ GEN_PPC64_R2(rldcr, 0x1E, 0x09);
1710 1743 /* rldimi - rldimi. */
1711 1744 static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1712 1745 {
1713   - uint64_t mask;
1714 1746 uint32_t sh, mb, me;
1715 1747  
1716 1748 sh = SH(ctx->opcode) | (shn << 5);
1717 1749 mb = MB(ctx->opcode) | (mbn << 5);
1718 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 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 1776 GEN_PPC64_R4(rldimi, 0x1E, 0x06);
1742 1777 #endif
... ...