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.dasc331
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]