aboutsummaryrefslogtreecommitdiff
path: root/src/vm_mips.dasc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/vm_mips.dasc310
1 files changed, 176 insertions, 134 deletions
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index a81dbeeb..e7d01dc4 100644
--- a/src/vm_mips.dasc
+++ b/src/vm_mips.dasc
@@ -138,6 +138,7 @@
138|.type NODE, Node 138|.type NODE, Node
139|.type NARGS8, int 139|.type NARGS8, int
140|.type TRACE, GCtrace 140|.type TRACE, GCtrace
141|.type SBUF, SBuf
141| 142|
142|//----------------------------------------------------------------------- 143|//-----------------------------------------------------------------------
143| 144|
@@ -486,12 +487,13 @@ static void build_subroutines(BuildCtx *ctx)
486 | addiu DISPATCH, DISPATCH, GG_G2DISP 487 | addiu DISPATCH, DISPATCH, GG_G2DISP
487 | sw r0, SAVE_NRES 488 | sw r0, SAVE_NRES
488 | sw r0, SAVE_ERRF 489 | sw r0, SAVE_ERRF
489 | sw TMP0, L->cframe 490 | sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
490 | sw r0, SAVE_CFRAME 491 | sw r0, SAVE_CFRAME
491 | beqz TMP1, >3 492 | beqz TMP1, >3
492 |. sw CARG1, SAVE_PC // Any value outside of bytecode is ok. 493 |. sw TMP0, L->cframe
493 | 494 |
494 | // Resume after yield (like a return). 495 | // Resume after yield (like a return).
496 | sw L, DISPATCH_GL(cur_L)(DISPATCH)
495 | move RA, BASE 497 | move RA, BASE
496 | lw BASE, L->base 498 | lw BASE, L->base
497 | lw TMP1, L->top 499 | lw TMP1, L->top
@@ -525,17 +527,18 @@ static void build_subroutines(BuildCtx *ctx)
525 | 527 |
526 |1: // Entry point for vm_pcall above (PC = ftype). 528 |1: // Entry point for vm_pcall above (PC = ftype).
527 | lw TMP1, L:CARG1->cframe 529 | lw TMP1, L:CARG1->cframe
528 | sw CARG3, SAVE_NRES
529 | move L, CARG1 530 | move L, CARG1
530 | sw CARG1, SAVE_L 531 | sw CARG3, SAVE_NRES
531 | move BASE, CARG2
532 | sw sp, L->cframe // Add our C frame to cframe chain.
533 | lw DISPATCH, L->glref // Setup pointer to dispatch table. 532 | lw DISPATCH, L->glref // Setup pointer to dispatch table.
533 | sw CARG1, SAVE_L
534 | move BASE, CARG2
535 | addiu DISPATCH, DISPATCH, GG_G2DISP
534 | sw CARG1, SAVE_PC // Any value outside of bytecode is ok. 536 | sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
535 | sw TMP1, SAVE_CFRAME 537 | sw TMP1, SAVE_CFRAME
536 | addiu DISPATCH, DISPATCH, GG_G2DISP 538 | sw sp, L->cframe // Add our C frame to cframe chain.
537 | 539 |
538 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). 540 |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
541 | sw L, DISPATCH_GL(cur_L)(DISPATCH)
539 | lw TMP2, L->base // TMP2 = old base (used in vmeta_call). 542 | lw TMP2, L->base // TMP2 = old base (used in vmeta_call).
540 | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). 543 | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
541 | lw TMP1, L->top 544 | lw TMP1, L->top
@@ -566,20 +569,21 @@ static void build_subroutines(BuildCtx *ctx)
566 | lw TMP0, L:CARG1->stack 569 | lw TMP0, L:CARG1->stack
567 | sw CARG1, SAVE_L 570 | sw CARG1, SAVE_L
568 | lw TMP1, L->top 571 | lw TMP1, L->top
572 | lw DISPATCH, L->glref // Setup pointer to dispatch table.
569 | sw CARG1, SAVE_PC // Any value outside of bytecode is ok. 573 | sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
570 | subu TMP0, TMP0, TMP1 // Compute -savestack(L, L->top). 574 | subu TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
571 | lw TMP1, L->cframe 575 | lw TMP1, L->cframe
572 | sw sp, L->cframe // Add our C frame to cframe chain. 576 | addiu DISPATCH, DISPATCH, GG_G2DISP
573 | sw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame. 577 | sw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
574 | sw r0, SAVE_ERRF // No error function. 578 | sw r0, SAVE_ERRF // No error function.
575 | move CFUNCADDR, CARG4 579 | sw TMP1, SAVE_CFRAME
580 | sw sp, L->cframe // Add our C frame to cframe chain.
581 | sw L, DISPATCH_GL(cur_L)(DISPATCH)
576 | jalr CARG4 // (lua_State *L, lua_CFunction func, void *ud) 582 | jalr CARG4 // (lua_State *L, lua_CFunction func, void *ud)
577 |. sw TMP1, SAVE_CFRAME 583 |. move CFUNCADDR, CARG4
578 | move BASE, CRET1 584 | move BASE, CRET1
579 | lw DISPATCH, L->glref // Setup pointer to dispatch table.
580 | li PC, FRAME_CP
581 | bnez CRET1, <3 // Else continue with the call. 585 | bnez CRET1, <3 // Else continue with the call.
582 |. addiu DISPATCH, DISPATCH, GG_G2DISP 586 |. li PC, FRAME_CP
583 | b ->vm_leave_cp // No base? Just remove C frame. 587 | b ->vm_leave_cp // No base? Just remove C frame.
584 |. nop 588 |. nop
585 | 589 |
@@ -688,6 +692,16 @@ static void build_subroutines(BuildCtx *ctx)
688 | b ->vm_call_dispatch_f 692 | b ->vm_call_dispatch_f
689 |. li NARGS8:RC, 16 // 2 args for func(t, k). 693 |. li NARGS8:RC, 16 // 2 args for func(t, k).
690 | 694 |
695 |->vmeta_tgetr:
696 | load_got lj_tab_getinth
697 | call_intern lj_tab_getinth // (GCtab *t, int32_t key)
698 |. nop
699 | // Returns cTValue * or NULL.
700 | beqz CRET1, >1
701 |. nop
702 | b ->BC_TGETR_Z
703 |. ldc1 f0, 0(CRET1)
704 |
691 |//----------------------------------------------------------------------- 705 |//-----------------------------------------------------------------------
692 | 706 |
693 |->vmeta_tsets1: 707 |->vmeta_tsets1:
@@ -740,6 +754,16 @@ static void build_subroutines(BuildCtx *ctx)
740 | b ->vm_call_dispatch_f 754 | b ->vm_call_dispatch_f
741 |. li NARGS8:RC, 24 // 3 args for func(t, k, v) 755 |. li NARGS8:RC, 24 // 3 args for func(t, k, v)
742 | 756 |
757 |->vmeta_tsetr:
758 | load_got lj_tab_setinth
759 | sw BASE, L->base
760 | sw PC, SAVE_PC
761 | call_intern lj_tab_setinth // (lua_State *L, GCtab *t, int32_t key)
762 |. move CARG1, L
763 | // Returns TValue *.
764 | b ->BC_TSETR_Z
765 |. nop
766 |
743 |//-- Comparison metamethods --------------------------------------------- 767 |//-- Comparison metamethods ---------------------------------------------
744 | 768 |
745 |->vmeta_comp: 769 |->vmeta_comp:
@@ -813,6 +837,18 @@ static void build_subroutines(BuildCtx *ctx)
813 |. nop 837 |. nop
814 |.endif 838 |.endif
815 | 839 |
840 |->vmeta_istype:
841 | load_got lj_meta_istype
842 | addiu PC, PC, -4
843 | sw BASE, L->base
844 | srl CARG2, RA, 3
845 | srl CARG3, RD, 3
846 | sw PC, SAVE_PC
847 | call_intern lj_meta_istype // (lua_State *L, BCReg ra, BCReg tp)
848 |. move CARG1, L
849 | b ->cont_nop
850 |. nop
851 |
816 |//-- Arithmetic metamethods --------------------------------------------- 852 |//-- Arithmetic metamethods ---------------------------------------------
817 | 853 |
818 |->vmeta_unm: 854 |->vmeta_unm:
@@ -1119,9 +1155,9 @@ static void build_subroutines(BuildCtx *ctx)
1119 |. sw BASE, L->base // Add frame since C call can throw. 1155 |. sw BASE, L->base // Add frame since C call can throw.
1120 | ffgccheck 1156 | ffgccheck
1121 |. sw PC, SAVE_PC // Redundant (but a defined value). 1157 |. sw PC, SAVE_PC // Redundant (but a defined value).
1122 | load_got lj_str_fromnum 1158 | load_got lj_strfmt_num
1123 | move CARG1, L 1159 | move CARG1, L
1124 | call_intern lj_str_fromnum // (lua_State *L, lua_Number *np) 1160 | call_intern lj_strfmt_num // (lua_State *L, lua_Number *np)
1125 |. move CARG2, BASE 1161 |. move CARG2, BASE
1126 | // Returns GCstr *. 1162 | // Returns GCstr *.
1127 | li CARG3, LJ_TSTR 1163 | li CARG3, LJ_TSTR
@@ -1188,7 +1224,7 @@ static void build_subroutines(BuildCtx *ctx)
1188 | mtc1 TMP0, FARG1 1224 | mtc1 TMP0, FARG1
1189 | beqz AT, ->fff_fallback 1225 | beqz AT, ->fff_fallback
1190 |. lw PC, FRAME_PC(BASE) 1226 |. lw PC, FRAME_PC(BASE)
1191 | cvt.w.d FRET1, FARG2 1227 | trunc.w.d FRET1, FARG2
1192 | cvt.d.w FARG1, FARG1 1228 | cvt.d.w FARG1, FARG1
1193 | lw TMP0, TAB:CARG1->asize 1229 | lw TMP0, TAB:CARG1->asize
1194 | lw TMP1, TAB:CARG1->array 1230 | lw TMP1, TAB:CARG1->array
@@ -1331,6 +1367,7 @@ static void build_subroutines(BuildCtx *ctx)
1331 | lw TMP3, L:RA->top 1367 | lw TMP3, L:RA->top
1332 | li_vmstate INTERP 1368 | li_vmstate INTERP
1333 | lw BASE, L->base 1369 | lw BASE, L->base
1370 | sw L, DISPATCH_GL(cur_L)(DISPATCH)
1334 | st_vmstate 1371 | st_vmstate
1335 | beqz AT, >8 1372 | beqz AT, >8
1336 |. subu RD, TMP3, TMP2 1373 |. subu RD, TMP3, TMP2
@@ -1521,14 +1558,8 @@ static void build_subroutines(BuildCtx *ctx)
1521 | b ->fff_resn 1558 | b ->fff_resn
1522 |. nop 1559 |. nop
1523 | 1560 |
1524 |->ff_math_deg:
1525 |.ffunc_n math_rad
1526 |. ldc1 FARG2, CFUNC:RB->upvalue[0]
1527 | b ->fff_resn
1528 |. mul.d FRET1, FARG1, FARG2
1529 |
1530 |.ffunc_nn math_ldexp 1561 |.ffunc_nn math_ldexp
1531 | cvt.w.d FARG2, FARG2 1562 | trunc.w.d FARG2, FARG2
1532 | load_got ldexp 1563 | load_got ldexp
1533 | mfc1 CARG3, FARG2 1564 | mfc1 CARG3, FARG2
1534 | call_extern 1565 | call_extern
@@ -1592,13 +1623,6 @@ static void build_subroutines(BuildCtx *ctx)
1592 | 1623 |
1593 |//-- String library ----------------------------------------------------- 1624 |//-- String library -----------------------------------------------------
1594 | 1625 |
1595 |.ffunc_1 string_len
1596 | li AT, LJ_TSTR
1597 | bne CARG3, AT, ->fff_fallback
1598 |. nop
1599 | b ->fff_resi
1600 |. lw CRET1, STR:CARG1->len
1601 |
1602 |.ffunc string_byte // Only handle the 1-arg case here. 1626 |.ffunc string_byte // Only handle the 1-arg case here.
1603 | lw CARG3, HI(BASE) 1627 | lw CARG3, HI(BASE)
1604 | lw STR:CARG1, LO(BASE) 1628 | lw STR:CARG1, LO(BASE)
@@ -1628,7 +1652,7 @@ static void build_subroutines(BuildCtx *ctx)
1628 |. sltiu AT, CARG3, LJ_TISNUM 1652 |. sltiu AT, CARG3, LJ_TISNUM
1629 | beqz AT, ->fff_fallback 1653 | beqz AT, ->fff_fallback
1630 |. li CARG3, 1 1654 |. li CARG3, 1
1631 | cvt.w.d FARG1, FARG1 1655 | trunc.w.d FARG1, FARG1
1632 | addiu CARG2, sp, ARG5_OFS 1656 | addiu CARG2, sp, ARG5_OFS
1633 | sltiu AT, TMP0, 256 1657 | sltiu AT, TMP0, 256
1634 | mfc1 TMP0, FARG1 1658 | mfc1 TMP0, FARG1
@@ -1642,6 +1666,7 @@ static void build_subroutines(BuildCtx *ctx)
1642 |. move CARG1, L 1666 |. move CARG1, L
1643 | // Returns GCstr *. 1667 | // Returns GCstr *.
1644 | lw BASE, L->base 1668 | lw BASE, L->base
1669 |->fff_resstr:
1645 | move CARG1, CRET1 1670 | move CARG1, CRET1
1646 | b ->fff_restv 1671 | b ->fff_restv
1647 |. li CARG3, LJ_TSTR 1672 |. li CARG3, LJ_TSTR
@@ -1658,7 +1683,7 @@ static void build_subroutines(BuildCtx *ctx)
1658 | ldc1 f2, 8(BASE) 1683 | ldc1 f2, 8(BASE)
1659 | beqz AT, >1 1684 | beqz AT, >1
1660 |. li CARG4, -1 1685 |. li CARG4, -1
1661 | cvt.w.d f0, f0 1686 | trunc.w.d f0, f0
1662 | sltiu AT, CARG3, LJ_TISNUM 1687 | sltiu AT, CARG3, LJ_TISNUM
1663 | beqz AT, ->fff_fallback 1688 | beqz AT, ->fff_fallback
1664 |. mfc1 CARG4, f0 1689 |. mfc1 CARG4, f0
@@ -1666,7 +1691,7 @@ static void build_subroutines(BuildCtx *ctx)
1666 | sltiu AT, CARG2, LJ_TISNUM 1691 | sltiu AT, CARG2, LJ_TISNUM
1667 | beqz AT, ->fff_fallback 1692 | beqz AT, ->fff_fallback
1668 |. li AT, LJ_TSTR 1693 |. li AT, LJ_TSTR
1669 | cvt.w.d f2, f2 1694 | trunc.w.d f2, f2
1670 | bne TMP0, AT, ->fff_fallback 1695 | bne TMP0, AT, ->fff_fallback
1671 |. lw CARG2, STR:CARG1->len 1696 |. lw CARG2, STR:CARG1->len
1672 | mfc1 CARG3, f2 1697 | mfc1 CARG3, f2
@@ -1695,108 +1720,32 @@ static void build_subroutines(BuildCtx *ctx)
1695 | b ->fff_restv 1720 | b ->fff_restv
1696 |. li CARG3, LJ_TSTR 1721 |. li CARG3, LJ_TSTR
1697 | 1722 |
1698 |.ffunc string_rep // Only handle the 1-char case inline. 1723 |.macro ffstring_op, name
1699 | ffgccheck 1724 | .ffunc string_ .. name
1700 | lw TMP0, HI(BASE)
1701 | addiu AT, NARGS8:RC, -16 // Exactly 2 arguments.
1702 | lw CARG4, 8+HI(BASE)
1703 | lw STR:CARG1, LO(BASE)
1704 | addiu TMP0, TMP0, -LJ_TSTR
1705 | ldc1 f0, 8(BASE)
1706 | or AT, AT, TMP0
1707 | bnez AT, ->fff_fallback
1708 |. sltiu AT, CARG4, LJ_TISNUM
1709 | cvt.w.d f0, f0
1710 | beqz AT, ->fff_fallback
1711 |. lw TMP0, STR:CARG1->len
1712 | mfc1 CARG3, f0
1713 | lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1714 | li AT, 1
1715 | blez CARG3, ->fff_emptystr // Count <= 0?
1716 |. sltu AT, AT, TMP0
1717 | beqz TMP0, ->fff_emptystr // Zero length string?
1718 |. sltu TMP0, TMP1, CARG3
1719 | or AT, AT, TMP0
1720 | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1721 | bnez AT, ->fff_fallback // Fallback for > 1-char strings.
1722 |. lbu TMP0, STR:CARG1[1]
1723 | addu TMP2, CARG2, CARG3
1724 |1: // Fill buffer with char. Yes, this is suboptimal code (do you care?).
1725 | addiu TMP2, TMP2, -1
1726 | sltu AT, CARG2, TMP2
1727 | bnez AT, <1
1728 |. sb TMP0, 0(TMP2)
1729 | b ->fff_newstr
1730 |. nop
1731 |
1732 |.ffunc string_reverse
1733 | ffgccheck 1725 | ffgccheck
1734 | lw CARG3, HI(BASE) 1726 | lw CARG3, HI(BASE)
1735 | lw STR:CARG1, LO(BASE) 1727 | lw STR:CARG2, LO(BASE)
1736 | beqz NARGS8:RC, ->fff_fallback 1728 | beqz NARGS8:RC, ->fff_fallback
1737 |. li AT, LJ_TSTR 1729 |. li AT, LJ_TSTR
1738 | bne CARG3, AT, ->fff_fallback 1730 | bne CARG3, AT, ->fff_fallback
1739 |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) 1731 |. addiu SBUF:CARG1, DISPATCH, DISPATCH_GL(tmpbuf)
1740 | lw CARG3, STR:CARG1->len 1732 | load_got lj_buf_putstr_ .. name
1741 | addiu CARG1, STR:CARG1, #STR 1733 | lw TMP0, SBUF:CARG1->b
1742 | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) 1734 | sw L, SBUF:CARG1->L
1743 | sltu AT, TMP1, CARG3 1735 | sw BASE, L->base
1744 | bnez AT, ->fff_fallback 1736 | sw TMP0, SBUF:CARG1->p
1745 |. addu TMP3, CARG1, CARG3 1737 | call_intern extern lj_buf_putstr_ .. name
1746 | addu CARG4, CARG2, CARG3 1738 |. sw PC, SAVE_PC
1747 |1: // Reverse string copy. 1739 | load_got lj_buf_tostr
1748 | lbu TMP1, 0(CARG1) 1740 | call_intern lj_buf_tostr
1749 | sltu AT, CARG1, TMP3 1741 |. move SBUF:CARG1, SBUF:CRET1
1750 | beqz AT, ->fff_newstr 1742 | b ->fff_resstr
1751 |. addiu CARG1, CARG1, 1 1743 |. lw BASE, L->base
1752 | addiu CARG4, CARG4, -1
1753 | b <1
1754 | sb TMP1, 0(CARG4)
1755 |
1756 |.macro ffstring_case, name, lo
1757 | .ffunc name
1758 | ffgccheck
1759 | lw CARG3, HI(BASE)
1760 | lw STR:CARG1, LO(BASE)
1761 | beqz NARGS8:RC, ->fff_fallback
1762 |. li AT, LJ_TSTR
1763 | bne CARG3, AT, ->fff_fallback
1764 |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1765 | lw CARG3, STR:CARG1->len
1766 | addiu CARG1, STR:CARG1, #STR
1767 | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1768 | sltu AT, TMP1, CARG3
1769 | bnez AT, ->fff_fallback
1770 |. addu TMP3, CARG1, CARG3
1771 | move CARG4, CARG2
1772 |1: // ASCII case conversion.
1773 | lbu TMP1, 0(CARG1)
1774 | sltu AT, CARG1, TMP3
1775 | beqz AT, ->fff_newstr
1776 |. addiu TMP0, TMP1, -lo
1777 | xori TMP2, TMP1, 0x20
1778 | sltiu AT, TMP0, 26
1779 | movn TMP1, TMP2, AT
1780 | addiu CARG1, CARG1, 1
1781 | sb TMP1, 0(CARG4)
1782 | b <1
1783 |. addiu CARG4, CARG4, 1
1784 |.endmacro 1744 |.endmacro
1785 | 1745 |
1786 |ffstring_case string_lower, 65 1746 |ffstring_op reverse
1787 |ffstring_case string_upper, 97 1747 |ffstring_op lower
1788 | 1748 |ffstring_op upper
1789 |//-- Table library ------------------------------------------------------
1790 |
1791 |.ffunc_1 table_getn
1792 | li AT, LJ_TTAB
1793 | bne CARG3, AT, ->fff_fallback
1794 |. load_got lj_tab_len
1795 | call_intern lj_tab_len // (GCtab *t)
1796 |. nop
1797 | // Returns uint32_t (but less than 2^31).
1798 | b ->fff_resi
1799 |. nop
1800 | 1749 |
1801 |//-- Bit library -------------------------------------------------------- 1750 |//-- Bit library --------------------------------------------------------
1802 | 1751 |
@@ -2062,6 +2011,20 @@ static void build_subroutines(BuildCtx *ctx)
2062 | jr CRET1 2011 | jr CRET1
2063 |. lw INS, -4(PC) 2012 |. lw INS, -4(PC)
2064 | 2013 |
2014 |->vm_profhook: // Dispatch target for profiler hook.
2015#if LJ_HASPROFILE
2016 | load_got lj_dispatch_profile
2017 | sw MULTRES, SAVE_MULTRES
2018 | move CARG2, PC
2019 | sw BASE, L->base
2020 | call_intern lj_dispatch_profile // (lua_State *L, const BCIns *pc)
2021 |. move CARG1, L
2022 | // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction.
2023 | addiu PC, PC, -4
2024 | b ->cont_nop
2025 |. lw BASE, L->base
2026#endif
2027 |
2065 |//----------------------------------------------------------------------- 2028 |//-----------------------------------------------------------------------
2066 |//-- Trace exit handler ------------------------------------------------- 2029 |//-- Trace exit handler -------------------------------------------------
2067 |//----------------------------------------------------------------------- 2030 |//-----------------------------------------------------------------------
@@ -2100,14 +2063,15 @@ static void build_subroutines(BuildCtx *ctx)
2100 | lw TMP1, 0(TMP2) // Load exit number. 2063 | lw TMP1, 0(TMP2) // Load exit number.
2101 | st_vmstate 2064 | st_vmstate
2102 | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP. 2065 | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP.
2103 | lw L, DISPATCH_GL(jit_L)(DISPATCH) 2066 | lw L, DISPATCH_GL(cur_L)(DISPATCH)
2104 | lw BASE, DISPATCH_GL(jit_base)(DISPATCH) 2067 | lw BASE, DISPATCH_GL(jit_base)(DISPATCH)
2105 | load_got lj_trace_exit 2068 | load_got lj_trace_exit
2106 | sw L, DISPATCH_J(L)(DISPATCH) 2069 | sw L, DISPATCH_J(L)(DISPATCH)
2107 | sw ra, DISPATCH_J(parent)(DISPATCH) // Store trace number. 2070 | sw ra, DISPATCH_J(parent)(DISPATCH) // Store trace number.
2071 | sw BASE, L->base
2108 | sw TMP1, DISPATCH_J(exitno)(DISPATCH) // Store exit number. 2072 | sw TMP1, DISPATCH_J(exitno)(DISPATCH) // Store exit number.
2109 | addiu CARG1, DISPATCH, GG_DISP2J 2073 | addiu CARG1, DISPATCH, GG_DISP2J
2110 | sw BASE, L->base 2074 | sw r0, DISPATCH_GL(jit_base)(DISPATCH)
2111 | call_intern lj_trace_exit // (jit_State *J, ExitState *ex) 2075 | call_intern lj_trace_exit // (jit_State *J, ExitState *ex)
2112 |. addiu CARG2, sp, 16 2076 |. addiu CARG2, sp, 16
2113 | // Returns MULTRES (unscaled) or negated error code. 2077 | // Returns MULTRES (unscaled) or negated error code.
@@ -2123,7 +2087,8 @@ static void build_subroutines(BuildCtx *ctx)
2123 |.if JIT 2087 |.if JIT
2124 | // CRET1 = MULTRES or negated error code, BASE, PC and JGL set. 2088 | // CRET1 = MULTRES or negated error code, BASE, PC and JGL set.
2125 | lw L, SAVE_L 2089 | lw L, SAVE_L
2126 | addiu DISPATCH, JGL, -GG_DISP2G-32768 2090 | addiu DISPATCH, JGL, -GG_DISP2G-32768
2091 | sw BASE, L->base
2127 |1: 2092 |1:
2128 | bltz CRET1, >3 // Check for error from exit. 2093 | bltz CRET1, >3 // Check for error from exit.
2129 |. lw LFUNC:TMP1, FRAME_FUNC(BASE) 2094 |. lw LFUNC:TMP1, FRAME_FUNC(BASE)
@@ -2133,7 +2098,7 @@ static void build_subroutines(BuildCtx *ctx)
2133 | sw MULTRES, SAVE_MULTRES 2098 | sw MULTRES, SAVE_MULTRES
2134 | mtc1 TMP3, TOBIT 2099 | mtc1 TMP3, TOBIT
2135 | lw TMP1, LFUNC:TMP1->pc 2100 | lw TMP1, LFUNC:TMP1->pc
2136 | sw r0, DISPATCH_GL(jit_L)(DISPATCH) 2101 | sw r0, DISPATCH_GL(jit_base)(DISPATCH)
2137 | lw KBASE, PC2PROTO(k)(TMP1) 2102 | lw KBASE, PC2PROTO(k)(TMP1)
2138 | cvt.d.s TOBIT, TOBIT 2103 | cvt.d.s TOBIT, TOBIT
2139 | // Modified copy of ins_next which handles function header dispatch, too. 2104 | // Modified copy of ins_next which handles function header dispatch, too.
@@ -2572,6 +2537,26 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2572 | ins_next 2537 | ins_next
2573 break; 2538 break;
2574 2539
2540 case BC_ISTYPE:
2541 | // RA = src*8, RD = -type*8
2542 | addu TMP2, BASE, RA
2543 | srl TMP1, RD, 3
2544 | lw TMP0, HI(TMP2)
2545 | ins_next1
2546 | addu AT, TMP0, TMP1
2547 | bnez AT, ->vmeta_istype
2548 |. ins_next2
2549 break;
2550 case BC_ISNUM:
2551 | // RA = src*8, RD = -(TISNUM-1)*8
2552 | addu TMP2, BASE, RA
2553 | lw TMP0, HI(TMP2)
2554 | ins_next1
2555 | sltiu AT, TMP0, LJ_TISNUM
2556 | beqz AT, ->vmeta_istype
2557 |. ins_next2
2558 break;
2559
2575 /* -- Unary ops --------------------------------------------------------- */ 2560 /* -- Unary ops --------------------------------------------------------- */
2576 2561
2577 case BC_MOV: 2562 case BC_MOV:
@@ -3210,6 +3195,30 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3210 | b ->vmeta_tgetb // Caveat: preserve TMP0! 3195 | b ->vmeta_tgetb // Caveat: preserve TMP0!
3211 |. nop 3196 |. nop
3212 break; 3197 break;
3198 case BC_TGETR:
3199 | // RA = dst*8, RB = table*8, RC = key*8
3200 | decode_RB8a RB, INS
3201 | decode_RB8b RB
3202 | decode_RDtoRC8 RC, RD
3203 | addu CARG2, BASE, RB
3204 | addu CARG3, BASE, RC
3205 | lw TAB:CARG1, LO(CARG2)
3206 | ldc1 f0, 0(CARG3)
3207 | trunc.w.d f2, f0
3208 | lw TMP0, TAB:CARG1->asize
3209 | mfc1 CARG2, f2
3210 | lw TMP1, TAB:CARG1->array
3211 | sltu AT, CARG2, TMP0
3212 | sll TMP2, CARG2, 3
3213 | beqz AT, ->vmeta_tgetr // In array part?
3214 |. addu TMP2, TMP1, TMP2
3215 | ldc1 f0, 0(TMP2)
3216 |->BC_TGETR_Z:
3217 | addu RA, BASE, RA
3218 | ins_next1
3219 | sdc1 f0, 0(RA)
3220 | ins_next2
3221 break;
3213 3222
3214 case BC_TSETV: 3223 case BC_TSETV:
3215 | // RA = src*8, RB = table*8, RC = key*8 3224 | // RA = src*8, RB = table*8, RC = key*8
@@ -3398,6 +3407,38 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3398 |7: // Possible table write barrier for the value. Skip valiswhite check. 3407 |7: // Possible table write barrier for the value. Skip valiswhite check.
3399 | barrierback TAB:RB, TMP3, TMP0, <2 3408 | barrierback TAB:RB, TMP3, TMP0, <2
3400 break; 3409 break;
3410 case BC_TSETR:
3411 | // RA = dst*8, RB = table*8, RC = key*8
3412 | decode_RB8a RB, INS
3413 | decode_RB8b RB
3414 | decode_RDtoRC8 RC, RD
3415 | addu CARG1, BASE, RB
3416 | addu CARG3, BASE, RC
3417 | lw TAB:CARG2, LO(CARG1)
3418 | ldc1 f0, 0(CARG3)
3419 | trunc.w.d f2, f0
3420 | lbu TMP3, TAB:CARG2->marked
3421 | lw TMP0, TAB:CARG2->asize
3422 | mfc1 CARG3, f2
3423 | lw TMP1, TAB:CARG2->array
3424 | andi AT, TMP3, LJ_GC_BLACK // isblack(table)
3425 | bnez AT, >7
3426 |. addu RA, BASE, RA
3427 |2:
3428 | sltu AT, CARG3, TMP0
3429 | sll TMP2, CARG3, 3
3430 | beqz AT, ->vmeta_tsetr // In array part?
3431 |. ldc1 f20, 0(RA)
3432 | addu CRET1, TMP1, TMP2
3433 |->BC_TSETR_Z:
3434 | ins_next1
3435 | sdc1 f20, 0(CRET1)
3436 | ins_next2
3437 |
3438 |7: // Possible table write barrier for the value. Skip valiswhite check.
3439 | barrierback TAB:RB, TMP3, TMP0, <2
3440 break;
3441
3401 3442
3402 case BC_TSETM: 3443 case BC_TSETM:
3403 | // RA = base*8 (table at base-1), RD = num_const*8 (start index) 3444 | // RA = base*8 (table at base-1), RD = num_const*8 (start index)
@@ -3957,8 +3998,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3957 | sw AT, DISPATCH_GL(vmstate)(DISPATCH) 3998 | sw AT, DISPATCH_GL(vmstate)(DISPATCH)
3958 | lw TRACE:TMP2, 0(TMP1) 3999 | lw TRACE:TMP2, 0(TMP1)
3959 | sw BASE, DISPATCH_GL(jit_base)(DISPATCH) 4000 | sw BASE, DISPATCH_GL(jit_base)(DISPATCH)
3960 | sw L, DISPATCH_GL(jit_L)(DISPATCH)
3961 | lw TMP2, TRACE:TMP2->mcode 4001 | lw TMP2, TRACE:TMP2->mcode
4002 | sw L, DISPATCH_GL(tmpbuf.L)(DISPATCH)
3962 | jr TMP2 4003 | jr TMP2
3963 |. addiu JGL, DISPATCH, GG_DISP2G+32768 4004 |. addiu JGL, DISPATCH, GG_DISP2G+32768
3964 |.endif 4005 |.endif
@@ -4084,6 +4125,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4084 | li_vmstate INTERP 4125 | li_vmstate INTERP
4085 | lw PC, FRAME_PC(BASE) // Fetch PC of caller. 4126 | lw PC, FRAME_PC(BASE) // Fetch PC of caller.
4086 | subu RA, TMP1, RD // RA = L->top - nresults*8 4127 | subu RA, TMP1, RD // RA = L->top - nresults*8
4128 | sw L, DISPATCH_GL(cur_L)(DISPATCH)
4087 | b ->vm_returnc 4129 | b ->vm_returnc
4088 |. st_vmstate 4130 |. st_vmstate
4089 break; 4131 break;