diff options
Diffstat (limited to 'src/vm_arm.dasc')
-rw-r--r-- | src/vm_arm.dasc | 331 |
1 files changed, 215 insertions, 116 deletions
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 82cba909..58efabce 100644 --- a/src/vm_arm.dasc +++ b/src/vm_arm.dasc | |||
@@ -99,6 +99,7 @@ | |||
99 | |.type NODE, Node | 99 | |.type NODE, Node |
100 | |.type NARGS8, int | 100 | |.type NARGS8, int |
101 | |.type TRACE, GCtrace | 101 | |.type TRACE, GCtrace |
102 | |.type SBUF, SBuf | ||
102 | | | 103 | | |
103 | |//----------------------------------------------------------------------- | 104 | |//----------------------------------------------------------------------- |
104 | | | 105 | | |
@@ -418,13 +419,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
418 | | add CARG2, sp, #CFRAME_RESUME | 419 | | add CARG2, sp, #CFRAME_RESUME |
419 | | ldrb CARG1, L->status | 420 | | ldrb CARG1, L->status |
420 | | str CARG3, SAVE_ERRF | 421 | | str CARG3, SAVE_ERRF |
421 | | str CARG2, L->cframe | 422 | | str L, SAVE_PC // Any value outside of bytecode is ok. |
422 | | str CARG3, SAVE_CFRAME | 423 | | str CARG3, SAVE_CFRAME |
423 | | cmp CARG1, #0 | 424 | | cmp CARG1, #0 |
424 | | str L, SAVE_PC // Any value outside of bytecode is ok. | 425 | | str CARG2, L->cframe |
425 | | beq >3 | 426 | | beq >3 |
426 | | | 427 | | |
427 | | // Resume after yield (like a return). | 428 | | // Resume after yield (like a return). |
429 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
428 | | mov RA, BASE | 430 | | mov RA, BASE |
429 | | ldr BASE, L->base | 431 | | ldr BASE, L->base |
430 | | ldr CARG1, L->top | 432 | | ldr CARG1, L->top |
@@ -458,14 +460,15 @@ static void build_subroutines(BuildCtx *ctx) | |||
458 | | str CARG3, SAVE_NRES | 460 | | str CARG3, SAVE_NRES |
459 | | mov L, CARG1 | 461 | | mov L, CARG1 |
460 | | str CARG1, SAVE_L | 462 | | str CARG1, SAVE_L |
461 | | mov BASE, CARG2 | ||
462 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
463 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | 463 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. |
464 | | mov BASE, CARG2 | ||
464 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. | 465 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. |
465 | | str RC, SAVE_CFRAME | 466 | | str RC, SAVE_CFRAME |
466 | | add DISPATCH, DISPATCH, #GG_G2DISP | 467 | | add DISPATCH, DISPATCH, #GG_G2DISP |
468 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
467 | | | 469 | | |
468 | |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). | 470 | |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). |
471 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
469 | | ldr RB, L->base // RB = old base (for vmeta_call). | 472 | | ldr RB, L->base // RB = old base (for vmeta_call). |
470 | | ldr CARG1, L->top | 473 | | ldr CARG1, L->top |
471 | | mov MASKR8, #255 | 474 | | mov MASKR8, #255 |
@@ -491,20 +494,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
491 | | mov L, CARG1 | 494 | | mov L, CARG1 |
492 | | ldr RA, L:CARG1->stack | 495 | | ldr RA, L:CARG1->stack |
493 | | str CARG1, SAVE_L | 496 | | str CARG1, SAVE_L |
497 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ||
494 | | ldr RB, L->top | 498 | | ldr RB, L->top |
495 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. | 499 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. |
496 | | ldr RC, L->cframe | 500 | | ldr RC, L->cframe |
501 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
497 | | sub RA, RA, RB // Compute -savestack(L, L->top). | 502 | | sub RA, RA, RB // Compute -savestack(L, L->top). |
498 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
499 | | mov RB, #0 | 503 | | mov RB, #0 |
500 | | str RA, SAVE_NRES // Neg. delta means cframe w/o frame. | 504 | | str RA, SAVE_NRES // Neg. delta means cframe w/o frame. |
501 | | str RB, SAVE_ERRF // No error function. | 505 | | str RB, SAVE_ERRF // No error function. |
502 | | str RC, SAVE_CFRAME | 506 | | str RC, SAVE_CFRAME |
507 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
508 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
503 | | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud) | 509 | | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud) |
504 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ||
505 | | movs BASE, CRET1 | 510 | | movs BASE, CRET1 |
506 | | mov PC, #FRAME_CP | 511 | | mov PC, #FRAME_CP |
507 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
508 | | bne <3 // Else continue with the call. | 512 | | bne <3 // Else continue with the call. |
509 | | b ->vm_leave_cp // No base? Just remove C frame. | 513 | | b ->vm_leave_cp // No base? Just remove C frame. |
510 | | | 514 | | |
@@ -615,6 +619,16 @@ static void build_subroutines(BuildCtx *ctx) | |||
615 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. | 619 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. |
616 | | b ->vm_call_dispatch_f | 620 | | b ->vm_call_dispatch_f |
617 | | | 621 | | |
622 | |->vmeta_tgetr: | ||
623 | | .IOS mov RC, BASE | ||
624 | | bl extern lj_tab_getinth // (GCtab *t, int32_t key) | ||
625 | | // Returns cTValue * or NULL. | ||
626 | | .IOS mov BASE, RC | ||
627 | | cmp CRET1, #0 | ||
628 | | ldrdne CARG12, [CRET1] | ||
629 | | mvneq CARG2, #~LJ_TNIL | ||
630 | | b ->BC_TGETR_Z | ||
631 | | | ||
618 | |//----------------------------------------------------------------------- | 632 | |//----------------------------------------------------------------------- |
619 | | | 633 | | |
620 | |->vmeta_tsets1: | 634 | |->vmeta_tsets1: |
@@ -672,6 +686,15 @@ static void build_subroutines(BuildCtx *ctx) | |||
672 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. | 686 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. |
673 | | b ->vm_call_dispatch_f | 687 | | b ->vm_call_dispatch_f |
674 | | | 688 | | |
689 | |->vmeta_tsetr: | ||
690 | | str BASE, L->base | ||
691 | | .IOS mov RC, BASE | ||
692 | | str PC, SAVE_PC | ||
693 | | bl extern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key) | ||
694 | | // Returns TValue *. | ||
695 | | .IOS mov BASE, RC | ||
696 | | b ->BC_TSETR_Z | ||
697 | | | ||
675 | |//-- Comparison metamethods --------------------------------------------- | 698 | |//-- Comparison metamethods --------------------------------------------- |
676 | | | 699 | | |
677 | |->vmeta_comp: | 700 | |->vmeta_comp: |
@@ -736,6 +759,17 @@ static void build_subroutines(BuildCtx *ctx) | |||
736 | | b <3 | 759 | | b <3 |
737 | |.endif | 760 | |.endif |
738 | | | 761 | | |
762 | |->vmeta_istype: | ||
763 | | sub PC, PC, #4 | ||
764 | | str BASE, L->base | ||
765 | | mov CARG1, L | ||
766 | | lsr CARG2, RA, #3 | ||
767 | | mov CARG3, RC | ||
768 | | str PC, SAVE_PC | ||
769 | | bl extern lj_meta_istype // (lua_State *L, BCReg ra, BCReg tp) | ||
770 | | .IOS ldr BASE, L->base | ||
771 | | b ->cont_nop | ||
772 | | | ||
739 | |//-- Arithmetic metamethods --------------------------------------------- | 773 | |//-- Arithmetic metamethods --------------------------------------------- |
740 | | | 774 | | |
741 | |->vmeta_arith_vn: | 775 | |->vmeta_arith_vn: |
@@ -1053,7 +1087,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1053 | | ffgccheck | 1087 | | ffgccheck |
1054 | | mov CARG1, L | 1088 | | mov CARG1, L |
1055 | | mov CARG2, BASE | 1089 | | mov CARG2, BASE |
1056 | | bl extern lj_str_fromnumber // (lua_State *L, cTValue *o) | 1090 | | bl extern lj_strfmt_number // (lua_State *L, cTValue *o) |
1057 | | // Returns GCstr *. | 1091 | | // Returns GCstr *. |
1058 | | ldr BASE, L->base | 1092 | | ldr BASE, L->base |
1059 | | mvn CARG2, #~LJ_TSTR | 1093 | | mvn CARG2, #~LJ_TSTR |
@@ -1231,9 +1265,10 @@ static void build_subroutines(BuildCtx *ctx) | |||
1231 | | ldr CARG3, L:RA->base | 1265 | | ldr CARG3, L:RA->base |
1232 | | mv_vmstate CARG2, INTERP | 1266 | | mv_vmstate CARG2, INTERP |
1233 | | ldr CARG4, L:RA->top | 1267 | | ldr CARG4, L:RA->top |
1234 | | st_vmstate CARG2 | ||
1235 | | cmp CRET1, #LUA_YIELD | 1268 | | cmp CRET1, #LUA_YIELD |
1236 | | ldr BASE, L->base | 1269 | | ldr BASE, L->base |
1270 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
1271 | | st_vmstate CARG2 | ||
1237 | | bhi >8 | 1272 | | bhi >8 |
1238 | | subs RC, CARG4, CARG3 | 1273 | | subs RC, CARG4, CARG3 |
1239 | | ldr CARG1, L->maxstack | 1274 | | ldr CARG1, L->maxstack |
@@ -1501,19 +1536,6 @@ static void build_subroutines(BuildCtx *ctx) | |||
1501 | | math_extern2 atan2 | 1536 | | math_extern2 atan2 |
1502 | | math_extern2 fmod | 1537 | | math_extern2 fmod |
1503 | | | 1538 | | |
1504 | |->ff_math_deg: | ||
1505 | |.if FPU | ||
1506 | | .ffunc_d math_rad | ||
1507 | | vldr d1, CFUNC:CARG3->upvalue[0] | ||
1508 | | vmul.f64 d0, d0, d1 | ||
1509 | | b ->fff_resd | ||
1510 | |.else | ||
1511 | | .ffunc_n math_rad | ||
1512 | | ldrd CARG34, CFUNC:CARG3->upvalue[0] | ||
1513 | | bl extern __aeabi_dmul | ||
1514 | | b ->fff_restv | ||
1515 | |.endif | ||
1516 | | | ||
1517 | |.if HFABI | 1539 | |.if HFABI |
1518 | | .ffunc math_ldexp | 1540 | | .ffunc math_ldexp |
1519 | | ldr CARG4, [BASE, #4] | 1541 | | ldr CARG4, [BASE, #4] |
@@ -1688,12 +1710,6 @@ static void build_subroutines(BuildCtx *ctx) | |||
1688 | | | 1710 | | |
1689 | |//-- String library ----------------------------------------------------- | 1711 | |//-- String library ----------------------------------------------------- |
1690 | | | 1712 | | |
1691 | |.ffunc_1 string_len | ||
1692 | | checkstr CARG2, ->fff_fallback | ||
1693 | | ldr CARG1, STR:CARG1->len | ||
1694 | | mvn CARG2, #~LJ_TISNUM | ||
1695 | | b ->fff_restv | ||
1696 | | | ||
1697 | |.ffunc string_byte // Only handle the 1-arg case here. | 1713 | |.ffunc string_byte // Only handle the 1-arg case here. |
1698 | | ldrd CARG12, [BASE] | 1714 | | ldrd CARG12, [BASE] |
1699 | | ldr PC, [BASE, FRAME_PC] | 1715 | | ldr PC, [BASE, FRAME_PC] |
@@ -1726,6 +1742,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1726 | | mov CARG1, L | 1742 | | mov CARG1, L |
1727 | | str PC, SAVE_PC | 1743 | | str PC, SAVE_PC |
1728 | | bl extern lj_str_new // (lua_State *L, char *str, size_t l) | 1744 | | bl extern lj_str_new // (lua_State *L, char *str, size_t l) |
1745 | |->fff_resstr: | ||
1729 | | // Returns GCstr *. | 1746 | | // Returns GCstr *. |
1730 | | ldr BASE, L->base | 1747 | | ldr BASE, L->base |
1731 | | mvn CARG2, #~LJ_TSTR | 1748 | | mvn CARG2, #~LJ_TSTR |
@@ -1769,91 +1786,28 @@ static void build_subroutines(BuildCtx *ctx) | |||
1769 | | mvn CARG2, #~LJ_TSTR | 1786 | | mvn CARG2, #~LJ_TSTR |
1770 | | b ->fff_restv | 1787 | | b ->fff_restv |
1771 | | | 1788 | | |
1772 | |.ffunc string_rep // Only handle the 1-char case inline. | 1789 | |.macro ffstring_op, name |
1773 | | ffgccheck | 1790 | | .ffunc string_ .. name |
1774 | | ldrd CARG12, [BASE] | ||
1775 | | ldrd CARG34, [BASE, #8] | ||
1776 | | cmp NARGS8:RC, #16 | ||
1777 | | bne ->fff_fallback // Exactly 2 arguments | ||
1778 | | checktp CARG2, LJ_TSTR | ||
1779 | | checktpeq CARG4, LJ_TISNUM | ||
1780 | | bne ->fff_fallback | ||
1781 | | subs CARG4, CARG3, #1 | ||
1782 | | ldr CARG2, STR:CARG1->len | ||
1783 | | blt ->fff_emptystr // Count <= 0? | ||
1784 | | cmp CARG2, #1 | ||
1785 | | blo ->fff_emptystr // Zero-length string? | ||
1786 | | bne ->fff_fallback // Fallback for > 1-char strings. | ||
1787 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | ||
1788 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | ||
1789 | | ldr CARG1, STR:CARG1[1] | ||
1790 | | cmp RB, CARG3 | ||
1791 | | blo ->fff_fallback | ||
1792 | |1: // Fill buffer with char. | ||
1793 | | strb CARG1, [CARG2, CARG4] | ||
1794 | | subs CARG4, CARG4, #1 | ||
1795 | | bge <1 | ||
1796 | | b ->fff_newstr | ||
1797 | | | ||
1798 | |.ffunc string_reverse | ||
1799 | | ffgccheck | ||
1800 | | ldrd CARG12, [BASE] | ||
1801 | | cmp NARGS8:RC, #8 | ||
1802 | | blo ->fff_fallback | ||
1803 | | checkstr CARG2, ->fff_fallback | ||
1804 | | ldr CARG3, STR:CARG1->len | ||
1805 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | ||
1806 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | ||
1807 | | mov CARG4, CARG3 | ||
1808 | | add CARG1, STR:CARG1, #sizeof(GCstr) | ||
1809 | | cmp RB, CARG3 | ||
1810 | | blo ->fff_fallback | ||
1811 | |1: // Reverse string copy. | ||
1812 | | ldrb RB, [CARG1], #1 | ||
1813 | | subs CARG4, CARG4, #1 | ||
1814 | | blt ->fff_newstr | ||
1815 | | strb RB, [CARG2, CARG4] | ||
1816 | | b <1 | ||
1817 | | | ||
1818 | |.macro ffstring_case, name, lo | ||
1819 | | .ffunc name | ||
1820 | | ffgccheck | 1791 | | ffgccheck |
1821 | | ldrd CARG12, [BASE] | 1792 | | ldr CARG3, [BASE, #4] |
1822 | | cmp NARGS8:RC, #8 | 1793 | | cmp NARGS8:RC, #8 |
1794 | | ldr STR:CARG2, [BASE] | ||
1823 | | blo ->fff_fallback | 1795 | | blo ->fff_fallback |
1824 | | checkstr CARG2, ->fff_fallback | 1796 | | sub SBUF:CARG1, DISPATCH, #-DISPATCH_GL(tmpbuf) |
1825 | | ldr CARG3, STR:CARG1->len | 1797 | | checkstr CARG3, ->fff_fallback |
1826 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | 1798 | | ldr CARG4, SBUF:CARG1->b |
1827 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | 1799 | | str BASE, L->base |
1828 | | mov CARG4, #0 | 1800 | | str PC, SAVE_PC |
1829 | | add CARG1, STR:CARG1, #sizeof(GCstr) | 1801 | | str L, SBUF:CARG1->L |
1830 | | cmp RB, CARG3 | 1802 | | str CARG4, SBUF:CARG1->p |
1831 | | blo ->fff_fallback | 1803 | | bl extern lj_buf_putstr_ .. name |
1832 | |1: // ASCII case conversion. | 1804 | | bl extern lj_buf_tostr |
1833 | | ldrb RB, [CARG1, CARG4] | 1805 | | b ->fff_resstr |
1834 | | cmp CARG4, CARG3 | ||
1835 | | bhs ->fff_newstr | ||
1836 | | sub RC, RB, #lo | ||
1837 | | cmp RC, #26 | ||
1838 | | eorlo RB, RB, #0x20 | ||
1839 | | strb RB, [CARG2, CARG4] | ||
1840 | | add CARG4, CARG4, #1 | ||
1841 | | b <1 | ||
1842 | |.endmacro | 1806 | |.endmacro |
1843 | | | 1807 | | |
1844 | |ffstring_case string_lower, 65 | 1808 | |ffstring_op reverse |
1845 | |ffstring_case string_upper, 97 | 1809 | |ffstring_op lower |
1846 | | | 1810 | |ffstring_op upper |
1847 | |//-- Table library ------------------------------------------------------ | ||
1848 | | | ||
1849 | |.ffunc_1 table_getn | ||
1850 | | checktab CARG2, ->fff_fallback | ||
1851 | | .IOS mov RA, BASE | ||
1852 | | bl extern lj_tab_len // (GCtab *t) | ||
1853 | | // Returns uint32_t (but less than 2^31). | ||
1854 | | .IOS mov BASE, RA | ||
1855 | | mvn CARG2, #~LJ_TISNUM | ||
1856 | | b ->fff_restv | ||
1857 | | | 1811 | | |
1858 | |//-- Bit library -------------------------------------------------------- | 1812 | |//-- Bit library -------------------------------------------------------- |
1859 | | | 1813 | | |
@@ -2128,6 +2082,69 @@ static void build_subroutines(BuildCtx *ctx) | |||
2128 | | ldr INS, [PC, #-4] | 2082 | | ldr INS, [PC, #-4] |
2129 | | bx CRET1 | 2083 | | bx CRET1 |
2130 | | | 2084 | | |
2085 | |->cont_stitch: // Trace stitching. | ||
2086 | |.if JIT | ||
2087 | | // RA = resultptr, CARG4 = meta base | ||
2088 | | ldr RB, SAVE_MULTRES | ||
2089 | | ldr INS, [PC, #-4] | ||
2090 | | ldr CARG3, [CARG4, #-24] // Save previous trace number. | ||
2091 | | subs RB, RB, #8 | ||
2092 | | decode_RA8 RC, INS // Call base. | ||
2093 | | beq >2 | ||
2094 | |1: // Move results down. | ||
2095 | | ldrd CARG12, [RA] | ||
2096 | | add RA, RA, #8 | ||
2097 | | subs RB, RB, #8 | ||
2098 | | strd CARG12, [BASE, RC] | ||
2099 | | add RC, RC, #8 | ||
2100 | | bne <1 | ||
2101 | |2: | ||
2102 | | decode_RA8 RA, INS | ||
2103 | | decode_RB8 RB, INS | ||
2104 | | add RA, RA, RB | ||
2105 | | ldr CARG1, [DISPATCH, #DISPATCH_J(trace)] | ||
2106 | |3: | ||
2107 | | cmp RA, RC | ||
2108 | | mvn CARG2, #~LJ_TNIL | ||
2109 | | bhi >9 // More results wanted? | ||
2110 | | | ||
2111 | | ldr TRACE:RA, [CARG1, CARG3, lsl #2] | ||
2112 | | cmp TRACE:RA, #0 | ||
2113 | | beq ->cont_nop | ||
2114 | | ldrh RC, TRACE:RA->link | ||
2115 | | cmp RC, CARG3 | ||
2116 | | beq ->cont_nop // Blacklisted. | ||
2117 | | cmp RC, #0 | ||
2118 | | bne =>BC_JLOOP // Jump to stitched trace. | ||
2119 | | | ||
2120 | | // Stitch a new trace to the previous trace. | ||
2121 | | str CARG3, [DISPATCH, #DISPATCH_J(exitno)] | ||
2122 | | str L, [DISPATCH, #DISPATCH_J(L)] | ||
2123 | | str BASE, L->base | ||
2124 | | sub CARG1, DISPATCH, #-GG_DISP2J | ||
2125 | | mov CARG2, PC | ||
2126 | | bl extern lj_dispatch_stitch // (jit_State *J, const BCIns *pc) | ||
2127 | | ldr BASE, L->base | ||
2128 | | b ->cont_nop | ||
2129 | | | ||
2130 | |9: // Fill up results with nil. | ||
2131 | | strd CARG12, [BASE, RC] | ||
2132 | | add RC, RC, #8 | ||
2133 | | b <3 | ||
2134 | |.endif | ||
2135 | | | ||
2136 | |->vm_profhook: // Dispatch target for profiler hook. | ||
2137 | #if LJ_HASPROFILE | ||
2138 | | mov CARG1, L | ||
2139 | | str BASE, L->base | ||
2140 | | mov CARG2, PC | ||
2141 | | bl extern lj_dispatch_profile // (lua_State *L, const BCIns *pc) | ||
2142 | | // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction. | ||
2143 | | ldr BASE, L->base | ||
2144 | | sub PC, PC, #4 | ||
2145 | | b ->cont_nop | ||
2146 | #endif | ||
2147 | | | ||
2131 | |//----------------------------------------------------------------------- | 2148 | |//----------------------------------------------------------------------- |
2132 | |//-- Trace exit handler ------------------------------------------------- | 2149 | |//-- Trace exit handler ------------------------------------------------- |
2133 | |//----------------------------------------------------------------------- | 2150 | |//----------------------------------------------------------------------- |
@@ -2152,14 +2169,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
2152 | | add CARG1, CARG1, CARG2, asr #6 | 2169 | | add CARG1, CARG1, CARG2, asr #6 |
2153 | | ldr CARG2, [lr, #4] // Load exit stub group offset. | 2170 | | ldr CARG2, [lr, #4] // Load exit stub group offset. |
2154 | | sub CARG1, CARG1, lr | 2171 | | sub CARG1, CARG1, lr |
2155 | | ldr L, [DISPATCH, #DISPATCH_GL(jit_L)] | 2172 | | ldr L, [DISPATCH, #DISPATCH_GL(cur_L)] |
2156 | | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. | 2173 | | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. |
2157 | | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | 2174 | | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] |
2158 | | str CARG1, [DISPATCH, #DISPATCH_J(exitno)] | 2175 | | str CARG1, [DISPATCH, #DISPATCH_J(exitno)] |
2159 | | mov CARG4, #0 | 2176 | | mov CARG4, #0 |
2160 | | str L, [DISPATCH, #DISPATCH_J(L)] | ||
2161 | | str BASE, L->base | 2177 | | str BASE, L->base |
2162 | | str CARG4, [DISPATCH, #DISPATCH_GL(jit_L)] | 2178 | | str L, [DISPATCH, #DISPATCH_J(L)] |
2179 | | str CARG4, [DISPATCH, #DISPATCH_GL(jit_base)] | ||
2163 | | sub CARG1, DISPATCH, #-GG_DISP2J | 2180 | | sub CARG1, DISPATCH, #-GG_DISP2J |
2164 | | mov CARG2, sp | 2181 | | mov CARG2, sp |
2165 | | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) | 2182 | | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) |
@@ -2178,13 +2195,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
2178 | | ldr L, SAVE_L | 2195 | | ldr L, SAVE_L |
2179 | |1: | 2196 | |1: |
2180 | | cmp CARG1, #0 | 2197 | | cmp CARG1, #0 |
2181 | | blt >3 // Check for error from exit. | 2198 | | blt >9 // Check for error from exit. |
2182 | | lsl RC, CARG1, #3 | 2199 | | lsl RC, CARG1, #3 |
2183 | | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] | 2200 | | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] |
2184 | | str RC, SAVE_MULTRES | 2201 | | str RC, SAVE_MULTRES |
2185 | | mov CARG3, #0 | 2202 | | mov CARG3, #0 |
2203 | | str BASE, L->base | ||
2186 | | ldr CARG2, LFUNC:CARG2->field_pc | 2204 | | ldr CARG2, LFUNC:CARG2->field_pc |
2187 | | str CARG3, [DISPATCH, #DISPATCH_GL(jit_L)] | 2205 | | str CARG3, [DISPATCH, #DISPATCH_GL(jit_base)] |
2188 | | mv_vmstate CARG4, INTERP | 2206 | | mv_vmstate CARG4, INTERP |
2189 | | ldr KBASE, [CARG2, #PC2PROTO(k)] | 2207 | | ldr KBASE, [CARG2, #PC2PROTO(k)] |
2190 | | // Modified copy of ins_next which handles function header dispatch, too. | 2208 | | // Modified copy of ins_next which handles function header dispatch, too. |
@@ -2193,15 +2211,32 @@ static void build_subroutines(BuildCtx *ctx) | |||
2193 | | ldr INS, [PC], #4 | 2211 | | ldr INS, [PC], #4 |
2194 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. | 2212 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. |
2195 | | st_vmstate CARG4 | 2213 | | st_vmstate CARG4 |
2214 | | cmp OP, #BC_FUNCC+2 // Fast function? | ||
2215 | | bhs >4 | ||
2216 | |2: | ||
2196 | | cmp OP, #BC_FUNCF // Function header? | 2217 | | cmp OP, #BC_FUNCF // Function header? |
2197 | | ldr OP, [DISPATCH, OP, lsl #2] | 2218 | | ldr OP, [DISPATCH, OP, lsl #2] |
2198 | | decode_RA8 RA, INS | 2219 | | decode_RA8 RA, INS |
2199 | | lsrlo RC, INS, #16 // No: Decode operands A*8 and D. | 2220 | | lsrlo RC, INS, #16 // No: Decode operands A*8 and D. |
2200 | | subhs RC, RC, #8 | 2221 | | subhs RC, RC, #8 |
2201 | | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8 | 2222 | | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8 |
2223 | | ldrhs CARG3, [BASE, FRAME_FUNC] | ||
2202 | | bx OP | 2224 | | bx OP |
2203 | | | 2225 | | |
2204 | |3: // Rethrow error from the right C frame. | 2226 | |4: // Check frame below fast function. |
2227 | | ldr CARG1, [BASE, FRAME_PC] | ||
2228 | | ands CARG2, CARG1, #FRAME_TYPE | ||
2229 | | bne <2 // Trace stitching continuation? | ||
2230 | | // Otherwise set KBASE for Lua function below fast function. | ||
2231 | | ldr CARG3, [CARG1, #-4] | ||
2232 | | decode_RA8 CARG1, CARG3 | ||
2233 | | sub CARG2, BASE, CARG1 | ||
2234 | | ldr LFUNC:CARG3, [CARG2, #-16] | ||
2235 | | ldr CARG3, LFUNC:CARG3->field_pc | ||
2236 | | ldr KBASE, [CARG3, #PC2PROTO(k)] | ||
2237 | | b <2 | ||
2238 | | | ||
2239 | |9: // Rethrow error from the right C frame. | ||
2205 | | rsb CARG2, CARG1, #0 | 2240 | | rsb CARG2, CARG1, #0 |
2206 | | mov CARG1, L | 2241 | | mov CARG1, L |
2207 | | bl extern lj_err_throw // (lua_State *L, int errcode) | 2242 | | bl extern lj_err_throw // (lua_State *L, int errcode) |
@@ -2834,6 +2869,25 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
2834 | | ins_next | 2869 | | ins_next |
2835 | break; | 2870 | break; |
2836 | 2871 | ||
2872 | case BC_ISTYPE: | ||
2873 | | // RA = src*8, RC = -type | ||
2874 | | ldrd CARG12, [BASE, RA] | ||
2875 | | ins_next1 | ||
2876 | | cmn CARG2, RC | ||
2877 | | ins_next2 | ||
2878 | | bne ->vmeta_istype | ||
2879 | | ins_next3 | ||
2880 | break; | ||
2881 | case BC_ISNUM: | ||
2882 | | // RA = src*8, RC = -(TISNUM-1) | ||
2883 | | ldrd CARG12, [BASE, RA] | ||
2884 | | ins_next1 | ||
2885 | | checktp CARG2, LJ_TISNUM | ||
2886 | | ins_next2 | ||
2887 | | bhs ->vmeta_istype | ||
2888 | | ins_next3 | ||
2889 | break; | ||
2890 | |||
2837 | /* -- Unary ops --------------------------------------------------------- */ | 2891 | /* -- Unary ops --------------------------------------------------------- */ |
2838 | 2892 | ||
2839 | case BC_MOV: | 2893 | case BC_MOV: |
@@ -3504,6 +3558,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3504 | | bne <1 // 'no __index' flag set: done. | 3558 | | bne <1 // 'no __index' flag set: done. |
3505 | | b ->vmeta_tgetb | 3559 | | b ->vmeta_tgetb |
3506 | break; | 3560 | break; |
3561 | case BC_TGETR: | ||
3562 | | decode_RB8 RB, INS | ||
3563 | | decode_RC8 RC, INS | ||
3564 | | // RA = dst*8, RB = table*8, RC = key*8 | ||
3565 | | ldr TAB:CARG1, [BASE, RB] | ||
3566 | | ldr CARG2, [BASE, RC] | ||
3567 | | ldr CARG4, TAB:CARG1->array | ||
3568 | | ldr CARG3, TAB:CARG1->asize | ||
3569 | | add CARG4, CARG4, CARG2, lsl #3 | ||
3570 | | cmp CARG2, CARG3 // In array part? | ||
3571 | | bhs ->vmeta_tgetr | ||
3572 | | ldrd CARG12, [CARG4] | ||
3573 | |->BC_TGETR_Z: | ||
3574 | | ins_next1 | ||
3575 | | ins_next2 | ||
3576 | | strd CARG12, [BASE, RA] | ||
3577 | | ins_next3 | ||
3578 | break; | ||
3507 | 3579 | ||
3508 | case BC_TSETV: | 3580 | case BC_TSETV: |
3509 | | decode_RB8 RB, INS | 3581 | | decode_RB8 RB, INS |
@@ -3674,6 +3746,32 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3674 | | barrierback TAB:CARG1, INS, CARG3 | 3746 | | barrierback TAB:CARG1, INS, CARG3 |
3675 | | b <2 | 3747 | | b <2 |
3676 | break; | 3748 | break; |
3749 | case BC_TSETR: | ||
3750 | | decode_RB8 RB, INS | ||
3751 | | decode_RC8 RC, INS | ||
3752 | | // RA = dst*8, RB = table*8, RC = key*8 | ||
3753 | | ldr TAB:CARG2, [BASE, RB] | ||
3754 | | ldr CARG3, [BASE, RC] | ||
3755 | | ldrb INS, TAB:CARG2->marked | ||
3756 | | ldr CARG1, TAB:CARG2->array | ||
3757 | | ldr CARG4, TAB:CARG2->asize | ||
3758 | | tst INS, #LJ_GC_BLACK // isblack(table) | ||
3759 | | add CARG1, CARG1, CARG3, lsl #3 | ||
3760 | | bne >7 | ||
3761 | |2: | ||
3762 | | cmp CARG3, CARG4 // In array part? | ||
3763 | | bhs ->vmeta_tsetr | ||
3764 | |->BC_TSETR_Z: | ||
3765 | | ldrd CARG34, [BASE, RA] | ||
3766 | | ins_next1 | ||
3767 | | ins_next2 | ||
3768 | | strd CARG34, [CARG1] | ||
3769 | | ins_next3 | ||
3770 | | | ||
3771 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
3772 | | barrierback TAB:CARG2, INS, RB | ||
3773 | | b <2 | ||
3774 | break; | ||
3677 | 3775 | ||
3678 | case BC_TSETM: | 3776 | case BC_TSETM: |
3679 | | // RA = base*8 (table at base-1), RC = num_const (start index) | 3777 | | // RA = base*8 (table at base-1), RC = num_const (start index) |
@@ -4271,7 +4369,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
4271 | | st_vmstate CARG2 | 4369 | | st_vmstate CARG2 |
4272 | | ldr RA, TRACE:RC->mcode | 4370 | | ldr RA, TRACE:RC->mcode |
4273 | | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | 4371 | | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] |
4274 | | str L, [DISPATCH, #DISPATCH_GL(jit_L)] | 4372 | | str L, [DISPATCH, #DISPATCH_GL(tmpbuf.L)] |
4275 | | bx RA | 4373 | | bx RA |
4276 | |.endif | 4374 | |.endif |
4277 | break; | 4375 | break; |
@@ -4389,6 +4487,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
4389 | | ldr BASE, L->base | 4487 | | ldr BASE, L->base |
4390 | | mv_vmstate CARG3, INTERP | 4488 | | mv_vmstate CARG3, INTERP |
4391 | | ldr CRET2, L->top | 4489 | | ldr CRET2, L->top |
4490 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
4392 | | lsl RC, CRET1, #3 | 4491 | | lsl RC, CRET1, #3 |
4393 | | st_vmstate CARG3 | 4492 | | st_vmstate CARG3 |
4394 | | ldr PC, [BASE, FRAME_PC] | 4493 | | ldr PC, [BASE, FRAME_PC] |