aboutsummaryrefslogtreecommitdiff
path: root/src/vm_mips.dasc
diff options
context:
space:
mode:
Diffstat (limited to 'src/vm_mips.dasc')
-rw-r--r--src/vm_mips.dasc390
1 files changed, 252 insertions, 138 deletions
diff --git a/src/vm_mips.dasc b/src/vm_mips.dasc
index 0ec13e60..3bf5a993 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
1734 | lw CARG3, HI(BASE)
1735 | lw STR:CARG1, LO(BASE)
1736 | beqz NARGS8:RC, ->fff_fallback
1737 |. li AT, LJ_TSTR
1738 | bne CARG3, AT, ->fff_fallback
1739 |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH)
1740 | lw CARG3, STR:CARG1->len
1741 | addiu CARG1, STR:CARG1, #STR
1742 | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH)
1743 | sltu AT, TMP1, CARG3
1744 | bnez AT, ->fff_fallback
1745 |. addu TMP3, CARG1, CARG3
1746 | addu CARG4, CARG2, CARG3
1747 |1: // Reverse string copy.
1748 | lbu TMP1, 0(CARG1)
1749 | sltu AT, CARG1, TMP3
1750 | beqz AT, ->fff_newstr
1751 |. addiu CARG1, CARG1, 1
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 1725 | ffgccheck
1759 | lw CARG3, HI(BASE) 1726 | lw CARG3, HI(BASE)
1760 | lw STR:CARG1, LO(BASE) 1727 | lw STR:CARG2, LO(BASE)
1761 | beqz NARGS8:RC, ->fff_fallback 1728 | beqz NARGS8:RC, ->fff_fallback
1762 |. li AT, LJ_TSTR 1729 |. li AT, LJ_TSTR
1763 | bne CARG3, AT, ->fff_fallback 1730 | bne CARG3, AT, ->fff_fallback
1764 |. lw TMP1, DISPATCH_GL(tmpbuf.sz)(DISPATCH) 1731 |. addiu SBUF:CARG1, DISPATCH, DISPATCH_GL(tmpbuf)
1765 | lw CARG3, STR:CARG1->len 1732 | load_got lj_buf_putstr_ .. name
1766 | addiu CARG1, STR:CARG1, #STR 1733 | lw TMP0, SBUF:CARG1->b
1767 | lw CARG2, DISPATCH_GL(tmpbuf.buf)(DISPATCH) 1734 | sw L, SBUF:CARG1->L
1768 | sltu AT, TMP1, CARG3 1735 | sw BASE, L->base
1769 | bnez AT, ->fff_fallback 1736 | sw TMP0, SBUF:CARG1->p
1770 |. addu TMP3, CARG1, CARG3 1737 | call_intern extern lj_buf_putstr_ .. name
1771 | move CARG4, CARG2 1738 |. sw PC, SAVE_PC
1772 |1: // ASCII case conversion. 1739 | load_got lj_buf_tostr
1773 | lbu TMP1, 0(CARG1) 1740 | call_intern lj_buf_tostr
1774 | sltu AT, CARG1, TMP3 1741 |. move SBUF:CARG1, SBUF:CRET1
1775 | beqz AT, ->fff_newstr 1742 | b ->fff_resstr
1776 |. addiu TMP0, TMP1, -lo 1743 |. lw BASE, L->base
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,76 @@ 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 |->cont_stitch: // Trace stitching.
2015 |.if JIT
2016 | // RA = resultptr, RB = meta base
2017 | lw INS, -4(PC)
2018 | lw TMP3, -24+LO(RB) // Save previous trace number.
2019 | decode_RA8a RC, INS
2020 | addiu AT, MULTRES, -8
2021 | decode_RA8b RC
2022 | beqz AT, >2
2023 |. addu RC, BASE, RC // Call base.
2024 |1: // Move results down.
2025 | ldc1 f0, 0(RA)
2026 | addiu AT, AT, -8
2027 | addiu RA, RA, 8
2028 | sdc1 f0, 0(RC)
2029 | bnez AT, <1
2030 |. addiu RC, RC, 8
2031 |2:
2032 | decode_RA8a RA, INS
2033 | decode_RB8a RB, INS
2034 | decode_RA8b RA
2035 | decode_RB8b RB
2036 | addu RA, RA, RB
2037 | lw TMP1, DISPATCH_J(trace)(DISPATCH)
2038 | addu RA, BASE, RA
2039 |3:
2040 | sltu AT, RC, RA
2041 | bnez AT, >9 // More results wanted?
2042 |. sll TMP2, TMP3, 2
2043 |
2044 | addu TMP2, TMP1, TMP2
2045 | lw TRACE:TMP2, 0(TMP2)
2046 | beqz TRACE:TMP2, ->cont_nop
2047 |. nop
2048 | lhu RD, TRACE:TMP2->link
2049 | beq RD, TMP3, ->cont_nop // Blacklisted.
2050 |. load_got lj_dispatch_stitch
2051 | bnez RD, =>BC_JLOOP // Jump to stitched trace.
2052 |. sll RD, RD, 3
2053 |
2054 | // Stitch a new trace to the previous trace.
2055 | sw TMP3, DISPATCH_J(exitno)(DISPATCH)
2056 | sw L, DISPATCH_J(L)(DISPATCH)
2057 | sw BASE, L->base
2058 | addiu CARG1, DISPATCH, GG_DISP2J
2059 | call_intern lj_dispatch_stitch // (jit_State *J, const BCIns *pc)
2060 |. move CARG2, PC
2061 | b ->cont_nop
2062 |. lw BASE, L->base
2063 |
2064 |9:
2065 | sw TISNIL, HI(RC)
2066 | b <3
2067 |. addiu RC, RC, 8
2068 |.endif
2069 |
2070 |->vm_profhook: // Dispatch target for profiler hook.
2071#if LJ_HASPROFILE
2072 | load_got lj_dispatch_profile
2073 | sw MULTRES, SAVE_MULTRES
2074 | move CARG2, PC
2075 | sw BASE, L->base
2076 | call_intern lj_dispatch_profile // (lua_State *L, const BCIns *pc)
2077 |. move CARG1, L
2078 | // HOOK_PROFILE is off again, so re-dispatch to dynamic instruction.
2079 | addiu PC, PC, -4
2080 | b ->cont_nop
2081 |. lw BASE, L->base
2082#endif
2083 |
2065 |//----------------------------------------------------------------------- 2084 |//-----------------------------------------------------------------------
2066 |//-- Trace exit handler ------------------------------------------------- 2085 |//-- Trace exit handler -------------------------------------------------
2067 |//----------------------------------------------------------------------- 2086 |//-----------------------------------------------------------------------
@@ -2100,14 +2119,15 @@ static void build_subroutines(BuildCtx *ctx)
2100 | lw TMP1, 0(TMP2) // Load exit number. 2119 | lw TMP1, 0(TMP2) // Load exit number.
2101 | st_vmstate 2120 | st_vmstate
2102 | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP. 2121 | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP.
2103 | lw L, DISPATCH_GL(jit_L)(DISPATCH) 2122 | lw L, DISPATCH_GL(cur_L)(DISPATCH)
2104 | lw BASE, DISPATCH_GL(jit_base)(DISPATCH) 2123 | lw BASE, DISPATCH_GL(jit_base)(DISPATCH)
2105 | load_got lj_trace_exit 2124 | load_got lj_trace_exit
2106 | sw L, DISPATCH_J(L)(DISPATCH) 2125 | sw L, DISPATCH_J(L)(DISPATCH)
2107 | sw ra, DISPATCH_J(parent)(DISPATCH) // Store trace number. 2126 | sw ra, DISPATCH_J(parent)(DISPATCH) // Store trace number.
2127 | sw BASE, L->base
2108 | sw TMP1, DISPATCH_J(exitno)(DISPATCH) // Store exit number. 2128 | sw TMP1, DISPATCH_J(exitno)(DISPATCH) // Store exit number.
2109 | addiu CARG1, DISPATCH, GG_DISP2J 2129 | addiu CARG1, DISPATCH, GG_DISP2J
2110 | sw BASE, L->base 2130 | sw r0, DISPATCH_GL(jit_base)(DISPATCH)
2111 | call_intern lj_trace_exit // (jit_State *J, ExitState *ex) 2131 | call_intern lj_trace_exit // (jit_State *J, ExitState *ex)
2112 |. addiu CARG2, sp, 16 2132 |. addiu CARG2, sp, 16
2113 | // Returns MULTRES (unscaled) or negated error code. 2133 | // Returns MULTRES (unscaled) or negated error code.
@@ -2123,17 +2143,18 @@ static void build_subroutines(BuildCtx *ctx)
2123 |.if JIT 2143 |.if JIT
2124 | // CRET1 = MULTRES or negated error code, BASE, PC and JGL set. 2144 | // CRET1 = MULTRES or negated error code, BASE, PC and JGL set.
2125 | lw L, SAVE_L 2145 | lw L, SAVE_L
2126 | addiu DISPATCH, JGL, -GG_DISP2G-32768 2146 | addiu DISPATCH, JGL, -GG_DISP2G-32768
2147 | sw BASE, L->base
2127 |1: 2148 |1:
2128 | bltz CRET1, >3 // Check for error from exit. 2149 | bltz CRET1, >9 // Check for error from exit.
2129 |. lw LFUNC:TMP1, FRAME_FUNC(BASE) 2150 |. lw LFUNC:RB, FRAME_FUNC(BASE)
2130 | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). 2151 | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
2131 | sll MULTRES, CRET1, 3 2152 | sll MULTRES, CRET1, 3
2132 | li TISNIL, LJ_TNIL 2153 | li TISNIL, LJ_TNIL
2133 | sw MULTRES, SAVE_MULTRES 2154 | sw MULTRES, SAVE_MULTRES
2134 | mtc1 TMP3, TOBIT 2155 | mtc1 TMP3, TOBIT
2135 | lw TMP1, LFUNC:TMP1->pc 2156 | lw TMP1, LFUNC:RB->pc
2136 | sw r0, DISPATCH_GL(jit_L)(DISPATCH) 2157 | sw r0, DISPATCH_GL(jit_base)(DISPATCH)
2137 | lw KBASE, PC2PROTO(k)(TMP1) 2158 | lw KBASE, PC2PROTO(k)(TMP1)
2138 | cvt.d.s TOBIT, TOBIT 2159 | cvt.d.s TOBIT, TOBIT
2139 | // Modified copy of ins_next which handles function header dispatch, too. 2160 | // Modified copy of ins_next which handles function header dispatch, too.
@@ -2153,11 +2174,27 @@ static void build_subroutines(BuildCtx *ctx)
2153 | jr AT 2174 | jr AT
2154 |. decode_RD8b RD 2175 |. decode_RD8b RD
2155 |2: 2176 |2:
2177 | sltiu TMP2, TMP1, (BC_FUNCC+2)*4 // Fast function?
2178 | bnez TMP2, >3
2179 |. lw TMP1, FRAME_PC(BASE)
2180 | // Check frame below fast function.
2181 | andi TMP0, TMP1, FRAME_TYPE
2182 | bnez TMP0, >3 // Trace stitching continuation?
2183 |. nop
2184 | // Otherwise set KBASE for Lua function below fast function.
2185 | lw TMP2, -4(TMP1)
2186 | decode_RA8a TMP0, TMP2
2187 | decode_RA8b TMP0
2188 | subu TMP1, BASE, TMP0
2189 | lw LFUNC:TMP2, -8+FRAME_FUNC(TMP1)
2190 | lw TMP1, LFUNC:TMP2->pc
2191 | lw KBASE, PC2PROTO(k)(TMP1)
2192 |3:
2156 | addiu RC, MULTRES, -8 2193 | addiu RC, MULTRES, -8
2157 | jr AT 2194 | jr AT
2158 |. addu RA, RA, BASE 2195 |. addu RA, RA, BASE
2159 | 2196 |
2160 |3: // Rethrow error from the right C frame. 2197 |9: // Rethrow error from the right C frame.
2161 | load_got lj_err_throw 2198 | load_got lj_err_throw
2162 | negu CARG2, CRET1 2199 | negu CARG2, CRET1
2163 | call_intern lj_err_throw // (lua_State *L, int errcode) 2200 | call_intern lj_err_throw // (lua_State *L, int errcode)
@@ -2572,6 +2609,26 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
2572 | ins_next 2609 | ins_next
2573 break; 2610 break;
2574 2611
2612 case BC_ISTYPE:
2613 | // RA = src*8, RD = -type*8
2614 | addu TMP2, BASE, RA
2615 | srl TMP1, RD, 3
2616 | lw TMP0, HI(TMP2)
2617 | ins_next1
2618 | addu AT, TMP0, TMP1
2619 | bnez AT, ->vmeta_istype
2620 |. ins_next2
2621 break;
2622 case BC_ISNUM:
2623 | // RA = src*8, RD = -(TISNUM-1)*8
2624 | addu TMP2, BASE, RA
2625 | lw TMP0, HI(TMP2)
2626 | ins_next1
2627 | sltiu AT, TMP0, LJ_TISNUM
2628 | beqz AT, ->vmeta_istype
2629 |. ins_next2
2630 break;
2631
2575 /* -- Unary ops --------------------------------------------------------- */ 2632 /* -- Unary ops --------------------------------------------------------- */
2576 2633
2577 case BC_MOV: 2634 case BC_MOV:
@@ -3210,6 +3267,30 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3210 | b ->vmeta_tgetb // Caveat: preserve TMP0! 3267 | b ->vmeta_tgetb // Caveat: preserve TMP0!
3211 |. nop 3268 |. nop
3212 break; 3269 break;
3270 case BC_TGETR:
3271 | // RA = dst*8, RB = table*8, RC = key*8
3272 | decode_RB8a RB, INS
3273 | decode_RB8b RB
3274 | decode_RDtoRC8 RC, RD
3275 | addu CARG2, BASE, RB
3276 | addu CARG3, BASE, RC
3277 | lw TAB:CARG1, LO(CARG2)
3278 | ldc1 f0, 0(CARG3)
3279 | trunc.w.d f2, f0
3280 | lw TMP0, TAB:CARG1->asize
3281 | mfc1 CARG2, f2
3282 | lw TMP1, TAB:CARG1->array
3283 | sltu AT, CARG2, TMP0
3284 | sll TMP2, CARG2, 3
3285 | beqz AT, ->vmeta_tgetr // In array part?
3286 |. addu TMP2, TMP1, TMP2
3287 | ldc1 f0, 0(TMP2)
3288 |->BC_TGETR_Z:
3289 | addu RA, BASE, RA
3290 | ins_next1
3291 | sdc1 f0, 0(RA)
3292 | ins_next2
3293 break;
3213 3294
3214 case BC_TSETV: 3295 case BC_TSETV:
3215 | // RA = src*8, RB = table*8, RC = key*8 3296 | // RA = src*8, RB = table*8, RC = key*8
@@ -3398,6 +3479,38 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3398 |7: // Possible table write barrier for the value. Skip valiswhite check. 3479 |7: // Possible table write barrier for the value. Skip valiswhite check.
3399 | barrierback TAB:RB, TMP3, TMP0, <2 3480 | barrierback TAB:RB, TMP3, TMP0, <2
3400 break; 3481 break;
3482 case BC_TSETR:
3483 | // RA = dst*8, RB = table*8, RC = key*8
3484 | decode_RB8a RB, INS
3485 | decode_RB8b RB
3486 | decode_RDtoRC8 RC, RD
3487 | addu CARG1, BASE, RB
3488 | addu CARG3, BASE, RC
3489 | lw TAB:CARG2, LO(CARG1)
3490 | ldc1 f0, 0(CARG3)
3491 | trunc.w.d f2, f0
3492 | lbu TMP3, TAB:CARG2->marked
3493 | lw TMP0, TAB:CARG2->asize
3494 | mfc1 CARG3, f2
3495 | lw TMP1, TAB:CARG2->array
3496 | andi AT, TMP3, LJ_GC_BLACK // isblack(table)
3497 | bnez AT, >7
3498 |. addu RA, BASE, RA
3499 |2:
3500 | sltu AT, CARG3, TMP0
3501 | sll TMP2, CARG3, 3
3502 | beqz AT, ->vmeta_tsetr // In array part?
3503 |. ldc1 f20, 0(RA)
3504 | addu CRET1, TMP1, TMP2
3505 |->BC_TSETR_Z:
3506 | ins_next1
3507 | sdc1 f20, 0(CRET1)
3508 | ins_next2
3509 |
3510 |7: // Possible table write barrier for the value. Skip valiswhite check.
3511 | barrierback TAB:RB, TMP3, TMP0, <2
3512 break;
3513
3401 3514
3402 case BC_TSETM: 3515 case BC_TSETM:
3403 | // RA = base*8 (table at base-1), RD = num_const*8 (start index) 3516 | // RA = base*8 (table at base-1), RD = num_const*8 (start index)
@@ -3957,8 +4070,8 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
3957 | sw AT, DISPATCH_GL(vmstate)(DISPATCH) 4070 | sw AT, DISPATCH_GL(vmstate)(DISPATCH)
3958 | lw TRACE:TMP2, 0(TMP1) 4071 | lw TRACE:TMP2, 0(TMP1)
3959 | sw BASE, DISPATCH_GL(jit_base)(DISPATCH) 4072 | sw BASE, DISPATCH_GL(jit_base)(DISPATCH)
3960 | sw L, DISPATCH_GL(jit_L)(DISPATCH)
3961 | lw TMP2, TRACE:TMP2->mcode 4073 | lw TMP2, TRACE:TMP2->mcode
4074 | sw L, DISPATCH_GL(tmpbuf.L)(DISPATCH)
3962 | jr TMP2 4075 | jr TMP2
3963 |. addiu JGL, DISPATCH, GG_DISP2G+32768 4076 |. addiu JGL, DISPATCH, GG_DISP2G+32768
3964 |.endif 4077 |.endif
@@ -4084,6 +4197,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
4084 | li_vmstate INTERP 4197 | li_vmstate INTERP
4085 | lw PC, FRAME_PC(BASE) // Fetch PC of caller. 4198 | lw PC, FRAME_PC(BASE) // Fetch PC of caller.
4086 | subu RA, TMP1, RD // RA = L->top - nresults*8 4199 | subu RA, TMP1, RD // RA = L->top - nresults*8
4200 | sw L, DISPATCH_GL(cur_L)(DISPATCH)
4087 | b ->vm_returnc 4201 | b ->vm_returnc
4088 |. st_vmstate 4202 |. st_vmstate
4089 break; 4203 break;