aboutsummaryrefslogtreecommitdiff
path: root/src/vm_arm.dasc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm_arm.dasc')
-rw-r--r--src/vm_arm.dasc339
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]