diff options
Diffstat (limited to 'src/lj_opt_split.c')
-rw-r--r-- | src/lj_opt_split.c | 50 |
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. */ |