aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_asm.c21
-rw-r--r--src/lj_opt_split.c129
2 files changed, 109 insertions, 41 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 0402bf7a..3c0575ab 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -741,8 +741,9 @@ static int asm_snap_checkrename(ASMState *as, IRRef ren)
741 SnapEntry *map = &as->T->snapmap[snap->mapofs]; 741 SnapEntry *map = &as->T->snapmap[snap->mapofs];
742 MSize n, nent = snap->nent; 742 MSize n, nent = snap->nent;
743 for (n = 0; n < nent; n++) { 743 for (n = 0; n < nent; n++) {
744 IRRef ref = snap_ref(map[n]); 744 SnapEntry sn = map[n];
745 if (ref == ren) { 745 IRRef ref = snap_ref(sn);
746 if (ref == ren || (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && ++ref == ren)) {
746 IRIns *ir = IR(ref); 747 IRIns *ir = IR(ref);
747 ra_spill(as, ir); /* Register renamed, so force a spill slot. */ 748 ra_spill(as, ir); /* Register renamed, so force a spill slot. */
748 RA_DBGX((as, "snaprensp $f $s", ref, ir->s)); 749 RA_DBGX((as, "snaprensp $f $s", ref, ir->s));
@@ -785,9 +786,9 @@ static void asm_collectargs(ASMState *as, IRIns *ir,
785 while (n-- > 1) { 786 while (n-- > 1) {
786 ir = IR(ir->op1); 787 ir = IR(ir->op1);
787 lua_assert(ir->o == IR_CARG); 788 lua_assert(ir->o == IR_CARG);
788 args[n] = ir->op2; 789 args[n] = ir->op2 == REF_NIL ? 0 : ir->op2;
789 } 790 }
790 args[0] = ir->op1; 791 args[0] = ir->op1 == REF_NIL ? 0 : ir->op1;
791 lua_assert(IR(ir->op1)->o != IR_CARG); 792 lua_assert(IR(ir->op1)->o != IR_CARG);
792} 793}
793 794
@@ -1181,12 +1182,6 @@ static void asm_head_side(ASMState *as)
1181 } 1182 }
1182 as->T->spadjust = (uint16_t)spadj; 1183 as->T->spadjust = (uint16_t)spadj;
1183 1184
1184#if !LJ_TARGET_X86ORX64
1185 /* Restore BASE register from parent spill slot. */
1186 if (ra_hasspill(irp->s))
1187 emit_spload(as, IR(REF_BASE), IR(REF_BASE)->r, spdelta + sps_scale(irp->s));
1188#endif
1189
1190 /* Reload spilled target registers. */ 1185 /* Reload spilled target registers. */
1191 if (pass2) { 1186 if (pass2) {
1192 for (i = as->stopins; i > REF_BASE; i--) { 1187 for (i = as->stopins; i > REF_BASE; i--) {
@@ -1222,6 +1217,12 @@ static void asm_head_side(ASMState *as)
1222 emit_setvmstate(as, (int32_t)as->T->traceno); 1217 emit_setvmstate(as, (int32_t)as->T->traceno);
1223 emit_spsub(as, spdelta); 1218 emit_spsub(as, spdelta);
1224 1219
1220#if !LJ_TARGET_X86ORX64
1221 /* Restore BASE register from parent spill slot. */
1222 if (ra_hasspill(irp->s))
1223 emit_spload(as, IR(REF_BASE), IR(REF_BASE)->r, sps_scale(irp->s));
1224#endif
1225
1225 /* Restore target registers from parent spill slots. */ 1226 /* Restore target registers from parent spill slots. */
1226 if (pass3) { 1227 if (pass3) {
1227 RegSet work = ~as->freeset & RSET_ALL; 1228 RegSet work = ~as->freeset & RSET_ALL;
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c
index 07c52564..ea9b6fe3 100644
--- a/src/lj_opt_split.c
+++ b/src/lj_opt_split.c
@@ -107,6 +107,25 @@ static IRRef split_emit(jit_State *J, uint16_t ot, IRRef1 op1, IRRef1 op2)
107} 107}
108 108
109#if LJ_SOFTFP 109#if LJ_SOFTFP
110/* Emit a (checked) number to integer conversion. */
111static IRRef split_num2int(jit_State *J, IRRef lo, IRRef hi, int check)
112{
113 IRRef tmp, res;
114#if LJ_LE
115 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), lo, hi);
116#else
117 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hi, lo);
118#endif
119 res = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_softfp_d2i);
120 if (check) {
121 tmp = split_emit(J, IRTI(IR_CALLN), res, IRCALL_softfp_i2d);
122 split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), tmp, tmp);
123 split_emit(J, IRTGI(IR_EQ), tmp, lo);
124 split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP), tmp+1, hi);
125 }
126 return res;
127}
128
110/* Emit a CALLN with one split 64 bit argument. */ 129/* Emit a CALLN with one split 64 bit argument. */
111static IRRef split_call_l(jit_State *J, IRRef1 *hisubst, IRIns *oir, 130static IRRef split_call_l(jit_State *J, IRRef1 *hisubst, IRIns *oir,
112 IRIns *ir, IRCallID id) 131 IRIns *ir, IRCallID id)
@@ -161,16 +180,18 @@ static IRRef split_call_ll(jit_State *J, IRRef1 *hisubst, IRIns *oir,
161} 180}
162 181
163/* Get a pointer to the other 32 bit word (LE: hiword, BE: loword). */ 182/* Get a pointer to the other 32 bit word (LE: hiword, BE: loword). */
164static IRRef split_ptr(jit_State *J, IRRef ref) 183static IRRef split_ptr(jit_State *J, IRIns *oir, IRRef ref)
165{ 184{
166 IRIns *ir = IR(ref); 185 IRRef nref = oir[ref].prev;
186 IRIns *ir = IR(nref);
167 int32_t ofs = 4; 187 int32_t ofs = 4;
168 if (ir->o == IR_ADD && irref_isk(ir->op2)) { /* Reassociate address. */ 188 if (ir->o == IR_ADD && irref_isk(ir->op2) && !irt_isphi(oir[ref].t)) {
189 /* Reassociate address. */
169 ofs += IR(ir->op2)->i; 190 ofs += IR(ir->op2)->i;
170 ref = ir->op1; 191 nref = ir->op1;
171 if (ofs == 0) return ref; 192 if (ofs == 0) return nref;
172 } 193 }
173 return split_emit(J, IRTI(IR_ADD), ref, lj_ir_kint(J, ofs)); 194 return split_emit(J, IRTI(IR_ADD), nref, lj_ir_kint(J, ofs));
174} 195}
175 196
176/* Transform the old IR to the new IR. */ 197/* Transform the old IR to the new IR. */
@@ -279,13 +300,22 @@ static void split_ir(jit_State *J)
279 hi = split_emit(J, IRT(ir->o == IR_NEG ? IR_BXOR : IR_BAND, IRT_SOFTFP), 300 hi = split_emit(J, IRT(ir->o == IR_NEG ? IR_BXOR : IR_BAND, IRT_SOFTFP),
280 hisubst[ir->op1], hisubst[ir->op2]); 301 hisubst[ir->op1], hisubst[ir->op2]);
281 break; 302 break;
282 case IR_SLOAD: case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD: 303 case IR_SLOAD:
283 case IR_MIN: case IR_MAX: case IR_STRTO: 304 if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from int to number. */
305 nir->op2 &= ~IRSLOAD_CONVERT;
306 ir->prev = nref = split_emit(J, IRTI(IR_CALLN), nref,
307 IRCALL_softfp_i2d);
308 hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
309 break;
310 }
311 /* fallthrough */
312 case IR_ALOAD: case IR_HLOAD: case IR_ULOAD: case IR_VLOAD:
313 case IR_STRTO:
284 hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref); 314 hi = split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
285 break; 315 break;
286 case IR_XLOAD: 316 case IR_XLOAD:
287 hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP), 317 hi = split_emit(J, IRT(IR_XLOAD, IRT_SOFTFP),
288 split_ptr(J, nir->op1), ir->op2); 318 split_ptr(J, oir, ir->op1), ir->op2);
289#if LJ_BE 319#if LJ_BE
290 ir->prev = hi; hi = nref; 320 ir->prev = hi; hi = nref;
291#endif 321#endif
@@ -300,7 +330,7 @@ static void split_ir(jit_State *J)
300 IRRef hiref = nir->op2; nir->op2 = hisubst[ir->op2]; 330 IRRef hiref = nir->op2; nir->op2 = hisubst[ir->op2];
301#endif 331#endif
302 split_emit(J, IRT(IR_XSTORE, IRT_SOFTFP), 332 split_emit(J, IRT(IR_XSTORE, IRT_SOFTFP),
303 split_ptr(J, nir->op1), hiref); 333 split_ptr(J, oir, ir->op1), hiref);
304 break; 334 break;
305 } 335 }
306 case IR_CONV: { /* Conversion to number. Others handled below. */ 336 case IR_CONV: { /* Conversion to number. Others handled below. */
@@ -336,9 +366,9 @@ static void split_ir(jit_State *J)
336 hisubst[ir->op1], hisubst[ir->op2]); 366 hisubst[ir->op1], hisubst[ir->op2]);
337 break; 367 break;
338 default: 368 default:
339 lua_assert(ir->o <= IR_NE); 369 lua_assert(ir->o <= IR_NE || ir->o == IR_MIN || ir->o == IR_MAX);
340 split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP), 370 hi = split_emit(J, IRTG(IR_HIOP, IRT_SOFTFP),
341 hisubst[ir->op1], hisubst[ir->op2]); 371 hisubst[ir->op1], hisubst[ir->op2]);
342 break; 372 break;
343 } 373 }
344 } else 374 } else
@@ -387,7 +417,7 @@ static void split_ir(jit_State *J)
387#endif 417#endif
388 break; 418 break;
389 case IR_XLOAD: 419 case IR_XLOAD:
390 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2); 420 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, oir, ir->op1), ir->op2);
391#if LJ_BE 421#if LJ_BE
392 ir->prev = hi; hi = nref; 422 ir->prev = hi; hi = nref;
393#endif 423#endif
@@ -398,14 +428,14 @@ static void split_ir(jit_State *J)
398#else 428#else
399 hiref = nir->op2; nir->op2 = hisubst[ir->op2]; 429 hiref = nir->op2; nir->op2 = hisubst[ir->op2];
400#endif 430#endif
401 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hiref); 431 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, oir, ir->op1), hiref);
402 break; 432 break;
403 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ 433 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */
404 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); 434 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
405#if LJ_SOFTFP 435#if LJ_SOFTFP
406 if (st == IRT_NUM) { /* NUM to 64 bit int conv. */ 436 if (st == IRT_NUM) { /* NUM to 64 bit int conv. */
407 split_call_l(J, hisubst, oir, ir, 437 hi = split_call_l(J, hisubst, oir, ir,
408 irt_isi64(ir->t) ? IRCALL_softfp_d2l : IRCALL_softfp_d2ul); 438 irt_isi64(ir->t) ? IRCALL_softfp_d2l : IRCALL_softfp_d2ul);
409 } else if (st == IRT_FLOAT) { /* FLOAT to 64 bit int conv. */ 439 } else if (st == IRT_FLOAT) { /* FLOAT to 64 bit int conv. */
410 nir->o = IR_CALLN; 440 nir->o = IR_CALLN;
411 nir->op2 = irt_isi64(ir->t) ? IRCALL_softfp_f2l : IRCALL_softfp_f2ul; 441 nir->op2 = irt_isi64(ir->t) ? IRCALL_softfp_f2l : IRCALL_softfp_f2ul;
@@ -452,7 +482,15 @@ static void split_ir(jit_State *J)
452 } else 482 } else
453#endif 483#endif
454#if LJ_SOFTFP 484#if LJ_SOFTFP
455 if (ir->o == IR_TOBIT) { 485 if (ir->o == IR_SLOAD) {
486 if ((nir->op2 & IRSLOAD_CONVERT)) { /* Convert from number to int. */
487 nir->op2 &= ~IRSLOAD_CONVERT;
488 if (!(nir->op2 & IRSLOAD_TYPECHECK))
489 nir->t.irt = IRT_INT; /* Drop guard. */
490 split_emit(J, IRT(IR_HIOP, IRT_SOFTFP), nref, nref);
491 ir->prev = split_num2int(J, nref, nref+1, irt_isguard(ir->t));
492 }
493 } else if (ir->o == IR_TOBIT) {
456 IRRef tmp, op1 = ir->op1; 494 IRRef tmp, op1 = ir->op1;
457 J->cur.nins--; 495 J->cur.nins--;
458#if LJ_LE 496#if LJ_LE
@@ -461,6 +499,16 @@ static void split_ir(jit_State *J)
461 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev); 499 tmp = split_emit(J, IRT(IR_CARG, IRT_NIL), hisubst[op1], oir[op1].prev);
462#endif 500#endif
463 ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit); 501 ir->prev = split_emit(J, IRTI(IR_CALLN), tmp, IRCALL_lj_vm_tobit);
502 } else if (ir->o == IR_TOSTR) {
503 if (hisubst[ir->op1]) {
504 if (irref_isk(ir->op1))
505 nir->op1 = ir->op1;
506 else
507 split_emit(J, IRT(IR_HIOP, IRT_NIL), hisubst[ir->op1], nref);
508 }
509 } else if (ir->o == IR_HREF || ir->o == IR_NEWREF) {
510 if (irref_isk(ir->op2) && hisubst[ir->op2])
511 nir->op2 = ir->op2;
464 } else 512 } else
465#endif 513#endif
466 if (ir->o == IR_CONV) { /* See above, too. */ 514 if (ir->o == IR_CONV) { /* See above, too. */
@@ -505,16 +553,21 @@ static void split_ir(jit_State *J)
505#if LJ_SOFTFP 553#if LJ_SOFTFP
506 if (st == IRT_NUM || (LJ_32 && LJ_HASFFI && st == IRT_FLOAT)) { 554 if (st == IRT_NUM || (LJ_32 && LJ_HASFFI && st == IRT_FLOAT)) {
507 if (irt_isguard(ir->t)) { 555 if (irt_isguard(ir->t)) {
508 lua_assert(0); /* NYI: missing check. */ 556 lua_assert(st == IRT_NUM && irt_isint(ir->t));
509 } 557 J->cur.nins--;
510 split_call_l(J, hisubst, oir, ir, 558 ir->prev = split_num2int(J, nir->op1, hisubst[ir->op1], 1);
559 } else {
560 split_call_l(J, hisubst, oir, ir,
511#if LJ_32 && LJ_HASFFI 561#if LJ_32 && LJ_HASFFI
512 st == IRT_NUM ? IRCALL_softfp_d2i : IRCALL_softfp_f2i 562 st == IRT_NUM ?
563 (irt_isint(ir->t) ? IRCALL_softfp_d2i : IRCALL_softfp_d2ui) :
564 (irt_isint(ir->t) ? IRCALL_softfp_f2i : IRCALL_softfp_f2ui)
513#else 565#else
514 IRCALL_softfp_d2i 566 IRCALL_softfp_d2i
515#endif 567#endif
516 ); 568 );
517 J->cur.nins--; /* Drop unused HIOP. */ 569 J->cur.nins--; /* Drop unused HIOP. */
570 }
518 } 571 }
519#endif 572#endif
520 } else if (ir->o == IR_CALLXS) { 573 } else if (ir->o == IR_CALLXS) {
@@ -550,8 +603,20 @@ static void split_ir(jit_State *J)
550 } 603 }
551 hiref = hisubst[ir->op2]; 604 hiref = hisubst[ir->op2];
552 if (hiref) { 605 if (hiref) {
606#if !LJ_TARGET_X86
607 int carg = 0;
608 IRIns *cir;
609 for (cir = IR(nir->op1); cir->o == IR_CARG; cir = IR(cir->op1))
610 carg++;
611 if ((carg & 1) == 0) { /* Align 64 bit arguments. */
612 IRRef op2 = nir->op2;
613 nir->op2 = REF_NIL;
614 nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2);
615 nir = IR(nref);
616 }
617#endif
553#if LJ_BE 618#if LJ_BE
554 IRRef tmp = nir->op2; nir->op2 = hiref; hiref = tmp; 619 { IRRef tmp = nir->op2; nir->op2 = hiref; hiref = tmp; }
555#endif 620#endif
556 ir->prev = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, hiref); 621 ir->prev = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, hiref);
557 } 622 }
@@ -580,14 +645,11 @@ static void split_ir(jit_State *J)
580 SnapShot *snap = &J->cur.snap[i]; 645 SnapShot *snap = &J->cur.snap[i];
581 SnapEntry *map = &J->cur.snapmap[snap->mapofs]; 646 SnapEntry *map = &J->cur.snapmap[snap->mapofs];
582 MSize n, nent = snap->nent; 647 MSize n, nent = snap->nent;
583 snap->ref = oir[snap->ref].prev; 648 snap->ref = snap->ref == REF_FIRST ? REF_FIRST : oir[snap->ref].prev;
584 for (n = 0; n < nent; n++) { 649 for (n = 0; n < nent; n++) {
585 SnapEntry sn = map[n]; 650 SnapEntry sn = map[n];
586 IRIns *ir = &oir[snap_ref(sn)]; 651 IRIns *ir = &oir[snap_ref(sn)];
587 if (LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))) 652 if (!(LJ_SOFTFP && (sn & SNAP_SOFTFPNUM) && irref_isk(snap_ref(sn))))
588 map[n] = ((sn & 0xffff0000) |
589 (IRRef1)lj_ir_k64(J, IR_KNUM, ir_knum(ir)));
590 else
591 map[n] = ((sn & 0xffff0000) | ir->prev); 653 map[n] = ((sn & 0xffff0000) | ir->prev);
592 } 654 }
593 } 655 }
@@ -612,6 +674,11 @@ static int split_needsplit(jit_State *J)
612 for (ir = IR(REF_FIRST), irend = IR(J->cur.nins); ir < irend; ir++) 674 for (ir = IR(REF_FIRST), irend = IR(J->cur.nins); ir < irend; ir++)
613 if (LJ_SOFTFP ? irt_is64(ir->t) : irt_isint64(ir->t)) 675 if (LJ_SOFTFP ? irt_is64(ir->t) : irt_isint64(ir->t))
614 return 1; 676 return 1;
677 if (LJ_SOFTFP) {
678 for (ref = J->chain[IR_SLOAD]; ref; ref = IR(ref)->prev)
679 if ((IR(ref)->op2 & IRSLOAD_CONVERT))
680 return 1;
681 }
615 for (ref = J->chain[IR_CONV]; ref; ref = IR(ref)->prev) 682 for (ref = J->chain[IR_CONV]; ref; ref = IR(ref)->prev)
616 if ((LJ_SOFTFP && (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_NUM) || 683 if ((LJ_SOFTFP && (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_NUM) ||
617 (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_I64 || 684 (IR(ref)->op2 & IRCONV_SRCMASK) == IRT_I64 ||