aboutsummaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 1a78e32a..4da1a0a3 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1079,6 +1079,64 @@ static void asm_phi_shuffle(ASMState *as)
1079 } 1079 }
1080} 1080}
1081 1081
1082/* Copy unsynced left/right PHI spill slots. Rarely needed. */
1083static void asm_phi_copyspill(ASMState *as)
1084{
1085 int need = 0;
1086 IRIns *ir;
1087 for (ir = IR(as->orignins-1); ir->o == IR_PHI; ir--)
1088 if (ra_hasspill(ir->s) && ra_hasspill(IR(ir->op1)->s))
1089 need |= irt_isfp(ir->t) ? 2 : 1; /* Unsynced spill slot? */
1090 if ((need & 1)) { /* Copy integer spill slots. */
1091#if !LJ_TARGET_X86ORX64
1092 Reg r = RID_TMP;
1093#else
1094 Reg r = RID_RET;
1095 if ((as->freeset & RSET_GPR))
1096 r = rset_pickbot((as->freeset & RSET_GPR));
1097 else
1098 emit_spload(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
1099#endif
1100 for (ir = IR(as->orignins-1); ir->o == IR_PHI; ir--) {
1101 if (ra_hasspill(ir->s)) {
1102 IRIns *irl = IR(ir->op1);
1103 if (ra_hasspill(irl->s) && !irt_isfp(ir->t)) {
1104 emit_spstore(as, irl, r, sps_scale(irl->s));
1105 emit_spload(as, ir, r, sps_scale(ir->s));
1106 }
1107 }
1108 }
1109#if LJ_TARGET_X86ORX64
1110 if (!rset_test(as->freeset, r))
1111 emit_spstore(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
1112#endif
1113 }
1114#if !LJ_SOFTFP
1115 if ((need & 2)) { /* Copy FP spill slots. */
1116#if LJ_TARGET_X86
1117 Reg r = RID_XMM0;
1118#else
1119 Reg r = RID_FPRET;
1120#endif
1121 if ((as->freeset & RSET_FPR))
1122 r = rset_pickbot((as->freeset & RSET_FPR));
1123 if (!rset_test(as->freeset, r))
1124 emit_spload(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
1125 for (ir = IR(as->orignins-1); ir->o == IR_PHI; ir--) {
1126 if (ra_hasspill(ir->s)) {
1127 IRIns *irl = IR(ir->op1);
1128 if (ra_hasspill(irl->s) && irt_isfp(ir->t)) {
1129 emit_spstore(as, irl, r, sps_scale(irl->s));
1130 emit_spload(as, ir, r, sps_scale(ir->s));
1131 }
1132 }
1133 }
1134 if (!rset_test(as->freeset, r))
1135 emit_spstore(as, IR(regcost_ref(as->cost[r])), r, SPOFS_TMP);
1136 }
1137#endif
1138}
1139
1082/* Emit renames for left PHIs which are only spilled outside the loop. */ 1140/* Emit renames for left PHIs which are only spilled outside the loop. */
1083static void asm_phi_fixup(ASMState *as) 1141static void asm_phi_fixup(ASMState *as)
1084{ 1142{
@@ -1132,7 +1190,7 @@ static void asm_phi(ASMState *as, IRIns *ir)
1132 if (ra_hasreg(irl->r) || ra_hasreg(irr->r)) 1190 if (ra_hasreg(irl->r) || ra_hasreg(irr->r))
1133 lj_trace_err(as->J, LJ_TRERR_NYIPHI); 1191 lj_trace_err(as->J, LJ_TRERR_NYIPHI);
1134 ra_spill(as, ir); 1192 ra_spill(as, ir);
1135 irl->s = irr->s = ir->s; /* Sync left/right PHI spill slots. */ 1193 irr->s = ir->s; /* Set right PHI spill slot. Sync left slot later. */
1136 } 1194 }
1137} 1195}
1138 1196
@@ -1142,6 +1200,7 @@ static void asm_loop_fixup(ASMState *as);
1142/* Middle part of a loop. */ 1200/* Middle part of a loop. */
1143static void asm_loop(ASMState *as) 1201static void asm_loop(ASMState *as)
1144{ 1202{
1203 MCode *mcspill;
1145 /* LOOP is a guard, so the snapno is up to date. */ 1204 /* LOOP is a guard, so the snapno is up to date. */
1146 as->loopsnapno = as->snapno; 1205 as->loopsnapno = as->snapno;
1147 if (as->gcsteps) 1206 if (as->gcsteps)
@@ -1151,10 +1210,14 @@ static void asm_loop(ASMState *as)
1151 as->sectref = 0; 1210 as->sectref = 0;
1152 if (!neverfuse(as)) as->fuseref = 0; 1211 if (!neverfuse(as)) as->fuseref = 0;
1153 asm_phi_shuffle(as); 1212 asm_phi_shuffle(as);
1213 mcspill = as->mcp;
1214 asm_phi_copyspill(as);
1154 asm_loop_fixup(as); 1215 asm_loop_fixup(as);
1155 as->mcloop = as->mcp; 1216 as->mcloop = as->mcp;
1156 RA_DBGX((as, "===== LOOP =====")); 1217 RA_DBGX((as, "===== LOOP ====="));
1157 if (!as->realign) RA_DBG_FLUSH(); 1218 if (!as->realign) RA_DBG_FLUSH();
1219 if (as->mcp != mcspill)
1220 emit_jmp(as, mcspill);
1158} 1221}
1159 1222
1160/* -- Target-specific assembler ------------------------------------------- */ 1223/* -- Target-specific assembler ------------------------------------------- */