diff options
author | Mike Pall <mike> | 2013-04-22 22:32:41 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2013-04-22 22:32:41 +0200 |
commit | a2c78810ca0162c06b3ae02b52d6b4c04a8d5be3 (patch) | |
tree | d82fe00c6ca8ff6a2bfce89176e0d97b3095be38 /src/lj_asm_mips.h | |
parent | 2ab5e7c5dce9e8bd19b7f4c9d7a90ef30af53d0a (diff) | |
download | luajit-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.h | 181 |
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 | ||
852 | static void asm_xstore(ASMState *as, IRIns *ir, int32_t ofs) | 852 | static 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 | |||
861 | static void asm_ahuvload(ASMState *as, IRIns *ir) | 863 | static 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 | ||
1088 | static 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 | |||
1086 | static void asm_add(ASMState *as, IRIns *ir) | 1100 | static 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 | |||
1129 | static void asm_neg(ASMState *as, IRIns *ir) | 1147 | static 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 | |||
1140 | static void asm_arithov(ASMState *as, IRIns *ir) | 1162 | static 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 | |||
1173 | static void asm_mulov(ASMState *as, IRIns *ir) | 1198 | static 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 | ||
1266 | static void asm_bitnot(ASMState *as, IRIns *ir) | 1291 | static 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 | ||
1280 | static void asm_bitswap(ASMState *as, IRIns *ir) | 1305 | static 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 | |||
1316 | static void asm_bitshift(ASMState *as, IRIns *ir, MIPSIns mi, MIPSIns mik) | 1345 | static 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 | ||
1329 | static 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 | |||
1363 | static 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 | ||
1380 | static void asm_comp(ASMState *as, IRIns *ir) | 1417 | static 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 | ||
1415 | static void asm_compeq(ASMState *as, IRIns *ir) | 1452 | static 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. */ | ||
1689 | static 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. */ |