aboutsummaryrefslogtreecommitdiff
path: root/src/lj_opt_split.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_opt_split.c')
-rw-r--r--src/lj_opt_split.c50
1 files changed, 31 insertions, 19 deletions
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c
index f53616b3..90b2b49c 100644
--- a/src/lj_opt_split.c
+++ b/src/lj_opt_split.c
@@ -159,7 +159,8 @@ static void split_ir(jit_State *J)
159 ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo); 159 ir->prev = lj_ir_kint(J, (int32_t)tv.u32.lo);
160 hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi); 160 hisubst[ref] = lj_ir_kint(J, (int32_t)tv.u32.hi);
161 } else { 161 } else {
162 ir->prev = (IRRef1)ref; /* Identity substitution for loword. */ 162 ir->prev = ref; /* Identity substitution for loword. */
163 hisubst[ref] = 0;
163 } 164 }
164 } 165 }
165 166
@@ -168,6 +169,7 @@ static void split_ir(jit_State *J)
168 IRIns *ir = &oir[ref]; 169 IRIns *ir = &oir[ref];
169 IRRef nref = lj_ir_nextins(J); 170 IRRef nref = lj_ir_nextins(J);
170 IRIns *nir = IR(nref); 171 IRIns *nir = IR(nref);
172 IRRef hi = 0;
171 173
172 /* Copy-substitute old instruction to new instruction. */ 174 /* Copy-substitute old instruction to new instruction. */
173 nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev; 175 nir->op1 = ir->op1 < nk ? ir->op1 : oir[ir->op1].prev;
@@ -175,10 +177,11 @@ static void split_ir(jit_State *J)
175 ir->prev = nref; /* Loword substitution. */ 177 ir->prev = nref; /* Loword substitution. */
176 nir->o = ir->o; 178 nir->o = ir->o;
177 nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI); 179 nir->t.irt = ir->t.irt & ~(IRT_MARK|IRT_ISPHI);
180 hisubst[ref] = 0;
178 181
179 /* Split 64 bit instructions. */ 182 /* Split 64 bit instructions. */
180 if (irt_isint64(ir->t)) { 183 if (irt_isint64(ir->t)) {
181 IRRef hi = hisubst[ir->op1]; 184 IRRef hiref = hisubst[ir->op1];
182 nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */ 185 nir->t.irt = IRT_INT | (nir->t.irt & IRT_GUARD); /* Turn into INT op. */
183 switch (ir->o) { 186 switch (ir->o) {
184 case IR_ADD: 187 case IR_ADD:
@@ -186,13 +189,13 @@ static void split_ir(jit_State *J)
186 /* Use plain op for hiword if loword cannot produce a carry/borrow. */ 189 /* Use plain op for hiword if loword cannot produce a carry/borrow. */
187 if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) { 190 if (irref_isk(nir->op2) && IR(nir->op2)->i == 0) {
188 ir->prev = nir->op1; /* Pass through loword. */ 191 ir->prev = nir->op1; /* Pass through loword. */
189 nir->op1 = hi; nir->op2 = hisubst[ir->op2]; 192 nir->op1 = hiref; nir->op2 = hisubst[ir->op2];
190 hi = nref; 193 hi = nref;
191 break; 194 break;
192 } 195 }
193 /* fallthrough */ 196 /* fallthrough */
194 case IR_NEG: 197 case IR_NEG:
195 hi = split_emit(J, IRTI(IR_HIOP), hi, hisubst[ir->op2]); 198 hi = split_emit(J, IRTI(IR_HIOP), hiref, hisubst[ir->op2]);
196 break; 199 break;
197 case IR_MUL: 200 case IR_MUL:
198 hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64); 201 hi = split_call64(J, hisubst, oir, ir, IRCALL_lj_carith_mul64);
@@ -212,6 +215,13 @@ static void split_ir(jit_State *J)
212 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 : 215 irt_isi64(ir->t) ? IRCALL_lj_carith_powi64 :
213 IRCALL_lj_carith_powu64); 216 IRCALL_lj_carith_powu64);
214 break; 217 break;
218 case IR_FLOAD:
219 lua_assert(ir->op2 == IRFL_CDATA_INT64);
220 hi = split_emit(J, IRTI(IR_FLOAD), nir->op1, IRFL_CDATA_INT64HI);
221#if LJ_BE
222 ir->prev = hi; hi = nref;
223#endif
224 break;
215 case IR_XLOAD: 225 case IR_XLOAD:
216 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2); 226 hi = split_emit(J, IRTI(IR_XLOAD), split_ptr(J, nir->op1), ir->op2);
217#if LJ_BE 227#if LJ_BE
@@ -220,19 +230,18 @@ static void split_ir(jit_State *J)
220 break; 230 break;
221 case IR_XSTORE: 231 case IR_XSTORE:
222#if LJ_LE 232#if LJ_LE
223 hi = hisubst[ir->op2]; 233 hiref = hisubst[ir->op2];
224#else 234#else
225 hi = nir->op2; nir->op2 = hisubst[ir->op2]; 235 hiref = nir->op2; nir->op2 = hisubst[ir->op2];
226#endif 236#endif
227 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hi); 237 split_emit(J, IRTI(IR_XSTORE), split_ptr(J, nir->op1), hiref);
228 continue; 238 break;
229 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */ 239 case IR_CONV: { /* Conversion to 64 bit integer. Others handled below. */
230 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); 240 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
231 if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */ 241 if (st == IRT_NUM || st == IRT_FLOAT) { /* FP to 64 bit int conv. */
232 hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref); 242 hi = split_emit(J, IRTI(IR_HIOP), nir->op1, nref);
233 } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */ 243 } else if (st == IRT_I64 || st == IRT_U64) { /* 64/64 bit cast. */
234 /* Drop cast, since assembler doesn't care. */ 244 /* Drop cast, since assembler doesn't care. */
235 hisubst[ref] = hi;
236 goto fwdlo; 245 goto fwdlo;
237 } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */ 246 } else if ((ir->op2 & IRCONV_SEXT)) { /* Sign-extend to 64 bit. */
238 IRRef k31 = lj_ir_kint(J, 31); 247 IRRef k31 = lj_ir_kint(J, 31);
@@ -242,27 +251,26 @@ static void split_ir(jit_State *J)
242 nir->op2 = k31; 251 nir->op2 = k31;
243 hi = nref; 252 hi = nref;
244 } else { /* Zero-extend to 64 bit. */ 253 } else { /* Zero-extend to 64 bit. */
245 hisubst[ref] = lj_ir_kint(J, 0); 254 hi = lj_ir_kint(J, 0);
246 goto fwdlo; 255 goto fwdlo;
247 } 256 }
248 break; 257 break;
249 } 258 }
250 case IR_PHI: { 259 case IR_PHI: {
251 IRRef hi2; 260 IRRef hiref2;
252 if ((irref_isk(nir->op1) && irref_isk(nir->op2)) || 261 if ((irref_isk(nir->op1) && irref_isk(nir->op2)) ||
253 nir->op1 == nir->op2) 262 nir->op1 == nir->op2)
254 J->cur.nins--; /* Drop useless PHIs. */ 263 J->cur.nins--; /* Drop useless PHIs. */
255 hi2 = hisubst[ir->op2]; 264 hiref2 = hisubst[ir->op2];
256 if (!((irref_isk(hi) && irref_isk(hi2)) || hi == hi2)) 265 if (!((irref_isk(hiref) && irref_isk(hiref2)) || hiref == hiref2))
257 split_emit(J, IRTI(IR_PHI), hi, hi2); 266 split_emit(J, IRTI(IR_PHI), hiref, hiref2);
258 continue; 267 break;
259 } 268 }
260 default: 269 default:
261 lua_assert(ir->o <= IR_NE); 270 lua_assert(ir->o <= IR_NE); /* Comparisons. */
262 split_emit(J, IRTGI(IR_HIOP), hi, hisubst[ir->op2]); /* Comparisons. */ 271 split_emit(J, IRTGI(IR_HIOP), hiref, hisubst[ir->op2]);
263 continue; 272 break;
264 } 273 }
265 hisubst[ref] = hi; /* Store hiword substitution. */
266 } else if (ir->o == IR_CONV) { /* See above, too. */ 274 } else if (ir->o == IR_CONV) { /* See above, too. */
267 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK); 275 IRType st = (IRType)(ir->op2 & IRCONV_SRCMASK);
268 if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */ 276 if (st == IRT_I64 || st == IRT_U64) { /* Conversion from 64 bit int. */
@@ -277,9 +285,13 @@ static void split_ir(jit_State *J)
277 nir->op1 = nir->op2 = 0; 285 nir->op1 = nir->op2 = 0;
278 } 286 }
279 } 287 }
288 } else if (ir->o == IR_CNEWI) {
289 if (hisubst[ir->op2])
290 split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]);
280 } else if (ir->o == IR_LOOP) { 291 } else if (ir->o == IR_LOOP) {
281 J->loopref = nref; /* Needed by assembler. */ 292 J->loopref = nref; /* Needed by assembler. */
282 } 293 }
294 hisubst[ref] = hi; /* Store hiword substitution. */
283 } 295 }
284 296
285 /* Add PHI marks. */ 297 /* Add PHI marks. */