diff options
Diffstat (limited to '')
-rw-r--r-- | src/vm_arm.dasc | 481 |
1 files changed, 336 insertions, 145 deletions
diff --git a/src/vm_arm.dasc b/src/vm_arm.dasc index 7dae1a53..4f0798e0 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,16 @@ 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 | | mov CARG1, L | ||
703 | | str PC, SAVE_PC | ||
704 | | bl extern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key) | ||
705 | | // Returns TValue *. | ||
706 | | .IOS mov BASE, RC | ||
707 | | b ->BC_TSETR_Z | ||
708 | | | ||
674 | |//-- Comparison metamethods --------------------------------------------- | 709 | |//-- Comparison metamethods --------------------------------------------- |
675 | | | 710 | | |
676 | |->vmeta_comp: | 711 | |->vmeta_comp: |
@@ -735,6 +770,17 @@ static void build_subroutines(BuildCtx *ctx) | |||
735 | | b <3 | 770 | | b <3 |
736 | |.endif | 771 | |.endif |
737 | | | 772 | | |
773 | |->vmeta_istype: | ||
774 | | sub PC, PC, #4 | ||
775 | | str BASE, L->base | ||
776 | | mov CARG1, L | ||
777 | | lsr CARG2, RA, #3 | ||
778 | | mov CARG3, RC | ||
779 | | str PC, SAVE_PC | ||
780 | | bl extern lj_meta_istype // (lua_State *L, BCReg ra, BCReg tp) | ||
781 | | .IOS ldr BASE, L->base | ||
782 | | b ->cont_nop | ||
783 | | | ||
738 | |//-- Arithmetic metamethods --------------------------------------------- | 784 | |//-- Arithmetic metamethods --------------------------------------------- |
739 | | | 785 | | |
740 | |->vmeta_arith_vn: | 786 | |->vmeta_arith_vn: |
@@ -966,9 +1012,9 @@ static void build_subroutines(BuildCtx *ctx) | |||
966 | | cmp TAB:RB, #0 | 1012 | | cmp TAB:RB, #0 |
967 | | beq ->fff_restv | 1013 | | beq ->fff_restv |
968 | | ldr CARG3, TAB:RB->hmask | 1014 | | ldr CARG3, TAB:RB->hmask |
969 | | ldr CARG4, STR:RC->hash | 1015 | | ldr CARG4, STR:RC->sid |
970 | | ldr NODE:INS, TAB:RB->node | 1016 | | ldr NODE:INS, TAB:RB->node |
971 | | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask | 1017 | | and CARG3, CARG3, CARG4 // idx = str->sid & tab->hmask |
972 | | add CARG3, CARG3, CARG3, lsl #1 | 1018 | | add CARG3, CARG3, CARG3, lsl #1 |
973 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 | 1019 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 |
974 | |3: // Rearranged logic, because we expect _not_ to find the key. | 1020 | |3: // Rearranged logic, because we expect _not_ to find the key. |
@@ -1052,7 +1098,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1052 | | ffgccheck | 1098 | | ffgccheck |
1053 | | mov CARG1, L | 1099 | | mov CARG1, L |
1054 | | mov CARG2, BASE | 1100 | | mov CARG2, BASE |
1055 | | bl extern lj_str_fromnumber // (lua_State *L, cTValue *o) | 1101 | | bl extern lj_strfmt_number // (lua_State *L, cTValue *o) |
1056 | | // Returns GCstr *. | 1102 | | // Returns GCstr *. |
1057 | | ldr BASE, L->base | 1103 | | ldr BASE, L->base |
1058 | | mvn CARG2, #~LJ_TSTR | 1104 | | mvn CARG2, #~LJ_TSTR |
@@ -1065,24 +1111,18 @@ static void build_subroutines(BuildCtx *ctx) | |||
1065 | | checktab CARG2, ->fff_fallback | 1111 | | checktab CARG2, ->fff_fallback |
1066 | | strd CARG34, [BASE, NARGS8:RC] // Set missing 2nd arg to nil. | 1112 | | strd CARG34, [BASE, NARGS8:RC] // Set missing 2nd arg to nil. |
1067 | | ldr PC, [BASE, FRAME_PC] | 1113 | | ldr PC, [BASE, FRAME_PC] |
1068 | | mov CARG2, CARG1 | 1114 | | add CARG2, BASE, #8 |
1069 | | str BASE, L->base // Add frame since C call can throw. | 1115 | | sub CARG3, BASE, #8 |
1070 | | mov CARG1, L | 1116 | | bl extern lj_tab_next // (GCtab *t, cTValue *key, TValue *o) |
1071 | | str BASE, L->top // Dummy frame length is ok. | 1117 | | // Returns 1=found, 0=end, -1=error. |
1072 | | add CARG3, BASE, #8 | ||
1073 | | str PC, SAVE_PC | ||
1074 | | bl extern lj_tab_next // (lua_State *L, GCtab *t, TValue *key) | ||
1075 | | // Returns 0 at end of traversal. | ||
1076 | | .IOS ldr BASE, L->base | 1118 | | .IOS ldr BASE, L->base |
1077 | | cmp CRET1, #0 | 1119 | | cmp CRET1, #0 |
1078 | | mvneq CRET2, #~LJ_TNIL | 1120 | | mov RC, #(2+1)*8 |
1079 | | beq ->fff_restv // End of traversal: return nil. | 1121 | | bgt ->fff_res // Found key/value. |
1080 | | ldrd CARG12, [BASE, #8] // Copy key and value to results. | 1122 | | bmi ->fff_fallback // Invalid key. |
1081 | | ldrd CARG34, [BASE, #16] | 1123 | | // End of traversal: return nil. |
1082 | | mov RC, #(2+1)*8 | 1124 | | mvn CRET2, #~LJ_TNIL |
1083 | | strd CARG12, [BASE, #-8] | 1125 | | b ->fff_restv |
1084 | | strd CARG34, [BASE] | ||
1085 | | b ->fff_res | ||
1086 | | | 1126 | | |
1087 | |.ffunc_1 pairs | 1127 | |.ffunc_1 pairs |
1088 | | checktab CARG2, ->fff_fallback | 1128 | | checktab CARG2, ->fff_fallback |
@@ -1230,9 +1270,10 @@ static void build_subroutines(BuildCtx *ctx) | |||
1230 | | ldr CARG3, L:RA->base | 1270 | | ldr CARG3, L:RA->base |
1231 | | mv_vmstate CARG2, INTERP | 1271 | | mv_vmstate CARG2, INTERP |
1232 | | ldr CARG4, L:RA->top | 1272 | | ldr CARG4, L:RA->top |
1233 | | st_vmstate CARG2 | ||
1234 | | cmp CRET1, #LUA_YIELD | 1273 | | cmp CRET1, #LUA_YIELD |
1235 | | ldr BASE, L->base | 1274 | | ldr BASE, L->base |
1275 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
1276 | | st_vmstate CARG2 | ||
1236 | | bhi >8 | 1277 | | bhi >8 |
1237 | | subs RC, CARG4, CARG3 | 1278 | | subs RC, CARG4, CARG3 |
1238 | | ldr CARG1, L->maxstack | 1279 | | ldr CARG1, L->maxstack |
@@ -1500,19 +1541,6 @@ static void build_subroutines(BuildCtx *ctx) | |||
1500 | | math_extern2 atan2 | 1541 | | math_extern2 atan2 |
1501 | | math_extern2 fmod | 1542 | | math_extern2 fmod |
1502 | | | 1543 | | |
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 | 1544 | |.if HFABI |
1517 | | .ffunc math_ldexp | 1545 | | .ffunc math_ldexp |
1518 | | ldr CARG4, [BASE, #4] | 1546 | | ldr CARG4, [BASE, #4] |
@@ -1682,17 +1710,11 @@ static void build_subroutines(BuildCtx *ctx) | |||
1682 | |.endif | 1710 | |.endif |
1683 | |.endmacro | 1711 | |.endmacro |
1684 | | | 1712 | | |
1685 | | math_minmax math_min, gt, hi | 1713 | | math_minmax math_min, gt, pl |
1686 | | math_minmax math_max, lt, lo | 1714 | | math_minmax math_max, lt, le |
1687 | | | 1715 | | |
1688 | |//-- String library ----------------------------------------------------- | 1716 | |//-- String library ----------------------------------------------------- |
1689 | | | 1717 | | |
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. | 1718 | |.ffunc string_byte // Only handle the 1-arg case here. |
1697 | | ldrd CARG12, [BASE] | 1719 | | ldrd CARG12, [BASE] |
1698 | | ldr PC, [BASE, FRAME_PC] | 1720 | | ldr PC, [BASE, FRAME_PC] |
@@ -1725,6 +1747,7 @@ static void build_subroutines(BuildCtx *ctx) | |||
1725 | | mov CARG1, L | 1747 | | mov CARG1, L |
1726 | | str PC, SAVE_PC | 1748 | | str PC, SAVE_PC |
1727 | | bl extern lj_str_new // (lua_State *L, char *str, size_t l) | 1749 | | bl extern lj_str_new // (lua_State *L, char *str, size_t l) |
1750 | |->fff_resstr: | ||
1728 | | // Returns GCstr *. | 1751 | | // Returns GCstr *. |
1729 | | ldr BASE, L->base | 1752 | | ldr BASE, L->base |
1730 | | mvn CARG2, #~LJ_TSTR | 1753 | | mvn CARG2, #~LJ_TSTR |
@@ -1768,91 +1791,28 @@ static void build_subroutines(BuildCtx *ctx) | |||
1768 | | mvn CARG2, #~LJ_TSTR | 1791 | | mvn CARG2, #~LJ_TSTR |
1769 | | b ->fff_restv | 1792 | | b ->fff_restv |
1770 | | | 1793 | | |
1771 | |.ffunc string_rep // Only handle the 1-char case inline. | 1794 | |.macro ffstring_op, name |
1795 | | .ffunc string_ .. name | ||
1772 | | ffgccheck | 1796 | | ffgccheck |
1773 | | ldrd CARG12, [BASE] | 1797 | | ldr CARG3, [BASE, #4] |
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 | ||
1799 | | ldrd CARG12, [BASE] | ||
1800 | | cmp NARGS8:RC, #8 | ||
1801 | | blo ->fff_fallback | ||
1802 | | checkstr CARG2, ->fff_fallback | ||
1803 | | ldr CARG3, STR:CARG1->len | ||
1804 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | ||
1805 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | ||
1806 | | mov CARG4, CARG3 | ||
1807 | | add CARG1, STR:CARG1, #sizeof(GCstr) | ||
1808 | | cmp RB, CARG3 | ||
1809 | | blo ->fff_fallback | ||
1810 | |1: // Reverse string copy. | ||
1811 | | ldrb RB, [CARG1], #1 | ||
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 | 1798 | | cmp NARGS8:RC, #8 |
1799 | | ldr STR:CARG2, [BASE] | ||
1822 | | blo ->fff_fallback | 1800 | | blo ->fff_fallback |
1823 | | checkstr CARG2, ->fff_fallback | 1801 | | sub SBUF:CARG1, DISPATCH, #-DISPATCH_GL(tmpbuf) |
1824 | | ldr CARG3, STR:CARG1->len | 1802 | | checkstr CARG3, ->fff_fallback |
1825 | | ldr RB, [DISPATCH, #DISPATCH_GL(tmpbuf.sz)] | 1803 | | ldr CARG4, SBUF:CARG1->b |
1826 | | ldr CARG2, [DISPATCH, #DISPATCH_GL(tmpbuf.buf)] | 1804 | | str BASE, L->base |
1827 | | mov CARG4, #0 | 1805 | | str PC, SAVE_PC |
1828 | | add CARG1, STR:CARG1, #sizeof(GCstr) | 1806 | | str L, SBUF:CARG1->L |
1829 | | cmp RB, CARG3 | 1807 | | str CARG4, SBUF:CARG1->w |
1830 | | blo ->fff_fallback | 1808 | | bl extern lj_buf_putstr_ .. name |
1831 | |1: // ASCII case conversion. | 1809 | | bl extern lj_buf_tostr |
1832 | | ldrb RB, [CARG1, CARG4] | 1810 | | b ->fff_resstr |
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 | 1811 | |.endmacro |
1842 | | | 1812 | | |
1843 | |ffstring_case string_lower, 65 | 1813 | |ffstring_op reverse |
1844 | |ffstring_case string_upper, 97 | 1814 | |ffstring_op lower |
1845 | | | 1815 | |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 | | | 1816 | | |
1857 | |//-- Bit library -------------------------------------------------------- | 1817 | |//-- Bit library -------------------------------------------------------- |
1858 | | | 1818 | | |
@@ -2127,6 +2087,66 @@ static void build_subroutines(BuildCtx *ctx) | |||
2127 | | ldr INS, [PC, #-4] | 2087 | | ldr INS, [PC, #-4] |
2128 | | bx CRET1 | 2088 | | bx CRET1 |
2129 | | | 2089 | | |
2090 | |->cont_stitch: // Trace stitching. | ||
2091 | |.if JIT | ||
2092 | | // RA = resultptr, CARG4 = meta base | ||
2093 | | ldr RB, SAVE_MULTRES | ||
2094 | | ldr INS, [PC, #-4] | ||
2095 | | ldr TRACE:CARG3, [CARG4, #-24] // Save previous trace. | ||
2096 | | subs RB, RB, #8 | ||
2097 | | decode_RA8 RC, INS // Call base. | ||
2098 | | beq >2 | ||
2099 | |1: // Move results down. | ||
2100 | | ldrd CARG12, [RA] | ||
2101 | | add RA, RA, #8 | ||
2102 | | subs RB, RB, #8 | ||
2103 | | strd CARG12, [BASE, RC] | ||
2104 | | add RC, RC, #8 | ||
2105 | | bne <1 | ||
2106 | |2: | ||
2107 | | decode_RA8 RA, INS | ||
2108 | | decode_RB8 RB, INS | ||
2109 | | add RA, RA, RB | ||
2110 | |3: | ||
2111 | | cmp RA, RC | ||
2112 | | mvn CARG2, #~LJ_TNIL | ||
2113 | | bhi >9 // More results wanted? | ||
2114 | | | ||
2115 | | ldrh RA, TRACE:CARG3->traceno | ||
2116 | | ldrh RC, TRACE:CARG3->link | ||
2117 | | cmp RC, RA | ||
2118 | | beq ->cont_nop // Blacklisted. | ||
2119 | | cmp RC, #0 | ||
2120 | | bne =>BC_JLOOP // Jump to stitched trace. | ||
2121 | | | ||
2122 | | // Stitch a new trace to the previous trace. | ||
2123 | | str RA, [DISPATCH, #DISPATCH_J(exitno)] | ||
2124 | | str L, [DISPATCH, #DISPATCH_J(L)] | ||
2125 | | str BASE, L->base | ||
2126 | | sub CARG1, DISPATCH, #-GG_DISP2J | ||
2127 | | mov CARG2, PC | ||
2128 | | bl extern lj_dispatch_stitch // (jit_State *J, const BCIns *pc) | ||
2129 | | ldr BASE, L->base | ||
2130 | | b ->cont_nop | ||
2131 | | | ||
2132 | |9: // Fill up results with nil. | ||
2133 | | strd CARG12, [BASE, RC] | ||
2134 | | add RC, RC, #8 | ||
2135 | | b <3 | ||
2136 | |.endif | ||
2137 | | | ||
2138 | |->vm_profhook: // Dispatch target for profiler hook. | ||
2139 | #if LJ_HASPROFILE | ||
2140 | | mov CARG1, L | ||
2141 | | str BASE, L->base | ||
2142 | | mov CARG2, PC | ||
2143 | | bl extern lj_dispatch_profile // (lua_State *L, const BCIns *pc) | ||
2144 | | // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction. | ||
2145 | | ldr BASE, L->base | ||
2146 | | sub PC, PC, #4 | ||
2147 | | b ->cont_nop | ||
2148 | #endif | ||
2149 | | | ||
2130 | |//----------------------------------------------------------------------- | 2150 | |//----------------------------------------------------------------------- |
2131 | |//-- Trace exit handler ------------------------------------------------- | 2151 | |//-- Trace exit handler ------------------------------------------------- |
2132 | |//----------------------------------------------------------------------- | 2152 | |//----------------------------------------------------------------------- |
@@ -2151,14 +2171,14 @@ static void build_subroutines(BuildCtx *ctx) | |||
2151 | | add CARG1, CARG1, CARG2, asr #6 | 2171 | | add CARG1, CARG1, CARG2, asr #6 |
2152 | | ldr CARG2, [lr, #4] // Load exit stub group offset. | 2172 | | ldr CARG2, [lr, #4] // Load exit stub group offset. |
2153 | | sub CARG1, CARG1, lr | 2173 | | sub CARG1, CARG1, lr |
2154 | | ldr L, [DISPATCH, #DISPATCH_GL(jit_L)] | 2174 | | ldr L, [DISPATCH, #DISPATCH_GL(cur_L)] |
2155 | | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. | 2175 | | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. |
2156 | | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | 2176 | | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] |
2157 | | str CARG1, [DISPATCH, #DISPATCH_J(exitno)] | 2177 | | str CARG1, [DISPATCH, #DISPATCH_J(exitno)] |
2158 | | mov CARG4, #0 | 2178 | | mov CARG4, #0 |
2159 | | str L, [DISPATCH, #DISPATCH_J(L)] | ||
2160 | | str BASE, L->base | 2179 | | str BASE, L->base |
2161 | | str CARG4, [DISPATCH, #DISPATCH_GL(jit_L)] | 2180 | | str L, [DISPATCH, #DISPATCH_J(L)] |
2181 | | str CARG4, [DISPATCH, #DISPATCH_GL(jit_base)] | ||
2162 | | sub CARG1, DISPATCH, #-GG_DISP2J | 2182 | | sub CARG1, DISPATCH, #-GG_DISP2J |
2163 | | mov CARG2, sp | 2183 | | mov CARG2, sp |
2164 | | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) | 2184 | | bl extern lj_trace_exit // (jit_State *J, ExitState *ex) |
@@ -2176,14 +2196,15 @@ static void build_subroutines(BuildCtx *ctx) | |||
2176 | |.if JIT | 2196 | |.if JIT |
2177 | | ldr L, SAVE_L | 2197 | | ldr L, SAVE_L |
2178 | |1: | 2198 | |1: |
2179 | | cmp CARG1, #0 | 2199 | | cmn CARG1, #LUA_ERRERR |
2180 | | blt >3 // Check for error from exit. | 2200 | | bhs >9 // Check for error from exit. |
2181 | | lsl RC, CARG1, #3 | 2201 | | lsl RC, CARG1, #3 |
2182 | | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] | 2202 | | ldr LFUNC:CARG2, [BASE, FRAME_FUNC] |
2183 | | str RC, SAVE_MULTRES | 2203 | | str RC, SAVE_MULTRES |
2184 | | mov CARG3, #0 | 2204 | | mov CARG3, #0 |
2205 | | str BASE, L->base | ||
2185 | | ldr CARG2, LFUNC:CARG2->field_pc | 2206 | | ldr CARG2, LFUNC:CARG2->field_pc |
2186 | | str CARG3, [DISPATCH, #DISPATCH_GL(jit_L)] | 2207 | | str CARG3, [DISPATCH, #DISPATCH_GL(jit_base)] |
2187 | | mv_vmstate CARG4, INTERP | 2208 | | mv_vmstate CARG4, INTERP |
2188 | | ldr KBASE, [CARG2, #PC2PROTO(k)] | 2209 | | ldr KBASE, [CARG2, #PC2PROTO(k)] |
2189 | | // Modified copy of ins_next which handles function header dispatch, too. | 2210 | | // Modified copy of ins_next which handles function header dispatch, too. |
@@ -2192,17 +2213,48 @@ static void build_subroutines(BuildCtx *ctx) | |||
2192 | | ldr INS, [PC], #4 | 2213 | | ldr INS, [PC], #4 |
2193 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. | 2214 | | lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8. |
2194 | | st_vmstate CARG4 | 2215 | | st_vmstate CARG4 |
2216 | | cmn CARG1, #17 // Static dispatch? | ||
2217 | | beq >5 | ||
2218 | | cmp OP, #BC_FUNCC+2 // Fast function? | ||
2219 | | bhs >4 | ||
2220 | |2: | ||
2195 | | cmp OP, #BC_FUNCF // Function header? | 2221 | | cmp OP, #BC_FUNCF // Function header? |
2196 | | ldr OP, [DISPATCH, OP, lsl #2] | 2222 | | ldr OP, [DISPATCH, OP, lsl #2] |
2197 | | decode_RA8 RA, INS | 2223 | | decode_RA8 RA, INS |
2198 | | lsrlo RC, INS, #16 // No: Decode operands A*8 and D. | 2224 | | lsrlo RC, INS, #16 // No: Decode operands A*8 and D. |
2199 | | subhs RC, RC, #8 | 2225 | | subhs RC, RC, #8 |
2200 | | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8 | 2226 | | addhs RA, RA, BASE // Yes: RA = BASE+framesize*8, RC = nargs*8 |
2227 | | ldrhs CARG3, [BASE, FRAME_FUNC] | ||
2201 | | bx OP | 2228 | | bx OP |
2202 | | | 2229 | | |
2203 | |3: // Rethrow error from the right C frame. | 2230 | |4: // Check frame below fast function. |
2231 | | ldr CARG1, [BASE, FRAME_PC] | ||
2232 | | ands CARG2, CARG1, #FRAME_TYPE | ||
2233 | | bne <2 // Trace stitching continuation? | ||
2234 | | // Otherwise set KBASE for Lua function below fast function. | ||
2235 | | ldr CARG3, [CARG1, #-4] | ||
2236 | | decode_RA8 CARG1, CARG3 | ||
2237 | | sub CARG2, BASE, CARG1 | ||
2238 | | ldr LFUNC:CARG3, [CARG2, #-16] | ||
2239 | | ldr CARG3, LFUNC:CARG3->field_pc | ||
2240 | | ldr KBASE, [CARG3, #PC2PROTO(k)] | ||
2241 | | b <2 | ||
2242 | | | ||
2243 | |5: // Dispatch to static entry of original ins replaced by BC_JLOOP. | ||
2244 | | ldr CARG1, [DISPATCH, #DISPATCH_J(trace)] | ||
2245 | | decode_RD RC, INS | ||
2246 | | ldr TRACE:CARG1, [CARG1, RC, lsl #2] | ||
2247 | | ldr INS, TRACE:CARG1->startins | ||
2248 | | decode_OP OP, INS | ||
2249 | | decode_RA8 RA, INS | ||
2250 | | add OP, DISPATCH, OP, lsl #2 | ||
2251 | | decode_RD RC, INS | ||
2252 | | ldr pc, [OP, #GG_DISP2STATIC] | ||
2253 | | | ||
2254 | |9: // Rethrow error from the right C frame. | ||
2255 | | rsb CARG2, CARG1, #0 | ||
2204 | | mov CARG1, L | 2256 | | mov CARG1, L |
2205 | | bl extern lj_err_run // (lua_State *L) | 2257 | | bl extern lj_err_trace // (lua_State *L, int errcode) |
2206 | |.endif | 2258 | |.endif |
2207 | | | 2259 | | |
2208 | |//----------------------------------------------------------------------- | 2260 | |//----------------------------------------------------------------------- |
@@ -2385,6 +2437,64 @@ static void build_subroutines(BuildCtx *ctx) | |||
2385 | |//-- Miscellaneous functions -------------------------------------------- | 2437 | |//-- Miscellaneous functions -------------------------------------------- |
2386 | |//----------------------------------------------------------------------- | 2438 | |//----------------------------------------------------------------------- |
2387 | | | 2439 | | |
2440 | |.define NEXT_TAB, TAB:CARG1 | ||
2441 | |.define NEXT_RES, CARG1 | ||
2442 | |.define NEXT_IDX, CARG2 | ||
2443 | |.define NEXT_TMP0, CARG3 | ||
2444 | |.define NEXT_TMP1, CARG4 | ||
2445 | |.define NEXT_LIM, r12 | ||
2446 | |.define NEXT_RES_PTR, sp | ||
2447 | |.define NEXT_RES_VAL, [sp] | ||
2448 | |.define NEXT_RES_KEY_I, [sp, #8] | ||
2449 | |.define NEXT_RES_KEY_IT, [sp, #12] | ||
2450 | | | ||
2451 | |// TValue *lj_vm_next(GCtab *t, uint32_t idx) | ||
2452 | |// Next idx returned in CRET2. | ||
2453 | |->vm_next: | ||
2454 | |.if JIT | ||
2455 | | ldr NEXT_TMP0, NEXT_TAB->array | ||
2456 | | ldr NEXT_LIM, NEXT_TAB->asize | ||
2457 | | add NEXT_TMP0, NEXT_TMP0, NEXT_IDX, lsl #3 | ||
2458 | |1: // Traverse array part. | ||
2459 | | subs NEXT_TMP1, NEXT_IDX, NEXT_LIM | ||
2460 | | bhs >5 | ||
2461 | | ldr NEXT_TMP1, [NEXT_TMP0, #4] | ||
2462 | | str NEXT_IDX, NEXT_RES_KEY_I | ||
2463 | | add NEXT_TMP0, NEXT_TMP0, #8 | ||
2464 | | add NEXT_IDX, NEXT_IDX, #1 | ||
2465 | | checktp NEXT_TMP1, LJ_TNIL | ||
2466 | | beq <1 // Skip holes in array part. | ||
2467 | | ldr NEXT_TMP0, [NEXT_TMP0, #-8] | ||
2468 | | mov NEXT_RES, NEXT_RES_PTR | ||
2469 | | strd NEXT_TMP0, NEXT_RES_VAL // Stores NEXT_TMP1, too. | ||
2470 | | mvn NEXT_TMP0, #~LJ_TISNUM | ||
2471 | | str NEXT_TMP0, NEXT_RES_KEY_IT | ||
2472 | | bx lr | ||
2473 | | | ||
2474 | |5: // Traverse hash part. | ||
2475 | | ldr NEXT_TMP0, NEXT_TAB->hmask | ||
2476 | | ldr NODE:NEXT_RES, NEXT_TAB->node | ||
2477 | | add NEXT_TMP1, NEXT_TMP1, NEXT_TMP1, lsl #1 | ||
2478 | | add NEXT_LIM, NEXT_LIM, NEXT_TMP0 | ||
2479 | | add NODE:NEXT_RES, NODE:NEXT_RES, NEXT_TMP1, lsl #3 | ||
2480 | |6: | ||
2481 | | cmp NEXT_IDX, NEXT_LIM | ||
2482 | | bhi >9 | ||
2483 | | ldr NEXT_TMP1, NODE:NEXT_RES->val.it | ||
2484 | | checktp NEXT_TMP1, LJ_TNIL | ||
2485 | | add NEXT_IDX, NEXT_IDX, #1 | ||
2486 | | bxne lr | ||
2487 | | // Skip holes in hash part. | ||
2488 | | add NEXT_RES, NEXT_RES, #sizeof(Node) | ||
2489 | | b <6 | ||
2490 | | | ||
2491 | |9: // End of iteration. Set the key to nil (not the value). | ||
2492 | | mvn NEXT_TMP0, #0 | ||
2493 | | mov NEXT_RES, NEXT_RES_PTR | ||
2494 | | str NEXT_TMP0, NEXT_RES_KEY_IT | ||
2495 | | bx lr | ||
2496 | |.endif | ||
2497 | | | ||
2388 | |//----------------------------------------------------------------------- | 2498 | |//----------------------------------------------------------------------- |
2389 | |//-- FFI helper functions ----------------------------------------------- | 2499 | |//-- FFI helper functions ----------------------------------------------- |
2390 | |//----------------------------------------------------------------------- | 2500 | |//----------------------------------------------------------------------- |
@@ -2832,6 +2942,25 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
2832 | | ins_next | 2942 | | ins_next |
2833 | break; | 2943 | break; |
2834 | 2944 | ||
2945 | case BC_ISTYPE: | ||
2946 | | // RA = src*8, RC = -type | ||
2947 | | ldrd CARG12, [BASE, RA] | ||
2948 | | ins_next1 | ||
2949 | | cmn CARG2, RC | ||
2950 | | ins_next2 | ||
2951 | | bne ->vmeta_istype | ||
2952 | | ins_next3 | ||
2953 | break; | ||
2954 | case BC_ISNUM: | ||
2955 | | // RA = src*8, RC = -(TISNUM-1) | ||
2956 | | ldrd CARG12, [BASE, RA] | ||
2957 | | ins_next1 | ||
2958 | | checktp CARG2, LJ_TISNUM | ||
2959 | | ins_next2 | ||
2960 | | bhs ->vmeta_istype | ||
2961 | | ins_next3 | ||
2962 | break; | ||
2963 | |||
2835 | /* -- Unary ops --------------------------------------------------------- */ | 2964 | /* -- Unary ops --------------------------------------------------------- */ |
2836 | 2965 | ||
2837 | case BC_MOV: | 2966 | case BC_MOV: |
@@ -3436,10 +3565,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3436 | |->BC_TGETS_Z: | 3565 | |->BC_TGETS_Z: |
3437 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 | 3566 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 |
3438 | | ldr CARG3, TAB:CARG1->hmask | 3567 | | ldr CARG3, TAB:CARG1->hmask |
3439 | | ldr CARG4, STR:RC->hash | 3568 | | ldr CARG4, STR:RC->sid |
3440 | | ldr NODE:INS, TAB:CARG1->node | 3569 | | ldr NODE:INS, TAB:CARG1->node |
3441 | | mov TAB:RB, TAB:CARG1 | 3570 | | mov TAB:RB, TAB:CARG1 |
3442 | | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask | 3571 | | and CARG3, CARG3, CARG4 // idx = str->sid & tab->hmask |
3443 | | add CARG3, CARG3, CARG3, lsl #1 | 3572 | | add CARG3, CARG3, CARG3, lsl #1 |
3444 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 | 3573 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 |
3445 | |1: | 3574 | |1: |
@@ -3502,6 +3631,24 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3502 | | bne <1 // 'no __index' flag set: done. | 3631 | | bne <1 // 'no __index' flag set: done. |
3503 | | b ->vmeta_tgetb | 3632 | | b ->vmeta_tgetb |
3504 | break; | 3633 | break; |
3634 | case BC_TGETR: | ||
3635 | | decode_RB8 RB, INS | ||
3636 | | decode_RC8 RC, INS | ||
3637 | | // RA = dst*8, RB = table*8, RC = key*8 | ||
3638 | | ldr TAB:CARG1, [BASE, RB] | ||
3639 | | ldr CARG2, [BASE, RC] | ||
3640 | | ldr CARG4, TAB:CARG1->array | ||
3641 | | ldr CARG3, TAB:CARG1->asize | ||
3642 | | add CARG4, CARG4, CARG2, lsl #3 | ||
3643 | | cmp CARG2, CARG3 // In array part? | ||
3644 | | bhs ->vmeta_tgetr | ||
3645 | | ldrd CARG12, [CARG4] | ||
3646 | |->BC_TGETR_Z: | ||
3647 | | ins_next1 | ||
3648 | | ins_next2 | ||
3649 | | strd CARG12, [BASE, RA] | ||
3650 | | ins_next3 | ||
3651 | break; | ||
3505 | 3652 | ||
3506 | case BC_TSETV: | 3653 | case BC_TSETV: |
3507 | | decode_RB8 RB, INS | 3654 | | decode_RB8 RB, INS |
@@ -3565,10 +3712,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3565 | |->BC_TSETS_Z: | 3712 | |->BC_TSETS_Z: |
3566 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 | 3713 | | // (TAB:RB =) TAB:CARG1 = GCtab *, STR:RC = GCstr *, RA = dst*8 |
3567 | | ldr CARG3, TAB:CARG1->hmask | 3714 | | ldr CARG3, TAB:CARG1->hmask |
3568 | | ldr CARG4, STR:RC->hash | 3715 | | ldr CARG4, STR:RC->sid |
3569 | | ldr NODE:INS, TAB:CARG1->node | 3716 | | ldr NODE:INS, TAB:CARG1->node |
3570 | | mov TAB:RB, TAB:CARG1 | 3717 | | mov TAB:RB, TAB:CARG1 |
3571 | | and CARG3, CARG3, CARG4 // idx = str->hash & tab->hmask | 3718 | | and CARG3, CARG3, CARG4 // idx = str->sid & tab->hmask |
3572 | | add CARG3, CARG3, CARG3, lsl #1 | 3719 | | add CARG3, CARG3, CARG3, lsl #1 |
3573 | | mov CARG4, #0 | 3720 | | mov CARG4, #0 |
3574 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 | 3721 | | add NODE:INS, NODE:INS, CARG3, lsl #3 // node = tab->node + idx*3*8 |
@@ -3672,6 +3819,32 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3672 | | barrierback TAB:CARG1, INS, CARG3 | 3819 | | barrierback TAB:CARG1, INS, CARG3 |
3673 | | b <2 | 3820 | | b <2 |
3674 | break; | 3821 | break; |
3822 | case BC_TSETR: | ||
3823 | | decode_RB8 RB, INS | ||
3824 | | decode_RC8 RC, INS | ||
3825 | | // RA = src*8, RB = table*8, RC = key*8 | ||
3826 | | ldr TAB:CARG2, [BASE, RB] | ||
3827 | | ldr CARG3, [BASE, RC] | ||
3828 | | ldrb INS, TAB:CARG2->marked | ||
3829 | | ldr CARG1, TAB:CARG2->array | ||
3830 | | ldr CARG4, TAB:CARG2->asize | ||
3831 | | tst INS, #LJ_GC_BLACK // isblack(table) | ||
3832 | | add CARG1, CARG1, CARG3, lsl #3 | ||
3833 | | bne >7 | ||
3834 | |2: | ||
3835 | | cmp CARG3, CARG4 // In array part? | ||
3836 | | bhs ->vmeta_tsetr | ||
3837 | |->BC_TSETR_Z: | ||
3838 | | ldrd CARG34, [BASE, RA] | ||
3839 | | ins_next1 | ||
3840 | | ins_next2 | ||
3841 | | strd CARG34, [CARG1] | ||
3842 | | ins_next3 | ||
3843 | | | ||
3844 | |7: // Possible table write barrier for the value. Skip valiswhite check. | ||
3845 | | barrierback TAB:CARG2, INS, RB | ||
3846 | | b <2 | ||
3847 | break; | ||
3675 | 3848 | ||
3676 | case BC_TSETM: | 3849 | case BC_TSETM: |
3677 | | // RA = base*8 (table at base-1), RC = num_const (start index) | 3850 | | // RA = base*8 (table at base-1), RC = num_const (start index) |
@@ -3812,10 +3985,11 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3812 | break; | 3985 | break; |
3813 | 3986 | ||
3814 | case BC_ITERN: | 3987 | case BC_ITERN: |
3815 | | // RA = base*8, (RB = nresults+1, RC = nargs+1 (2+1)) | ||
3816 | |.if JIT | 3988 | |.if JIT |
3817 | | // NYI: add hotloop, record BC_ITERN. | 3989 | | hotloop |
3818 | |.endif | 3990 | |.endif |
3991 | |->vm_IITERN: | ||
3992 | | // RA = base*8, (RB = nresults+1, RC = nargs+1 (2+1)) | ||
3819 | | add RA, BASE, RA | 3993 | | add RA, BASE, RA |
3820 | | ldr TAB:RB, [RA, #-16] | 3994 | | ldr TAB:RB, [RA, #-16] |
3821 | | ldr CARG1, [RA, #-8] // Get index from control var. | 3995 | | ldr CARG1, [RA, #-8] // Get index from control var. |
@@ -3881,7 +4055,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3881 | | ins_next1 | 4055 | | ins_next1 |
3882 | | ins_next2 | 4056 | | ins_next2 |
3883 | | mov CARG1, #0 | 4057 | | mov CARG1, #0 |
3884 | | mvn CARG2, #0x00018000 | 4058 | | mvn CARG2, #~LJ_KEYINDEX |
3885 | | strd CARG1, [RA, #-8] // Initialize control var. | 4059 | | strd CARG1, [RA, #-8] // Initialize control var. |
3886 | |1: | 4060 | |1: |
3887 | | ins_next3 | 4061 | | ins_next3 |
@@ -3890,9 +4064,25 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
3890 | | mov OP, #BC_ITERC | 4064 | | mov OP, #BC_ITERC |
3891 | | strb CARG1, [PC, #-4] | 4065 | | strb CARG1, [PC, #-4] |
3892 | | sub PC, RC, #0x20000 | 4066 | | sub PC, RC, #0x20000 |
4067 | |.if JIT | ||
4068 | | ldrb CARG1, [PC] | ||
4069 | | cmp CARG1, #BC_ITERN | ||
4070 | | bne >6 | ||
4071 | |.endif | ||
3893 | | strb OP, [PC] // Subsumes ins_next1. | 4072 | | strb OP, [PC] // Subsumes ins_next1. |
3894 | | ins_next2 | 4073 | | ins_next2 |
3895 | | b <1 | 4074 | | b <1 |
4075 | |.if JIT | ||
4076 | |6: // Unpatch JLOOP. | ||
4077 | | ldr CARG1, [DISPATCH, #DISPATCH_J(trace)] | ||
4078 | | ldrh CARG2, [PC, #2] | ||
4079 | | ldr TRACE:CARG1, [CARG1, CARG2, lsl #2] | ||
4080 | | // Subsumes ins_next1 and ins_next2. | ||
4081 | | ldr INS, TRACE:CARG1->startins | ||
4082 | | bfi INS, OP, #0, #8 | ||
4083 | | str INS, [PC], #4 | ||
4084 | | b <1 | ||
4085 | |.endif | ||
3896 | break; | 4086 | break; |
3897 | 4087 | ||
3898 | case BC_VARG: | 4088 | case BC_VARG: |
@@ -4269,7 +4459,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
4269 | | st_vmstate CARG2 | 4459 | | st_vmstate CARG2 |
4270 | | ldr RA, TRACE:RC->mcode | 4460 | | ldr RA, TRACE:RC->mcode |
4271 | | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | 4461 | | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] |
4272 | | str L, [DISPATCH, #DISPATCH_GL(jit_L)] | 4462 | | str L, [DISPATCH, #DISPATCH_GL(tmpbuf.L)] |
4273 | | bx RA | 4463 | | bx RA |
4274 | |.endif | 4464 | |.endif |
4275 | break; | 4465 | break; |
@@ -4387,6 +4577,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop) | |||
4387 | | ldr BASE, L->base | 4577 | | ldr BASE, L->base |
4388 | | mv_vmstate CARG3, INTERP | 4578 | | mv_vmstate CARG3, INTERP |
4389 | | ldr CRET2, L->top | 4579 | | ldr CRET2, L->top |
4580 | | str L, [DISPATCH, #DISPATCH_GL(cur_L)] | ||
4390 | | lsl RC, CRET1, #3 | 4581 | | lsl RC, CRET1, #3 |
4391 | | st_vmstate CARG3 | 4582 | | st_vmstate CARG3 |
4392 | | ldr PC, [BASE, FRAME_PC] | 4583 | | ldr PC, [BASE, FRAME_PC] |