aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm_mips.h
diff options
context:
space:
mode:
authorMike Pall <mike>2013-04-22 22:32:41 +0200
committerMike Pall <mike>2013-04-22 22:32:41 +0200
commita2c78810ca0162c06b3ae02b52d6b4c04a8d5be3 (patch)
treed82fe00c6ca8ff6a2bfce89176e0d97b3095be38 /src/lj_asm_mips.h
parent2ab5e7c5dce9e8bd19b7f4c9d7a90ef30af53d0a (diff)
downloadluajit-a2c78810ca0162c06b3ae02b52d6b4c04a8d5be3.tar.gz
luajit-a2c78810ca0162c06b3ae02b52d6b4c04a8d5be3.tar.bz2
luajit-a2c78810ca0162c06b3ae02b52d6b4c04a8d5be3.zip
Combine IR instruction dispatch for all assembler backends.
Diffstat (limited to 'src/lj_asm_mips.h')
-rw-r--r--src/lj_asm_mips.h181
1 files changed, 44 insertions, 137 deletions
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h
index cbbd2966..122e5ecd 100644
--- a/src/lj_asm_mips.h
+++ b/src/lj_asm_mips.h
@@ -849,7 +849,7 @@ static void asm_xload(ASMState *as, IRIns *ir)
849 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0); 849 asm_fusexref(as, asm_fxloadins(ir), dest, ir->op1, RSET_GPR, 0);
850} 850}
851 851
852static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs) 852static void asm_xstore_(ASMState *as, IRIns *ir, int32_t ofs)
853{ 853{
854 if (ir->r != RID_SINK) { 854 if (ir->r != RID_SINK) {
855 Reg src = ra_alloc1z(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); 855 Reg src = ra_alloc1z(as, ir->op2, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR);
@@ -858,6 +858,8 @@ static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs)
858 } 858 }
859} 859}
860 860
861#define asm_xstore(as, ir) asm_xstore_(as, ir, 0)
862
861static void asm_ahuvload(ASMState *as, IRIns *ir) 863static void asm_ahuvload(ASMState *as, IRIns *ir)
862{ 864{
863 IRType1 t = ir->t; 865 IRType1 t = ir->t;
@@ -1083,6 +1085,18 @@ static void asm_fpunary(ASMState *as, IRIns *ir, MIPSIns mi)
1083 emit_fg(as, mi, dest, left); 1085 emit_fg(as, mi, dest, left);
1084} 1086}
1085 1087
1088static void asm_fpmath(ASMState *as, IRIns *ir)
1089{
1090 if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
1091 return;
1092 if (ir->op2 <= IRFPM_TRUNC)
1093 asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2);
1094 else if (ir->op2 == IRFPM_SQRT)
1095 asm_fpunary(as, ir, MIPSI_SQRT_D);
1096 else
1097 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
1098}
1099
1086static void asm_add(ASMState *as, IRIns *ir) 1100static void asm_add(ASMState *as, IRIns *ir)
1087{ 1101{
1088 if (irt_isnum(ir->t)) { 1102 if (irt_isnum(ir->t)) {
@@ -1126,6 +1140,10 @@ static void asm_mul(ASMState *as, IRIns *ir)
1126 } 1140 }
1127} 1141}
1128 1142
1143#define asm_div(as, ir) asm_fparith(as, ir, MIPSI_DIV_D)
1144#define asm_mod(as, ir) asm_callid(as, ir, IRCALL_lj_vm_modi)
1145#define asm_pow(as, ir) asm_callid(as, ir, IRCALL_lj_vm_powi)
1146
1129static void asm_neg(ASMState *as, IRIns *ir) 1147static void asm_neg(ASMState *as, IRIns *ir)
1130{ 1148{
1131 if (irt_isnum(ir->t)) { 1149 if (irt_isnum(ir->t)) {
@@ -1137,6 +1155,10 @@ static void asm_neg(ASMState *as, IRIns *ir)
1137 } 1155 }
1138} 1156}
1139 1157
1158#define asm_abs(as, ir) asm_fpunary(as, ir, MIPSI_ABS_D)
1159#define asm_atan2(as, ir) asm_callid(as, ir, IRCALL_atan2)
1160#define asm_ldexp(as, ir) asm_callid(as, ir, IRCALL_ldexp)
1161
1140static void asm_arithov(ASMState *as, IRIns *ir) 1162static void asm_arithov(ASMState *as, IRIns *ir)
1141{ 1163{
1142 Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR); 1164 Reg right, left, tmp, dest = ra_dest(as, ir, RSET_GPR);
@@ -1170,6 +1192,9 @@ static void asm_arithov(ASMState *as, IRIns *ir)
1170 emit_move(as, RID_TMP, dest == left ? left : right); 1192 emit_move(as, RID_TMP, dest == left ? left : right);
1171} 1193}
1172 1194
1195#define asm_addov(as, ir) asm_arithov(as, ir)
1196#define asm_subov(as, ir) asm_arithov(as, ir)
1197
1173static void asm_mulov(ASMState *as, IRIns *ir) 1198static void asm_mulov(ASMState *as, IRIns *ir)
1174{ 1199{
1175#if LJ_DUALNUM 1200#if LJ_DUALNUM
@@ -1263,7 +1288,7 @@ static void asm_neg64(ASMState *as, IRIns *ir)
1263} 1288}
1264#endif 1289#endif
1265 1290
1266static void asm_bitnot(ASMState *as, IRIns *ir) 1291static void asm_bnot(ASMState *as, IRIns *ir)
1267{ 1292{
1268 Reg left, right, dest = ra_dest(as, ir, RSET_GPR); 1293 Reg left, right, dest = ra_dest(as, ir, RSET_GPR);
1269 IRIns *irl = IR(ir->op1); 1294 IRIns *irl = IR(ir->op1);
@@ -1277,7 +1302,7 @@ static void asm_bitnot(ASMState *as, IRIns *ir)
1277 emit_dst(as, MIPSI_NOR, dest, left, right); 1302 emit_dst(as, MIPSI_NOR, dest, left, right);
1278} 1303}
1279 1304
1280static void asm_bitswap(ASMState *as, IRIns *ir) 1305static void asm_bswap(ASMState *as, IRIns *ir)
1281{ 1306{
1282 Reg dest = ra_dest(as, ir, RSET_GPR); 1307 Reg dest = ra_dest(as, ir, RSET_GPR);
1283 Reg left = ra_alloc1(as, ir->op1, RSET_GPR); 1308 Reg left = ra_alloc1(as, ir->op1, RSET_GPR);
@@ -1313,6 +1338,10 @@ static void asm_bitop(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
1313 emit_dst(as, mi, dest, left, right); 1338 emit_dst(as, mi, dest, left, right);
1314} 1339}
1315 1340
1341#define asm_band(as, ir) asm_bitop(as, ir, MIPSI_AND, MIPSI_ANDI)
1342#define asm_bor(as, ir) asm_bitop(as, ir, MIPSI_OR, MIPSI_ORI)
1343#define asm_bxor(as, ir) asm_bitop(as, ir, MIPSI_XOR, MIPSI_XORI)
1344
1316static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik) 1345static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
1317{ 1346{
1318 Reg dest = ra_dest(as, ir, RSET_GPR); 1347 Reg dest = ra_dest(as, ir, RSET_GPR);
@@ -1326,7 +1355,12 @@ static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik)
1326 } 1355 }
1327} 1356}
1328 1357
1329static void asm_bitror(ASMState *as, IRIns *ir) 1358#define asm_bshl(as, ir) asm_bitshift(as, ir, MIPSI_SLLV, MIPSI_SLL)
1359#define asm_bshr(as, ir) asm_bitshift(as, ir, MIPSI_SRLV, MIPSI_SRL)
1360#define asm_bsar(as, ir) asm_bitshift(as, ir, MIPSI_SRAV, MIPSI_SRA)
1361#define asm_brol(as, ir) lua_assert(0)
1362
1363static void asm_bror(ASMState *as, IRIns *ir)
1330{ 1364{
1331 if ((as->flags & JIT_F_MIPS32R2)) { 1365 if ((as->flags & JIT_F_MIPS32R2)) {
1332 asm_bitshift(as, ir, MIPSI_ROTRV, MIPSI_ROTR); 1366 asm_bitshift(as, ir, MIPSI_ROTRV, MIPSI_ROTR);
@@ -1375,6 +1409,9 @@ static void asm_min_max(ASMState *as, IRIns *ir, int ismax)
1375 } 1409 }
1376} 1410}
1377 1411
1412#define asm_min(as, ir) asm_min_max(as, ir, 0)
1413#define asm_max(as, ir) asm_min_max(as, ir, 1)
1414
1378/* -- Comparisons --------------------------------------------------------- */ 1415/* -- Comparisons --------------------------------------------------------- */
1379 1416
1380static void asm_comp(ASMState *as, IRIns *ir) 1417static void asm_comp(ASMState *as, IRIns *ir)
@@ -1412,7 +1449,7 @@ static void asm_comp(ASMState *as, IRIns *ir)
1412 } 1449 }
1413} 1450}
1414 1451
1415static void asm_compeq(ASMState *as, IRIns *ir) 1452static void asm_equal(ASMState *as, IRIns *ir)
1416{ 1453{
1417 Reg right, left = ra_alloc2(as, ir, irt_isnum(ir->t) ? RSET_FPR : RSET_GPR); 1454 Reg right, left = ra_alloc2(as, ir, irt_isnum(ir->t) ? RSET_FPR : RSET_GPR);
1418 right = (left >> 8); left &= 255; 1455 right = (left >> 8); left &= 255;
@@ -1486,8 +1523,8 @@ static void asm_hiop(ASMState *as, IRIns *ir)
1486 } else if ((ir-1)->o == IR_XSTORE) { 1523 } else if ((ir-1)->o == IR_XSTORE) {
1487 as->curins--; /* Handle both stores here. */ 1524 as->curins--; /* Handle both stores here. */
1488 if ((ir-1)->r != RID_SINK) { 1525 if ((ir-1)->r != RID_SINK) {
1489 asm_xstore(as, ir, LJ_LE ? 4 : 0); 1526 asm_xstore_(as, ir, LJ_LE ? 4 : 0);
1490 asm_xstore(as, ir-1, LJ_LE ? 0 : 4); 1527 asm_xstore_(as, ir-1, LJ_LE ? 0 : 4);
1491 } 1528 }
1492 return; 1529 return;
1493 } 1530 }
@@ -1683,136 +1720,6 @@ static void asm_tail_prep(ASMState *as)
1683 as->invmcp = as->loopref ? as->mcp : NULL; 1720 as->invmcp = as->loopref ? as->mcp : NULL;
1684} 1721}
1685 1722
1686/* -- Instruction dispatch ------------------------------------------------ */
1687
1688/* Assemble a single instruction. */
1689static void asm_ir(ASMState *as, IRIns *ir)
1690{
1691 switch ((IROp)ir->o) {
1692 /* Miscellaneous ops. */
1693 case IR_LOOP: asm_loop(as); break;
1694 case IR_NOP: case IR_XBAR: lua_assert(!ra_used(ir)); break;
1695 case IR_USE:
1696 ra_alloc1(as, ir->op1, irt_isfp(ir->t) ? RSET_FPR : RSET_GPR); break;
1697 case IR_PHI: asm_phi(as, ir); break;
1698 case IR_HIOP: asm_hiop(as, ir); break;
1699 case IR_GCSTEP: asm_gcstep(as, ir); break;
1700
1701 /* Guarded assertions. */
1702 case IR_EQ: case IR_NE:
1703 if ((ir-1)->o == IR_HREF && ir->op1 == as->curins-1) {
1704 as->curins--;
1705 asm_href(as, ir-1, (IROp)ir->o);
1706 break;
1707 }
1708 asm_compeq(as, ir);
1709 break;
1710 case IR_LT: case IR_GE: case IR_LE: case IR_GT:
1711 case IR_ULT: case IR_UGE: case IR_ULE: case IR_UGT:
1712 case IR_ABC:
1713 asm_comp(as, ir);
1714 break;
1715
1716 case IR_RETF: asm_retf(as, ir); break;
1717
1718 /* Bit ops. */
1719 case IR_BNOT: asm_bitnot(as, ir); break;
1720 case IR_BSWAP: asm_bitswap(as, ir); break;
1721
1722 case IR_BAND: asm_bitop(as, ir, MIPSI_AND, MIPSI_ANDI); break;
1723 case IR_BOR: asm_bitop(as, ir, MIPSI_OR, MIPSI_ORI); break;
1724 case IR_BXOR: asm_bitop(as, ir, MIPSI_XOR, MIPSI_XORI); break;
1725
1726 case IR_BSHL: asm_bitshift(as, ir, MIPSI_SLLV, MIPSI_SLL); break;
1727 case IR_BSHR: asm_bitshift(as, ir, MIPSI_SRLV, MIPSI_SRL); break;
1728 case IR_BSAR: asm_bitshift(as, ir, MIPSI_SRAV, MIPSI_SRA); break;
1729 case IR_BROL: lua_assert(0); break;
1730 case IR_BROR: asm_bitror(as, ir); break;
1731
1732 /* Arithmetic ops. */
1733 case IR_ADD: asm_add(as, ir); break;
1734 case IR_SUB: asm_sub(as, ir); break;
1735 case IR_MUL: asm_mul(as, ir); break;
1736 case IR_DIV: asm_fparith(as, ir, MIPSI_DIV_D); break;
1737 case IR_MOD: asm_callid(as, ir, IRCALL_lj_vm_modi); break;
1738 case IR_POW: asm_callid(as, ir, IRCALL_lj_vm_powi); break;
1739 case IR_NEG: asm_neg(as, ir); break;
1740
1741 case IR_ABS: asm_fpunary(as, ir, MIPSI_ABS_D); break;
1742 case IR_ATAN2: asm_callid(as, ir, IRCALL_atan2); break;
1743 case IR_LDEXP: asm_callid(as, ir, IRCALL_ldexp); break;
1744 case IR_MIN: asm_min_max(as, ir, 0); break;
1745 case IR_MAX: asm_min_max(as, ir, 1); break;
1746 case IR_FPMATH:
1747 if (ir->op2 == IRFPM_EXP2 && asm_fpjoin_pow(as, ir))
1748 break;
1749 if (ir->op2 <= IRFPM_TRUNC)
1750 asm_callround(as, ir, IRCALL_lj_vm_floor + ir->op2);
1751 else if (ir->op2 == IRFPM_SQRT)
1752 asm_fpunary(as, ir, MIPSI_SQRT_D);
1753 else
1754 asm_callid(as, ir, IRCALL_lj_vm_floor + ir->op2);
1755 break;
1756
1757 /* Overflow-checking arithmetic ops. */
1758 case IR_ADDOV: asm_arithov(as, ir); break;
1759 case IR_SUBOV: asm_arithov(as, ir); break;
1760 case IR_MULOV: asm_mulov(as, ir); break;
1761
1762 /* Memory references. */
1763 case IR_AREF: asm_aref(as, ir); break;
1764 case IR_HREF: asm_href(as, ir, 0); break;
1765 case IR_HREFK: asm_hrefk(as, ir); break;
1766 case IR_NEWREF: asm_newref(as, ir); break;
1767 case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break;
1768 case IR_FREF: asm_fref(as, ir); break;
1769 case IR_STRREF: asm_strref(as, ir); break;
1770
1771 /* Loads and stores. */
1772 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
1773 asm_ahuvload(as, ir);
1774 break;
1775 case IR_FLOAD: asm_fload(as, ir); break;
1776 case IR_XLOAD: asm_xload(as, ir); break;
1777 case IR_SLOAD: asm_sload(as, ir); break;
1778
1779 case IR_ASTORE: case IR_HSTORE: case IR_USTORE: asm_ahustore(as, ir); break;
1780 case IR_FSTORE: asm_fstore(as, ir); break;
1781 case IR_XSTORE: asm_xstore(as, ir, 0); break;
1782
1783 /* Allocations. */
1784 case IR_SNEW: case IR_XSNEW: asm_snew(as, ir); break;
1785 case IR_TNEW: asm_tnew(as, ir); break;
1786 case IR_TDUP: asm_tdup(as, ir); break;
1787 case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break;
1788
1789 /* Buffer operations. */
1790 case IR_BUFHDR: asm_bufhdr(as, ir); break;
1791 case IR_BUFPUT: asm_bufput(as, ir); break;
1792 case IR_BUFSTR: asm_bufstr(as, ir); break;
1793
1794 /* Write barriers. */
1795 case IR_TBAR: asm_tbar(as, ir); break;
1796 case IR_OBAR: asm_obar(as, ir); break;
1797
1798 /* Type conversions. */
1799 case IR_CONV: asm_conv(as, ir); break;
1800 case IR_TOBIT: asm_tobit(as, ir); break;
1801 case IR_TOSTR: asm_tostr(as, ir); break;
1802 case IR_STRTO: asm_strto(as, ir); break;
1803
1804 /* Calls. */
1805 case IR_CALLN: case IR_CALLL: case IR_CALLS: asm_call(as, ir); break;
1806 case IR_CALLXS: asm_callx(as, ir); break;
1807 case IR_CARG: break;
1808
1809 default:
1810 setintV(&as->J->errinfo, ir->o);
1811 lj_trace_err_info(as->J, LJ_TRERR_NYIIR);
1812 break;
1813 }
1814}
1815
1816/* -- Trace setup --------------------------------------------------------- */ 1723/* -- Trace setup --------------------------------------------------------- */
1817 1724
1818/* Ensure there are enough stack slots for call arguments. */ 1725/* Ensure there are enough stack slots for call arguments. */