diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 90 | ||||
-rw-r--r-- | src/lj_crecord.c | 8 | ||||
-rw-r--r-- | src/lj_ir.h | 6 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 27 |
4 files changed, 47 insertions, 84 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 215dfb13..27ccfe9a 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -2283,55 +2283,12 @@ static void asm_tdup(ASMState *as, IRIns *ir) | |||
2283 | } | 2283 | } |
2284 | 2284 | ||
2285 | #if LJ_HASFFI | 2285 | #if LJ_HASFFI |
2286 | static RegSet asm_cnew_init(ASMState *as, IRRef ref, int32_t ofs, RegSet allow) | ||
2287 | { | ||
2288 | IRIns *ir = IR(ref); | ||
2289 | if (irref_isk(ref)) { | ||
2290 | #if LJ_64 | ||
2291 | if (ir->o == IR_KNUM || ir->o == IR_KINT64) { | ||
2292 | uint64_t k = ir_k64(ir)->u64; | ||
2293 | if (checki32((int64_t)k)) { | ||
2294 | emit_i32(as, (int32_t)k); | ||
2295 | emit_rmro(as, XO_MOVmi, REX_64, RID_RET, ofs); | ||
2296 | } else { | ||
2297 | emit_movtomro(as, RID_ECX|REX_64, RID_RET, ofs); | ||
2298 | emit_loadu64(as, RID_ECX, k); | ||
2299 | } | ||
2300 | } else { | ||
2301 | emit_movmroi(as, RID_RET, ofs, ir->i); | ||
2302 | } | ||
2303 | #else | ||
2304 | if (ir->o == IR_KNUM) { | ||
2305 | emit_rmro(as, XO_MOVSDto, RID_XMM0, RID_RET, ofs); | ||
2306 | emit_loadn(as, RID_XMM0, ir_k64(ir)); | ||
2307 | } else if (ir->o == IR_KINT64) { | ||
2308 | uint64_t k = ir_k64(ir)->u64; | ||
2309 | emit_movmroi(as, RID_RET, ofs, (int32_t)k); | ||
2310 | emit_movmroi(as, RID_RET, ofs+4, (int32_t)(k >> 32)); | ||
2311 | } else { | ||
2312 | emit_movmroi(as, RID_RET, ofs, ir->i); | ||
2313 | } | ||
2314 | #endif | ||
2315 | } else { | ||
2316 | Reg r; | ||
2317 | if (irt_isnum(ir->t)) { | ||
2318 | r = ra_alloc1(as, ref, (RSET_FPR & allow)); | ||
2319 | emit_rmro(as, XO_MOVSDto, r, RID_RET, ofs); | ||
2320 | } else { | ||
2321 | r = ra_alloc1(as, ref, (RSET_GPR & allow)); | ||
2322 | emit_movtomro(as, REX_64IR(ir, r), RID_RET, ofs); | ||
2323 | } | ||
2324 | rset_clear(allow, r); | ||
2325 | } | ||
2326 | return allow; | ||
2327 | } | ||
2328 | |||
2329 | static void asm_cnew(ASMState *as, IRIns *ir) | 2286 | static void asm_cnew(ASMState *as, IRIns *ir) |
2330 | { | 2287 | { |
2331 | CTState *cts = ctype_ctsG(J2G(as->J)); | 2288 | CTState *cts = ctype_ctsG(J2G(as->J)); |
2332 | CTypeID typeid = (CTypeID)IR(ir->op2)->i; | 2289 | CTypeID typeid = (CTypeID)IR(ir->op1)->i; |
2333 | CTSize sz = (ir->o == IR_CNEWI || ir->op1 == REF_NIL) ? | 2290 | CTSize sz = (ir->o == IR_CNEWP || ir->op2 == REF_NIL) ? |
2334 | lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op1)->i; | 2291 | lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i; |
2335 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; | 2292 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; |
2336 | IRRef args[2]; | 2293 | IRRef args[2]; |
2337 | lua_assert(sz != CTSIZE_INVALID); | 2294 | lua_assert(sz != CTSIZE_INVALID); |
@@ -2339,18 +2296,35 @@ static void asm_cnew(ASMState *as, IRIns *ir) | |||
2339 | args[0] = ASMREF_L; /* lua_State *L */ | 2296 | args[0] = ASMREF_L; /* lua_State *L */ |
2340 | args[1] = ASMREF_TMP1; /* MSize size */ | 2297 | args[1] = ASMREF_TMP1; /* MSize size */ |
2341 | as->gcsteps++; | 2298 | as->gcsteps++; |
2342 | asm_setupresult(as, ir, ci); /* GCobj * */ | 2299 | asm_setupresult(as, ir, ci); /* GCcdata * */ |
2343 | 2300 | ||
2344 | /* Initialize immutable cdata object. */ | 2301 | /* Initialize pointer cdata object. */ |
2345 | if (ir->o == IR_CNEWI) { | 2302 | if (ir->o == IR_CNEWP) { |
2346 | RegSet allow = ~RSET_SCRATCH; | 2303 | if (irref_isk(ir->op2)) { |
2347 | IRRef ref = ir->op1; | 2304 | IRIns *irk = IR(ir->op2); |
2348 | if (IR(ref)->o == IR_CARG) { /* 2nd initializer. */ | 2305 | #if LJ_64 |
2349 | IRIns *ira = IR(ref); | 2306 | if (irk->o == IR_KINT64) { |
2350 | allow = asm_cnew_init(as, ira->op2, sizeof(GCcdata) + (sz>>1), allow); | 2307 | uint64_t k = ir_k64(irk)->u64; |
2351 | ref = ira->op1; | 2308 | lua_assert(sz == 8); |
2309 | if (checki32((int64_t)k)) { | ||
2310 | emit_i32(as, (int32_t)k); | ||
2311 | emit_rmro(as, XO_MOVmi, REX_64, RID_RET, sizeof(GCcdata)); | ||
2312 | } else { | ||
2313 | emit_movtomro(as, RID_ECX|REX_64, RID_RET, sizeof(GCcdata)); | ||
2314 | emit_loadu64(as, RID_ECX, k); | ||
2315 | } | ||
2316 | } else { | ||
2317 | #endif | ||
2318 | lua_assert(sz == 4); | ||
2319 | emit_movmroi(as, RID_RET, sizeof(GCcdata), irk->i); | ||
2320 | #if LJ_64 | ||
2321 | } | ||
2322 | #endif | ||
2323 | } else { | ||
2324 | Reg r = ra_alloc1(as, ir->op2, (RSET_GPR & ~RSET_SCRATCH)); | ||
2325 | emit_movtomro(as, r + ((LJ_64 && sz == 8) ? REX_64 : 0), | ||
2326 | RID_RET, sizeof(GCcdata)); | ||
2352 | } | 2327 | } |
2353 | asm_cnew_init(as, ref, sizeof(GCcdata), allow); /* 1st initializer. */ | ||
2354 | } | 2328 | } |
2355 | 2329 | ||
2356 | /* Combine initialization of marked, gct and typeid. */ | 2330 | /* Combine initialization of marked, gct and typeid. */ |
@@ -3675,7 +3649,7 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
3675 | case IR_SNEW: asm_snew(as, ir); break; | 3649 | case IR_SNEW: asm_snew(as, ir); break; |
3676 | case IR_TNEW: asm_tnew(as, ir); break; | 3650 | case IR_TNEW: asm_tnew(as, ir); break; |
3677 | case IR_TDUP: asm_tdup(as, ir); break; | 3651 | case IR_TDUP: asm_tdup(as, ir); break; |
3678 | case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break; | 3652 | case IR_CNEW: case IR_CNEWP: asm_cnew(as, ir); break; |
3679 | 3653 | ||
3680 | /* Write barriers. */ | 3654 | /* Write barriers. */ |
3681 | case IR_TBAR: asm_tbar(as, ir); break; | 3655 | case IR_TBAR: asm_tbar(as, ir); break; |
@@ -3793,7 +3767,7 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T) | |||
3793 | if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ | 3767 | if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ |
3794 | as->evenspill = 3; | 3768 | as->evenspill = 3; |
3795 | #endif | 3769 | #endif |
3796 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: | 3770 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWP: case IR_TOSTR: |
3797 | ir->prev = REGSP_HINT(RID_RET); | 3771 | ir->prev = REGSP_HINT(RID_RET); |
3798 | if (inloop) | 3772 | if (inloop) |
3799 | as->modset = RSET_SCRATCH; | 3773 | as->modset = RSET_SCRATCH; |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 2f7e0f34..1df6c70c 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -260,7 +260,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | |||
260 | ptrdiff_t esz = (ptrdiff_t)(s->size >> 1); | 260 | ptrdiff_t esz = (ptrdiff_t)(s->size >> 1); |
261 | TRef ptr, tr1, tr2, dp; | 261 | TRef ptr, tr1, tr2, dp; |
262 | if (t == IRT_CDATA) goto err_nyi; /* NYI: float IRType. */ | 262 | if (t == IRT_CDATA) goto err_nyi; /* NYI: float IRType. */ |
263 | dp = emitir(IRTG(IR_CNEW, IRT_CDATA), TREF_NIL, lj_ir_kint(J, sid)); | 263 | dp = emitir(IRTG(IR_CNEW, IRT_CDATA), lj_ir_kint(J, sid), TREF_NIL); |
264 | tr1 = emitir(IRT(IR_XLOAD, t), sp, 0); | 264 | tr1 = emitir(IRT(IR_XLOAD, t), sp, 0); |
265 | ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz)); | 265 | ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz)); |
266 | tr2 = emitir(IRT(IR_XLOAD, t), ptr, 0); | 266 | tr2 = emitir(IRT(IR_XLOAD, t), ptr, 0); |
@@ -274,7 +274,7 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | |||
274 | err_nyi: | 274 | err_nyi: |
275 | lj_trace_err(J, LJ_TRERR_NYICONV); | 275 | lj_trace_err(J, LJ_TRERR_NYICONV); |
276 | } | 276 | } |
277 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), sp, lj_ir_kint(J, sid)); | 277 | return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, sid), sp); |
278 | } | 278 | } |
279 | 279 | ||
280 | /* -- Convert TValue to C type (store) ------------------------------------ */ | 280 | /* -- Convert TValue to C type (store) ------------------------------------ */ |
@@ -300,7 +300,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
300 | s = ctype_raw(cts, sid); | 300 | s = ctype_raw(cts, sid); |
301 | if (ctype_isptr(s->info)) { | 301 | if (ctype_isptr(s->info)) { |
302 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; | 302 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; |
303 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INIT1); | 303 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); |
304 | if (ctype_isref(s->info)) | 304 | if (ctype_isref(s->info)) |
305 | s = ctype_rawchild(cts, s); | 305 | s = ctype_rawchild(cts, s); |
306 | else | 306 | else |
@@ -356,7 +356,7 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
356 | if (ctype_isptr(ct->info)) { | 356 | if (ctype_isptr(ct->info)) { |
357 | IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; | 357 | IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; |
358 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); | 358 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); |
359 | ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_INIT1); | 359 | ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_PTR); |
360 | ofs = 0; | 360 | ofs = 0; |
361 | ptr = crec_reassoc_ofs(J, ptr, &ofs, 1); | 361 | ptr = crec_reassoc_ofs(J, ptr, &ofs, 1); |
362 | } | 362 | } |
diff --git a/src/lj_ir.h b/src/lj_ir.h index 6495a780..33edf76c 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
@@ -111,7 +111,7 @@ | |||
111 | _(TNEW, AW, lit, lit) \ | 111 | _(TNEW, AW, lit, lit) \ |
112 | _(TDUP, AW, ref, ___) \ | 112 | _(TDUP, AW, ref, ___) \ |
113 | _(CNEW, AW, ref, ref) \ | 113 | _(CNEW, AW, ref, ref) \ |
114 | _(CNEWI, NW, ref, ref) /* CSE is ok, not marked as A. */ \ | 114 | _(CNEWP, NW, ref, ref) /* CSE is ok, not marked as A. */ \ |
115 | \ | 115 | \ |
116 | /* Write barriers. */ \ | 116 | /* Write barriers. */ \ |
117 | _(TBAR, S , ref, ___) \ | 117 | _(TBAR, S , ref, ___) \ |
@@ -188,9 +188,7 @@ IRFPMDEF(FPMENUM) | |||
188 | _(UDATA_UDTYPE, offsetof(GCudata, udtype)) \ | 188 | _(UDATA_UDTYPE, offsetof(GCudata, udtype)) \ |
189 | _(UDATA_FILE, sizeof(GCudata)) \ | 189 | _(UDATA_FILE, sizeof(GCudata)) \ |
190 | _(CDATA_TYPEID, offsetof(GCcdata, typeid)) \ | 190 | _(CDATA_TYPEID, offsetof(GCcdata, typeid)) \ |
191 | _(CDATA_INIT1, sizeof(GCcdata)) \ | 191 | _(CDATA_PTR, sizeof(GCcdata)) |
192 | _(CDATA_INIT2_4, sizeof(GCcdata)+4) \ | ||
193 | _(CDATA_INIT2_8, sizeof(GCcdata)+8) | ||
194 | 192 | ||
195 | typedef enum { | 193 | typedef enum { |
196 | #define FLENUM(name, ofs) IRFL_##name, | 194 | #define FLENUM(name, ofs) IRFL_##name, |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 74b15f32..d2c20546 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -153,7 +153,7 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J); | |||
153 | #define gcstep_barrier(J, ref) \ | 153 | #define gcstep_barrier(J, ref) \ |
154 | ((ref) < J->chain[IR_LOOP] && \ | 154 | ((ref) < J->chain[IR_LOOP] && \ |
155 | (J->chain[IR_SNEW] || J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ | 155 | (J->chain[IR_SNEW] || J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ |
156 | J->chain[IR_CNEW] || J->chain[IR_CNEWI] || J->chain[IR_TOSTR])) | 156 | J->chain[IR_CNEW] || J->chain[IR_CNEWP] || J->chain[IR_TOSTR])) |
157 | 157 | ||
158 | /* -- Constant folding for FP numbers ------------------------------------- */ | 158 | /* -- Constant folding for FP numbers ------------------------------------- */ |
159 | 159 | ||
@@ -1587,35 +1587,26 @@ LJFOLDF(fload_str_len_snew) | |||
1587 | 1587 | ||
1588 | /* The C type ID of cdata objects is immutable. */ | 1588 | /* The C type ID of cdata objects is immutable. */ |
1589 | LJFOLD(FLOAD CNEW IRFL_CDATA_TYPEID) | 1589 | LJFOLD(FLOAD CNEW IRFL_CDATA_TYPEID) |
1590 | LJFOLD(FLOAD CNEWI IRFL_CDATA_TYPEID) | 1590 | LJFOLD(FLOAD CNEWP IRFL_CDATA_TYPEID) |
1591 | LJFOLDF(fload_cdata_typeid_cnewi) | 1591 | LJFOLDF(fload_cdata_typeid_cnewi) |
1592 | { | 1592 | { |
1593 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) | 1593 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) |
1594 | return fleft->op2; /* No PHI barrier needed. CNEW/CNEWI op2 is const. */ | 1594 | return fleft->op1; /* No PHI barrier needed. CNEW/CNEWP op1 is const. */ |
1595 | return NEXTFOLD; | 1595 | return NEXTFOLD; |
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | /* Fixed initializers in cdata objects are immutable. */ | 1598 | /* Pointer cdata objects are immutable. */ |
1599 | LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT1) | 1599 | LJFOLD(FLOAD CNEWP IRFL_CDATA_PTR) |
1600 | LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT2_4) | 1600 | LJFOLDF(fload_cdata_ptr_cnewi) |
1601 | LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT2_8) | ||
1602 | LJFOLDF(fload_cdata_init_cnew) | ||
1603 | { | 1601 | { |
1604 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) { | 1602 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) |
1605 | IRIns *ir = fleft; | 1603 | return fleft->op2; /* Fold even across PHI to avoid allocations. */ |
1606 | /* Fold even across PHI to avoid expensive allocations. */ | ||
1607 | lua_assert(ir->op1 != REF_NIL); | ||
1608 | if (IR(ir->op1)->o == IR_CARG) ir = IR(ir->op1); | ||
1609 | return fins->op2 == IRFL_CDATA_INIT1 ? ir->op1 : ir->op2; | ||
1610 | } | ||
1611 | return NEXTFOLD; | 1604 | return NEXTFOLD; |
1612 | } | 1605 | } |
1613 | 1606 | ||
1614 | LJFOLD(FLOAD any IRFL_STR_LEN) | 1607 | LJFOLD(FLOAD any IRFL_STR_LEN) |
1615 | LJFOLD(FLOAD any IRFL_CDATA_TYPEID) | 1608 | LJFOLD(FLOAD any IRFL_CDATA_TYPEID) |
1616 | LJFOLD(FLOAD any IRFL_CDATA_INIT1) | 1609 | LJFOLD(FLOAD any IRFL_CDATA_PTR) |
1617 | LJFOLD(FLOAD any IRFL_CDATA_INIT2_4) | ||
1618 | LJFOLD(FLOAD any IRFL_CDATA_INIT2_8) | ||
1619 | LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */ | 1610 | LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */ |
1620 | LJFOLDX(lj_opt_cse) | 1611 | LJFOLDX(lj_opt_cse) |
1621 | 1612 | ||