trunk/src/emu/cpu/rsp/rsp.c
| r241990 | r241991 | |
| 349 | 349 | |
| 350 | 350 | /*****************************************************************************/ |
| 351 | 351 | |
| 352 | | #if 0 |
| 353 | | static const int vector_elements[16][8] = |
| 354 | | { |
| 355 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, // none |
| 356 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, // ??? |
| 357 | | { 0, 0, 2, 2, 4, 4, 6, 6 }, // 0q |
| 358 | | { 1, 1, 3, 3, 5, 5, 7, 7 }, // 1q |
| 359 | | { 0, 0, 0, 0, 4, 4, 4, 4 }, // 0h |
| 360 | | { 1, 1, 1, 1, 5, 5, 5, 5 }, // 1h |
| 361 | | { 2, 2, 2, 2, 6, 6, 6, 6 }, // 2h |
| 362 | | { 3, 3, 3, 3, 7, 7, 7, 7 }, // 3h |
| 363 | | { 0, 0, 0, 0, 0, 0, 0, 0 }, // 0 |
| 364 | | { 1, 1, 1, 1, 1, 1, 1, 1 }, // 1 |
| 365 | | { 2, 2, 2, 2, 2, 2, 2, 2 }, // 2 |
| 366 | | { 3, 3, 3, 3, 3, 3, 3, 3 }, // 3 |
| 367 | | { 4, 4, 4, 4, 4, 4, 4, 4 }, // 4 |
| 368 | | { 5, 5, 5, 5, 5, 5, 5, 5 }, // 5 |
| 369 | | { 6, 6, 6, 6, 6, 6, 6, 6 }, // 6 |
| 370 | | { 7, 7, 7, 7, 7, 7, 7, 7 }, // 7 |
| 371 | | }; |
| 372 | | #endif |
| 373 | | |
| 374 | 352 | void rsp_device::resolve_cb() |
| 375 | 353 | { |
| 376 | 354 | m_dp_reg_r_func.resolve(); |
trunk/src/emu/cpu/rsp/rspcp2d.c
| r241990 | r241991 | |
| 60 | 60 | #define ACCUM_M(x) (UINT16)m_accum[x].w[2] |
| 61 | 61 | #define ACCUM_L(x) (UINT16)m_accum[x].w[1] |
| 62 | 62 | #define ACCUM_LL(x) (UINT16)m_accum[x].w[0] |
| 63 | #define ACCUM(x) m_accum[x].q |
| 63 | 64 | |
| 64 | 65 | #define SET_ACCUM_H(v, x) m_accum[x].w[3] = v; |
| 65 | 66 | #define SET_ACCUM_M(v, x) m_accum[x].w[2] = v; |
| 66 | 67 | #define SET_ACCUM_L(v, x) m_accum[x].w[1] = v; |
| 67 | 68 | #define SET_ACCUM_LL(v, x) m_accum[x].w[0] = v; |
| 69 | #define SET_ACCUM(v, x) m_accum[x].q = v; |
| 68 | 70 | |
| 69 | | #define GET_VS1(out, i) out = VREG_S(VS1REG, i) |
| 70 | | #define GET_VS2(out, i) out = VREG_S(VS2REG, VEC_EL_2(EL, i)) |
| 71 | #define GET_VS1(out, i) out = VREG_S(vs1reg, i) |
| 72 | #define GET_VS2(out, i) out = VREG_S(vs2reg, VEC_EL_2(el, i)) |
| 71 | 73 | |
| 72 | 74 | #define CARRY_FLAG(x) (m_vflag[CARRY][x & 7] != 0 ? 0xffff : 0) |
| 73 | 75 | #define COMPARE_FLAG(x) (m_vflag[COMPARE][x & 7] != 0 ? 0xffff : 0) |
| r241990 | r241991 | |
| 93 | 95 | #define CLEAR_ZERO_FLAG(x) { m_vflag[ZERO][x & 7] = 0; } |
| 94 | 96 | #define CLEAR_CLIP2_FLAG(x) { m_vflag[CLIP2][x & 7] = 0; } |
| 95 | 97 | |
| 98 | #define CACHE_VALUES() \ |
| 99 | const int op = m_op; \ |
| 100 | const int vdreg = VDREG; \ |
| 101 | const int vs1reg = VS1REG; \ |
| 102 | const int vs2reg = VS2REG; \ |
| 103 | const int el = EL; |
| 104 | |
| 96 | 105 | #define WRITEBACK_RESULT() { \ |
| 97 | | W_VREG_S(VDREG, 0) = m_vres[0]; \ |
| 98 | | W_VREG_S(VDREG, 1) = m_vres[1]; \ |
| 99 | | W_VREG_S(VDREG, 2) = m_vres[2]; \ |
| 100 | | W_VREG_S(VDREG, 3) = m_vres[3]; \ |
| 101 | | W_VREG_S(VDREG, 4) = m_vres[4]; \ |
| 102 | | W_VREG_S(VDREG, 5) = m_vres[5]; \ |
| 103 | | W_VREG_S(VDREG, 6) = m_vres[6]; \ |
| 104 | | W_VREG_S(VDREG, 7) = m_vres[7]; \ |
| 106 | W_VREG_S(vdreg, 0) = m_vres[0]; \ |
| 107 | W_VREG_S(vdreg, 1) = m_vres[1]; \ |
| 108 | W_VREG_S(vdreg, 2) = m_vres[2]; \ |
| 109 | W_VREG_S(vdreg, 3) = m_vres[3]; \ |
| 110 | W_VREG_S(vdreg, 4) = m_vres[4]; \ |
| 111 | W_VREG_S(vdreg, 5) = m_vres[5]; \ |
| 112 | W_VREG_S(vdreg, 6) = m_vres[6]; \ |
| 113 | W_VREG_S(vdreg, 7) = m_vres[7]; \ |
| 105 | 114 | } |
| 106 | 115 | |
| 107 | 116 | static const int vector_elements_2[16][8] = |
| r241990 | r241991 | |
| 1346 | 1355 | |
| 1347 | 1356 | void rsp_cop2_drc::vmulf() |
| 1348 | 1357 | { |
| 1349 | | int op = m_op; |
| 1358 | CACHE_VALUES(); |
| 1350 | 1359 | |
| 1351 | 1360 | for (int i = 0; i < 8; i++) |
| 1352 | 1361 | { |
| r241990 | r241991 | |
| 1359 | 1368 | if (s1 == -32768 && s2 == -32768) |
| 1360 | 1369 | { |
| 1361 | 1370 | // overflow |
| 1362 | | SET_ACCUM_H(0, i); |
| 1363 | | SET_ACCUM_M(-32768, i); |
| 1364 | | SET_ACCUM_L(-32768, i); |
| 1371 | ACCUM(i) = 0x0000800080000000L; |
| 1365 | 1372 | m_vres[i] = 0x7fff; |
| 1366 | 1373 | } |
| 1367 | 1374 | else |
| 1368 | 1375 | { |
| 1369 | | INT64 r = s1 * s2 * 2; |
| 1370 | | r += 0x8000; // rounding ? |
| 1371 | | SET_ACCUM_H((r < 0) ? 0xffff : 0, i); |
| 1372 | | SET_ACCUM_M((INT16)(r >> 16), i); |
| 1373 | | SET_ACCUM_L((UINT16)(r), i); |
| 1376 | ACCUM(i) = (INT64)(s1 * s2 * 2 + 0x8000) << 16; // rounding? |
| 1374 | 1377 | m_vres[i] = ACCUM_M(i); |
| 1375 | 1378 | } |
| 1376 | 1379 | } |
| r241990 | r241991 | |
| 1393 | 1396 | |
| 1394 | 1397 | void rsp_cop2_drc::vmulu() |
| 1395 | 1398 | { |
| 1396 | | int op = m_op; |
| 1399 | CACHE_VALUES(); |
| 1397 | 1400 | |
| 1398 | 1401 | for (int i = 0; i < 8; i++) |
| 1399 | 1402 | { |
| r241990 | r241991 | |
| 1403 | 1406 | INT32 s1 = (INT32)(INT16)w1; |
| 1404 | 1407 | INT32 s2 = (INT32)(INT16)w2; |
| 1405 | 1408 | |
| 1406 | | INT64 r = s1 * s2 * 2; |
| 1407 | | r += 0x8000; // rounding ? |
| 1409 | INT64 r = s1 * s2 * 2 + 0x8000; // rounding? |
| 1408 | 1410 | |
| 1409 | | SET_ACCUM_H((UINT16)(r >> 32), i); |
| 1410 | | SET_ACCUM_M((UINT16)(r >> 16), i); |
| 1411 | | SET_ACCUM_L((UINT16)(r), i); |
| 1411 | ACCUM(i) = r << 16; |
| 1412 | 1412 | |
| 1413 | 1413 | if (r < 0) |
| 1414 | 1414 | { |
| r241990 | r241991 | |
| 1445 | 1445 | |
| 1446 | 1446 | void rsp_cop2_drc::vmudl() |
| 1447 | 1447 | { |
| 1448 | | int op = m_op; |
| 1448 | CACHE_VALUES(); |
| 1449 | 1449 | |
| 1450 | 1450 | for (int i = 0; i < 8; i++) |
| 1451 | 1451 | { |
| r241990 | r241991 | |
| 1455 | 1455 | UINT32 s1 = (UINT32)(UINT16)w1; |
| 1456 | 1456 | UINT32 s2 = (UINT32)(UINT16)w2; |
| 1457 | 1457 | |
| 1458 | | UINT32 r = s1 * s2; |
| 1458 | ACCUM(i) = s1 * s2; |
| 1459 | 1459 | |
| 1460 | | SET_ACCUM_H(0, i); |
| 1461 | | SET_ACCUM_M(0, i); |
| 1462 | | SET_ACCUM_L((UINT16)(r >> 16), i); |
| 1463 | | |
| 1464 | 1460 | m_vres[i] = ACCUM_L(i); |
| 1465 | 1461 | } |
| 1466 | 1462 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1485 | 1481 | |
| 1486 | 1482 | void rsp_cop2_drc::vmudm() |
| 1487 | 1483 | { |
| 1488 | | int op = m_op; |
| 1484 | CACHE_VALUES(); |
| 1489 | 1485 | |
| 1490 | 1486 | for (int i = 0; i < 8; i++) |
| 1491 | 1487 | { |
| r241990 | r241991 | |
| 1495 | 1491 | INT32 s1 = (INT32)(INT16)w1; |
| 1496 | 1492 | INT32 s2 = (UINT16)w2; |
| 1497 | 1493 | |
| 1498 | | INT32 r = s1 * s2; |
| 1494 | ACCUM(i) = (INT64)(s1 * s2) << 16; |
| 1499 | 1495 | |
| 1500 | | SET_ACCUM_H((r < 0) ? 0xffff : 0, i); // sign-extend to 48-bit |
| 1501 | | SET_ACCUM_M((INT16)(r >> 16), i); |
| 1502 | | SET_ACCUM_L((UINT16)r, i); |
| 1503 | | |
| 1504 | 1496 | m_vres[i] = ACCUM_M(i); |
| 1505 | 1497 | } |
| 1506 | 1498 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1525 | 1517 | |
| 1526 | 1518 | void rsp_cop2_drc::vmudn() |
| 1527 | 1519 | { |
| 1528 | | int op = m_op; |
| 1520 | CACHE_VALUES(); |
| 1529 | 1521 | |
| 1530 | 1522 | for (int i = 0; i < 8; i++) |
| 1531 | 1523 | { |
| r241990 | r241991 | |
| 1537 | 1529 | |
| 1538 | 1530 | INT32 r = s1 * s2; |
| 1539 | 1531 | |
| 1540 | | SET_ACCUM_H((r < 0) ? 0xffff : 0, i); // sign-extend to 48-bit |
| 1541 | | SET_ACCUM_M((INT16)(r >> 16), i); |
| 1542 | | SET_ACCUM_L((UINT16)(r), i); |
| 1532 | ACCUM(i) = (INT64)(s1 * s2) << 16; |
| 1543 | 1533 | |
| 1544 | 1534 | m_vres[i] = (UINT16)(r); |
| 1545 | 1535 | } |
| r241990 | r241991 | |
| 1565 | 1555 | |
| 1566 | 1556 | void rsp_cop2_drc::vmudh() |
| 1567 | 1557 | { |
| 1568 | | int op = m_op; |
| 1558 | CACHE_VALUES(); |
| 1569 | 1559 | |
| 1570 | 1560 | for (int i = 0; i < 8; i++) |
| 1571 | 1561 | { |
| r241990 | r241991 | |
| 1577 | 1567 | |
| 1578 | 1568 | INT32 r = s1 * s2; |
| 1579 | 1569 | |
| 1580 | | SET_ACCUM_H((INT16)(r >> 16), i); |
| 1581 | | SET_ACCUM_M((UINT16)(r), i); |
| 1582 | | SET_ACCUM_L(0, i); |
| 1570 | ACCUM(i) = (INT64)r << 32; |
| 1583 | 1571 | |
| 1584 | 1572 | if (r < -32768) r = -32768; |
| 1585 | 1573 | if (r > 32767) r = 32767; |
| r241990 | r241991 | |
| 1604 | 1592 | |
| 1605 | 1593 | void rsp_cop2_drc::vmacf() |
| 1606 | 1594 | { |
| 1607 | | int op = m_op; |
| 1595 | CACHE_VALUES(); |
| 1608 | 1596 | |
| 1609 | 1597 | for (int i = 0; i < 8; i++) |
| 1610 | 1598 | { |
| r241990 | r241991 | |
| 1614 | 1602 | INT32 s1 = (INT32)(INT16)w1; |
| 1615 | 1603 | INT32 s2 = (INT32)(INT16)w2; |
| 1616 | 1604 | |
| 1617 | | INT32 r = s1 * s2; |
| 1605 | ACCUM(i) += (INT64)(s1 * s2 * 2) << 16; |
| 1618 | 1606 | |
| 1619 | | UINT64 q = (UINT64)(UINT16)ACCUM_LL(i); |
| 1620 | | q |= (((UINT64)(UINT16)ACCUM_L(i)) << 16); |
| 1621 | | q |= (((UINT64)(UINT16)ACCUM_M(i)) << 32); |
| 1622 | | q |= (((UINT64)(UINT16)ACCUM_H(i)) << 48); |
| 1623 | | |
| 1624 | | q += (INT64)(r) << 17; |
| 1625 | | SET_ACCUM_LL((UINT16)q, i); |
| 1626 | | SET_ACCUM_L((UINT16)(q >> 16), i); |
| 1627 | | SET_ACCUM_M((UINT16)(q >> 32), i); |
| 1628 | | SET_ACCUM_H((UINT16)(q >> 48), i); |
| 1629 | | |
| 1630 | 1607 | m_vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff); |
| 1631 | 1608 | } |
| 1632 | 1609 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1648 | 1625 | |
| 1649 | 1626 | void rsp_cop2_drc::vmacu() |
| 1650 | 1627 | { |
| 1651 | | int op = m_op; |
| 1628 | CACHE_VALUES(); |
| 1652 | 1629 | |
| 1653 | 1630 | for (int i = 0; i < 8; i++) |
| 1654 | 1631 | { |
| r241990 | r241991 | |
| 1658 | 1635 | INT32 s1 = (INT32)(INT16)w1; |
| 1659 | 1636 | INT32 s2 = (INT32)(INT16)w2; |
| 1660 | 1637 | |
| 1661 | | INT32 r1 = s1 * s2; |
| 1662 | | UINT32 r2 = (UINT16)ACCUM_L(i) + ((UINT16)(r1) * 2); |
| 1663 | | UINT32 r3 = (UINT16)ACCUM_M(i) + (UINT16)((r1 >> 16) * 2) + (UINT16)(r2 >> 16); |
| 1638 | ACCUM(i) += (INT64)(s1 * s2 * 2) << 16; |
| 1664 | 1639 | |
| 1665 | | SET_ACCUM_L((UINT16)(r2), i); |
| 1666 | | SET_ACCUM_M((UINT16)(r3), i); |
| 1667 | | SET_ACCUM_H(ACCUM_H(i) + (UINT16)(r3 >> 16) + (UINT16)(r1 >> 31), i); |
| 1668 | | |
| 1669 | 1640 | if ((INT16)ACCUM_H(i) < 0) |
| 1670 | 1641 | { |
| 1671 | 1642 | m_vres[i] = 0; |
| r241990 | r241991 | |
| 1711 | 1682 | |
| 1712 | 1683 | void rsp_cop2_drc::vmadl() |
| 1713 | 1684 | { |
| 1714 | | int op = m_op; |
| 1685 | CACHE_VALUES(); |
| 1715 | 1686 | |
| 1716 | 1687 | for (int i = 0; i < 8; i++) |
| 1717 | 1688 | { |
| r241990 | r241991 | |
| 1721 | 1692 | UINT32 s1 = w1; |
| 1722 | 1693 | UINT32 s2 = w2; |
| 1723 | 1694 | |
| 1724 | | UINT32 r1 = s1 * s2; |
| 1725 | | UINT32 r2 = (UINT16)ACCUM_L(i) + (r1 >> 16); |
| 1726 | | UINT32 r3 = (UINT16)ACCUM_M(i) + (r2 >> 16); |
| 1695 | ACCUM(i) += (s1 * s2) & 0xffff0000; |
| 1727 | 1696 | |
| 1728 | | SET_ACCUM_L((UINT16)r2, i); |
| 1729 | | SET_ACCUM_M((UINT16)r3, i); |
| 1730 | | SET_ACCUM_H(ACCUM_H(i) + (INT16)(r3 >> 16), i); |
| 1731 | | |
| 1732 | 1697 | m_vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff); |
| 1733 | 1698 | } |
| 1734 | 1699 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1745 | 1710 | |
| 1746 | 1711 | void rsp_cop2_drc::vmadm() |
| 1747 | 1712 | { |
| 1748 | | int op = m_op; |
| 1713 | CACHE_VALUES(); |
| 1749 | 1714 | |
| 1750 | 1715 | for (int i = 0; i < 8; i++) |
| 1751 | 1716 | { |
| r241990 | r241991 | |
| 1755 | 1720 | UINT32 s1 = (INT32)(INT16)w1; |
| 1756 | 1721 | UINT32 s2 = (UINT16)w2; |
| 1757 | 1722 | |
| 1758 | | UINT32 r1 = s1 * s2; |
| 1759 | | UINT32 r2 = (UINT16)ACCUM_L(i) + (UINT16)(r1); |
| 1760 | | UINT32 r3 = (UINT16)ACCUM_M(i) + (r1 >> 16) + (r2 >> 16); |
| 1723 | ACCUM(i) += (INT64)(INT32)(s1 * s2) << 16; |
| 1761 | 1724 | |
| 1762 | | SET_ACCUM_L((UINT16)r2, i); |
| 1763 | | SET_ACCUM_M((UINT16)r3, i); |
| 1764 | | SET_ACCUM_H((UINT16)ACCUM_H(i) + (UINT16)(r3 >> 16), i); |
| 1765 | | if ((INT32)(r1) < 0) |
| 1766 | | { |
| 1767 | | SET_ACCUM_H((UINT16)ACCUM_H(i) - 1, i); |
| 1768 | | } |
| 1769 | | |
| 1770 | 1725 | m_vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff); |
| 1771 | 1726 | } |
| 1772 | 1727 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1783 | 1738 | |
| 1784 | 1739 | void rsp_cop2_drc::vmadn() |
| 1785 | 1740 | { |
| 1786 | | int op = m_op; |
| 1741 | CACHE_VALUES(); |
| 1787 | 1742 | |
| 1788 | 1743 | for (int i = 0; i < 8; i++) |
| 1789 | 1744 | { |
| r241990 | r241991 | |
| 1793 | 1748 | INT32 s1 = (UINT16)w1; |
| 1794 | 1749 | INT32 s2 = (INT32)(INT16)w2; |
| 1795 | 1750 | |
| 1796 | | UINT64 q = (UINT64)ACCUM_LL(i); |
| 1797 | | q |= (((UINT64)ACCUM_L(i)) << 16); |
| 1798 | | q |= (((UINT64)ACCUM_M(i)) << 32); |
| 1799 | | q |= (((UINT64)ACCUM_H(i)) << 48); |
| 1800 | | q += (INT64)(s1*s2) << 16; |
| 1751 | ACCUM(i) += (INT64)(s1 * s2) << 16; |
| 1801 | 1752 | |
| 1802 | | SET_ACCUM_LL((UINT16)q, i); |
| 1803 | | SET_ACCUM_L((UINT16)(q >> 16), i); |
| 1804 | | SET_ACCUM_M((UINT16)(q >> 32), i); |
| 1805 | | SET_ACCUM_H((UINT16)(q >> 48), i); |
| 1806 | | |
| 1807 | 1753 | m_vres[i] = SATURATE_ACCUM(i, 0, 0x0000, 0xffff); |
| 1808 | 1754 | } |
| 1809 | 1755 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1828 | 1774 | |
| 1829 | 1775 | void rsp_cop2_drc::vmadh() |
| 1830 | 1776 | { |
| 1831 | | int op = m_op; |
| 1777 | CACHE_VALUES(); |
| 1832 | 1778 | |
| 1833 | 1779 | for (int i = 0; i < 8; i++) |
| 1834 | 1780 | { |
| r241990 | r241991 | |
| 1838 | 1784 | INT32 s1 = (INT32)(INT16)w1; |
| 1839 | 1785 | INT32 s2 = (INT32)(INT16)w2; |
| 1840 | 1786 | |
| 1841 | | INT32 accum = (UINT32)(UINT16)ACCUM_M(i); |
| 1842 | | accum |= ((UINT32)((UINT16)ACCUM_H(i))) << 16; |
| 1843 | | accum += s1 * s2; |
| 1787 | ACCUM(i) += (INT64)(s1 * s2) << 32; |
| 1844 | 1788 | |
| 1845 | | SET_ACCUM_H((UINT16)(accum >> 16), i); |
| 1846 | | SET_ACCUM_M((UINT16)accum, i); |
| 1847 | | |
| 1848 | 1789 | m_vres[i] = SATURATE_ACCUM(i, 1, 0x8000, 0x7fff); |
| 1849 | 1790 | } |
| 1850 | 1791 | WRITEBACK_RESULT(); |
| r241990 | r241991 | |
| 1866 | 1807 | |
| 1867 | 1808 | void rsp_cop2_drc::vadd() |
| 1868 | 1809 | { |
| 1869 | | int op = m_op; |
| 1810 | CACHE_VALUES(); |
| 1870 | 1811 | |
| 1871 | 1812 | for (int i = 0; i < 8; i++) |
| 1872 | 1813 | { |
| r241990 | r241991 | |
| 1906 | 1847 | |
| 1907 | 1848 | void rsp_cop2_drc::vsub() |
| 1908 | 1849 | { |
| 1909 | | int op = m_op; |
| 1850 | CACHE_VALUES(); |
| 1910 | 1851 | |
| 1911 | 1852 | for (int i = 0; i < 8; i++) |
| 1912 | 1853 | { |
| r241990 | r241991 | |
| 1946 | 1887 | |
| 1947 | 1888 | void rsp_cop2_drc::vabs() |
| 1948 | 1889 | { |
| 1949 | | int op = m_op; |
| 1890 | CACHE_VALUES(); |
| 1950 | 1891 | |
| 1951 | 1892 | for (int i = 0; i < 8; i++) |
| 1952 | 1893 | { |
| r241990 | r241991 | |
| 1997 | 1938 | |
| 1998 | 1939 | void rsp_cop2_drc::vaddc() |
| 1999 | 1940 | { |
| 2000 | | int op = m_op; |
| 1941 | CACHE_VALUES(); |
| 2001 | 1942 | |
| 2002 | 1943 | CLEAR_ZERO_FLAGS(); |
| 2003 | 1944 | CLEAR_CARRY_FLAGS(); |
| r241990 | r241991 | |
| 2040 | 1981 | |
| 2041 | 1982 | void rsp_cop2_drc::vsubc() |
| 2042 | 1983 | { |
| 2043 | | int op = m_op; |
| 1984 | CACHE_VALUES(); |
| 2044 | 1985 | |
| 2045 | 1986 | CLEAR_ZERO_FLAGS(); |
| 2046 | 1987 | CLEAR_CARRY_FLAGS(); |
| r241990 | r241991 | |
| 2086 | 2027 | |
| 2087 | 2028 | void rsp_cop2_drc::vaddb() |
| 2088 | 2029 | { |
| 2089 | | const int op = m_op; |
| 2090 | | const int round = (EL == 0) ? 0 : (1 << (EL - 1)); |
| 2030 | CACHE_VALUES(); |
| 2031 | const int round = (el == 0) ? 0 : (1 << (el - 1)); |
| 2091 | 2032 | |
| 2092 | 2033 | for (int i = 0; i < 8; i++) |
| 2093 | 2034 | { |
| r241990 | r241991 | |
| 2140 | 2081 | |
| 2141 | 2082 | void rsp_cop2_drc::vsaw() |
| 2142 | 2083 | { |
| 2143 | | int op = m_op; |
| 2084 | const int op = m_op; |
| 2085 | const int vdreg = VDREG; |
| 2086 | const int el = EL; |
| 2144 | 2087 | |
| 2145 | | switch (EL) |
| 2088 | switch (el) |
| 2146 | 2089 | { |
| 2147 | 2090 | case 0x08: // VSAWH |
| 2148 | 2091 | for (int i = 0; i < 8; i++) |
| 2149 | 2092 | { |
| 2150 | | W_VREG_S(VDREG, i) = ACCUM_H(i); |
| 2093 | W_VREG_S(vdreg, i) = ACCUM_H(i); |
| 2151 | 2094 | } |
| 2152 | 2095 | break; |
| 2153 | 2096 | case 0x09: // VSAWM |
| 2154 | 2097 | for (int i = 0; i < 8; i++) |
| 2155 | 2098 | { |
| 2156 | | W_VREG_S(VDREG, i) = ACCUM_M(i); |
| 2099 | W_VREG_S(vdreg, i) = ACCUM_M(i); |
| 2157 | 2100 | } |
| 2158 | 2101 | break; |
| 2159 | 2102 | case 0x0a: // VSAWL |
| 2160 | 2103 | for (int i = 0; i < 8; i++) |
| 2161 | 2104 | { |
| 2162 | | W_VREG_S(VDREG, i) = ACCUM_L(i); |
| 2105 | W_VREG_S(vdreg, i) = ACCUM_L(i); |
| 2163 | 2106 | } |
| 2164 | 2107 | break; |
| 2165 | 2108 | default: // Unsupported |
| 2166 | 2109 | { |
| 2167 | 2110 | for (int i = 0; i < 8; i++) |
| 2168 | 2111 | { |
| 2169 | | W_VREG_S(VDREG, i) = 0; |
| 2112 | W_VREG_S(vdreg, i) = 0; |
| 2170 | 2113 | } |
| 2171 | 2114 | } |
| 2172 | 2115 | } |
| r241990 | r241991 | |
| 2190 | 2133 | |
| 2191 | 2134 | void rsp_cop2_drc::vlt() |
| 2192 | 2135 | { |
| 2193 | | int op = m_op; |
| 2136 | CACHE_VALUES(); |
| 2194 | 2137 | |
| 2195 | 2138 | CLEAR_COMPARE_FLAGS(); |
| 2196 | 2139 | CLEAR_CLIP2_FLAGS(); |
| r241990 | r241991 | |
| 2248 | 2191 | |
| 2249 | 2192 | void rsp_cop2_drc::veq() |
| 2250 | 2193 | { |
| 2251 | | int op = m_op; |
| 2194 | CACHE_VALUES(); |
| 2252 | 2195 | |
| 2253 | 2196 | CLEAR_COMPARE_FLAGS(); |
| 2254 | 2197 | CLEAR_CLIP2_FLAGS(); |
| r241990 | r241991 | |
| 2295 | 2238 | |
| 2296 | 2239 | void rsp_cop2_drc::vne() |
| 2297 | 2240 | { |
| 2298 | | int op = m_op; |
| 2241 | CACHE_VALUES(); |
| 2299 | 2242 | |
| 2300 | 2243 | CLEAR_COMPARE_FLAGS(); |
| 2301 | 2244 | CLEAR_CLIP2_FLAGS(); |
| r241990 | r241991 | |
| 2342 | 2285 | |
| 2343 | 2286 | void rsp_cop2_drc::vge() |
| 2344 | 2287 | { |
| 2345 | | int op = m_op; |
| 2288 | CACHE_VALUES(); |
| 2346 | 2289 | |
| 2347 | 2290 | CLEAR_COMPARE_FLAGS(); |
| 2348 | 2291 | CLEAR_CLIP2_FLAGS(); |
| r241990 | r241991 | |
| 2387 | 2330 | |
| 2388 | 2331 | void rsp_cop2_drc::vcl() |
| 2389 | 2332 | { |
| 2390 | | int op = m_op; |
| 2333 | CACHE_VALUES(); |
| 2391 | 2334 | |
| 2392 | 2335 | for (int i = 0; i < 8; i++) |
| 2393 | 2336 | { |
| r241990 | r241991 | |
| 2490 | 2433 | |
| 2491 | 2434 | void rsp_cop2_drc::vch() |
| 2492 | 2435 | { |
| 2493 | | int op = m_op; |
| 2436 | CACHE_VALUES(); |
| 2494 | 2437 | |
| 2495 | 2438 | CLEAR_CARRY_FLAGS(); |
| 2496 | 2439 | CLEAR_COMPARE_FLAGS(); |
| r241990 | r241991 | |
| 2577 | 2520 | |
| 2578 | 2521 | void rsp_cop2_drc::vcr() |
| 2579 | 2522 | { |
| 2580 | | int op = m_op; |
| 2523 | CACHE_VALUES(); |
| 2581 | 2524 | |
| 2582 | 2525 | CLEAR_CARRY_FLAGS(); |
| 2583 | 2526 | CLEAR_COMPARE_FLAGS(); |
| r241990 | r241991 | |
| 2646 | 2589 | |
| 2647 | 2590 | void rsp_cop2_drc::vmrg() |
| 2648 | 2591 | { |
| 2649 | | int op = m_op; |
| 2592 | CACHE_VALUES(); |
| 2650 | 2593 | |
| 2651 | 2594 | for (int i = 0; i < 8; i++) |
| 2652 | 2595 | { |
| r241990 | r241991 | |
| 2684 | 2627 | |
| 2685 | 2628 | void rsp_cop2_drc::vand() |
| 2686 | 2629 | { |
| 2687 | | int op = m_op; |
| 2630 | CACHE_VALUES(); |
| 2688 | 2631 | |
| 2689 | 2632 | for (int i = 0; i < 8; i++) |
| 2690 | 2633 | { |
| r241990 | r241991 | |
| 2714 | 2657 | |
| 2715 | 2658 | void rsp_cop2_drc::vnand() |
| 2716 | 2659 | { |
| 2717 | | int op = m_op; |
| 2660 | CACHE_VALUES(); |
| 2718 | 2661 | |
| 2719 | 2662 | for (int i = 0; i < 8; i++) |
| 2720 | 2663 | { |
| r241990 | r241991 | |
| 2744 | 2687 | |
| 2745 | 2688 | void rsp_cop2_drc::vor() |
| 2746 | 2689 | { |
| 2747 | | int op = m_op; |
| 2690 | CACHE_VALUES(); |
| 2748 | 2691 | |
| 2749 | 2692 | for (int i = 0; i < 8; i++) |
| 2750 | 2693 | { |
| r241990 | r241991 | |
| 2774 | 2717 | |
| 2775 | 2718 | void rsp_cop2_drc::vnor() |
| 2776 | 2719 | { |
| 2777 | | int op = m_op; |
| 2720 | CACHE_VALUES(); |
| 2778 | 2721 | |
| 2779 | 2722 | for (int i = 0; i < 8; i++) |
| 2780 | 2723 | { |
| r241990 | r241991 | |
| 2804 | 2747 | |
| 2805 | 2748 | void rsp_cop2_drc::vxor() |
| 2806 | 2749 | { |
| 2807 | | int op = m_op; |
| 2750 | CACHE_VALUES(); |
| 2808 | 2751 | |
| 2809 | 2752 | for (int i = 0; i < 8; i++) |
| 2810 | 2753 | { |
| r241990 | r241991 | |
| 2834 | 2777 | |
| 2835 | 2778 | void rsp_cop2_drc::vnxor() |
| 2836 | 2779 | { |
| 2837 | | int op = m_op; |
| 2780 | CACHE_VALUES(); |
| 2838 | 2781 | |
| 2839 | 2782 | for (int i = 0; i < 8; i++) |
| 2840 | 2783 | { |
| r241990 | r241991 | |
| 2864 | 2807 | |
| 2865 | 2808 | void rsp_cop2_drc::vrcp() |
| 2866 | 2809 | { |
| 2867 | | int op = m_op; |
| 2810 | CACHE_VALUES(); |
| 2868 | 2811 | |
| 2869 | 2812 | INT32 shifter = 0; |
| 2870 | | INT32 rec = (INT16)(VREG_S(VS2REG, EL & 7)); |
| 2813 | INT32 rec = (INT16)(VREG_S(vs2reg, el & 7)); |
| 2871 | 2814 | INT32 datainput = (rec < 0) ? (-rec) : rec; |
| 2872 | 2815 | if (datainput) |
| 2873 | 2816 | { |
| r241990 | r241991 | |
| 2905 | 2848 | m_reciprocal_res = rec; |
| 2906 | 2849 | m_dp_allowed = 0; |
| 2907 | 2850 | |
| 2908 | | W_VREG_S(VDREG, VS1REG & 7) = (UINT16)rec; |
| 2851 | W_VREG_S(vdreg, vs1reg & 7) = (UINT16)rec; |
| 2909 | 2852 | for (int i = 0; i < 8; i++) |
| 2910 | 2853 | { |
| 2911 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 2854 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 2912 | 2855 | } |
| 2913 | 2856 | } |
| 2914 | 2857 | |
| r241990 | r241991 | |
| 2929 | 2872 | |
| 2930 | 2873 | void rsp_cop2_drc::vrcpl() |
| 2931 | 2874 | { |
| 2932 | | int op = m_op; |
| 2875 | CACHE_VALUES(); |
| 2933 | 2876 | |
| 2934 | 2877 | INT32 shifter = 0; |
| 2935 | | INT32 rec = (INT16)VREG_S(VS2REG, EL & 7); |
| 2878 | INT32 rec = (INT16)VREG_S(vs2reg, el & 7); |
| 2936 | 2879 | INT32 datainput = rec; |
| 2937 | 2880 | |
| 2938 | 2881 | if (m_dp_allowed) |
| r241990 | r241991 | |
| 2989 | 2932 | m_reciprocal_res = rec; |
| 2990 | 2933 | m_dp_allowed = 0; |
| 2991 | 2934 | |
| 2992 | | W_VREG_S(VDREG, VS1REG & 7) = (UINT16)rec; |
| 2935 | W_VREG_S(vdreg, vs1reg & 7) = (UINT16)rec; |
| 2993 | 2936 | |
| 2994 | 2937 | for (int i = 0; i < 8; i++) |
| 2995 | 2938 | { |
| 2996 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 2939 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 2997 | 2940 | } |
| 2998 | 2941 | } |
| 2999 | 2942 | |
| r241990 | r241991 | |
| 3014 | 2957 | |
| 3015 | 2958 | void rsp_cop2_drc::vrcph() |
| 3016 | 2959 | { |
| 3017 | | int op = m_op; |
| 2960 | CACHE_VALUES(); |
| 3018 | 2961 | |
| 3019 | | m_reciprocal_high = (VREG_S(VS2REG, EL & 7)) << 16; |
| 2962 | m_reciprocal_high = (VREG_S(vs2reg, el & 7)) << 16; |
| 3020 | 2963 | m_dp_allowed = 1; |
| 3021 | 2964 | |
| 3022 | 2965 | for (int i = 0; i < 8; i++) |
| 3023 | 2966 | { |
| 3024 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 2967 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 3025 | 2968 | } |
| 3026 | 2969 | |
| 3027 | | W_VREG_S(VDREG, VS1REG & 7) = (INT16)(m_reciprocal_res >> 16); |
| 2970 | W_VREG_S(vdreg, vs1reg & 7) = (INT16)(m_reciprocal_res >> 16); |
| 3028 | 2971 | } |
| 3029 | 2972 | |
| 3030 | 2973 | static void cfunc_vrcph(void *param) |
| r241990 | r241991 | |
| 3044 | 2987 | |
| 3045 | 2988 | void rsp_cop2_drc::vmov() |
| 3046 | 2989 | { |
| 3047 | | int op = m_op; |
| 2990 | CACHE_VALUES(); |
| 3048 | 2991 | |
| 3049 | | W_VREG_S(VDREG, VS1REG & 7) = VREG_S(VS2REG, EL & 7); |
| 2992 | W_VREG_S(vdreg, vs1reg & 7) = VREG_S(vs2reg, el & 7); |
| 3050 | 2993 | for (int i = 0; i < 8; i++) |
| 3051 | 2994 | { |
| 3052 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 2995 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 3053 | 2996 | } |
| 3054 | 2997 | } |
| 3055 | 2998 | |
| r241990 | r241991 | |
| 3070 | 3013 | |
| 3071 | 3014 | void rsp_cop2_drc::vrsq() |
| 3072 | 3015 | { |
| 3073 | | int op = m_op; |
| 3016 | CACHE_VALUES(); |
| 3074 | 3017 | |
| 3075 | 3018 | INT32 shifter = 0; |
| 3076 | | INT32 rec = (INT16)VREG_S(VS2REG, EL & 7); |
| 3019 | INT32 rec = (INT16)VREG_S(vs2reg, el & 7); |
| 3077 | 3020 | INT32 datainput = (rec < 0) ? (-rec) : (rec); |
| 3078 | 3021 | |
| 3079 | 3022 | if (rec < 0) |
| r241990 | r241991 | |
| 3177 | 3120 | } |
| 3178 | 3121 | rec = temp; |
| 3179 | 3122 | |
| 3180 | | W_VREG_S(VDREG, VS1REG & 7) = (UINT16)rec; |
| 3123 | W_VREG_S(vdreg, vs1reg & 7) = (UINT16)rec; |
| 3181 | 3124 | for (int i = 0; i < 8; i++) |
| 3182 | 3125 | { |
| 3183 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 3126 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 3184 | 3127 | } |
| 3185 | 3128 | } |
| 3186 | 3129 | |
| r241990 | r241991 | |
| 3201 | 3144 | |
| 3202 | 3145 | void rsp_cop2_drc::vrsql() |
| 3203 | 3146 | { |
| 3204 | | int op = m_op; |
| 3147 | CACHE_VALUES(); |
| 3205 | 3148 | |
| 3206 | 3149 | INT32 shifter = 0; |
| 3207 | | INT32 rec = (INT16)VREG_S(VS2REG, EL & 7); |
| 3150 | INT32 rec = (INT16)VREG_S(vs2reg, el & 7); |
| 3208 | 3151 | INT32 datainput = rec; |
| 3209 | 3152 | |
| 3210 | 3153 | if (m_dp_allowed) |
| r241990 | r241991 | |
| 3263 | 3206 | m_reciprocal_res = rec; |
| 3264 | 3207 | m_dp_allowed = 0; |
| 3265 | 3208 | |
| 3266 | | W_VREG_S(VDREG, VS1REG & 7) = (UINT16)(rec & 0xffff); |
| 3209 | W_VREG_S(vdreg, vs1reg & 7) = (UINT16)(rec & 0xffff); |
| 3267 | 3210 | for (int i = 0; i < 8; i++) |
| 3268 | 3211 | { |
| 3269 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 3212 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 3270 | 3213 | } |
| 3271 | 3214 | } |
| 3272 | 3215 | |
| r241990 | r241991 | |
| 3287 | 3230 | |
| 3288 | 3231 | void rsp_cop2_drc::vrsqh() |
| 3289 | 3232 | { |
| 3290 | | int op = m_op; |
| 3233 | CACHE_VALUES(); |
| 3291 | 3234 | |
| 3292 | | m_reciprocal_high = (VREG_S(VS2REG, EL & 7)) << 16; |
| 3235 | m_reciprocal_high = (VREG_S(vs2reg, el & 7)) << 16; |
| 3293 | 3236 | m_dp_allowed = 1; |
| 3294 | 3237 | |
| 3295 | 3238 | for (int i = 0; i < 8; i++) |
| 3296 | 3239 | { |
| 3297 | | SET_ACCUM_L(VREG_S(VS2REG, VEC_EL_2(EL, i)), i); |
| 3240 | SET_ACCUM_L(VREG_S(vs2reg, VEC_EL_2(el, i)), i); |
| 3298 | 3241 | } |
| 3299 | 3242 | |
| 3300 | | W_VREG_S(VDREG, VS1REG & 7) = (INT16)(m_reciprocal_res >> 16); // store high part |
| 3243 | W_VREG_S(vdreg, vs1reg & 7) = (INT16)(m_reciprocal_res >> 16); // store high part |
| 3301 | 3244 | } |
| 3302 | 3245 | |
| 3303 | 3246 | static void cfunc_vrsqh(void *param) |