aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_ppc.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm_ppc.h')
-rw-r--r--src/lj_asm_ppc.h232
1 files changed, 72 insertions, 160 deletions
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h
index 9c9c3ea4..d9174e7d 100644
--- a/src/lj_asm_ppc.h
+++ b/src/lj_asm_ppc.h
@@ -840,7 +840,7 @@ static void asm_xload(ASMState *as, IRIns *ir)
840 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0); 840 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
841} 841}
842 842
843static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs) 843static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
844{ 844{
845 IRIns *irb; 845 IRIns *irb;
846 if (ir->r == RID_SINK) 846 if (ir->r == RID_SINK)
@@ -857,6 +857,8 @@ static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs)
857 } 857 }
858} 858}
859 859
860#define asm_xstore(as, ir) asm_xstore_(as, ir, 0)
861
860static void asm_ahuvload(ASMState *as, IRIns *ir) 862static void asm_ahuvload(ASMState *as, IRIns *ir)
861{ 863{
862 IRType1 t = ir->t; 864 IRType1 t = ir->t;
@@ -1120,6 +1122,16 @@ static void asm_fpunary(ASMState *as, IRIns *ir, PPCIns pi)
1120 emit_fb(as, pi, dest, left); 1122 emit_fb(as, pi, dest, left);
1121} 1123}
1122 1124
1125static void asm_fpmath(ASMState *as, IRIns *ir)
1126{
1127 if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
1128 return;
1129 if (ir->op2 == IRFPM_SQRT && (as->flags & JIT_F_SQRT))
1130 asm_fpunary(as, ir, PPCI_FSQRT);
1131 else
1132 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
1133}
1134
1123static void asm_add(ASMState *as, IRIns *ir) 1135static void asm_add(ASMState *as, IRIns *ir)
1124{ 1136{
1125 if (irt_isnum(ir->t)) { 1137 if (irt_isnum(ir->t)) {
@@ -1217,6 +1229,10 @@ static void asm_mul(ASMState *as, IRIns *ir)
1217 } 1229 }
1218} 1230}
1219 1231
1232#define asm_div(as, ir) asm_fparith(as, ir, PPCI_FDIV)
1233#define asm_mod(as, ir) asm_callid(as, ir, IRCALL_lj_vm_modi)
1234#define asm_pow(as, ir) asm_callid(as, ir, IRCALL_lj_vm_powi)
1235
1220static void asm_neg(ASMState *as, IRIns *ir) 1236static void asm_neg(ASMState *as, IRIns *ir)
1221{ 1237{
1222 if (irt_isnum(ir->t)) { 1238 if (irt_isnum(ir->t)) {
@@ -1235,6 +1251,10 @@ static void asm_neg(ASMState *as, IRIns *ir)
1235 } 1251 }
1236} 1252}
1237 1253
1254#define asm_abs(as, ir) asm_fpunary(as, ir, PPCI_FABS)
1255#define asm_atan2(as, ir) asm_callid(as, ir, IRCALL_atan2)
1256#define asm_ldexp(as, ir) asm_callid(as, ir, IRCALL_ldexp)
1257
1238static void asm_arithov(ASMState *as, IRIns *ir, PPCIns pi) 1258static void asm_arithov(ASMState *as, IRIns *ir, PPCIns pi)
1239{ 1259{
1240 Reg dest, left, right; 1260 Reg dest, left, right;
@@ -1250,6 +1270,10 @@ static void asm_arithov(ASMState *as, IRIns *ir, PPCIns pi)
1250 emit_tab(as, pi|PPCF_DOT, dest, left, right); 1270 emit_tab(as, pi|PPCF_DOT, dest, left, right);
1251} 1271}
1252 1272
1273#define asm_addov(as, ir) asm_arithov(as, ir, PPCI_ADDO)
1274#define asm_subov(as, ir) asm_arithov(as, ir, PPCI_SUBFO)
1275#define asm_mulov(as, ir) asm_arithov(as, ir, PPCI_MULLWO)
1276
1253#if LJ_HASFFI 1277#if LJ_HASFFI
1254static void asm_add64(ASMState *as, IRIns *ir) 1278static void asm_add64(ASMState *as, IRIns *ir)
1255{ 1279{
@@ -1329,7 +1353,7 @@ static void asm_neg64(ASMState *as, IRIns *ir)
1329} 1353}
1330#endif 1354#endif
1331 1355
1332static void asm_bitnot(ASMState *as, IRIns *ir) 1356static void asm_bnot(ASMState *as, IRIns *ir)
1333{ 1357{
1334 Reg dest, left, right; 1358 Reg dest, left, right;
1335 PPCIns pi = PPCI_NOR; 1359 PPCIns pi = PPCI_NOR;
@@ -1356,7 +1380,7 @@ nofuse:
1356 emit_asb(as, pi, dest, left, right); 1380 emit_asb(as, pi, dest, left, right);
1357} 1381}
1358 1382
1359static void asm_bitswap(ASMState *as, IRIns *ir) 1383static void asm_bswap(ASMState *as, IRIns *ir)
1360{ 1384{
1361 Reg dest = ra_dest(as, ir, RSET_GPR); 1385 Reg dest = ra_dest(as, ir, RSET_GPR);
1362 IRIns *irx; 1386 IRIns *irx;
@@ -1377,32 +1401,6 @@ static void asm_bitswap(ASMState *as, IRIns *ir)
1377 } 1401 }
1378} 1402}
1379 1403
1380static void asm_bitop(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1381{
1382 Reg dest = ra_dest(as, ir, RSET_GPR);
1383 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1384 if (irref_isk(ir->op2)) {
1385 int32_t k = IR(ir->op2)->i;
1386 Reg tmp = left;
1387 if ((checku16(k) || (k & 0xffff) == 0) || (tmp = dest, !as->sectref)) {
1388 if (!checku16(k)) {
1389 emit_asi(as, pik ^ (PPCI_ORI ^ PPCI_ORIS), dest, tmp, (k >> 16));
1390 if ((k & 0xffff) == 0) return;
1391 }
1392 emit_asi(as, pik, dest, left, k);
1393 return;
1394 }
1395 }
1396 /* May fail due to spills/restores above, but simplifies the logic. */
1397 if (as->flagmcp == as->mcp) {
1398 as->flagmcp = NULL;
1399 as->mcp++;
1400 pi |= PPCF_DOT;
1401 }
1402 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1403 emit_asb(as, pi, dest, left, right);
1404}
1405
1406/* Fuse BAND with contiguous bitmask and a shift to rlwinm. */ 1404/* Fuse BAND with contiguous bitmask and a shift to rlwinm. */
1407static void asm_fuseandsh(ASMState *as, PPCIns pi, int32_t mask, IRRef ref) 1405static void asm_fuseandsh(ASMState *as, PPCIns pi, int32_t mask, IRRef ref)
1408{ 1406{
@@ -1433,7 +1431,7 @@ nofuse:
1433 *--as->mcp = pi | PPCF_T(left); 1431 *--as->mcp = pi | PPCF_T(left);
1434} 1432}
1435 1433
1436static void asm_bitand(ASMState *as, IRIns *ir) 1434static void asm_band(ASMState *as, IRIns *ir)
1437{ 1435{
1438 Reg dest, left, right; 1436 Reg dest, left, right;
1439 IRRef lref = ir->op1; 1437 IRRef lref = ir->op1;
@@ -1488,6 +1486,35 @@ static void asm_bitand(ASMState *as, IRIns *ir)
1488 emit_asb(as, PPCI_AND ^ dot, dest, left, right); 1486 emit_asb(as, PPCI_AND ^ dot, dest, left, right);
1489} 1487}
1490 1488
1489static void asm_bitop(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1490{
1491 Reg dest = ra_dest(as, ir, RSET_GPR);
1492 Reg right, left = ra_hintalloc(as, ir->op1, dest, RSET_GPR);
1493 if (irref_isk(ir->op2)) {
1494 int32_t k = IR(ir->op2)->i;
1495 Reg tmp = left;
1496 if ((checku16(k) || (k & 0xffff) == 0) || (tmp = dest, !as->sectref)) {
1497 if (!checku16(k)) {
1498 emit_asi(as, pik ^ (PPCI_ORI ^ PPCI_ORIS), dest, tmp, (k >> 16));
1499 if ((k & 0xffff) == 0) return;
1500 }
1501 emit_asi(as, pik, dest, left, k);
1502 return;
1503 }
1504 }
1505 /* May fail due to spills/restores above, but simplifies the logic. */
1506 if (as->flagmcp == as->mcp) {
1507 as->flagmcp = NULL;
1508 as->mcp++;
1509 pi |= PPCF_DOT;
1510 }
1511 right = ra_alloc1(as, ir->op2, rset_exclude(RSET_GPR, left));
1512 emit_asb(as, pi, dest, left, right);
1513}
1514
1515#define asm_bor(as, ir) asm_bitop(as, ir, PPCI_OR, PPCI_ORI)
1516#define asm_bxor(as, ir) asm_bitop(as, ir, PPCI_XOR, PPCI_XORI)
1517
1491static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik) 1518static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1492{ 1519{
1493 Reg dest, left; 1520 Reg dest, left;
@@ -1513,6 +1540,14 @@ static void asm_bitshift(ASMState *as, IRIns *ir, PPCIns pi, PPCIns pik)
1513 } 1540 }
1514} 1541}
1515 1542
1543#define asm_bshl(as, ir) asm_bitshift(as, ir, PPCI_SLW, 0)
1544#define asm_bshr(as, ir) asm_bitshift(as, ir, PPCI_SRW, 1)
1545#define asm_bsar(as, ir) asm_bitshift(as, ir, PPCI_SRAW, PPCI_SRAWI)
1546#define asm_brol(as, ir) \
1547 asm_bitshift(as, ir, PPCI_RLWNM|PPCF_MB(0)|PPCF_ME(31), \
1548 PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31))
1549#define asm_bror(as, ir) lua_assert(0)
1550
1516static void asm_min_max(ASMState *as, IRIns *ir, int ismax) 1551static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
1517{ 1552{
1518 if (irt_isnum(ir->t)) { 1553 if (irt_isnum(ir->t)) {
@@ -1543,6 +1578,9 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
1543 } 1578 }
1544} 1579}
1545 1580
1581#define asm_min(as, ir) asm_min_max(as, ir, 0)
1582#define asm_max(as, ir) asm_min_max(as, ir, 1)
1583
1546/* -- Comparisons --------------------------------------------------------- */ 1584/* -- Comparisons --------------------------------------------------------- */
1547 1585
1548#define CC_UNSIGNED 0x08 /* Unsigned integer comparison. */ 1586#define CC_UNSIGNED 0x08 /* Unsigned integer comparison. */
@@ -1619,6 +1657,8 @@ static void asm_comp(ASMState *as, IRIns *ir)
1619 } 1657 }
1620} 1658}
1621 1659
1660#define asm_equal(as, ir) asm_comp(as, ir)
1661
1622#if LJ_HASFFI 1662#if LJ_HASFFI
1623/* 64 bit integer comparisons. */ 1663/* 64 bit integer comparisons. */
1624static void asm_comp64(ASMState *as, IRIns *ir) 1664static void asm_comp64(ASMState *as, IRIns *ir)
@@ -1664,8 +1704,8 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1664 } else if ((ir-1)->o == IR_XSTORE) { 1704 } else if ((ir-1)->o == IR_XSTORE) {
1665 as->curins--; /* Handle both stores here. */ 1705 as->curins--; /* Handle both stores here. */
1666 if ((ir-1)->r != RID_SINK) { 1706 if ((ir-1)->r != RID_SINK) {
1667 asm_xstore(as, ir, 0); 1707 asm_xstore_(as, ir, 0);
1668 asm_xstore(as, ir-1, 4); 1708 asm_xstore_(as, ir-1, 4);
1669 } 1709 }
1670 return; 1710 return;
1671 } 1711 }
@@ -1871,134 +1911,6 @@ static void asm_tail_prep(ASMState *as)
1871 } 1911 }
1872} 1912}
1873 1913
1874/* -- Instruction dispatch ------------------------------------------------ */
1875
1876/* Assemble a single instruction. */
1877static void asm_ir(ASMState *as, IRIns *ir)
1878{
1879 switch ((IROp)ir->o) {
1880 /* Miscellaneous ops. */
1881 case IR_LOOP: asm_loop(as); break;
1882 case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
1883 case IR_USE:
1884 ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
1885 case IR_PHI: asm_phi(as, ir); break;
1886 case IR_HIOP: asm_hiop(as, ir); break;
1887 case IR_GCSTEP: asm_gcstep(as, ir); break;
1888
1889 /* Guarded assertions. */
1890 case IR_EQ: case IR_NE:
1891 if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
1892 as->curins--;
1893 asm_href(as, ir-1, (IROp)ir->o);
1894 break;
1895 }
1896 /* fallthrough */
1897 case IR_LT: case IR_GE: case IR_LE: case IR_GT:
1898 case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
1899 case IR_ABC:
1900 asm_comp(as, ir);
1901 break;
1902
1903 case IR_RETF: asm_retf(as, ir); break;
1904
1905 /* Bit ops. */
1906 case IR_BNOT: asm_bitnot(as, ir); break;
1907 case IR_BSWAP: asm_bitswap(as, ir); break;
1908
1909 case IR_BAND: asm_bitand(as, ir); break;
1910 case IR_BOR: asm_bitop(as, ir, PPCI_OR, PPCI_ORI); break;
1911 case IR_BXOR: asm_bitop(as, ir, PPCI_XOR, PPCI_XORI); break;
1912
1913 case IR_BSHL: asm_bitshift(as, ir, PPCI_SLW, 0); break;
1914 case IR_BSHR: asm_bitshift(as, ir, PPCI_SRW, 1); break;
1915 case IR_BSAR: asm_bitshift(as, ir, PPCI_SRAW, PPCI_SRAWI); break;
1916 case IR_BROL: asm_bitshift(as, ir, PPCI_RLWNM|PPCF_MB(0)|PPCF_ME(31),
1917 PPCI_RLWINM|PPCF_MB(0)|PPCF_ME(31)); break;
1918 case IR_BROR: lua_assert(0); break;
1919
1920 /* Arithmetic ops. */
1921 case IR_ADD: asm_add(as, ir); break;
1922 case IR_SUB: asm_sub(as, ir); break;
1923 case IR_MUL: asm_mul(as, ir); break;
1924 case IR_DIV: asm_fparith(as, ir, PPCI_FDIV); break;
1925 case IR_MOD: asm_callid(as, ir, IRCALL_lj_vm_modi); break;
1926 case IR_POW: asm_callid(as, ir, IRCALL_lj_vm_powi); break;
1927 case IR_NEG: asm_neg(as, ir); break;
1928
1929 case IR_ABS: asm_fpunary(as, ir, PPCI_FABS); break;
1930 case IR_ATAN2: asm_callid(as, ir, IRCALL_atan2); break;
1931 case IR_LDEXP: asm_callid(as, ir, IRCALL_ldexp); break;
1932 case IR_MIN: asm_min_max(as, ir, 0); break;
1933 case IR_MAX: asm_min_max(as, ir, 1); break;
1934 case IR_FPMATH:
1935 if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
1936 break;
1937 if (ir->op2 == IRFPM_SQRT && (as->flags & JIT_F_SQRT))
1938 asm_fpunary(as, ir, PPCI_FSQRT);
1939 else
1940 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
1941 break;
1942
1943 /* Overflow-checking arithmetic ops. */
1944 case IR_ADDOV: asm_arithov(as, ir, PPCI_ADDO); break;
1945 case IR_SUBOV: asm_arithov(as, ir, PPCI_SUBFO); break;
1946 case IR_MULOV: asm_arithov(as, ir, PPCI_MULLWO); break;
1947
1948 /* Memory references. */
1949 case IR_AREF: asm_aref(as, ir); break;
1950 case IR_HREF: asm_href(as, ir, 0); break;
1951 case IR_HREFK: asm_hrefk(as, ir); break;
1952 case IR_NEWREF: asm_newref(as, ir); break;
1953 case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
1954 case IR_FREF: asm_fref(as, ir); break;
1955 case IR_STRREF: asm_strref(as, ir); break;
1956
1957 /* Loads and stores. */
1958 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1959 asm_ahuvload(as, ir);
1960 break;
1961 case IR_FLOAD: asm_fload(as, ir); break;
1962 case IR_XLOAD: asm_xload(as, ir); break;
1963 case IR_SLOAD: asm_sload(as, ir); break;
1964
1965 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
1966 case IR_FSTORE: asm_fstore(as, ir); break;
1967 case IR_XSTORE: asm_xstore(as, ir, 0); break;
1968
1969 /* Allocations. */
1970 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
1971 case IR_TNEW: asm_tnew(as, ir); break;
1972 case IR_TDUP: asm_tdup(as, ir); break;
1973 case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
1974
1975 /* Buffer operations. */
1976 case IR_BUFHDR: asm_bufhdr(as, ir); break;
1977 case IR_BUFPUT: asm_bufput(as, ir); break;
1978 case IR_BUFSTR: asm_bufstr(as, ir); break;
1979
1980 /* Write barriers. */
1981 case IR_TBAR: asm_tbar(as, ir); break;
1982 case IR_OBAR: asm_obar(as, ir); break;
1983
1984 /* Type conversions. */
1985 case IR_CONV: asm_conv(as, ir); break;
1986 case IR_TOBIT: asm_tobit(as, ir); break;
1987 case IR_TOSTR: asm_tostr(as, ir); break;
1988 case IR_STRTO: asm_strto(as, ir); break;
1989
1990 /* Calls. */
1991 case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
1992 case IR_CALLXS: asm_callx(as, ir); break;
1993 case IR_CARG: break;
1994
1995 default:
1996 setintV(&as->J->errinfo, ir->o);
1997 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
1998 break;
1999 }
2000}
2001
2002/* -- Trace setup --------------------------------------------------------- */ 1914/* -- Trace setup --------------------------------------------------------- */
2003 1915
2004/* Ensure there are enough stack slots for call arguments. */ 1916/* Ensure there are enough stack slots for call arguments. */