Commit 57951c27422fc41586a5d4032e05bb300cced78d
1 parent
970d622e
target-ppc: convert most SPE integer instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5668 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
602 additions
and
471 deletions
target-ppc/cpu.h
| ... | ... | @@ -832,10 +832,14 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp) |
| 832 | 832 | |
| 833 | 833 | /*****************************************************************************/ |
| 834 | 834 | /* CRF definitions */ |
| 835 | -#define CRF_LT 3 | |
| 836 | -#define CRF_GT 2 | |
| 837 | -#define CRF_EQ 1 | |
| 838 | -#define CRF_SO 0 | |
| 835 | +#define CRF_LT 3 | |
| 836 | +#define CRF_GT 2 | |
| 837 | +#define CRF_EQ 1 | |
| 838 | +#define CRF_SO 0 | |
| 839 | +#define CRF_CH (1 << 4) | |
| 840 | +#define CRF_CL (1 << 3) | |
| 841 | +#define CRF_CH_OR_CL (1 << 2) | |
| 842 | +#define CRF_CH_AND_CL (1 << 1) | |
| 839 | 843 | |
| 840 | 844 | /* XER definitions */ |
| 841 | 845 | #define XER_SO 31 | ... | ... |
target-ppc/helper.h
| ... | ... | @@ -23,3 +23,6 @@ DEF_HELPER(target_ulong, helper_popcntb_64, (target_ulong val)) |
| 23 | 23 | DEF_HELPER(target_ulong, helper_srad, (target_ulong, target_ulong)) |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | +DEF_HELPER(uint32_t, helper_cntlsw32, (uint32_t)) | |
| 27 | +DEF_HELPER(uint32_t, helper_cntlzw32, (uint32_t)) | |
| 28 | +DEF_HELPER(uint32_t, helper_brinc, (uint32_t, uint32_t)) | ... | ... |
target-ppc/op.c
| ... | ... | @@ -1227,22 +1227,6 @@ void OPPROTO op_splatw_T1_64 (void) |
| 1227 | 1227 | RETURN(); |
| 1228 | 1228 | } |
| 1229 | 1229 | |
| 1230 | -void OPPROTO op_splatwi_T0_64 (void) | |
| 1231 | -{ | |
| 1232 | - uint64_t tmp = PARAM1; | |
| 1233 | - | |
| 1234 | - T0_64 = (tmp << 32) | tmp; | |
| 1235 | - RETURN(); | |
| 1236 | -} | |
| 1237 | - | |
| 1238 | -void OPPROTO op_splatwi_T1_64 (void) | |
| 1239 | -{ | |
| 1240 | - uint64_t tmp = PARAM1; | |
| 1241 | - | |
| 1242 | - T1_64 = (tmp << 32) | tmp; | |
| 1243 | - RETURN(); | |
| 1244 | -} | |
| 1245 | - | |
| 1246 | 1230 | void OPPROTO op_extsh_T1_64 (void) |
| 1247 | 1231 | { |
| 1248 | 1232 | T1_64 = (int32_t)((int16_t)T1_64); |
| ... | ... | @@ -1267,152 +1251,6 @@ void OPPROTO op_srli32_T1_64 (void) |
| 1267 | 1251 | RETURN(); |
| 1268 | 1252 | } |
| 1269 | 1253 | |
| 1270 | -void OPPROTO op_evsel (void) | |
| 1271 | -{ | |
| 1272 | - do_evsel(); | |
| 1273 | - RETURN(); | |
| 1274 | -} | |
| 1275 | - | |
| 1276 | -void OPPROTO op_evaddw (void) | |
| 1277 | -{ | |
| 1278 | - do_evaddw(); | |
| 1279 | - RETURN(); | |
| 1280 | -} | |
| 1281 | - | |
| 1282 | -void OPPROTO op_evsubfw (void) | |
| 1283 | -{ | |
| 1284 | - do_evsubfw(); | |
| 1285 | - RETURN(); | |
| 1286 | -} | |
| 1287 | - | |
| 1288 | -void OPPROTO op_evneg (void) | |
| 1289 | -{ | |
| 1290 | - do_evneg(); | |
| 1291 | - RETURN(); | |
| 1292 | -} | |
| 1293 | - | |
| 1294 | -void OPPROTO op_evabs (void) | |
| 1295 | -{ | |
| 1296 | - do_evabs(); | |
| 1297 | - RETURN(); | |
| 1298 | -} | |
| 1299 | - | |
| 1300 | -void OPPROTO op_evextsh (void) | |
| 1301 | -{ | |
| 1302 | - T0_64 = ((uint64_t)((int32_t)(int16_t)(T0_64 >> 32)) << 32) | | |
| 1303 | - (uint64_t)((int32_t)(int16_t)T0_64); | |
| 1304 | - RETURN(); | |
| 1305 | -} | |
| 1306 | - | |
| 1307 | -void OPPROTO op_evextsb (void) | |
| 1308 | -{ | |
| 1309 | - T0_64 = ((uint64_t)((int32_t)(int8_t)(T0_64 >> 32)) << 32) | | |
| 1310 | - (uint64_t)((int32_t)(int8_t)T0_64); | |
| 1311 | - RETURN(); | |
| 1312 | -} | |
| 1313 | - | |
| 1314 | -void OPPROTO op_evcntlzw (void) | |
| 1315 | -{ | |
| 1316 | - do_evcntlzw(); | |
| 1317 | - RETURN(); | |
| 1318 | -} | |
| 1319 | - | |
| 1320 | -void OPPROTO op_evrndw (void) | |
| 1321 | -{ | |
| 1322 | - do_evrndw(); | |
| 1323 | - RETURN(); | |
| 1324 | -} | |
| 1325 | - | |
| 1326 | -void OPPROTO op_brinc (void) | |
| 1327 | -{ | |
| 1328 | - do_brinc(); | |
| 1329 | - RETURN(); | |
| 1330 | -} | |
| 1331 | - | |
| 1332 | -void OPPROTO op_evcntlsw (void) | |
| 1333 | -{ | |
| 1334 | - do_evcntlsw(); | |
| 1335 | - RETURN(); | |
| 1336 | -} | |
| 1337 | - | |
| 1338 | -void OPPROTO op_evsrws (void) | |
| 1339 | -{ | |
| 1340 | - do_evsrws(); | |
| 1341 | - RETURN(); | |
| 1342 | -} | |
| 1343 | - | |
| 1344 | -void OPPROTO op_evsrwu (void) | |
| 1345 | -{ | |
| 1346 | - do_evsrwu(); | |
| 1347 | - RETURN(); | |
| 1348 | -} | |
| 1349 | - | |
| 1350 | -void OPPROTO op_evslw (void) | |
| 1351 | -{ | |
| 1352 | - do_evslw(); | |
| 1353 | - RETURN(); | |
| 1354 | -} | |
| 1355 | - | |
| 1356 | -void OPPROTO op_evrlw (void) | |
| 1357 | -{ | |
| 1358 | - do_evrlw(); | |
| 1359 | - RETURN(); | |
| 1360 | -} | |
| 1361 | - | |
| 1362 | -void OPPROTO op_evmergelo (void) | |
| 1363 | -{ | |
| 1364 | - T0_64 = (T0_64 << 32) | (T1_64 & 0x00000000FFFFFFFFULL); | |
| 1365 | - RETURN(); | |
| 1366 | -} | |
| 1367 | - | |
| 1368 | -void OPPROTO op_evmergehi (void) | |
| 1369 | -{ | |
| 1370 | - T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 >> 32); | |
| 1371 | - RETURN(); | |
| 1372 | -} | |
| 1373 | - | |
| 1374 | -void OPPROTO op_evmergelohi (void) | |
| 1375 | -{ | |
| 1376 | - T0_64 = (T0_64 << 32) | (T1_64 >> 32); | |
| 1377 | - RETURN(); | |
| 1378 | -} | |
| 1379 | - | |
| 1380 | -void OPPROTO op_evmergehilo (void) | |
| 1381 | -{ | |
| 1382 | - T0_64 = (T0_64 & 0xFFFFFFFF00000000ULL) | (T1_64 & 0x00000000FFFFFFFFULL); | |
| 1383 | - RETURN(); | |
| 1384 | -} | |
| 1385 | - | |
| 1386 | -void OPPROTO op_evcmpgts (void) | |
| 1387 | -{ | |
| 1388 | - do_evcmpgts(); | |
| 1389 | - RETURN(); | |
| 1390 | -} | |
| 1391 | - | |
| 1392 | -void OPPROTO op_evcmpgtu (void) | |
| 1393 | -{ | |
| 1394 | - do_evcmpgtu(); | |
| 1395 | - RETURN(); | |
| 1396 | -} | |
| 1397 | - | |
| 1398 | -void OPPROTO op_evcmplts (void) | |
| 1399 | -{ | |
| 1400 | - do_evcmplts(); | |
| 1401 | - RETURN(); | |
| 1402 | -} | |
| 1403 | - | |
| 1404 | -void OPPROTO op_evcmpltu (void) | |
| 1405 | -{ | |
| 1406 | - do_evcmpltu(); | |
| 1407 | - RETURN(); | |
| 1408 | -} | |
| 1409 | - | |
| 1410 | -void OPPROTO op_evcmpeq (void) | |
| 1411 | -{ | |
| 1412 | - do_evcmpeq(); | |
| 1413 | - RETURN(); | |
| 1414 | -} | |
| 1415 | - | |
| 1416 | 1254 | void OPPROTO op_evfssub (void) |
| 1417 | 1255 | { |
| 1418 | 1256 | do_evfssub(); | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -1624,46 +1624,18 @@ static always_inline uint32_t word_reverse (uint32_t val) |
| 1624 | 1624 | } |
| 1625 | 1625 | |
| 1626 | 1626 | #define MASKBITS 16 // Random value - to be fixed (implementation dependant) |
| 1627 | -void do_brinc (void) | |
| 1627 | +target_ulong helper_brinc (target_ulong arg1, target_ulong arg2) | |
| 1628 | 1628 | { |
| 1629 | 1629 | uint32_t a, b, d, mask; |
| 1630 | 1630 | |
| 1631 | 1631 | mask = UINT32_MAX >> (32 - MASKBITS); |
| 1632 | - a = T0 & mask; | |
| 1633 | - b = T1 & mask; | |
| 1632 | + a = arg1 & mask; | |
| 1633 | + b = arg2 & mask; | |
| 1634 | 1634 | d = word_reverse(1 + word_reverse(a | ~b)); |
| 1635 | - T0 = (T0 & ~mask) | (d & b); | |
| 1635 | + return (arg1 & ~mask) | (d & b); | |
| 1636 | 1636 | } |
| 1637 | 1637 | |
| 1638 | -#define DO_SPE_OP2(name) \ | |
| 1639 | -void do_ev##name (void) \ | |
| 1640 | -{ \ | |
| 1641 | - T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32, T1_64 >> 32) << 32) | \ | |
| 1642 | - (uint64_t)_do_e##name(T0_64, T1_64); \ | |
| 1643 | -} | |
| 1644 | - | |
| 1645 | -#define DO_SPE_OP1(name) \ | |
| 1646 | -void do_ev##name (void) \ | |
| 1647 | -{ \ | |
| 1648 | - T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32) << 32) | \ | |
| 1649 | - (uint64_t)_do_e##name(T0_64); \ | |
| 1650 | -} | |
| 1651 | - | |
| 1652 | -/* Fixed-point vector arithmetic */ | |
| 1653 | -static always_inline uint32_t _do_eabs (uint32_t val) | |
| 1654 | -{ | |
| 1655 | - if ((val & 0x80000000) && val != 0x80000000) | |
| 1656 | - val -= val; | |
| 1657 | - | |
| 1658 | - return val; | |
| 1659 | -} | |
| 1660 | - | |
| 1661 | -static always_inline uint32_t _do_eaddw (uint32_t op1, uint32_t op2) | |
| 1662 | -{ | |
| 1663 | - return op1 + op2; | |
| 1664 | -} | |
| 1665 | - | |
| 1666 | -static always_inline int _do_ecntlsw (uint32_t val) | |
| 1638 | +uint32_t helper_cntlsw32 (uint32_t val) | |
| 1667 | 1639 | { |
| 1668 | 1640 | if (val & 0x80000000) |
| 1669 | 1641 | return clz32(~val); |
| ... | ... | @@ -1671,88 +1643,23 @@ static always_inline int _do_ecntlsw (uint32_t val) |
| 1671 | 1643 | return clz32(val); |
| 1672 | 1644 | } |
| 1673 | 1645 | |
| 1674 | -static always_inline int _do_ecntlzw (uint32_t val) | |
| 1646 | +uint32_t helper_cntlzw32 (uint32_t val) | |
| 1675 | 1647 | { |
| 1676 | 1648 | return clz32(val); |
| 1677 | 1649 | } |
| 1678 | 1650 | |
| 1679 | -static always_inline uint32_t _do_eneg (uint32_t val) | |
| 1680 | -{ | |
| 1681 | - if (val != 0x80000000) | |
| 1682 | - val -= val; | |
| 1683 | - | |
| 1684 | - return val; | |
| 1685 | -} | |
| 1686 | - | |
| 1687 | -static always_inline uint32_t _do_erlw (uint32_t op1, uint32_t op2) | |
| 1688 | -{ | |
| 1689 | - return rotl32(op1, op2); | |
| 1690 | -} | |
| 1691 | - | |
| 1692 | -static always_inline uint32_t _do_erndw (uint32_t val) | |
| 1693 | -{ | |
| 1694 | - return (val + 0x000080000000) & 0xFFFF0000; | |
| 1695 | -} | |
| 1696 | - | |
| 1697 | -static always_inline uint32_t _do_eslw (uint32_t op1, uint32_t op2) | |
| 1698 | -{ | |
| 1699 | - /* No error here: 6 bits are used */ | |
| 1700 | - return op1 << (op2 & 0x3F); | |
| 1701 | -} | |
| 1702 | - | |
| 1703 | -static always_inline int32_t _do_esrws (int32_t op1, uint32_t op2) | |
| 1704 | -{ | |
| 1705 | - /* No error here: 6 bits are used */ | |
| 1706 | - return op1 >> (op2 & 0x3F); | |
| 1707 | -} | |
| 1708 | - | |
| 1709 | -static always_inline uint32_t _do_esrwu (uint32_t op1, uint32_t op2) | |
| 1710 | -{ | |
| 1711 | - /* No error here: 6 bits are used */ | |
| 1712 | - return op1 >> (op2 & 0x3F); | |
| 1713 | -} | |
| 1714 | - | |
| 1715 | -static always_inline uint32_t _do_esubfw (uint32_t op1, uint32_t op2) | |
| 1716 | -{ | |
| 1717 | - return op2 - op1; | |
| 1718 | -} | |
| 1719 | - | |
| 1720 | -/* evabs */ | |
| 1721 | -DO_SPE_OP1(abs); | |
| 1722 | -/* evaddw */ | |
| 1723 | -DO_SPE_OP2(addw); | |
| 1724 | -/* evcntlsw */ | |
| 1725 | -DO_SPE_OP1(cntlsw); | |
| 1726 | -/* evcntlzw */ | |
| 1727 | -DO_SPE_OP1(cntlzw); | |
| 1728 | -/* evneg */ | |
| 1729 | -DO_SPE_OP1(neg); | |
| 1730 | -/* evrlw */ | |
| 1731 | -DO_SPE_OP2(rlw); | |
| 1732 | -/* evrnd */ | |
| 1733 | -DO_SPE_OP1(rndw); | |
| 1734 | -/* evslw */ | |
| 1735 | -DO_SPE_OP2(slw); | |
| 1736 | -/* evsrws */ | |
| 1737 | -DO_SPE_OP2(srws); | |
| 1738 | -/* evsrwu */ | |
| 1739 | -DO_SPE_OP2(srwu); | |
| 1740 | -/* evsubfw */ | |
| 1741 | -DO_SPE_OP2(subfw); | |
| 1742 | - | |
| 1743 | -/* evsel is a little bit more complicated... */ | |
| 1744 | -static always_inline uint32_t _do_esel (uint32_t op1, uint32_t op2, int n) | |
| 1745 | -{ | |
| 1746 | - if (n) | |
| 1747 | - return op1; | |
| 1748 | - else | |
| 1749 | - return op2; | |
| 1651 | +#define DO_SPE_OP1(name) \ | |
| 1652 | +void do_ev##name (void) \ | |
| 1653 | +{ \ | |
| 1654 | + T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32) << 32) | \ | |
| 1655 | + (uint64_t)_do_e##name(T0_64); \ | |
| 1750 | 1656 | } |
| 1751 | 1657 | |
| 1752 | -void do_evsel (void) | |
| 1753 | -{ | |
| 1754 | - T0_64 = ((uint64_t)_do_esel(T0_64 >> 32, T1_64 >> 32, T0 >> 3) << 32) | | |
| 1755 | - (uint64_t)_do_esel(T0_64, T1_64, (T0 >> 2) & 1); | |
| 1658 | +#define DO_SPE_OP2(name) \ | |
| 1659 | +void do_ev##name (void) \ | |
| 1660 | +{ \ | |
| 1661 | + T0_64 = ((uint64_t)_do_e##name(T0_64 >> 32, T1_64 >> 32) << 32) | \ | |
| 1662 | + (uint64_t)_do_e##name(T0_64, T1_64); \ | |
| 1756 | 1663 | } |
| 1757 | 1664 | |
| 1758 | 1665 | /* Fixed-point vector comparisons */ |
| ... | ... | @@ -1768,41 +1675,6 @@ static always_inline uint32_t _do_evcmp_merge (int t0, int t1) |
| 1768 | 1675 | { |
| 1769 | 1676 | return (t0 << 3) | (t1 << 2) | ((t0 | t1) << 1) | (t0 & t1); |
| 1770 | 1677 | } |
| 1771 | -static always_inline int _do_ecmpeq (uint32_t op1, uint32_t op2) | |
| 1772 | -{ | |
| 1773 | - return op1 == op2 ? 1 : 0; | |
| 1774 | -} | |
| 1775 | - | |
| 1776 | -static always_inline int _do_ecmpgts (int32_t op1, int32_t op2) | |
| 1777 | -{ | |
| 1778 | - return op1 > op2 ? 1 : 0; | |
| 1779 | -} | |
| 1780 | - | |
| 1781 | -static always_inline int _do_ecmpgtu (uint32_t op1, uint32_t op2) | |
| 1782 | -{ | |
| 1783 | - return op1 > op2 ? 1 : 0; | |
| 1784 | -} | |
| 1785 | - | |
| 1786 | -static always_inline int _do_ecmplts (int32_t op1, int32_t op2) | |
| 1787 | -{ | |
| 1788 | - return op1 < op2 ? 1 : 0; | |
| 1789 | -} | |
| 1790 | - | |
| 1791 | -static always_inline int _do_ecmpltu (uint32_t op1, uint32_t op2) | |
| 1792 | -{ | |
| 1793 | - return op1 < op2 ? 1 : 0; | |
| 1794 | -} | |
| 1795 | - | |
| 1796 | -/* evcmpeq */ | |
| 1797 | -DO_SPE_CMP(cmpeq); | |
| 1798 | -/* evcmpgts */ | |
| 1799 | -DO_SPE_CMP(cmpgts); | |
| 1800 | -/* evcmpgtu */ | |
| 1801 | -DO_SPE_CMP(cmpgtu); | |
| 1802 | -/* evcmplts */ | |
| 1803 | -DO_SPE_CMP(cmplts); | |
| 1804 | -/* evcmpltu */ | |
| 1805 | -DO_SPE_CMP(cmpltu); | |
| 1806 | 1678 | |
| 1807 | 1679 | /* Single precision floating-point conversions from/to integer */ |
| 1808 | 1680 | static always_inline uint32_t _do_efscfsi (int32_t val) | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -6023,158 +6023,564 @@ GEN_SPE_STX(name) |
| 6023 | 6023 | GEN_SPEOP_LD(name, sh); \ |
| 6024 | 6024 | GEN_SPEOP_ST(name, sh) |
| 6025 | 6025 | |
| 6026 | -/* SPE arithmetic and logic */ | |
| 6027 | -#define GEN_SPEOP_ARITH2(name) \ | |
| 6026 | +/* SPE logic */ | |
| 6027 | +#if defined(TARGET_PPC64) | |
| 6028 | +#define GEN_SPEOP_LOGIC2(name, tcg_op) \ | |
| 6028 | 6029 | static always_inline void gen_##name (DisasContext *ctx) \ |
| 6029 | 6030 | { \ |
| 6030 | 6031 | if (unlikely(!ctx->spe_enabled)) { \ |
| 6031 | 6032 | GEN_EXCP_NO_AP(ctx); \ |
| 6032 | 6033 | return; \ |
| 6033 | 6034 | } \ |
| 6034 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6035 | - gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ | |
| 6036 | - gen_op_##name(); \ | |
| 6037 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
| 6035 | + tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ | |
| 6036 | + cpu_gpr[rB(ctx->opcode)]); \ | |
| 6037 | +} | |
| 6038 | +#else | |
| 6039 | +#define GEN_SPEOP_LOGIC2(name, tcg_op) \ | |
| 6040 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6041 | +{ \ | |
| 6042 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6043 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6044 | + return; \ | |
| 6045 | + } \ | |
| 6046 | + tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ | |
| 6047 | + cpu_gpr[rB(ctx->opcode)]); \ | |
| 6048 | + tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \ | |
| 6049 | + cpu_gprh[rB(ctx->opcode)]); \ | |
| 6038 | 6050 | } |
| 6051 | +#endif | |
| 6052 | + | |
| 6053 | +GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl); | |
| 6054 | +GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl); | |
| 6055 | +GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl); | |
| 6056 | +GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl); | |
| 6057 | +GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl); | |
| 6058 | +GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl); | |
| 6059 | +GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl); | |
| 6060 | +GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl); | |
| 6039 | 6061 | |
| 6040 | -#define GEN_SPEOP_TCG_ARITH2(name, tcg_op) \ | |
| 6062 | +/* SPE logic immediate */ | |
| 6063 | +#if defined(TARGET_PPC64) | |
| 6064 | +#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \ | |
| 6041 | 6065 | static always_inline void gen_##name (DisasContext *ctx) \ |
| 6042 | 6066 | { \ |
| 6043 | 6067 | if (unlikely(!ctx->spe_enabled)) { \ |
| 6044 | 6068 | GEN_EXCP_NO_AP(ctx); \ |
| 6045 | 6069 | return; \ |
| 6046 | 6070 | } \ |
| 6047 | - TCGv t0 = tcg_temp_new(TCG_TYPE_I64); \ | |
| 6048 | - TCGv t1 = tcg_temp_new(TCG_TYPE_I64); \ | |
| 6049 | - gen_load_gpr64(t0, rA(ctx->opcode)); \ | |
| 6050 | - gen_load_gpr64(t1, rB(ctx->opcode)); \ | |
| 6051 | - tcg_op(t0, t0, t1); \ | |
| 6052 | - gen_store_gpr64(rD(ctx->opcode), t0); \ | |
| 6071 | + TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6072 | + TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6073 | + TCGv t2 = tcg_temp_local_new(TCG_TYPE_I64); \ | |
| 6074 | + tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ | |
| 6075 | + tcg_opi(t0, t0, rB(ctx->opcode)); \ | |
| 6076 | + tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32); \ | |
| 6077 | + tcg_gen_trunc_i64_i32(t1, t2); \ | |
| 6078 | + tcg_temp_free(t2); \ | |
| 6079 | + tcg_opi(t1, t1, rB(ctx->opcode)); \ | |
| 6080 | + tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ | |
| 6053 | 6081 | tcg_temp_free(t0); \ |
| 6054 | 6082 | tcg_temp_free(t1); \ |
| 6055 | 6083 | } |
| 6056 | - | |
| 6057 | -#define GEN_SPEOP_ARITH1(name) \ | |
| 6084 | +#else | |
| 6085 | +#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi) \ | |
| 6058 | 6086 | static always_inline void gen_##name (DisasContext *ctx) \ |
| 6059 | 6087 | { \ |
| 6060 | 6088 | if (unlikely(!ctx->spe_enabled)) { \ |
| 6061 | 6089 | GEN_EXCP_NO_AP(ctx); \ |
| 6062 | 6090 | return; \ |
| 6063 | 6091 | } \ |
| 6064 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6065 | - gen_op_##name(); \ | |
| 6066 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
| 6092 | + tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ | |
| 6093 | + rB(ctx->opcode)); \ | |
| 6094 | + tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \ | |
| 6095 | + rB(ctx->opcode)); \ | |
| 6067 | 6096 | } |
| 6097 | +#endif | |
| 6098 | +GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32); | |
| 6099 | +GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32); | |
| 6100 | +GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32); | |
| 6101 | +GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32); | |
| 6068 | 6102 | |
| 6069 | -#define GEN_SPEOP_COMP(name) \ | |
| 6103 | +/* SPE arithmetic */ | |
| 6104 | +#if defined(TARGET_PPC64) | |
| 6105 | +#define GEN_SPEOP_ARITH1(name, tcg_op) \ | |
| 6070 | 6106 | static always_inline void gen_##name (DisasContext *ctx) \ |
| 6071 | 6107 | { \ |
| 6072 | 6108 | if (unlikely(!ctx->spe_enabled)) { \ |
| 6073 | 6109 | GEN_EXCP_NO_AP(ctx); \ |
| 6074 | 6110 | return; \ |
| 6075 | 6111 | } \ |
| 6076 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6077 | - gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ | |
| 6078 | - gen_op_##name(); \ | |
| 6079 | - tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf); \ | |
| 6112 | + TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6113 | + TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6114 | + TCGv t2 = tcg_temp_local_new(TCG_TYPE_I64); \ | |
| 6115 | + tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ | |
| 6116 | + tcg_op(t0, t0); \ | |
| 6117 | + tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32); \ | |
| 6118 | + tcg_gen_trunc_i64_i32(t1, t2); \ | |
| 6119 | + tcg_temp_free(t2); \ | |
| 6120 | + tcg_op(t1, t1); \ | |
| 6121 | + tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ | |
| 6122 | + tcg_temp_free(t0); \ | |
| 6123 | + tcg_temp_free(t1); \ | |
| 6080 | 6124 | } |
| 6125 | +#else | |
| 6126 | +#define GEN_SPEOP_ARITH1(name, tcg_op) \ | |
| 6127 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6128 | +{ \ | |
| 6129 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6130 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6131 | + return; \ | |
| 6132 | + } \ | |
| 6133 | + tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); \ | |
| 6134 | + tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); \ | |
| 6135 | +} | |
| 6136 | +#endif | |
| 6081 | 6137 | |
| 6082 | -/* Logical */ | |
| 6083 | -GEN_SPEOP_TCG_ARITH2(evand, tcg_gen_and_i64); | |
| 6084 | -GEN_SPEOP_TCG_ARITH2(evandc, tcg_gen_andc_i64); | |
| 6085 | -GEN_SPEOP_TCG_ARITH2(evxor, tcg_gen_xor_i64); | |
| 6086 | -GEN_SPEOP_TCG_ARITH2(evor, tcg_gen_or_i64); | |
| 6087 | -GEN_SPEOP_TCG_ARITH2(evnor, tcg_gen_nor_i64); | |
| 6088 | -GEN_SPEOP_TCG_ARITH2(eveqv, tcg_gen_eqv_i64); | |
| 6089 | -GEN_SPEOP_TCG_ARITH2(evorc, tcg_gen_orc_i64); | |
| 6090 | -GEN_SPEOP_TCG_ARITH2(evnand, tcg_gen_nand_i64); | |
| 6091 | -GEN_SPEOP_ARITH2(evsrwu); | |
| 6092 | -GEN_SPEOP_ARITH2(evsrws); | |
| 6093 | -GEN_SPEOP_ARITH2(evslw); | |
| 6094 | -GEN_SPEOP_ARITH2(evrlw); | |
| 6095 | -GEN_SPEOP_ARITH2(evmergehi); | |
| 6096 | -GEN_SPEOP_ARITH2(evmergelo); | |
| 6097 | -GEN_SPEOP_ARITH2(evmergehilo); | |
| 6098 | -GEN_SPEOP_ARITH2(evmergelohi); | |
| 6138 | +static always_inline void gen_op_evabs (TCGv ret, TCGv arg1) | |
| 6139 | +{ | |
| 6140 | + int l1 = gen_new_label(); | |
| 6141 | + int l2 = gen_new_label(); | |
| 6099 | 6142 | |
| 6100 | -/* Arithmetic */ | |
| 6101 | -GEN_SPEOP_ARITH2(evaddw); | |
| 6102 | -GEN_SPEOP_ARITH2(evsubfw); | |
| 6103 | -GEN_SPEOP_ARITH1(evabs); | |
| 6104 | -GEN_SPEOP_ARITH1(evneg); | |
| 6105 | -GEN_SPEOP_ARITH1(evextsb); | |
| 6106 | -GEN_SPEOP_ARITH1(evextsh); | |
| 6107 | -GEN_SPEOP_ARITH1(evrndw); | |
| 6108 | -GEN_SPEOP_ARITH1(evcntlzw); | |
| 6109 | -GEN_SPEOP_ARITH1(evcntlsw); | |
| 6110 | -static always_inline void gen_brinc (DisasContext *ctx) | |
| 6143 | + tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1); | |
| 6144 | + tcg_gen_neg_i32(ret, arg1); | |
| 6145 | + tcg_gen_br(l2); | |
| 6146 | + gen_set_label(l1); | |
| 6147 | + tcg_gen_mov_tl(ret, arg1); | |
| 6148 | + gen_set_label(l2); | |
| 6149 | +} | |
| 6150 | +GEN_SPEOP_ARITH1(evabs, gen_op_evabs); | |
| 6151 | +GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32); | |
| 6152 | +GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32); | |
| 6153 | +GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32); | |
| 6154 | +static always_inline void gen_op_evrndw (TCGv ret, TCGv arg1) | |
| 6111 | 6155 | { |
| 6112 | - /* Note: brinc is usable even if SPE is disabled */ | |
| 6113 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]); | |
| 6114 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]); | |
| 6115 | - gen_op_brinc(); | |
| 6116 | - tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]); | |
| 6156 | + tcg_gen_addi_i32(ret, arg1, 0x8000); | |
| 6157 | + tcg_gen_ext16u_i32(ret, ret); | |
| 6158 | +} | |
| 6159 | +GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw); | |
| 6160 | +static always_inline void gen_op_cntlsw (TCGv ret, TCGv arg1) | |
| 6161 | +{ | |
| 6162 | + tcg_gen_helper_1_1(helper_cntlsw32, ret, arg1); | |
| 6163 | +} | |
| 6164 | +GEN_SPEOP_ARITH1(evcntlsw, gen_op_cntlsw); | |
| 6165 | +static always_inline void gen_op_cntlzw (TCGv ret, TCGv arg1) | |
| 6166 | +{ | |
| 6167 | + tcg_gen_helper_1_1(helper_cntlzw32, ret, arg1); | |
| 6117 | 6168 | } |
| 6169 | +GEN_SPEOP_ARITH1(evcntlzw, gen_op_cntlzw); | |
| 6118 | 6170 | |
| 6119 | -#define GEN_SPEOP_ARITH_IMM2(name) \ | |
| 6120 | -static always_inline void gen_##name##i (DisasContext *ctx) \ | |
| 6171 | +#if defined(TARGET_PPC64) | |
| 6172 | +#define GEN_SPEOP_ARITH2(name, tcg_op) \ | |
| 6173 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6121 | 6174 | { \ |
| 6122 | 6175 | if (unlikely(!ctx->spe_enabled)) { \ |
| 6123 | 6176 | GEN_EXCP_NO_AP(ctx); \ |
| 6124 | 6177 | return; \ |
| 6125 | 6178 | } \ |
| 6126 | - gen_load_gpr64(cpu_T64[0], rB(ctx->opcode)); \ | |
| 6127 | - gen_op_splatwi_T1_64(rA(ctx->opcode)); \ | |
| 6128 | - gen_op_##name(); \ | |
| 6129 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
| 6179 | + TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6180 | + TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6181 | + TCGv t2 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6182 | + TCGv t3 = tcg_temp_local_new(TCG_TYPE_I64); \ | |
| 6183 | + tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ | |
| 6184 | + tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]); \ | |
| 6185 | + tcg_op(t0, t0, t2); \ | |
| 6186 | + tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32); \ | |
| 6187 | + tcg_gen_trunc_i64_i32(t1, t3); \ | |
| 6188 | + tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32); \ | |
| 6189 | + tcg_gen_trunc_i64_i32(t2, t3); \ | |
| 6190 | + tcg_temp_free(t3); \ | |
| 6191 | + tcg_op(t1, t1, t2); \ | |
| 6192 | + tcg_temp_free(t2); \ | |
| 6193 | + tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ | |
| 6194 | + tcg_temp_free(t0); \ | |
| 6195 | + tcg_temp_free(t1); \ | |
| 6130 | 6196 | } |
| 6131 | - | |
| 6132 | -#define GEN_SPEOP_LOGIC_IMM2(name) \ | |
| 6133 | -static always_inline void gen_##name##i (DisasContext *ctx) \ | |
| 6197 | +#else | |
| 6198 | +#define GEN_SPEOP_ARITH2(name, tcg_op) \ | |
| 6199 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6134 | 6200 | { \ |
| 6135 | 6201 | if (unlikely(!ctx->spe_enabled)) { \ |
| 6136 | 6202 | GEN_EXCP_NO_AP(ctx); \ |
| 6137 | 6203 | return; \ |
| 6138 | 6204 | } \ |
| 6139 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6140 | - gen_op_splatwi_T1_64(rB(ctx->opcode)); \ | |
| 6141 | - gen_op_##name(); \ | |
| 6142 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
| 6205 | + tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], \ | |
| 6206 | + cpu_gpr[rB(ctx->opcode)]); \ | |
| 6207 | + tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], \ | |
| 6208 | + cpu_gprh[rB(ctx->opcode)]); \ | |
| 6143 | 6209 | } |
| 6210 | +#endif | |
| 6144 | 6211 | |
| 6145 | -GEN_SPEOP_ARITH_IMM2(evaddw); | |
| 6146 | -#define gen_evaddiw gen_evaddwi | |
| 6147 | -GEN_SPEOP_ARITH_IMM2(evsubfw); | |
| 6148 | -#define gen_evsubifw gen_evsubfwi | |
| 6149 | -GEN_SPEOP_LOGIC_IMM2(evslw); | |
| 6150 | -GEN_SPEOP_LOGIC_IMM2(evsrwu); | |
| 6151 | -#define gen_evsrwis gen_evsrwsi | |
| 6152 | -GEN_SPEOP_LOGIC_IMM2(evsrws); | |
| 6153 | -#define gen_evsrwiu gen_evsrwui | |
| 6154 | -GEN_SPEOP_LOGIC_IMM2(evrlw); | |
| 6212 | +static always_inline void gen_op_evsrwu (TCGv ret, TCGv arg1, TCGv arg2) | |
| 6213 | +{ | |
| 6214 | + TCGv t0; | |
| 6215 | + int l1, l2; | |
| 6155 | 6216 | |
| 6156 | -static always_inline void gen_evsplati (DisasContext *ctx) | |
| 6217 | + l1 = gen_new_label(); | |
| 6218 | + l2 = gen_new_label(); | |
| 6219 | + t0 = tcg_temp_local_new(TCG_TYPE_I32); | |
| 6220 | + /* No error here: 6 bits are used */ | |
| 6221 | + tcg_gen_andi_i32(t0, arg2, 0x3F); | |
| 6222 | + tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1); | |
| 6223 | + tcg_gen_shr_i32(ret, arg1, t0); | |
| 6224 | + tcg_gen_br(l2); | |
| 6225 | + gen_set_label(l1); | |
| 6226 | + tcg_gen_movi_i32(ret, 0); | |
| 6227 | + tcg_gen_br(l2); | |
| 6228 | + tcg_temp_free(t0); | |
| 6229 | +} | |
| 6230 | +GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu); | |
| 6231 | +static always_inline void gen_op_evsrws (TCGv ret, TCGv arg1, TCGv arg2) | |
| 6232 | +{ | |
| 6233 | + TCGv t0; | |
| 6234 | + int l1, l2; | |
| 6235 | + | |
| 6236 | + l1 = gen_new_label(); | |
| 6237 | + l2 = gen_new_label(); | |
| 6238 | + t0 = tcg_temp_local_new(TCG_TYPE_I32); | |
| 6239 | + /* No error here: 6 bits are used */ | |
| 6240 | + tcg_gen_andi_i32(t0, arg2, 0x3F); | |
| 6241 | + tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1); | |
| 6242 | + tcg_gen_sar_i32(ret, arg1, t0); | |
| 6243 | + tcg_gen_br(l2); | |
| 6244 | + gen_set_label(l1); | |
| 6245 | + tcg_gen_movi_i32(ret, 0); | |
| 6246 | + tcg_gen_br(l2); | |
| 6247 | + tcg_temp_free(t0); | |
| 6248 | +} | |
| 6249 | +GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws); | |
| 6250 | +static always_inline void gen_op_evslw (TCGv ret, TCGv arg1, TCGv arg2) | |
| 6251 | +{ | |
| 6252 | + TCGv t0; | |
| 6253 | + int l1, l2; | |
| 6254 | + | |
| 6255 | + l1 = gen_new_label(); | |
| 6256 | + l2 = gen_new_label(); | |
| 6257 | + t0 = tcg_temp_local_new(TCG_TYPE_I32); | |
| 6258 | + /* No error here: 6 bits are used */ | |
| 6259 | + tcg_gen_andi_i32(t0, arg2, 0x3F); | |
| 6260 | + tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1); | |
| 6261 | + tcg_gen_shl_i32(ret, arg1, t0); | |
| 6262 | + tcg_gen_br(l2); | |
| 6263 | + gen_set_label(l1); | |
| 6264 | + tcg_gen_movi_i32(ret, 0); | |
| 6265 | + tcg_gen_br(l2); | |
| 6266 | + tcg_temp_free(t0); | |
| 6267 | +} | |
| 6268 | +GEN_SPEOP_ARITH2(evslw, gen_op_evslw); | |
| 6269 | +static always_inline void gen_op_evrlw (TCGv ret, TCGv arg1, TCGv arg2) | |
| 6270 | +{ | |
| 6271 | + TCGv t0 = tcg_temp_new(TCG_TYPE_I32); | |
| 6272 | + tcg_gen_andi_i32(t0, arg2, 0x1F); | |
| 6273 | + tcg_gen_rotl_i32(ret, arg1, t0); | |
| 6274 | + tcg_temp_free(t0); | |
| 6275 | +} | |
| 6276 | +GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw); | |
| 6277 | +static always_inline void gen_evmergehi (DisasContext *ctx) | |
| 6278 | +{ | |
| 6279 | + if (unlikely(!ctx->spe_enabled)) { | |
| 6280 | + GEN_EXCP_NO_AP(ctx); | |
| 6281 | + return; | |
| 6282 | + } | |
| 6283 | +#if defined(TARGET_PPC64) | |
| 6284 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 6285 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 6286 | + tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32); | |
| 6287 | + tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL); | |
| 6288 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); | |
| 6289 | + tcg_temp_free(t0); | |
| 6290 | + tcg_temp_free(t1); | |
| 6291 | +#else | |
| 6292 | + tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); | |
| 6293 | + tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); | |
| 6294 | +#endif | |
| 6295 | +} | |
| 6296 | +GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32); | |
| 6297 | +static always_inline void gen_op_evsubf (TCGv ret, TCGv arg1, TCGv arg2) | |
| 6157 | 6298 | { |
| 6158 | - int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27; | |
| 6299 | + tcg_gen_sub_i32(ret, arg2, arg1); | |
| 6300 | +} | |
| 6301 | +GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf); | |
| 6159 | 6302 | |
| 6160 | - gen_op_splatwi_T0_64(imm); | |
| 6161 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); | |
| 6303 | +/* SPE arithmetic immediate */ | |
| 6304 | +#if defined(TARGET_PPC64) | |
| 6305 | +#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \ | |
| 6306 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6307 | +{ \ | |
| 6308 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6309 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6310 | + return; \ | |
| 6311 | + } \ | |
| 6312 | + TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6313 | + TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6314 | + TCGv t2 = tcg_temp_local_new(TCG_TYPE_I64); \ | |
| 6315 | + tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]); \ | |
| 6316 | + tcg_op(t0, t0, rA(ctx->opcode)); \ | |
| 6317 | + tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32); \ | |
| 6318 | + tcg_gen_trunc_i64_i32(t1, t2); \ | |
| 6319 | + tcg_temp_free(t2); \ | |
| 6320 | + tcg_op(t1, t1, rA(ctx->opcode)); \ | |
| 6321 | + tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1); \ | |
| 6322 | + tcg_temp_free(t0); \ | |
| 6323 | + tcg_temp_free(t1); \ | |
| 6324 | +} | |
| 6325 | +#else | |
| 6326 | +#define GEN_SPEOP_ARITH_IMM2(name, tcg_op) \ | |
| 6327 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6328 | +{ \ | |
| 6329 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6330 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6331 | + return; \ | |
| 6332 | + } \ | |
| 6333 | + tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)], \ | |
| 6334 | + rA(ctx->opcode)); \ | |
| 6335 | + tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)], \ | |
| 6336 | + rA(ctx->opcode)); \ | |
| 6337 | +} | |
| 6338 | +#endif | |
| 6339 | +GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32); | |
| 6340 | +GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32); | |
| 6341 | + | |
| 6342 | +/* SPE comparison */ | |
| 6343 | +#if defined(TARGET_PPC64) | |
| 6344 | +#define GEN_SPEOP_COMP(name, tcg_cond) \ | |
| 6345 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6346 | +{ \ | |
| 6347 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6348 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6349 | + return; \ | |
| 6350 | + } \ | |
| 6351 | + int l1 = gen_new_label(); \ | |
| 6352 | + int l2 = gen_new_label(); \ | |
| 6353 | + int l3 = gen_new_label(); \ | |
| 6354 | + int l4 = gen_new_label(); \ | |
| 6355 | + TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6356 | + TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32); \ | |
| 6357 | + TCGv t2 = tcg_temp_local_new(TCG_TYPE_I64); \ | |
| 6358 | + tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]); \ | |
| 6359 | + tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]); \ | |
| 6360 | + tcg_gen_brcond_i32(tcg_cond, t0, t1, l1); \ | |
| 6361 | + tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0); \ | |
| 6362 | + tcg_gen_br(l2); \ | |
| 6363 | + gen_set_label(l1); \ | |
| 6364 | + tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \ | |
| 6365 | + CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \ | |
| 6366 | + gen_set_label(l2); \ | |
| 6367 | + tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32); \ | |
| 6368 | + tcg_gen_trunc_i64_i32(t0, t2); \ | |
| 6369 | + tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32); \ | |
| 6370 | + tcg_gen_trunc_i64_i32(t1, t2); \ | |
| 6371 | + tcg_temp_free(t2); \ | |
| 6372 | + tcg_gen_brcond_i32(tcg_cond, t0, t1, l3); \ | |
| 6373 | + tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ | |
| 6374 | + ~(CRF_CH | CRF_CH_AND_CL)); \ | |
| 6375 | + tcg_gen_br(l4); \ | |
| 6376 | + gen_set_label(l3); \ | |
| 6377 | + tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ | |
| 6378 | + CRF_CH | CRF_CH_OR_CL); \ | |
| 6379 | + gen_set_label(l4); \ | |
| 6380 | + tcg_temp_free(t0); \ | |
| 6381 | + tcg_temp_free(t1); \ | |
| 6382 | +} | |
| 6383 | +#else | |
| 6384 | +#define GEN_SPEOP_COMP(name, tcg_cond) \ | |
| 6385 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6386 | +{ \ | |
| 6387 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6388 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6389 | + return; \ | |
| 6390 | + } \ | |
| 6391 | + int l1 = gen_new_label(); \ | |
| 6392 | + int l2 = gen_new_label(); \ | |
| 6393 | + int l3 = gen_new_label(); \ | |
| 6394 | + int l4 = gen_new_label(); \ | |
| 6395 | + \ | |
| 6396 | + tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)], \ | |
| 6397 | + cpu_gpr[rB(ctx->opcode)], l1); \ | |
| 6398 | + tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0); \ | |
| 6399 | + tcg_gen_br(l2); \ | |
| 6400 | + gen_set_label(l1); \ | |
| 6401 | + tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], \ | |
| 6402 | + CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL); \ | |
| 6403 | + gen_set_label(l2); \ | |
| 6404 | + tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)], \ | |
| 6405 | + cpu_gprh[rB(ctx->opcode)], l3); \ | |
| 6406 | + tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ | |
| 6407 | + ~(CRF_CH | CRF_CH_AND_CL)); \ | |
| 6408 | + tcg_gen_br(l4); \ | |
| 6409 | + gen_set_label(l3); \ | |
| 6410 | + tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)], \ | |
| 6411 | + CRF_CH | CRF_CH_OR_CL); \ | |
| 6412 | + gen_set_label(l4); \ | |
| 6413 | +} | |
| 6414 | +#endif | |
| 6415 | +GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU); | |
| 6416 | +GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT); | |
| 6417 | +GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU); | |
| 6418 | +GEN_SPEOP_COMP(evcmplts, TCG_COND_LT); | |
| 6419 | +GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ); | |
| 6420 | + | |
| 6421 | +/* SPE misc */ | |
| 6422 | +static always_inline void gen_brinc (DisasContext *ctx) | |
| 6423 | +{ | |
| 6424 | + /* Note: brinc is usable even if SPE is disabled */ | |
| 6425 | + tcg_gen_helper_1_2(helper_brinc, cpu_gpr[rD(ctx->opcode)], | |
| 6426 | + cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 6162 | 6427 | } |
| 6428 | +static always_inline void gen_evmergelo (DisasContext *ctx) | |
| 6429 | +{ | |
| 6430 | + if (unlikely(!ctx->spe_enabled)) { | |
| 6431 | + GEN_EXCP_NO_AP(ctx); | |
| 6432 | + return; | |
| 6433 | + } | |
| 6434 | +#if defined(TARGET_PPC64) | |
| 6435 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 6436 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 6437 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL); | |
| 6438 | + tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32); | |
| 6439 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); | |
| 6440 | + tcg_temp_free(t0); | |
| 6441 | + tcg_temp_free(t1); | |
| 6442 | +#else | |
| 6443 | + tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 6444 | + tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 6445 | +#endif | |
| 6446 | +} | |
| 6447 | +static always_inline void gen_evmergehilo (DisasContext *ctx) | |
| 6448 | +{ | |
| 6449 | + if (unlikely(!ctx->spe_enabled)) { | |
| 6450 | + GEN_EXCP_NO_AP(ctx); | |
| 6451 | + return; | |
| 6452 | + } | |
| 6453 | +#if defined(TARGET_PPC64) | |
| 6454 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 6455 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 6456 | + tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL); | |
| 6457 | + tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL); | |
| 6458 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); | |
| 6459 | + tcg_temp_free(t0); | |
| 6460 | + tcg_temp_free(t1); | |
| 6461 | +#else | |
| 6462 | + tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 6463 | + tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); | |
| 6464 | +#endif | |
| 6465 | +} | |
| 6466 | +static always_inline void gen_evmergelohi (DisasContext *ctx) | |
| 6467 | +{ | |
| 6468 | + if (unlikely(!ctx->spe_enabled)) { | |
| 6469 | + GEN_EXCP_NO_AP(ctx); | |
| 6470 | + return; | |
| 6471 | + } | |
| 6472 | +#if defined(TARGET_PPC64) | |
| 6473 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 6474 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 6475 | + tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32); | |
| 6476 | + tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32); | |
| 6477 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); | |
| 6478 | + tcg_temp_free(t0); | |
| 6479 | + tcg_temp_free(t1); | |
| 6480 | +#else | |
| 6481 | + tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); | |
| 6482 | + tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 6483 | +#endif | |
| 6484 | +} | |
| 6485 | +static always_inline void gen_evsplati (DisasContext *ctx) | |
| 6486 | +{ | |
| 6487 | + int32_t imm = (int32_t)(rA(ctx->opcode) << 11) >> 27; | |
| 6163 | 6488 | |
| 6489 | +#if defined(TARGET_PPC64) | |
| 6490 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 6491 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 6492 | + tcg_gen_movi_tl(t0, imm); | |
| 6493 | + tcg_gen_shri_tl(t1, t0, 32); | |
| 6494 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); | |
| 6495 | + tcg_temp_free(t0); | |
| 6496 | + tcg_temp_free(t1); | |
| 6497 | +#else | |
| 6498 | + tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm); | |
| 6499 | + tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm); | |
| 6500 | +#endif | |
| 6501 | +} | |
| 6164 | 6502 | static always_inline void gen_evsplatfi (DisasContext *ctx) |
| 6165 | 6503 | { |
| 6166 | - uint32_t imm = rA(ctx->opcode) << 27; | |
| 6504 | + uint32_t imm = rA(ctx->opcode) << 11; | |
| 6167 | 6505 | |
| 6168 | - gen_op_splatwi_T0_64(imm); | |
| 6169 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); | |
| 6506 | +#if defined(TARGET_PPC64) | |
| 6507 | + TCGv t0 = tcg_temp_new(TCG_TYPE_TL); | |
| 6508 | + TCGv t1 = tcg_temp_new(TCG_TYPE_TL); | |
| 6509 | + tcg_gen_movi_tl(t0, imm); | |
| 6510 | + tcg_gen_shri_tl(t1, t0, 32); | |
| 6511 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1); | |
| 6512 | + tcg_temp_free(t0); | |
| 6513 | + tcg_temp_free(t1); | |
| 6514 | +#else | |
| 6515 | + tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm); | |
| 6516 | + tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm); | |
| 6517 | +#endif | |
| 6170 | 6518 | } |
| 6171 | 6519 | |
| 6172 | -/* Comparison */ | |
| 6173 | -GEN_SPEOP_COMP(evcmpgtu); | |
| 6174 | -GEN_SPEOP_COMP(evcmpgts); | |
| 6175 | -GEN_SPEOP_COMP(evcmpltu); | |
| 6176 | -GEN_SPEOP_COMP(evcmplts); | |
| 6177 | -GEN_SPEOP_COMP(evcmpeq); | |
| 6520 | +static always_inline void gen_evsel (DisasContext *ctx) | |
| 6521 | +{ | |
| 6522 | + int l1 = gen_new_label(); | |
| 6523 | + int l2 = gen_new_label(); | |
| 6524 | + int l3 = gen_new_label(); | |
| 6525 | + int l4 = gen_new_label(); | |
| 6526 | + TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32); | |
| 6527 | +#if defined(TARGET_PPC64) | |
| 6528 | + TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 6529 | + TCGv t2 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 6530 | +#endif | |
| 6531 | + tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3); | |
| 6532 | + tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1); | |
| 6533 | +#if defined(TARGET_PPC64) | |
| 6534 | + tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL); | |
| 6535 | +#else | |
| 6536 | + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]); | |
| 6537 | +#endif | |
| 6538 | + tcg_gen_br(l2); | |
| 6539 | + gen_set_label(l1); | |
| 6540 | +#if defined(TARGET_PPC64) | |
| 6541 | + tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL); | |
| 6542 | +#else | |
| 6543 | + tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]); | |
| 6544 | +#endif | |
| 6545 | + gen_set_label(l2); | |
| 6546 | + tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2); | |
| 6547 | + tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3); | |
| 6548 | +#if defined(TARGET_PPC64) | |
| 6549 | + tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL); | |
| 6550 | +#else | |
| 6551 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]); | |
| 6552 | +#endif | |
| 6553 | + tcg_gen_br(l4); | |
| 6554 | + gen_set_label(l3); | |
| 6555 | +#if defined(TARGET_PPC64) | |
| 6556 | + tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL); | |
| 6557 | +#else | |
| 6558 | + tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]); | |
| 6559 | +#endif | |
| 6560 | + gen_set_label(l4); | |
| 6561 | + tcg_temp_free(t0); | |
| 6562 | +#if defined(TARGET_PPC64) | |
| 6563 | + tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2); | |
| 6564 | + tcg_temp_free(t1); | |
| 6565 | + tcg_temp_free(t2); | |
| 6566 | +#endif | |
| 6567 | +} | |
| 6568 | +GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE) | |
| 6569 | +{ | |
| 6570 | + gen_evsel(ctx); | |
| 6571 | +} | |
| 6572 | +GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE) | |
| 6573 | +{ | |
| 6574 | + gen_evsel(ctx); | |
| 6575 | +} | |
| 6576 | +GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE) | |
| 6577 | +{ | |
| 6578 | + gen_evsel(ctx); | |
| 6579 | +} | |
| 6580 | +GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE) | |
| 6581 | +{ | |
| 6582 | + gen_evsel(ctx); | |
| 6583 | +} | |
| 6178 | 6584 | |
| 6179 | 6585 | GEN_SPE(evaddw, speundef, 0x00, 0x08, 0x00000000, PPC_SPE); //// |
| 6180 | 6586 | GEN_SPE(evaddiw, speundef, 0x01, 0x08, 0x00000000, PPC_SPE); |
| ... | ... | @@ -6202,36 +6608,6 @@ GEN_SPE(evcmpgtu, evcmpgts, 0x18, 0x08, 0x00600000, PPC_SPE); //// |
| 6202 | 6608 | GEN_SPE(evcmpltu, evcmplts, 0x19, 0x08, 0x00600000, PPC_SPE); //// |
| 6203 | 6609 | GEN_SPE(evcmpeq, speundef, 0x1A, 0x08, 0x00600000, PPC_SPE); //// |
| 6204 | 6610 | |
| 6205 | -static always_inline void gen_evsel (DisasContext *ctx) | |
| 6206 | -{ | |
| 6207 | - if (unlikely(!ctx->spe_enabled)) { | |
| 6208 | - GEN_EXCP_NO_AP(ctx); | |
| 6209 | - return; | |
| 6210 | - } | |
| 6211 | - tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]); | |
| 6212 | - gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); | |
| 6213 | - gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); | |
| 6214 | - gen_op_evsel(); | |
| 6215 | - gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); | |
| 6216 | -} | |
| 6217 | - | |
| 6218 | -GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE) | |
| 6219 | -{ | |
| 6220 | - gen_evsel(ctx); | |
| 6221 | -} | |
| 6222 | -GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE) | |
| 6223 | -{ | |
| 6224 | - gen_evsel(ctx); | |
| 6225 | -} | |
| 6226 | -GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE) | |
| 6227 | -{ | |
| 6228 | - gen_evsel(ctx); | |
| 6229 | -} | |
| 6230 | -GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE) | |
| 6231 | -{ | |
| 6232 | - gen_evsel(ctx); | |
| 6233 | -} | |
| 6234 | - | |
| 6235 | 6611 | /* Load and stores */ |
| 6236 | 6612 | GEN_SPEOP_LDST(dd, 3); |
| 6237 | 6613 | GEN_SPEOP_LDST(dw, 3); |
| ... | ... | @@ -6500,15 +6876,53 @@ static always_inline void gen_##name (DisasContext *ctx) \ |
| 6500 | 6876 | gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ |
| 6501 | 6877 | } |
| 6502 | 6878 | |
| 6879 | +#define GEN_SPEFPUOP_ARITH1(name) \ | |
| 6880 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6881 | +{ \ | |
| 6882 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6883 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6884 | + return; \ | |
| 6885 | + } \ | |
| 6886 | + gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6887 | + gen_op_##name(); \ | |
| 6888 | + gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
| 6889 | +} | |
| 6890 | + | |
| 6891 | +#define GEN_SPEFPUOP_ARITH2(name) \ | |
| 6892 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6893 | +{ \ | |
| 6894 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6895 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6896 | + return; \ | |
| 6897 | + } \ | |
| 6898 | + gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6899 | + gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ | |
| 6900 | + gen_op_##name(); \ | |
| 6901 | + gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]); \ | |
| 6902 | +} | |
| 6903 | + | |
| 6904 | +#define GEN_SPEFPUOP_COMP(name) \ | |
| 6905 | +static always_inline void gen_##name (DisasContext *ctx) \ | |
| 6906 | +{ \ | |
| 6907 | + if (unlikely(!ctx->spe_enabled)) { \ | |
| 6908 | + GEN_EXCP_NO_AP(ctx); \ | |
| 6909 | + return; \ | |
| 6910 | + } \ | |
| 6911 | + gen_load_gpr64(cpu_T64[0], rA(ctx->opcode)); \ | |
| 6912 | + gen_load_gpr64(cpu_T64[1], rB(ctx->opcode)); \ | |
| 6913 | + gen_op_##name(); \ | |
| 6914 | + tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf); \ | |
| 6915 | +} | |
| 6916 | + | |
| 6503 | 6917 | /* Single precision floating-point vectors operations */ |
| 6504 | 6918 | /* Arithmetic */ |
| 6505 | -GEN_SPEOP_ARITH2(evfsadd); | |
| 6506 | -GEN_SPEOP_ARITH2(evfssub); | |
| 6507 | -GEN_SPEOP_ARITH2(evfsmul); | |
| 6508 | -GEN_SPEOP_ARITH2(evfsdiv); | |
| 6509 | -GEN_SPEOP_ARITH1(evfsabs); | |
| 6510 | -GEN_SPEOP_ARITH1(evfsnabs); | |
| 6511 | -GEN_SPEOP_ARITH1(evfsneg); | |
| 6919 | +GEN_SPEFPUOP_ARITH2(evfsadd); | |
| 6920 | +GEN_SPEFPUOP_ARITH2(evfssub); | |
| 6921 | +GEN_SPEFPUOP_ARITH2(evfsmul); | |
| 6922 | +GEN_SPEFPUOP_ARITH2(evfsdiv); | |
| 6923 | +GEN_SPEFPUOP_ARITH1(evfsabs); | |
| 6924 | +GEN_SPEFPUOP_ARITH1(evfsnabs); | |
| 6925 | +GEN_SPEFPUOP_ARITH1(evfsneg); | |
| 6512 | 6926 | /* Conversion */ |
| 6513 | 6927 | GEN_SPEFPUOP_CONV(evfscfui); |
| 6514 | 6928 | GEN_SPEFPUOP_CONV(evfscfsi); |
| ... | ... | @@ -6521,12 +6935,12 @@ GEN_SPEFPUOP_CONV(evfsctsf); |
| 6521 | 6935 | GEN_SPEFPUOP_CONV(evfsctuiz); |
| 6522 | 6936 | GEN_SPEFPUOP_CONV(evfsctsiz); |
| 6523 | 6937 | /* Comparison */ |
| 6524 | -GEN_SPEOP_COMP(evfscmpgt); | |
| 6525 | -GEN_SPEOP_COMP(evfscmplt); | |
| 6526 | -GEN_SPEOP_COMP(evfscmpeq); | |
| 6527 | -GEN_SPEOP_COMP(evfststgt); | |
| 6528 | -GEN_SPEOP_COMP(evfststlt); | |
| 6529 | -GEN_SPEOP_COMP(evfststeq); | |
| 6938 | +GEN_SPEFPUOP_COMP(evfscmpgt); | |
| 6939 | +GEN_SPEFPUOP_COMP(evfscmplt); | |
| 6940 | +GEN_SPEFPUOP_COMP(evfscmpeq); | |
| 6941 | +GEN_SPEFPUOP_COMP(evfststgt); | |
| 6942 | +GEN_SPEFPUOP_COMP(evfststlt); | |
| 6943 | +GEN_SPEFPUOP_COMP(evfststeq); | |
| 6530 | 6944 | |
| 6531 | 6945 | /* Opcodes definitions */ |
| 6532 | 6946 | GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPEFPU); // |
| ... | ... | @@ -6546,13 +6960,13 @@ GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPEFPU); // |
| 6546 | 6960 | |
| 6547 | 6961 | /* Single precision floating-point operations */ |
| 6548 | 6962 | /* Arithmetic */ |
| 6549 | -GEN_SPEOP_ARITH2(efsadd); | |
| 6550 | -GEN_SPEOP_ARITH2(efssub); | |
| 6551 | -GEN_SPEOP_ARITH2(efsmul); | |
| 6552 | -GEN_SPEOP_ARITH2(efsdiv); | |
| 6553 | -GEN_SPEOP_ARITH1(efsabs); | |
| 6554 | -GEN_SPEOP_ARITH1(efsnabs); | |
| 6555 | -GEN_SPEOP_ARITH1(efsneg); | |
| 6963 | +GEN_SPEFPUOP_ARITH2(efsadd); | |
| 6964 | +GEN_SPEFPUOP_ARITH2(efssub); | |
| 6965 | +GEN_SPEFPUOP_ARITH2(efsmul); | |
| 6966 | +GEN_SPEFPUOP_ARITH2(efsdiv); | |
| 6967 | +GEN_SPEFPUOP_ARITH1(efsabs); | |
| 6968 | +GEN_SPEFPUOP_ARITH1(efsnabs); | |
| 6969 | +GEN_SPEFPUOP_ARITH1(efsneg); | |
| 6556 | 6970 | /* Conversion */ |
| 6557 | 6971 | GEN_SPEFPUOP_CONV(efscfui); |
| 6558 | 6972 | GEN_SPEFPUOP_CONV(efscfsi); |
| ... | ... | @@ -6566,12 +6980,12 @@ GEN_SPEFPUOP_CONV(efsctuiz); |
| 6566 | 6980 | GEN_SPEFPUOP_CONV(efsctsiz); |
| 6567 | 6981 | GEN_SPEFPUOP_CONV(efscfd); |
| 6568 | 6982 | /* Comparison */ |
| 6569 | -GEN_SPEOP_COMP(efscmpgt); | |
| 6570 | -GEN_SPEOP_COMP(efscmplt); | |
| 6571 | -GEN_SPEOP_COMP(efscmpeq); | |
| 6572 | -GEN_SPEOP_COMP(efststgt); | |
| 6573 | -GEN_SPEOP_COMP(efststlt); | |
| 6574 | -GEN_SPEOP_COMP(efststeq); | |
| 6983 | +GEN_SPEFPUOP_COMP(efscmpgt); | |
| 6984 | +GEN_SPEFPUOP_COMP(efscmplt); | |
| 6985 | +GEN_SPEFPUOP_COMP(efscmpeq); | |
| 6986 | +GEN_SPEFPUOP_COMP(efststgt); | |
| 6987 | +GEN_SPEFPUOP_COMP(efststlt); | |
| 6988 | +GEN_SPEFPUOP_COMP(efststeq); | |
| 6575 | 6989 | |
| 6576 | 6990 | /* Opcodes definitions */ |
| 6577 | 6991 | GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPEFPU); // |
| ... | ... | @@ -6591,13 +7005,13 @@ GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPEFPU); // |
| 6591 | 7005 | |
| 6592 | 7006 | /* Double precision floating-point operations */ |
| 6593 | 7007 | /* Arithmetic */ |
| 6594 | -GEN_SPEOP_ARITH2(efdadd); | |
| 6595 | -GEN_SPEOP_ARITH2(efdsub); | |
| 6596 | -GEN_SPEOP_ARITH2(efdmul); | |
| 6597 | -GEN_SPEOP_ARITH2(efddiv); | |
| 6598 | -GEN_SPEOP_ARITH1(efdabs); | |
| 6599 | -GEN_SPEOP_ARITH1(efdnabs); | |
| 6600 | -GEN_SPEOP_ARITH1(efdneg); | |
| 7008 | +GEN_SPEFPUOP_ARITH2(efdadd); | |
| 7009 | +GEN_SPEFPUOP_ARITH2(efdsub); | |
| 7010 | +GEN_SPEFPUOP_ARITH2(efdmul); | |
| 7011 | +GEN_SPEFPUOP_ARITH2(efddiv); | |
| 7012 | +GEN_SPEFPUOP_ARITH1(efdabs); | |
| 7013 | +GEN_SPEFPUOP_ARITH1(efdnabs); | |
| 7014 | +GEN_SPEFPUOP_ARITH1(efdneg); | |
| 6601 | 7015 | /* Conversion */ |
| 6602 | 7016 | |
| 6603 | 7017 | GEN_SPEFPUOP_CONV(efdcfui); |
| ... | ... | @@ -6616,12 +7030,12 @@ GEN_SPEFPUOP_CONV(efdcfsid); |
| 6616 | 7030 | GEN_SPEFPUOP_CONV(efdctuidz); |
| 6617 | 7031 | GEN_SPEFPUOP_CONV(efdctsidz); |
| 6618 | 7032 | /* Comparison */ |
| 6619 | -GEN_SPEOP_COMP(efdcmpgt); | |
| 6620 | -GEN_SPEOP_COMP(efdcmplt); | |
| 6621 | -GEN_SPEOP_COMP(efdcmpeq); | |
| 6622 | -GEN_SPEOP_COMP(efdtstgt); | |
| 6623 | -GEN_SPEOP_COMP(efdtstlt); | |
| 6624 | -GEN_SPEOP_COMP(efdtsteq); | |
| 7033 | +GEN_SPEFPUOP_COMP(efdcmpgt); | |
| 7034 | +GEN_SPEFPUOP_COMP(efdcmplt); | |
| 7035 | +GEN_SPEFPUOP_COMP(efdcmpeq); | |
| 7036 | +GEN_SPEFPUOP_COMP(efdtstgt); | |
| 7037 | +GEN_SPEFPUOP_COMP(efdtstlt); | |
| 7038 | +GEN_SPEFPUOP_COMP(efdtsteq); | |
| 6625 | 7039 | |
| 6626 | 7040 | /* Opcodes definitions */ |
| 6627 | 7041 | GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPEFPU); // | ... | ... |