diff options
Diffstat (limited to 'src/vm_arm.dasc')
-rw-r--r-- | src/vm_arm.dasc | 339 |
1 files changed, 223 insertions, 116 deletions
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index c5e0498e..edefac32 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 | | |
@@ -372,6 +373,17 @@ static void build_subroutines(BuildCtx *ctx) | |||
372 | | st_vmstate CARG2 | 373 | | st_vmstate CARG2 |
373 | | b ->vm_returnc | 374 | | b ->vm_returnc |
374 | | | 375 | | |
376 | |->vm_unwind_ext: // Complete external unwind. | ||
377 | #if !LJ_NO_UNWIND | ||
378 | | push {r0, r1, r2, lr} | ||
379 | | bl extern _Unwind_Complete | ||
380 | | ldr r0, [sp] | ||
381 | | bl extern _Unwind_DeleteException | ||
382 | | pop {r0, r1, r2, lr} | ||
383 | | mov r0, r1 | ||
384 | | bx r2 | ||
385 | #endif | ||
386 | | | ||
375 | |//----------------------------------------------------------------------- | 387 | |//----------------------------------------------------------------------- |
376 | |//-- Grow stack for calls ----------------------------------------------- | 388 | |//-- Grow stack for calls ----------------------------------------------- |
377 | |//----------------------------------------------------------------------- | 389 | |//----------------------------------------------------------------------- |
@@ -418,13 +430,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
418 | | add CARG2, sp, #CFRAME_RESUME | 430 | | add CARG2, sp, #CFRAME_RESUME |
419 | | ldrb CARG1, L->status | 431 | | ldrb CARG1, L->status |
420 | | str CARG3, SAVE_ERRF | 432 | | str CARG3, SAVE_ERRF |
421 | | str CARG2, L->cframe | 433 | | str L, SAVE_PC // Any value outside of bytecode is ok. |
422 | | str CARG3, SAVE_CFRAME | 434 | | str CARG3, SAVE_CFRAME |
423 | | cmp CARG1, #0 | 435 | | cmp CARG1, #0 |
424 | | str L, SAVE_PC // Any value outside of bytecode is ok. | 436 | | str CARG2, L->cframe |
425 | | beq >3 | 437 | | beq >3 |
426 | | | 438 | | |
427 | | // Resume after yield (like a return). | 439 | | // Resume after yield (like a return). |
440 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
428 | | mov RA, BASE | 441 | | mov RA, BASE |
429 | | ldr BASE, L->base | 442 | | ldr BASE, L->base |
430 | | ldr CARG1, L->top | 443 | | ldr CARG1, L->top |
@@ -458,14 +471,15 @@ static void build_subroutines(BuildCtx *ctx) | |||
458 | | str CARG3, SAVE_NRES | 471 | | str CARG3, SAVE_NRES |
459 | | mov L, CARG1 | 472 | | mov L, CARG1 |
460 | | str CARG1, SAVE_L | 473 | | 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. | 474 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. |
475 | | mov BASE, CARG2 | ||
464 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. | 476 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. |
465 | | str RC, SAVE_CFRAME | 477 | | str RC, SAVE_CFRAME |
466 | | add DISPATCH, DISPATCH, #GG_G2DISP | 478 | | add DISPATCH, DISPATCH, #GG_G2DISP |
479 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
467 | | | 480 | | |
468 | |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). | 481 | |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). |
482 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
469 | | ldr RB, L->base // RB = old base (for vmeta_call). | 483 | | ldr RB, L->base // RB = old base (for vmeta_call). |
470 | | ldr CARG1, L->top | 484 | | ldr CARG1, L->top |
471 | | mov MASKR8, #255 | 485 | | mov MASKR8, #255 |
@@ -491,20 +505,21 @@ static void build_subroutines(BuildCtx *ctx) | |||
491 | | mov L, CARG1 | 505 | | mov L, CARG1 |
492 | | ldr RA, L:CARG1->stack | 506 | | ldr RA, L:CARG1->stack |
493 | | str CARG1, SAVE_L | 507 | | str CARG1, SAVE_L |
508 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ||
494 | | ldr RB, L->top | 509 | | ldr RB, L->top |
495 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. | 510 | | str CARG1, SAVE_PC // Any value outside of bytecode is ok. |
496 | | ldr RC, L->cframe | 511 | | ldr RC, L->cframe |
512 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
497 | | sub RA, RA, RB // Compute -savestack(L, L->top). | 513 | | 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 | 514 | | mov RB, #0 |
500 | | str RA, SAVE_NRES // Neg. delta means cframe w/o frame. | 515 | | str RA, SAVE_NRES // Neg. delta means cframe w/o frame. |
501 | | str RB, SAVE_ERRF // No error function. | 516 | | str RB, SAVE_ERRF // No error function. |
502 | | str RC, SAVE_CFRAME | 517 | | str RC, SAVE_CFRAME |
518 | | str sp, L->cframe // Add our C frame to cframe chain. | ||
519 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
503 | | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud) | 520 | | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud) |
504 | | ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ||
505 | | movs BASE, CRET1 | 521 | | movs BASE, CRET1 |
506 | | mov PC, #FRAME_CP | 522 | | mov PC, #FRAME_CP |
507 | | add DISPATCH, DISPATCH, #GG_G2DISP | ||
508 | | bne <3 // Else continue with the call. | 523 | | bne <3 // Else continue with the call. |
509 | | b ->vm_leave_cp // No base? Just remove C frame. | 524 | | b ->vm_leave_cp // No base? Just remove C frame. |
510 | | | 525 | | |
@@ -614,6 +629,16 @@ static void build_subroutines(BuildCtx *ctx) | |||
614 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. | 629 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. |
615 | | b ->vm_call_dispatch_f | 630 | | b ->vm_call_dispatch_f |
616 | | | 631 | | |
632 | |->vmeta_tgetr: | ||
633 | | .IOS mov RC, BASE | ||
634 | | bl extern lj_tab_getinth // (GCtab *t, int32_t key) | ||
635 | | // Returns cTValue * or NULL. | ||
636 | | .IOS mov BASE, RC | ||
637 | | cmp CRET1, #0 | ||
638 | | ldrdne CARG12, [CRET1] | ||
639 | | mvneq CARG2, #~LJ_TNIL | ||
640 | | b ->BC_TGETR_Z | ||
641 | | | ||
617 | |//----------------------------------------------------------------------- | 642 | |//----------------------------------------------------------------------- |
618 | | | 643 | | |
619 | |->vmeta_tsets1: | 644 | |->vmeta_tsets1: |
@@ -671,6 +696,15 @@ static void build_subroutines(BuildCtx *ctx) | |||
671 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. | 696 | | ldr LFUNC:CARG3, [BASE, FRAME_FUNC] // Guaranteed to be a function here. |
672 | | b ->vm_call_dispatch_f | 697 | | b ->vm_call_dispatch_f |
673 | | | 698 | | |
699 | |->vmeta_tsetr: | ||
700 | | str BASE, L->base | ||
701 | | .IOS mov RC, BASE | ||
702 | | str PC, SAVE_PC | ||
703 | | bl extern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key) | ||
704 | | // Returns TValue *. | ||
705 | | .IOS mov BASE, RC | ||
706 | | b ->BC_TSETR_Z | ||
707 | | | ||
674 | |//-- Comparison metamethods --------------------------------------------- | 708 | |//-- Comparison metamethods --------------------------------------------- |
675 | | | 709 | | |
676 | |->vmeta_comp: | 710 | |->vmeta_comp: |
@@ -735,6 +769,17 @@ static void build_subroutines(BuildCtx *ctx) | |||
735 | | b <3 | 769 | | b <3 |
736 | |.endif | 770 | |.endif |
737 | | | 771 | | |
772 | |->vmeta_istype: | ||
773 | | sub PC, PC, #4 | ||
774 | | str BASE, L->base | ||
775 | | mov CARG1, L | ||
776 | | lsr CARG2, RA, #3 | ||
777 | | mov CARG3, RC | ||
778 | | str PC, SAVE_PC | ||
779 | | bl extern lj_meta_istype // (lua_State *L, BCReg ra, BCReg tp) | ||
780 | | .IOS ldr BASE, L->base | ||
781 | | b ->cont_nop | ||
782 | | | ||
738 | |//-- Arithmetic metamethods --------------------------------------------- | 783 | |//-- Arithmetic metamethods --------------------------------------------- |
739 | | | 784 | | |
740 | |->vmeta_arith_vn: | 785 | |->vmeta_arith_vn: |
@@ -1052,7 +1097,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1052 | | ffgccheck | 1097 | | ffgccheck |
1053 | | mov CARG1, L | 1098 | | mov CARG1, L |
1054 | | mov CARG2, BASE | 1099 | | mov CARG2, BASE |
1055 | | bl extern lj_str_fromnumber // (lua_State *L, cTValue *o) | 1100 | | bl extern lj_strfmt_number // (lua_State *L, cTValue *o) |
1056 | | // Returns GCstr *. | 1101 | | // Returns GCstr *. |
1057 | | ldr BASE, L->base | 1102 | | ldr BASE, L->base |
1058 | | mvn CARG2, #~LJ_TSTR | 1103 | | mvn CARG2, #~LJ_TSTR |
@@ -1230,9 +1275,10 @@ static void build_subroutines(BuildCtx *ctx) | |||
1230 | | ldr CARG3, L:RA->base | 1275 | | ldr CARG3, L:RA->base |
1231 | | mv_vmstate CARG2, INTERP | 1276 | | mv_vmstate CARG2, INTERP |
1232 | | ldr CARG4, L:RA->top | 1277 | | ldr CARG4, L:RA->top |
1233 | | st_vmstate CARG2 | ||
1234 | | cmp CRET1, #LUA_YIELD | 1278 | | cmp CRET1, #LUA_YIELD |
1235 | | ldr BASE, L->base | 1279 | | ldr BASE, L->base |
1280 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
1281 | | st_vmstate CARG2 | ||
1236 | | bhi >8 | 1282 | | bhi >8 |
1237 | | subs RC, CARG4, CARG3 | 1283 | | subs RC, CARG4, CARG3 |
1238 | | ldr CARG1, L->maxstack | 1284 | | ldr CARG1, L->maxstack |
@@ -1500,19 +1546,6 @@ static void build_subroutines(BuildCtx *ctx) | |||
1500 | | math_extern2 atan2 | 1546 | | math_extern2 atan2 |
1501 | | math_extern2 fmod | 1547 | | math_extern2 fmod |
1502 | | | 1548 | | |
1503 | |->ff_math_deg: | ||
1504 | |.if FPU | ||
1505 | | .ffunc_d math_rad | ||
1506 | | vldr d1, CFUNC:CARG3->upvalue[0] | ||
1507 | | vmul.f64 d0, d0, d1 | ||
1508 | | b ->fff_resd | ||
1509 | |.else | ||
1510 | | .ffunc_n math_rad | ||
1511 | | ldrd CARG34, CFUNC:CARG3->upvalue[0] | ||
1512 | | bl extern __aeabi_dmul | ||
1513 | | b ->fff_restv | ||
1514 | |.endif | ||
1515 | | | ||
1516 | |.if HFABI | 1549 | |.if HFABI |
1517 | | .ffunc math_ldexp | 1550 | | .ffunc math_ldexp |
1518 | | ldr CARG4, [BASE, #4] | 1551 | | ldr CARG4, [BASE, #4] |
@@ -1687,12 +1720,6 @@ static void build_subroutines(BuildCtx *ctx) | |||
1687 | | | 1720 | | |
1688 | |//-- String library ----------------------------------------------------- | 1721 | |//-- String library ----------------------------------------------------- |
1689 | | | 1722 | | |
1690 | |.ffunc_1 string_len | ||
1691 | | checkstr CARG2, ->fff_fallback | ||
1692 | | ldr CARG1, STR:CARG1->len | ||
1693 | | mvn CARG2, #~LJ_TISNUM | ||
1694 | | b ->fff_restv | ||
1695 | | | ||
1696 | |.ffunc string_byte // Only handle the 1-arg case here. | 1723 | |.ffunc string_byte // Only handle the 1-arg case here. |
1697 | | ldrd CARG12, [BASE] | 1724 | | ldrd CARG12, [BASE] |
1698 | | ldr PC, [BASE, FRAME_PC] | 1725 | | ldr PC, [BASE, FRAME_PC] |
@@ -1725,6 +1752,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1725 | | mov CARG1, L | 1752 | | mov CARG1, L |
1726 | | str PC, SAVE_PC | 1753 | | str PC, SAVE_PC |
1727 | | bl extern lj_str_new // (lua_State *L, char *str, size_t l) | 1754 | | bl extern lj_str_new // (lua_State *L, char *str, size_t l) |
1755 | |->fff_resstr: | ||
1728 | | // Returns GCstr *. | 1756 | | // Returns GCstr *. |
1729 | | ldr BASE, L->base | 1757 | | ldr BASE, L->base |
1730 | | mvn CARG2, #~LJ_TSTR | 1758 | | mvn CARG2, #~LJ_TSTR |
@@ -1768,91 +1796,28 @@ static void build_subroutines(BuildCtx *ctx) | |||
1768 | | mvn CARG2, #~LJ_TSTR | 1796 | | mvn CARG2, #~LJ_TSTR |
1769 | | b ->fff_restv | 1797 | | b ->fff_restv |
1770 | | | 1798 | | |
1771 | |.ffunc string_rep // Only handle the 1-char case inline. | 1799 | |.macro ffstring_op, name |
1772 | | ffgccheck | 1800 | | .ffunc string_ .. name |
1773 | | ldrd CARG12, [BASE] | ||
1774 | | ldrd CARG34, [BASE, #8] | ||
1775 | | cmp NARGS8:RC, #16 | ||
1776 | | bne ->fff_fallback // Exactly 2 arguments | ||
1777 | | checktp CARG2, LJ_TSTR | ||
1778 | | checktpeq CARG4, LJ_TISNUM | ||
1779 | | bne ->fff_fallback | ||
1780 | | subs CARG4, CARG3, #1 | ||
1781 | | ldr CARG2, STR:CARG1->len | ||
1782 | | blt ->fff_emptystr // Count <= 0? | ||
1783 | | cmp CARG2, #1 | ||
1784 | | blo ->fff_emptystr // Zero-length string? | ||
1785 | | bne ->fff_fallback // Fallback for > 1-char strings. | ||
1786 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | ||
1787 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | ||
1788 | | ldr CARG1, STR:CARG1[1] | ||
1789 | | cmp RB, CARG3 | ||
1790 | | blo ->fff_fallback | ||
1791 | |1: // Fill buffer with char. | ||
1792 | | strb CARG1, [CARG2, CARG4] | ||
1793 | | subs CARG4, CARG4, #1 | ||
1794 | | bge <1 | ||
1795 | | b ->fff_newstr | ||
1796 | | | ||
1797 | |.ffunc string_reverse | ||
1798 | | ffgccheck | 1801 | | ffgccheck |
1799 | | ldrd CARG12, [BASE] | 1802 | | ldr CARG3, [BASE, #4] |
1800 | | cmp NARGS8:RC, #8 | 1803 | | cmp NARGS8:RC, #8 |
1804 | | ldr STR:CARG2, [BASE] | ||
1801 | | blo ->fff_fallback | 1805 | | blo ->fff_fallback |
1802 | | checkstr CARG2, ->fff_fallback | 1806 | | sub SBUF:CARG1, DISPATCH, #-DISPATCH_GL(tmpbuf) |
1803 | | ldr CARG3, STR:CARG1->len | 1807 | | checkstr CARG3, ->fff_fallback |
1804 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | 1808 | | ldr CARG4, SBUF:CARG1->b |
1805 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | 1809 | | str BASE, L->base |
1806 | | mov CARG4, CARG3 | 1810 | | str PC, SAVE_PC |
1807 | | add CARG1, STR:CARG1, #sizeof(GCstr) | 1811 | | str L, SBUF:CARG1->L |
1808 | | cmp RB, CARG3 | 1812 | | str CARG4, SBUF:CARG1->p |
1809 | | blo ->fff_fallback | 1813 | | bl extern lj_buf_putstr_ .. name |
1810 | |1: // Reverse string copy. | 1814 | | bl extern lj_buf_tostr |
1811 | | ldrb RB, [CARG1], #1 | 1815 | | b ->fff_resstr |
1812 | | subs CARG4, CARG4, #1 | ||
1813 | | blt ->fff_newstr | ||
1814 | | strb RB, [CARG2, CARG4] | ||
1815 | | b <1 | ||
1816 | | | ||
1817 | |.macro ffstring_case, name, lo | ||
1818 | | .ffunc name | ||
1819 | | ffgccheck | ||
1820 | | ldrd CARG12, [BASE] | ||
1821 | | cmp NARGS8:RC, #8 | ||
1822 | | blo ->fff_fallback | ||
1823 | | checkstr CARG2, ->fff_fallback | ||
1824 | | ldr CARG3, STR:CARG1->len | ||
1825 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | ||
1826 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | ||
1827 | | mov CARG4, #0 | ||
1828 | | add CARG1, STR:CARG1, #sizeof(GCstr) | ||
1829 | | cmp RB, CARG3 | ||
1830 | | blo ->fff_fallback | ||
1831 | |1: // ASCII case conversion. | ||
1832 | | ldrb RB, [CARG1, CARG4] | ||
1833 | | cmp CARG4, CARG3 | ||
1834 | | bhs ->fff_newstr | ||
1835 | | sub RC, RB, #lo | ||
1836 | | cmp RC, #26 | ||
1837 | | eorlo RB, RB, #0x20 | ||
1838 | | strb RB, [CARG2, CARG4] | ||
1839 | | add CARG4, CARG4, #1 | ||
1840 | | b <1 | ||
1841 | |.endmacro | 1816 | |.endmacro |
1842 | | | 1817 | | |
1843 | |ffstring_case string_lower, 65 | 1818 | |ffstring_op reverse |
1844 | |ffstring_case string_upper, 97 | 1819 | |ffstring_op lower |
1845 | | | 1820 | |ffstring_op upper |
1846 | |//-- Table library ------------------------------------------------------ | ||
1847 | | | ||
1848 | |.ffunc_1 table_getn | ||
1849 | | checktab CARG2, ->fff_fallback | ||
1850 | | .IOS mov RA, BASE | ||
1851 | | bl extern lj_tab_len // (GCtab *t) | ||
1852 | | // Returns uint32_t (but less than 2^31). | ||
1853 | | .IOS mov BASE, RA | ||
1854 | | mvn CARG2, #~LJ_TISNUM | ||
1855 | | b ->fff_restv | ||
1856 | | | 1821 | | |
1857 | |//-- Bit library -------------------------------------------------------- | 1822 | |//-- Bit library -------------------------------------------------------- |
1858 | | | 1823 | | |
@@ -2127,6 +2092,66 @@ static void build_subroutines(BuildCtx *ctx) | |||
2127 | | ldr INS, [PC, #-4] | 2092 | | ldr INS, [PC, #-4] |
2128 | | bx CRET1 | 2093 | | bx CRET1 |
2129 | | | 2094 | | |
2095 | |->cont_stitch: // Trace stitching. | ||
2096 | |.if JIT | ||
2097 | | // RA = resultptr, CARG4 = meta base | ||
2098 | | ldr RB, SAVE_MULTRES | ||
2099 | | ldr INS, [PC, #-4] | ||
2100 | | ldr TRACE:CARG3, [CARG4, #-24] // Save previous trace. | ||
2101 | | subs RB, RB, #8 | ||
2102 | | decode_RA8 RC, INS // Call base. | ||
2103 | | beq >2 | ||
2104 | |1: // Move results down. | ||
2105 | | ldrd CARG12, [RA] | ||
2106 | | add RA, RA, #8 | ||
2107 | | subs RB, RB, #8 | ||
2108 | | strd CARG12, [BASE, RC] | ||
2109 | | add RC, RC, #8 | ||
2110 | | bne <1 | ||
2111 | |2: | ||
2112 | | decode_RA8 RA, INS | ||
2113 | | decode_RB8 RB, INS | ||
2114 | | add RA, RA, RB | ||
2115 | |3: | ||
2116 | | cmp RA, RC | ||
2117 | | mvn CARG2, #~LJ_TNIL | ||
2118 | | bhi >9 // More results wanted? | ||
2119 | | | ||
2120 | | ldrh RA, TRACE:CARG3->traceno | ||
2121 | | ldrh RC, TRACE:CARG3->link | ||
2122 | | cmp RC, RA | ||
2123 | | beq ->cont_nop // Blacklisted. | ||
2124 | | cmp RC, #0 | ||
2125 | | bne =>BC_JLOOP // Jump to stitched trace. | ||
2126 | | | ||
2127 | | // Stitch a new trace to the previous trace. | ||
2128 | | str RA, [DISPATCH, #DISPATCH_J(exitno)] | ||
2129 | | str L, [DISPATCH, #DISPATCH_J(L)] | ||
2130 | | str BASE, L->base | ||
2131 | | sub CARG1, DISPATCH, #-GG_DISP2J | ||
2132 | | mov CARG2, PC | ||
2133 | | bl extern lj_dispatch_stitch // (jit_State *J, const BCIns *pc) | ||
2134 | | ldr BASE, L->base | ||
2135 | | b ->cont_nop | ||
2136 | | | ||
2137 | |9: // Fill up results with nil. | ||
2138 | | strd CARG12, [BASE, RC] | ||
2139 | | add RC, RC, #8 | ||
2140 | | b <3 | ||
2141 | |.endif | ||
2142 | | | ||
2143 | |->vm_profhook: // Dispatch target for profiler hook. | ||
2144 | #if LJ_HASPROFILE | ||
2145 | | mov CARG1, L | ||
2146 | | str BASE, L->base | ||
2147 | | mov CARG2, PC | ||
2148 | | bl extern lj_dispatch_profile // (lua_State *L, const BCIns *pc) | ||
2149 | | // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction. | ||
2150 | | ldr BASE, L->base | ||
2151 | | sub PC, PC, #4 | ||
2152 | | b ->cont_nop | ||
2153 | #endif | ||
2154 | | | ||
2130 | |//----------------------------------------------------------------------- | 2155 | |//----------------------------------------------------------------------- |
2131 | |//-- Trace exit handler ------------------------------------------------- | 2156 | |//-- Trace exit handler ------------------------------------------------- |
2132 | |//----------------------------------------------------------------------- | 2157 | |//----------------------------------------------------------------------- |
@@ -2151,14 +2176,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
2151 | | add CARG1, CARG1, CARG2, asr #6 | 2176 | | add CARG1, CARG1, CARG2, asr #6 |
2152 | | ldr CARG2, [lr, #4] // Load exit stub group offset. | 2177 | | ldr CARG2, [lr, #4] // Load exit stub group offset. |
2153 | | sub CARG1, CARG1, lr | 2178 | | sub CARG1, CARG1, lr |
2154 | | ldr L, [DISPATCH, #DISPATCH_GL(jit_L)] | 2179 | | ldr L, [DISPATCH, #DISPATCH_GL(cur_L)] |
2155 | | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. | 2180 | | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. |
2156 | | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | 2181 | | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] |
2157 | | str CARG1, [DISPATCH, #DISPATCH_J(exitno)] | 2182 | | str CARG1, [DISPATCH, #DISPATCH_J(exitno)] |
2158 | | mov CARG4, #0 | 2183 | | mov CARG4, #0 |
2159 | | str L, [DISPATCH, #DISPATCH_J(L)] | ||
2160 | | str BASE, L->base | 2184 | | str BASE, L->base |
2161 | | str CARG4, [DISPATCH, #DISPATCH_GL(jit_L)] | 2185 | | str L, [DISPATCH, #DISPATCH_J(L)] |
2186 | | str CARG4, [DISPATCH, #DISPATCH_GL(jit_base)] | ||
2162 | | sub CARG1, DISPATCH, #-GG_DISP2J | 2187 | | sub CARG1, DISPATCH, #-GG_DISP2J |
2163 | | mov CARG2, sp | 2188 | | mov CARG2, sp |
2164 | | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) | 2189 | | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) |
@@ -2177,13 +2202,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
2177 | | ldr L, SAVE_L | 2202 | | ldr L, SAVE_L |
2178 | |1: | 2203 | |1: |
2179 | | cmp CARG1, #0 | 2204 | | cmp CARG1, #0 |
2180 | | blt >3 // Check for error from exit. | 2205 | | blt >9 // Check for error from exit. |
2181 | | lsl RC, CARG1, #3 | 2206 | | lsl RC, CARG1, #3 |
2182 | | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] | 2207 | | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] |
2183 | | str RC, SAVE_MULTRES | 2208 | | str RC, SAVE_MULTRES |
2184 | | mov CARG3, #0 | 2209 | | mov CARG3, #0 |
2210 | | str BASE, L->base | ||
2185 | | ldr CARG2, LFUNC:CARG2->field_pc | 2211 | | ldr CARG2, LFUNC:CARG2->field_pc |
2186 | | str CARG3, [DISPATCH, #DISPATCH_GL(jit_L)] | 2212 | | str CARG3, [DISPATCH, #DISPATCH_GL(jit_base)] |
2187 | | mv_vmstate CARG4, INTERP | 2213 | | mv_vmstate CARG4, INTERP |
2188 | | ldr KBASE, [CARG2, #PC2PROTO(k)] | 2214 | | ldr KBASE, [CARG2, #PC2PROTO(k)] |
2189 | | // Modified copy of ins_next which handles function header dispatch, too. | 2215 | | // Modified copy of ins_next which handles function header dispatch, too. |
@@ -2192,15 +2218,32 @@ static void build_subroutines(BuildCtx *ctx) | |||
2192 | | ldr INS, [PC], #4 | 2218 | | ldr INS, [PC], #4 |
2193 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. | 2219 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. |
2194 | | st_vmstate CARG4 | 2220 | | st_vmstate CARG4 |
2221 | | cmp OP, #BC_FUNCC+2 // Fast function? | ||
2222 | | bhs >4 | ||
2223 | |2: | ||
2195 | | cmp OP, #BC_FUNCF // Function header? | 2224 | | cmp OP, #BC_FUNCF // Function header? |
2196 | | ldr OP, [DISPATCH, OP, lsl #2] | 2225 | | ldr OP, [DISPATCH, OP, lsl #2] |
2197 | | decode_RA8 RA, INS | 2226 | | decode_RA8 RA, INS |
2198 | | lsrlo RC, INS, #16 // No: Decode operands A*8 and D. | 2227 | | lsrlo RC, INS, #16 // No: Decode operands A*8 and D. |
2199 | | subhs RC, RC, #8 | 2228 | | subhs RC, RC, #8 |
2200 | | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8 | 2229 | | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8 |
2230 | | ldrhs CARG3, [BASE, FRAME_FUNC] | ||
2201 | | bx OP | 2231 | | bx OP |
2202 | | | 2232 | | |
2203 | |3: // Rethrow error from the right C frame. | 2233 | |4: // Check frame below fast function. |
2234 | | ldr CARG1, [BASE, FRAME_PC] | ||
2235 | | ands CARG2, CARG1, #FRAME_TYPE | ||
2236 | | bne <2 // Trace stitching continuation? | ||
2237 | | // Otherwise set KBASE for Lua function below fast function. | ||
2238 | | ldr CARG3, [CARG1, #-4] | ||
2239 | | decode_RA8 CARG1, CARG3 | ||
2240 | | sub CARG2, BASE, CARG1 | ||
2241 | | ldr LFUNC:CARG3, [CARG2, #-16] | ||
2242 | | ldr CARG3, LFUNC:CARG3->field_pc | ||
2243 | | ldr KBASE, [CARG3, #PC2PROTO(k)] | ||
2244 | | b <2 | ||
2245 | | | ||
2246 | |9: // Rethrow error from the right C frame. | ||
2204 | | rsb CARG2, CARG1, #0 | 2247 | | rsb CARG2, CARG1, #0 |
2205 | | mov CARG1, L | 2248 | | mov CARG1, L |
2206 | | bl extern lj_err_throw // (lua_State *L, int errcode) | 2249 | | bl extern lj_err_throw // (lua_State *L, int errcode) |
@@ -2833,6 +2876,25 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
2833 | | ins_next | 2876 | | ins_next |
2834 | break; | 2877 | break; |
2835 | 2878 | ||
2879 | case BC_ISTYPE: | ||
2880 | | // RA = src*8, RC = -type | ||
2881 | | ldrd CARG12, [BASE, RA] | ||
2882 | | ins_next1 | ||
2883 | | cmn CARG2, RC | ||
2884 | | ins_next2 | ||
2885 | | bne ->vmeta_istype | ||
2886 | | ins_next3 | ||
2887 | break; | ||
2888 | case BC_ISNUM: | ||
2889 | | // RA = src*8, RC = -(TISNUM-1) | ||
2890 | | ldrd CARG12, [BASE, RA] | ||
2891 | | ins_next1 | ||
2892 | | checktp CARG2, LJ_TISNUM | ||
2893 | | ins_next2 | ||
2894 | | bhs ->vmeta_istype | ||
2895 | | ins_next3 | ||
2896 | break; | ||
2897 | |||
2836 | /* -- Unary ops --------------------------------------------------------- */ | 2898 | /* -- Unary ops --------------------------------------------------------- */ |
2837 | 2899 | ||
2838 | case BC_MOV: | 2900 | case BC_MOV: |
@@ -3503,6 +3565,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3503 | | bne <1 // 'no __index' flag set: done. | 3565 | | bne <1 // 'no __index' flag set: done. |
3504 | | b ->vmeta_tgetb | 3566 | | b ->vmeta_tgetb |
3505 | break; | 3567 | break; |
3568 | case BC_TGETR: | ||
3569 | | decode_RB8 RB, INS | ||
3570 | | decode_RC8 RC, INS | ||
3571 | | // RA = dst*8, RB = table*8, RC = key*8 | ||
3572 | | ldr TAB:CARG1, [BASE, RB] | ||
3573 | | ldr CARG2, [BASE, RC] | ||
3574 | | ldr CARG4, TAB:CARG1->array | ||
3575 | | ldr CARG3, TAB:CARG1->asize | ||
3576 | | add CARG4, CARG4, CARG2, lsl #3 | ||
3577 | | cmp CARG2, CARG3 // In array part? | ||
3578 | | bhs ->vmeta_tgetr | ||
3579 | | ldrd CARG12, [CARG4] | ||
3580 | |->BC_TGETR_Z: | ||
3581 | | ins_next1 | ||
3582 | | ins_next2 | ||
3583 | | strd CARG12, [BASE, RA] | ||
3584 | | ins_next3 | ||
3585 | break; | ||
3506 | 3586 | ||
3507 | case BC_TSETV: | 3587 | case BC_TSETV: |
3508 | | decode_RB8 RB, INS | 3588 | | decode_RB8 RB, INS |
@@ -3673,6 +3753,32 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3673 | | barrierback TAB:CARG1, INS, CARG3 | 3753 | | barrierback TAB:CARG1, INS, CARG3 |
3674 | | b <2 | 3754 | | b <2 |
3675 | break; | 3755 | break; |
3756 | case BC_TSETR: | ||
3757 | | decode_RB8 RB, INS | ||
3758 | | decode_RC8 RC, INS | ||
3759 | | // RA = src*8, RB = table*8, RC = key*8 | ||
3760 | | ldr TAB:CARG2, [BASE, RB] | ||
3761 | | ldr CARG3, [BASE, RC] | ||
3762 | | ldrb INS, TAB:CARG2->marked | ||
3763 | | ldr CARG1, TAB:CARG2->array | ||
3764 | | ldr CARG4, TAB:CARG2->asize | ||
3765 | | tst INS, #LJ_GC_BLACK // isblack(table) | ||
3766 | | add CARG1, CARG1, CARG3, lsl #3 | ||
3767 | | bne >7 | ||
3768 | |2: | ||
3769 | | cmp CARG3, CARG4 // In array part? | ||
3770 | | bhs ->vmeta_tsetr | ||
3771 | |->BC_TSETR_Z: | ||
3772 | | ldrd CARG34, [BASE, RA] | ||
3773 | | ins_next1 | ||
3774 | | ins_next2 | ||
3775 | | strd CARG34, [CARG1] | ||
3776 | | ins_next3 | ||
3777 | | | ||
3778 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
3779 | | barrierback TAB:CARG2, INS, RB | ||
3780 | | b <2 | ||
3781 | break; | ||
3676 | 3782 | ||
3677 | case BC_TSETM: | 3783 | case BC_TSETM: |
3678 | | // RA = base*8 (table at base-1), RC = num_const (start index) | 3784 | | // RA = base*8 (table at base-1), RC = num_const (start index) |
@@ -4270,7 +4376,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
4270 | | st_vmstate CARG2 | 4376 | | st_vmstate CARG2 |
4271 | | ldr RA, TRACE:RC->mcode | 4377 | | ldr RA, TRACE:RC->mcode |
4272 | | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | 4378 | | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] |
4273 | | str L, [DISPATCH, #DISPATCH_GL(jit_L)] | 4379 | | str L, [DISPATCH, #DISPATCH_GL(tmpbuf.L)] |
4274 | | bx RA | 4380 | | bx RA |
4275 | |.endif | 4381 | |.endif |
4276 | break; | 4382 | break; |
@@ -4388,6 +4494,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
4388 | | ldr BASE, L->base | 4494 | | ldr BASE, L->base |
4389 | | mv_vmstate CARG3, INTERP | 4495 | | mv_vmstate CARG3, INTERP |
4390 | | ldr CRET2, L->top | 4496 | | ldr CRET2, L->top |
4497 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
4391 | | lsl RC, CRET1, #3 | 4498 | | lsl RC, CRET1, #3 |
4392 | | st_vmstate CARG3 | 4499 | | st_vmstate CARG3 |
4393 | | ldr PC, [BASE, FRAME_PC] | 4500 | | ldr PC, [BASE, FRAME_PC] |