diff options
Diffstat (limited to 'src/vm_mips.dasc')
-rw-r--r-- | src/vm_mips.dasc | 390 |
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; |