diff options
| author | Mike Pall <mike> | 2021-07-19 16:23:12 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2021-07-19 16:23:12 +0200 |
| commit | 6df650fe3fa0e06d9645524918a9935e3a282156 (patch) | |
| tree | bc3487e71038a93d0f44afb4fd68f92c0553cec0 | |
| parent | 71db0cf04357391beb01732af691a4df25298911 (diff) | |
| download | luajit-6df650fe3fa0e06d9645524918a9935e3a282156.tar.gz luajit-6df650fe3fa0e06d9645524918a9935e3a282156.tar.bz2 luajit-6df650fe3fa0e06d9645524918a9935e3a282156.zip | |
String buffers, part 3a: Add IR_TMPREF for passing TValues to helpers.
Sponsored by fmad.io.
| -rw-r--r-- | src/jit/dump.lua | 1 | ||||
| -rw-r--r-- | src/lj_asm.c | 19 | ||||
| -rw-r--r-- | src/lj_asm_arm.h | 69 | ||||
| -rw-r--r-- | src/lj_asm_arm64.h | 28 | ||||
| -rw-r--r-- | src/lj_asm_mips.h | 82 | ||||
| -rw-r--r-- | src/lj_asm_ppc.h | 71 | ||||
| -rw-r--r-- | src/lj_asm_x86.h | 79 | ||||
| -rw-r--r-- | src/lj_ir.h | 6 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 1 | ||||
| -rw-r--r-- | src/lj_opt_split.c | 2 | ||||
| -rw-r--r-- | src/lj_record.c | 15 | ||||
| -rw-r--r-- | src/lj_record.h | 1 |
12 files changed, 249 insertions, 125 deletions
diff --git a/src/jit/dump.lua b/src/jit/dump.lua index 34ced76d..4806f4c4 100644 --- a/src/jit/dump.lua +++ b/src/jit/dump.lua | |||
| @@ -287,6 +287,7 @@ local litname = { | |||
| 287 | ["FLOAD "] = vmdef.irfield, | 287 | ["FLOAD "] = vmdef.irfield, |
| 288 | ["FREF "] = vmdef.irfield, | 288 | ["FREF "] = vmdef.irfield, |
| 289 | ["FPMATH"] = vmdef.irfpm, | 289 | ["FPMATH"] = vmdef.irfpm, |
| 290 | ["TMPREF"] = { [0] = "", "IN", "OUT", "INOUT", "", "", "OUT2", "INOUT2" }, | ||
| 290 | ["BUFHDR"] = { [0] = "RESET", "APPEND" }, | 291 | ["BUFHDR"] = { [0] = "RESET", "APPEND" }, |
| 291 | ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, | 292 | ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, |
| 292 | } | 293 | } |
diff --git a/src/lj_asm.c b/src/lj_asm.c index b613e6d3..ebcff43c 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
| @@ -1144,7 +1144,7 @@ static void asm_gcstep(ASMState *as, IRIns *ir) | |||
| 1144 | 1144 | ||
| 1145 | /* -- Buffer operations --------------------------------------------------- */ | 1145 | /* -- Buffer operations --------------------------------------------------- */ |
| 1146 | 1146 | ||
| 1147 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref); | 1147 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode); |
| 1148 | 1148 | ||
| 1149 | static void asm_bufhdr(ASMState *as, IRIns *ir) | 1149 | static void asm_bufhdr(ASMState *as, IRIns *ir) |
| 1150 | { | 1150 | { |
| @@ -1218,7 +1218,7 @@ static void asm_bufput(ASMState *as, IRIns *ir) | |||
| 1218 | if (args[1] == ASMREF_TMP1) { | 1218 | if (args[1] == ASMREF_TMP1) { |
| 1219 | Reg tmp = ra_releasetmp(as, ASMREF_TMP1); | 1219 | Reg tmp = ra_releasetmp(as, ASMREF_TMP1); |
| 1220 | if (kchar == -129) | 1220 | if (kchar == -129) |
| 1221 | asm_tvptr(as, tmp, irs->op1); | 1221 | asm_tvptr(as, tmp, irs->op1, IRTMPREF_IN1); |
| 1222 | else | 1222 | else |
| 1223 | ra_allockreg(as, kchar, tmp); | 1223 | ra_allockreg(as, kchar, tmp); |
| 1224 | } | 1224 | } |
| @@ -1256,7 +1256,7 @@ static void asm_tostr(ASMState *as, IRIns *ir) | |||
| 1256 | asm_setupresult(as, ir, ci); /* GCstr * */ | 1256 | asm_setupresult(as, ir, ci); /* GCstr * */ |
| 1257 | asm_gencall(as, ci, args); | 1257 | asm_gencall(as, ci, args); |
| 1258 | if (ir->op2 == IRTOSTR_NUM) | 1258 | if (ir->op2 == IRTOSTR_NUM) |
| 1259 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1); | 1259 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1, IRTMPREF_IN1); |
| 1260 | } | 1260 | } |
| 1261 | 1261 | ||
| 1262 | #if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86 | 1262 | #if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86 |
| @@ -1303,7 +1303,13 @@ static void asm_newref(ASMState *as, IRIns *ir) | |||
| 1303 | args[2] = ASMREF_TMP1; /* cTValue *key */ | 1303 | args[2] = ASMREF_TMP1; /* cTValue *key */ |
| 1304 | asm_setupresult(as, ir, ci); /* TValue * */ | 1304 | asm_setupresult(as, ir, ci); /* TValue * */ |
| 1305 | asm_gencall(as, ci, args); | 1305 | asm_gencall(as, ci, args); |
| 1306 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2); | 1306 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op2, IRTMPREF_IN1); |
| 1307 | } | ||
| 1308 | |||
| 1309 | static void asm_tmpref(ASMState *as, IRIns *ir) | ||
| 1310 | { | ||
| 1311 | Reg r = ra_dest(as, ir, RSET_GPR); | ||
| 1312 | asm_tvptr(as, r, ir->op1, ir->op2); | ||
| 1307 | } | 1313 | } |
| 1308 | 1314 | ||
| 1309 | static void asm_lref(ASMState *as, IRIns *ir) | 1315 | static void asm_lref(ASMState *as, IRIns *ir) |
| @@ -1785,6 +1791,7 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
| 1785 | case IR_NEWREF: asm_newref(as, ir); break; | 1791 | case IR_NEWREF: asm_newref(as, ir); break; |
| 1786 | case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break; | 1792 | case IR_UREFO: case IR_UREFC: asm_uref(as, ir); break; |
| 1787 | case IR_FREF: asm_fref(as, ir); break; | 1793 | case IR_FREF: asm_fref(as, ir); break; |
| 1794 | case IR_TMPREF: asm_tmpref(as, ir); break; | ||
| 1788 | case IR_STRREF: asm_strref(as, ir); break; | 1795 | case IR_STRREF: asm_strref(as, ir); break; |
| 1789 | case IR_LREF: asm_lref(as, ir); break; | 1796 | case IR_LREF: asm_lref(as, ir); break; |
| 1790 | 1797 | ||
| @@ -2192,6 +2199,10 @@ static void asm_setup_regsp(ASMState *as) | |||
| 2192 | ir->prev = (uint16_t)REGSP_HINT((rload & 15)); | 2199 | ir->prev = (uint16_t)REGSP_HINT((rload & 15)); |
| 2193 | rload = lj_ror(rload, 4); | 2200 | rload = lj_ror(rload, 4); |
| 2194 | continue; | 2201 | continue; |
| 2202 | case IR_TMPREF: | ||
| 2203 | if ((ir->op2 & IRTMPREF_OUT2) && as->evenspill < 4) | ||
| 2204 | as->evenspill = 4; /* TMPREF OUT2 needs two TValues on the stack. */ | ||
| 2205 | break; | ||
| 2195 | #endif | 2206 | #endif |
| 2196 | case IR_CALLXS: { | 2207 | case IR_CALLXS: { |
| 2197 | CCallInfo ci; | 2208 | CCallInfo ci; |
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index c93c99c9..208c3203 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
| @@ -185,6 +185,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow, | |||
| 185 | *ofsp = (ofs & 255); /* Mask out less bits to allow LDRD. */ | 185 | *ofsp = (ofs & 255); /* Mask out less bits to allow LDRD. */ |
| 186 | return ra_allock(as, (ofs & ~255), allow); | 186 | return ra_allock(as, (ofs & ~255), allow); |
| 187 | } | 187 | } |
| 188 | } else if (ir->o == IR_TMPREF) { | ||
| 189 | *ofsp = 0; | ||
| 190 | return RID_SP; | ||
| 188 | } | 191 | } |
| 189 | } | 192 | } |
| 190 | *ofsp = 0; | 193 | *ofsp = 0; |
| @@ -666,35 +669,55 @@ static void asm_strto(ASMState *as, IRIns *ir) | |||
| 666 | /* -- Memory references --------------------------------------------------- */ | 669 | /* -- Memory references --------------------------------------------------- */ |
| 667 | 670 | ||
| 668 | /* Get pointer to TValue. */ | 671 | /* Get pointer to TValue. */ |
| 669 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 672 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
| 670 | { | 673 | { |
| 671 | IRIns *ir = IR(ref); | 674 | if ((mode & IRTMPREF_IN1)) { |
| 672 | if (irt_isnum(ir->t)) { | 675 | IRIns *ir = IR(ref); |
| 673 | if (irref_isk(ref)) { | 676 | if (irt_isnum(ir->t)) { |
| 674 | /* Use the number constant itself as a TValue. */ | 677 | if ((mode & IRTMPREF_OUT1)) { |
| 675 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | 678 | #if LJ_SOFTFP |
| 676 | } else { | 679 | lj_assertA(irref_isk(ref), "unsplit FP op"); |
| 680 | emit_dm(as, ARMI_MOV, dest, RID_SP); | ||
| 681 | emit_lso(as, ARMI_STR, | ||
| 682 | ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR), | ||
| 683 | RID_SP, 0); | ||
| 684 | emit_lso(as, ARMI_STR, | ||
| 685 | ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR), | ||
| 686 | RID_SP, 4); | ||
| 687 | #else | ||
| 688 | Reg src = ra_alloc1(as, ref, RSET_FPR); | ||
| 689 | emit_dm(as, ARMI_MOV, dest, RID_SP); | ||
| 690 | emit_vlso(as, ARMI_VSTR_D, src, RID_SP, 0); | ||
| 691 | #endif | ||
| 692 | } else if (irref_isk(ref)) { | ||
| 693 | /* Use the number constant itself as a TValue. */ | ||
| 694 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | ||
| 695 | } else { | ||
| 677 | #if LJ_SOFTFP | 696 | #if LJ_SOFTFP |
| 678 | lj_assertA(0, "unsplit FP op"); | 697 | lj_assertA(0, "unsplit FP op"); |
| 679 | #else | 698 | #else |
| 680 | /* Otherwise force a spill and use the spill slot. */ | 699 | /* Otherwise force a spill and use the spill slot. */ |
| 681 | emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR); | 700 | emit_opk(as, ARMI_ADD, dest, RID_SP, ra_spill(as, ir), RSET_GPR); |
| 682 | #endif | 701 | #endif |
| 702 | } | ||
| 703 | } else { | ||
| 704 | /* Otherwise use [sp] and [sp+4] to hold the TValue. | ||
| 705 | ** This assumes the following call has max. 4 args. | ||
| 706 | */ | ||
| 707 | Reg type; | ||
| 708 | emit_dm(as, ARMI_MOV, dest, RID_SP); | ||
| 709 | if (!irt_ispri(ir->t)) { | ||
| 710 | Reg src = ra_alloc1(as, ref, RSET_GPR); | ||
| 711 | emit_lso(as, ARMI_STR, src, RID_SP, 0); | ||
| 712 | } | ||
| 713 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)) | ||
| 714 | type = ra_alloc1(as, ref+1, RSET_GPR); | ||
| 715 | else | ||
| 716 | type = ra_allock(as, irt_toitype(ir->t), RSET_GPR); | ||
| 717 | emit_lso(as, ARMI_STR, type, RID_SP, 4); | ||
| 683 | } | 718 | } |
| 684 | } else { | 719 | } else { |
| 685 | /* Otherwise use [sp] and [sp+4] to hold the TValue. */ | ||
| 686 | RegSet allow = rset_exclude(RSET_GPR, dest); | ||
| 687 | Reg type; | ||
| 688 | emit_dm(as, ARMI_MOV, dest, RID_SP); | 720 | emit_dm(as, ARMI_MOV, dest, RID_SP); |
| 689 | if (!irt_ispri(ir->t)) { | ||
| 690 | Reg src = ra_alloc1(as, ref, allow); | ||
| 691 | emit_lso(as, ARMI_STR, src, RID_SP, 0); | ||
| 692 | } | ||
| 693 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) | ||
| 694 | type = ra_alloc1(as, ref+1, allow); | ||
| 695 | else | ||
| 696 | type = ra_allock(as, irt_toitype(ir->t), allow); | ||
| 697 | emit_lso(as, ARMI_STR, type, RID_SP, 4); | ||
| 698 | } | 721 | } |
| 699 | } | 722 | } |
| 700 | 723 | ||
| @@ -1909,7 +1932,7 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 1909 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ | 1932 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ |
| 1910 | break; | 1933 | break; |
| 1911 | #if LJ_SOFTFP | 1934 | #if LJ_SOFTFP |
| 1912 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: | 1935 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF: |
| 1913 | #endif | 1936 | #endif |
| 1914 | case IR_CNEWI: | 1937 | case IR_CNEWI: |
| 1915 | /* Nothing to do here. Handled by lo op itself. */ | 1938 | /* Nothing to do here. Handled by lo op itself. */ |
diff --git a/src/lj_asm_arm64.h b/src/lj_asm_arm64.h index c9ba7b7b..5bd4e0d5 100644 --- a/src/lj_asm_arm64.h +++ b/src/lj_asm_arm64.h | |||
| @@ -198,6 +198,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow, | |||
| 198 | return RID_GL; | 198 | return RID_GL; |
| 199 | } | 199 | } |
| 200 | } | 200 | } |
| 201 | } else if (ir->o == IR_TMPREF) { | ||
| 202 | *ofsp = (int32_t)glofs(as, &J2G(as->J)->tmptv); | ||
| 203 | return RID_GL; | ||
| 201 | } | 204 | } |
| 202 | } | 205 | } |
| 203 | *ofsp = 0; | 206 | *ofsp = 0; |
| @@ -675,22 +678,23 @@ static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref) | |||
| 675 | } | 678 | } |
| 676 | 679 | ||
| 677 | /* Get pointer to TValue. */ | 680 | /* Get pointer to TValue. */ |
| 678 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 681 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
| 679 | { | 682 | { |
| 680 | IRIns *ir = IR(ref); | 683 | if ((mode & IRTMPREF_IN1)) { |
| 681 | if (irt_isnum(ir->t)) { | 684 | IRIns *ir = IR(ref); |
| 682 | if (irref_isk(ref)) { | 685 | if (irt_isnum(ir->t)) { |
| 683 | /* Use the number constant itself as a TValue. */ | 686 | if (irref_isk(ref) && !(mode & IRTMPREF_OUT1)) { |
| 684 | ra_allockreg(as, i64ptr(ir_knum(ir)), dest); | 687 | /* Use the number constant itself as a TValue. */ |
| 688 | ra_allockreg(as, i64ptr(ir_knum(ir)), dest); | ||
| 689 | return; | ||
| 690 | } | ||
| 691 | emit_lso(as, A64I_STRd, (ra_alloc1(as, ref, RSET_FPR) & 31), dest, 0); | ||
| 685 | } else { | 692 | } else { |
| 686 | /* Otherwise force a spill and use the spill slot. */ | 693 | asm_tvstore64(as, dest, 0, ref); |
| 687 | emit_opk(as, A64I_ADDx, dest, RID_SP, ra_spill(as, ir), RSET_GPR); | ||
| 688 | } | 694 | } |
| 689 | } else { | ||
| 690 | /* Otherwise use g->tmptv to hold the TValue. */ | ||
| 691 | asm_tvstore64(as, dest, 0, ref); | ||
| 692 | emit_dn(as, A64I_ADDx^emit_isk12(glofs(as, &J2G(as->J)->tmptv)), dest, RID_GL); | ||
| 693 | } | 695 | } |
| 696 | /* g->tmptv holds the TValue(s). */ | ||
| 697 | emit_dn(as, A64I_ADDx^emit_isk12(glofs(as, &J2G(as->J)->tmptv)), dest, RID_GL); | ||
| 694 | } | 698 | } |
| 695 | 699 | ||
| 696 | static void asm_aref(ASMState *as, IRIns *ir) | 700 | static void asm_aref(ASMState *as, IRIns *ir) |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index f775d08b..058df8be 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
| @@ -193,6 +193,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow) | |||
| 193 | return ra_allock(as, ofs-(int16_t)ofs, allow); | 193 | return ra_allock(as, ofs-(int16_t)ofs, allow); |
| 194 | } | 194 | } |
| 195 | } | 195 | } |
| 196 | } else if (ir->o == IR_TMPREF) { | ||
| 197 | *ofsp = (int32_t)(offsetof(global_State, tmptv)-32768); | ||
| 198 | return RID_JGL; | ||
| 196 | } | 199 | } |
| 197 | } | 200 | } |
| 198 | *ofsp = 0; | 201 | *ofsp = 0; |
| @@ -839,34 +842,63 @@ static void asm_tvstore64(ASMState *as, Reg base, int32_t ofs, IRRef ref) | |||
| 839 | #endif | 842 | #endif |
| 840 | 843 | ||
| 841 | /* Get pointer to TValue. */ | 844 | /* Get pointer to TValue. */ |
| 842 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 845 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
| 843 | { | 846 | { |
| 844 | IRIns *ir = IR(ref); | 847 | int32_t tmpofs = (int32_t)(offsetof(global_State, tmptv)-32768); |
| 845 | if (irt_isnum(ir->t)) { | 848 | if ((mode & IRTMPREF_IN1)) { |
| 846 | if (irref_isk(ref)) /* Use the number constant itself as a TValue. */ | 849 | IRIns *ir = IR(ref); |
| 847 | ra_allockreg(as, igcptr(ir_knum(ir)), dest); | 850 | if (irt_isnum(ir->t)) { |
| 848 | else /* Otherwise force a spill and use the spill slot. */ | 851 | if ((mode & IRTMPREF_OUT1)) { |
| 849 | emit_tsi(as, MIPSI_AADDIU, dest, RID_SP, ra_spill(as, ir)); | 852 | #if LJ_SOFTFP |
| 850 | } else { | 853 | emit_tsi(as, MIPSI_AADDIU, dest, RID_JGL, tmpofs); |
| 851 | /* Otherwise use g->tmptv to hold the TValue. */ | 854 | #if LJ_64 |
| 855 | emit_setgl(as, ra_alloc1(as, ref, RSET_GPR), tmptv.u64); | ||
| 856 | #else | ||
| 857 | lj_assertA(irref_isk(ref), "unsplit FP op"); | ||
| 858 | emit_setgl(as, | ||
| 859 | ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR), | ||
| 860 | tmptv.u32.lo); | ||
| 861 | emit_setgl(as, | ||
| 862 | ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR), | ||
| 863 | tmptv.u32.hi); | ||
| 864 | #endif | ||
| 865 | #else | ||
| 866 | Reg src = ra_alloc1(as, ref, RSET_FPR); | ||
| 867 | emit_tsi(as, MIPSI_AADDIU, dest, RID_JGL, tmpofs); | ||
| 868 | emit_tsi(as, MIPSI_SDC1, (src & 31), RID_JGL, tmpofs); | ||
| 869 | #endif | ||
| 870 | } else if (irref_isk(ref)) { | ||
| 871 | /* Use the number constant itself as a TValue. */ | ||
| 872 | ra_allockreg(as, igcptr(ir_knum(ir)), dest); | ||
| 873 | } else { | ||
| 874 | #if LJ_SOFTFP | ||
| 875 | lj_assertA(0, "unsplit FP op"); | ||
| 876 | #else | ||
| 877 | /* Otherwise force a spill and use the spill slot. */ | ||
| 878 | emit_tsi(as, MIPSI_AADDIU, dest, RID_SP, ra_spill(as, ir)); | ||
| 879 | #endif | ||
| 880 | } | ||
| 881 | } else { | ||
| 882 | /* Otherwise use g->tmptv to hold the TValue. */ | ||
| 852 | #if LJ_32 | 883 | #if LJ_32 |
| 853 | RegSet allow = rset_exclude(RSET_GPR, dest); | 884 | Reg type; |
| 854 | Reg type; | 885 | emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, tmpofs); |
| 855 | emit_tsi(as, MIPSI_ADDIU, dest, RID_JGL, (int32_t)(offsetof(global_State, tmptv)-32768)); | 886 | if (!irt_ispri(ir->t)) { |
| 856 | if (!irt_ispri(ir->t)) { | 887 | Reg src = ra_alloc1(as, ref, RSET_GPR); |
| 857 | Reg src = ra_alloc1(as, ref, allow); | 888 | emit_setgl(as, src, tmptv.gcr); |
| 858 | emit_setgl(as, src, tmptv.gcr); | 889 | } |
| 859 | } | 890 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)) |
| 860 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) | 891 | type = ra_alloc1(as, ref+1, RSET_GPR); |
| 861 | type = ra_alloc1(as, ref+1, allow); | 892 | else |
| 862 | else | 893 | type = ra_allock(as, (int32_t)irt_toitype(ir->t), RSET_GPR); |
| 863 | type = ra_allock(as, (int32_t)irt_toitype(ir->t), allow); | 894 | emit_setgl(as, type, tmptv.it); |
| 864 | emit_setgl(as, type, tmptv.it); | ||
| 865 | #else | 895 | #else |
| 866 | asm_tvstore64(as, dest, 0, ref); | 896 | asm_tvstore64(as, dest, 0, ref); |
| 867 | emit_tsi(as, MIPSI_DADDIU, dest, RID_JGL, | 897 | emit_tsi(as, MIPSI_DADDIU, dest, RID_JGL, tmpofs); |
| 868 | (int32_t)(offsetof(global_State, tmptv)-32768)); | ||
| 869 | #endif | 898 | #endif |
| 899 | } | ||
| 900 | } else { | ||
| 901 | emit_tsi(as, MIPSI_AADDIU, dest, RID_JGL, tmpofs); | ||
| 870 | } | 902 | } |
| 871 | } | 903 | } |
| 872 | 904 | ||
| @@ -2415,7 +2447,7 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 2415 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ | 2447 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ |
| 2416 | break; | 2448 | break; |
| 2417 | #if LJ_SOFTFP | 2449 | #if LJ_SOFTFP |
| 2418 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: | 2450 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF: |
| 2419 | #endif | 2451 | #endif |
| 2420 | case IR_CNEWI: | 2452 | case IR_CNEWI: |
| 2421 | /* Nothing to do here. Handled by lo op itself. */ | 2453 | /* Nothing to do here. Handled by lo op itself. */ |
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index 88869d9d..caef8fd7 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
| @@ -156,6 +156,9 @@ static Reg asm_fuseahuref(ASMState *as, IRRef ref, int32_t *ofsp, RegSet allow) | |||
| 156 | return ra_allock(as, ofs-(int16_t)ofs, allow); | 156 | return ra_allock(as, ofs-(int16_t)ofs, allow); |
| 157 | } | 157 | } |
| 158 | } | 158 | } |
| 159 | } else if (ir->o == IR_TMPREF) { | ||
| 160 | *ofsp = (int32_t)(offsetof(global_State, tmptv)-32768); | ||
| 161 | return RID_JGL; | ||
| 159 | } | 162 | } |
| 160 | } | 163 | } |
| 161 | *ofsp = 0; | 164 | *ofsp = 0; |
| @@ -567,28 +570,54 @@ static void asm_strto(ASMState *as, IRIns *ir) | |||
| 567 | /* -- Memory references --------------------------------------------------- */ | 570 | /* -- Memory references --------------------------------------------------- */ |
| 568 | 571 | ||
| 569 | /* Get pointer to TValue. */ | 572 | /* Get pointer to TValue. */ |
| 570 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 573 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
| 571 | { | 574 | { |
| 572 | IRIns *ir = IR(ref); | 575 | int32_t tmpofs = (int32_t)(offsetof(global_State, tmptv)-32768); |
| 573 | if (irt_isnum(ir->t)) { | 576 | if ((mode & IRTMPREF_IN1)) { |
| 574 | if (irref_isk(ref)) /* Use the number constant itself as a TValue. */ | 577 | IRIns *ir = IR(ref); |
| 575 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | 578 | if (irt_isnum(ir->t)) { |
| 576 | else /* Otherwise force a spill and use the spill slot. */ | 579 | if ((mode & IRTMPREF_OUT1)) { |
| 577 | emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir)); | 580 | #if LJ_SOFTFP |
| 578 | } else { | 581 | lj_assertA(irref_isk(ref), "unsplit FP op"); |
| 579 | /* Otherwise use g->tmptv to hold the TValue. */ | 582 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); |
| 580 | RegSet allow = rset_exclude(RSET_GPR, dest); | 583 | emit_setgl(as, |
| 581 | Reg type; | 584 | ra_allock(as, (int32_t)ir_knum(ir)->u32.lo, RSET_GPR), |
| 582 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, (int32_t)offsetof(global_State, tmptv)-32768); | 585 | tmptv.u32.lo); |
| 583 | if (!irt_ispri(ir->t)) { | 586 | emit_setgl(as, |
| 584 | Reg src = ra_alloc1(as, ref, allow); | 587 | ra_allock(as, (int32_t)ir_knum(ir)->u32.hi, RSET_GPR), |
| 585 | emit_setgl(as, src, tmptv.gcr); | 588 | tmptv.u32.hi); |
| 589 | #else | ||
| 590 | Reg src = ra_alloc1(as, ref, RSET_FPR); | ||
| 591 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); | ||
| 592 | emit_fai(as, PPCI_STFD, src, RID_JGL, tmpofs); | ||
| 593 | #endif | ||
| 594 | } else if (irref_isk(ref)) { | ||
| 595 | /* Use the number constant itself as a TValue. */ | ||
| 596 | ra_allockreg(as, i32ptr(ir_knum(ir)), dest); | ||
| 597 | } else { | ||
| 598 | #if LJ_SOFTFP | ||
| 599 | lj_assertA(0, "unsplit FP op"); | ||
| 600 | #else | ||
| 601 | /* Otherwise force a spill and use the spill slot. */ | ||
| 602 | emit_tai(as, PPCI_ADDI, dest, RID_SP, ra_spill(as, ir)); | ||
| 603 | #endif | ||
| 604 | } | ||
| 605 | } else { | ||
| 606 | /* Otherwise use g->tmptv to hold the TValue. */ | ||
| 607 | Reg type; | ||
| 608 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); | ||
| 609 | if (!irt_ispri(ir->t)) { | ||
| 610 | Reg src = ra_alloc1(as, ref, RSET_GPR); | ||
| 611 | emit_setgl(as, src, tmptv.gcr); | ||
| 612 | } | ||
| 613 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP && !irt_isnil((ir+1)->t)) | ||
| 614 | type = ra_alloc1(as, ref+1, RSET_GPR); | ||
| 615 | else | ||
| 616 | type = ra_allock(as, irt_toitype(ir->t), RSET_GPR); | ||
| 617 | emit_setgl(as, type, tmptv.it); | ||
| 586 | } | 618 | } |
| 587 | if (LJ_SOFTFP && (ir+1)->o == IR_HIOP) | 619 | } else { |
| 588 | type = ra_alloc1(as, ref+1, allow); | 620 | emit_tai(as, PPCI_ADDI, dest, RID_JGL, tmpofs); |
| 589 | else | ||
| 590 | type = ra_allock(as, irt_toitype(ir->t), allow); | ||
| 591 | emit_setgl(as, type, tmptv.it); | ||
| 592 | } | 621 | } |
| 593 | } | 622 | } |
| 594 | 623 | ||
| @@ -1958,7 +1987,7 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
| 1958 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ | 1987 | ra_allocref(as, ir->op1, RID2RSET(RID_RETLO)); /* Mark lo op as used. */ |
| 1959 | break; | 1988 | break; |
| 1960 | #if LJ_SOFTFP | 1989 | #if LJ_SOFTFP |
| 1961 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: | 1990 | case IR_ASTORE: case IR_HSTORE: case IR_USTORE: case IR_TOSTR: case IR_TMPREF: |
| 1962 | #endif | 1991 | #endif |
| 1963 | case IR_CNEWI: | 1992 | case IR_CNEWI: |
| 1964 | /* Nothing to do here. Handled by lo op itself. */ | 1993 | /* Nothing to do here. Handled by lo op itself. */ |
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 715e1535..b8abf9d6 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
| @@ -216,6 +216,16 @@ static void asm_fuseahuref(ASMState *as, IRRef ref, RegSet allow) | |||
| 216 | #endif | 216 | #endif |
| 217 | } | 217 | } |
| 218 | break; | 218 | break; |
| 219 | case IR_TMPREF: | ||
| 220 | #if LJ_GC64 | ||
| 221 | as->mrm.ofs = (int32_t)dispofs(as, &J2G(as->J)->tmptv); | ||
| 222 | as->mrm.base = RID_DISPATCH; | ||
| 223 | as->mrm.idx = RID_NONE; | ||
| 224 | #else | ||
| 225 | as->mrm.ofs = igcptr(&J2G(as->J)->tmptv); | ||
| 226 | as->mrm.base = as->mrm.idx = RID_NONE; | ||
| 227 | #endif | ||
| 228 | return; | ||
| 219 | default: | 229 | default: |
| 220 | lj_assertA(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO || | 230 | lj_assertA(ir->o == IR_HREF || ir->o == IR_NEWREF || ir->o == IR_UREFO || |
| 221 | ir->o == IR_KKPTR, | 231 | ir->o == IR_KKPTR, |
| @@ -1050,47 +1060,48 @@ static void asm_strto(ASMState *as, IRIns *ir) | |||
| 1050 | /* -- Memory references --------------------------------------------------- */ | 1060 | /* -- Memory references --------------------------------------------------- */ |
| 1051 | 1061 | ||
| 1052 | /* Get pointer to TValue. */ | 1062 | /* Get pointer to TValue. */ |
| 1053 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref) | 1063 | static void asm_tvptr(ASMState *as, Reg dest, IRRef ref, MSize mode) |
| 1054 | { | 1064 | { |
| 1055 | IRIns *ir = IR(ref); | 1065 | if ((mode & IRTMPREF_IN1)) { |
| 1056 | if (irt_isnum(ir->t)) { | 1066 | IRIns *ir = IR(ref); |
| 1057 | /* For numbers use the constant itself or a spill slot as a TValue. */ | 1067 | if (irt_isnum(ir->t)) { |
| 1058 | if (irref_isk(ref)) | 1068 | if (irref_isk(ref) && !(mode & IRTMPREF_OUT1)) { |
| 1059 | emit_loada(as, dest, ir_knum(ir)); | 1069 | /* Use the number constant itself as a TValue. */ |
| 1060 | else | 1070 | emit_loada(as, dest, ir_knum(ir)); |
| 1061 | emit_rmro(as, XO_LEA, dest|REX_64, RID_ESP, ra_spill(as, ir)); | 1071 | return; |
| 1062 | } else { | 1072 | } |
| 1063 | /* Otherwise use g->tmptv to hold the TValue. */ | 1073 | emit_rmro(as, XO_MOVSDto, ra_alloc1(as, ref, RSET_FPR), dest, 0); |
| 1064 | #if LJ_GC64 | ||
| 1065 | if (irref_isk(ref)) { | ||
| 1066 | TValue k; | ||
| 1067 | lj_ir_kvalue(as->J->L, &k, ir); | ||
| 1068 | emit_movmroi(as, dest, 4, k.u32.hi); | ||
| 1069 | emit_movmroi(as, dest, 0, k.u32.lo); | ||
| 1070 | } else { | 1074 | } else { |
| 1071 | /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */ | 1075 | #if LJ_GC64 |
| 1072 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); | 1076 | if (irref_isk(ref)) { |
| 1073 | if (irt_is64(ir->t)) { | 1077 | TValue k; |
| 1074 | emit_u32(as, irt_toitype(ir->t) << 15); | 1078 | lj_ir_kvalue(as->J->L, &k, ir); |
| 1075 | emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4); | 1079 | emit_movmroi(as, dest, 4, k.u32.hi); |
| 1080 | emit_movmroi(as, dest, 0, k.u32.lo); | ||
| 1076 | } else { | 1081 | } else { |
| 1077 | /* Currently, no caller passes integers that might end up here. */ | 1082 | /* TODO: 64 bit store + 32 bit load-modify-store is suboptimal. */ |
| 1078 | emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15)); | 1083 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); |
| 1084 | if (irt_is64(ir->t)) { | ||
| 1085 | emit_u32(as, irt_toitype(ir->t) << 15); | ||
| 1086 | emit_rmro(as, XO_ARITHi, XOg_OR, dest, 4); | ||
| 1087 | } else { | ||
| 1088 | emit_movmroi(as, dest, 4, (irt_toitype(ir->t) << 15)); | ||
| 1089 | } | ||
| 1090 | emit_movtomro(as, REX_64IR(ir, src), dest, 0); | ||
| 1079 | } | 1091 | } |
| 1080 | emit_movtomro(as, REX_64IR(ir, src), dest, 0); | ||
| 1081 | } | ||
| 1082 | #else | 1092 | #else |
| 1083 | if (!irref_isk(ref)) { | 1093 | if (!irref_isk(ref)) { |
| 1084 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); | 1094 | Reg src = ra_alloc1(as, ref, rset_exclude(RSET_GPR, dest)); |
| 1085 | emit_movtomro(as, REX_64IR(ir, src), dest, 0); | 1095 | emit_movtomro(as, REX_64IR(ir, src), dest, 0); |
| 1086 | } else if (!irt_ispri(ir->t)) { | 1096 | } else if (!irt_ispri(ir->t)) { |
| 1087 | emit_movmroi(as, dest, 0, ir->i); | 1097 | emit_movmroi(as, dest, 0, ir->i); |
| 1088 | } | 1098 | } |
| 1089 | if (!(LJ_64 && irt_islightud(ir->t))) | 1099 | if (!(LJ_64 && irt_islightud(ir->t))) |
| 1090 | emit_movmroi(as, dest, 4, irt_toitype(ir->t)); | 1100 | emit_movmroi(as, dest, 4, irt_toitype(ir->t)); |
| 1091 | #endif | 1101 | #endif |
| 1092 | emit_loada(as, dest, &J2G(as->J)->tmptv); | 1102 | } |
| 1093 | } | 1103 | } |
| 1104 | emit_loada(as, dest, &J2G(as->J)->tmptv); /* g->tmptv holds the TValue(s). */ | ||
| 1094 | } | 1105 | } |
| 1095 | 1106 | ||
| 1096 | static void asm_aref(ASMState *as, IRIns *ir) | 1107 | static void asm_aref(ASMState *as, IRIns *ir) |
diff --git a/src/lj_ir.h b/src/lj_ir.h index ea8616ec..22a3b79c 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
| @@ -95,6 +95,7 @@ | |||
| 95 | _(UREFO, LW, ref, lit) \ | 95 | _(UREFO, LW, ref, lit) \ |
| 96 | _(UREFC, LW, ref, lit) \ | 96 | _(UREFC, LW, ref, lit) \ |
| 97 | _(FREF, R , ref, lit) \ | 97 | _(FREF, R , ref, lit) \ |
| 98 | _(TMPREF, S , ref, lit) \ | ||
| 98 | _(STRREF, N , ref, ref) \ | 99 | _(STRREF, N , ref, ref) \ |
| 99 | _(LREF, L , ___, ___) \ | 100 | _(LREF, L , ___, ___) \ |
| 100 | \ | 101 | \ |
| @@ -218,6 +219,11 @@ IRFLDEF(FLENUM) | |||
| 218 | IRFL__MAX | 219 | IRFL__MAX |
| 219 | } IRFieldID; | 220 | } IRFieldID; |
| 220 | 221 | ||
| 222 | /* TMPREF mode bits, stored in op2. */ | ||
| 223 | #define IRTMPREF_IN1 0x01 /* First input value. */ | ||
| 224 | #define IRTMPREF_OUT1 0x02 /* First output value. */ | ||
| 225 | #define IRTMPREF_OUT2 0x04 /* Second output value. */ | ||
| 226 | |||
| 221 | /* SLOAD mode bits, stored in op2. */ | 227 | /* SLOAD mode bits, stored in op2. */ |
| 222 | #define IRSLOAD_PARENT 0x01 /* Coalesce with parent trace. */ | 228 | #define IRSLOAD_PARENT 0x01 /* Coalesce with parent trace. */ |
| 223 | #define IRSLOAD_FRAME 0x02 /* Load 32 bits of ftsz. */ | 229 | #define IRSLOAD_FRAME 0x02 /* Load 32 bits of ftsz. */ |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 3cf448d6..9a41a5a4 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -2421,6 +2421,7 @@ LJFOLD(XSTORE any any) | |||
| 2421 | LJFOLDX(lj_opt_dse_xstore) | 2421 | LJFOLDX(lj_opt_dse_xstore) |
| 2422 | 2422 | ||
| 2423 | LJFOLD(NEWREF any any) /* Treated like a store. */ | 2423 | LJFOLD(NEWREF any any) /* Treated like a store. */ |
| 2424 | LJFOLD(TMPREF any any) | ||
| 2424 | LJFOLD(CALLA any any) | 2425 | LJFOLD(CALLA any any) |
| 2425 | LJFOLD(CALLL any any) /* Safeguard fallback. */ | 2426 | LJFOLD(CALLL any any) /* Safeguard fallback. */ |
| 2426 | LJFOLD(CALLS any any) | 2427 | LJFOLD(CALLS any any) |
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c index 3a02abd4..25c1c234 100644 --- a/src/lj_opt_split.c +++ b/src/lj_opt_split.c | |||
| @@ -645,7 +645,7 @@ static void split_ir(jit_State *J) | |||
| 645 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev); | 645 | tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev); |
| 646 | #endif | 646 | #endif |
| 647 | ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit); | 647 | ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit); |
| 648 | } else if (ir->o == IR_TOSTR) { | 648 | } else if (ir->o == IR_TOSTR || ir->o == IR_TMPREF) { |
| 649 | if (hisubst[ir->op1]) { | 649 | if (hisubst[ir->op1]) { |
| 650 | if (irref_isk(ir->op1)) | 650 | if (irref_isk(ir->op1)) |
| 651 | nir->op1 = ir->op1; | 651 | nir->op1 = ir->op1; |
diff --git a/src/lj_record.c b/src/lj_record.c index 86f17abc..c0aea106 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -259,6 +259,14 @@ TRef lj_record_constify(jit_State *J, cTValue *o) | |||
| 259 | return 0; /* Can't represent lightuserdata (pointless). */ | 259 | return 0; /* Can't represent lightuserdata (pointless). */ |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | /* Emit a VLOAD with the correct type. */ | ||
| 263 | TRef lj_record_vload(jit_State *J, TRef ref, IRType t) | ||
| 264 | { | ||
| 265 | TRef tr = emitir(IRTG(IR_VLOAD, t), ref, 0); | ||
| 266 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ | ||
| 267 | return tr; | ||
| 268 | } | ||
| 269 | |||
| 262 | /* -- Record loop ops ----------------------------------------------------- */ | 270 | /* -- Record loop ops ----------------------------------------------------- */ |
| 263 | 271 | ||
| 264 | /* Loop event. */ | 272 | /* Loop event. */ |
| @@ -1832,9 +1840,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | |||
| 1832 | IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]); | 1840 | IRType t = itype2irt(&J->L->base[i-1-LJ_FR2-nvararg]); |
| 1833 | TRef aref = emitir(IRT(IR_AREF, IRT_PGC), | 1841 | TRef aref = emitir(IRT(IR_AREF, IRT_PGC), |
| 1834 | vbase, lj_ir_kint(J, (int32_t)i)); | 1842 | vbase, lj_ir_kint(J, (int32_t)i)); |
| 1835 | TRef tr = emitir(IRTG(IR_VLOAD, t), aref, 0); | 1843 | J->base[dst+i] = lj_record_vload(J, aref, t); |
| 1836 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ | ||
| 1837 | J->base[dst+i] = tr; | ||
| 1838 | } | 1844 | } |
| 1839 | } else { | 1845 | } else { |
| 1840 | emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs)); | 1846 | emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs)); |
| @@ -1881,8 +1887,7 @@ static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | |||
| 1881 | lj_ir_kint(J, frofs-(8<<LJ_FR2))); | 1887 | lj_ir_kint(J, frofs-(8<<LJ_FR2))); |
| 1882 | t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]); | 1888 | t = itype2irt(&J->L->base[idx-2-LJ_FR2-nvararg]); |
| 1883 | aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx); | 1889 | aref = emitir(IRT(IR_AREF, IRT_PGC), vbase, tridx); |
| 1884 | tr = emitir(IRTG(IR_VLOAD, t), aref, 0); | 1890 | tr = lj_record_vload(J, aref, t); |
| 1885 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ | ||
| 1886 | } | 1891 | } |
| 1887 | J->base[dst-2-LJ_FR2] = tr; | 1892 | J->base[dst-2-LJ_FR2] = tr; |
| 1888 | J->maxslot = dst-1-LJ_FR2; | 1893 | J->maxslot = dst-1-LJ_FR2; |
diff --git a/src/lj_record.h b/src/lj_record.h index de74277e..03d84a71 100644 --- a/src/lj_record.h +++ b/src/lj_record.h | |||
| @@ -30,6 +30,7 @@ LJ_FUNC int lj_record_objcmp(jit_State *J, TRef a, TRef b, | |||
| 30 | cTValue *av, cTValue *bv); | 30 | cTValue *av, cTValue *bv); |
| 31 | LJ_FUNC void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk); | 31 | LJ_FUNC void lj_record_stop(jit_State *J, TraceLink linktype, TraceNo lnk); |
| 32 | LJ_FUNC TRef lj_record_constify(jit_State *J, cTValue *o); | 32 | LJ_FUNC TRef lj_record_constify(jit_State *J, cTValue *o); |
| 33 | LJ_FUNC TRef lj_record_vload(jit_State *J, TRef ref, IRType t); | ||
| 33 | 34 | ||
| 34 | LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs); | 35 | LJ_FUNC void lj_record_call(jit_State *J, BCReg func, ptrdiff_t nargs); |
| 35 | LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs); | 36 | LJ_FUNC void lj_record_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs); |
