diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 1 | ||||
-rw-r--r-- | src/lj_crecord.c | 5 | ||||
-rw-r--r-- | src/lj_opt_split.c | 38 |
3 files changed, 42 insertions, 2 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index d5e74185..46142f5c 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -3346,6 +3346,7 @@ static void asm_hiop(ASMState *as, IRIns *ir) | |||
3346 | break; | 3346 | break; |
3347 | } | 3347 | } |
3348 | case IR_CALLN: | 3348 | case IR_CALLN: |
3349 | case IR_CALLXS: | ||
3349 | ra_destreg(as, ir, RID_RETHI); | 3350 | ra_destreg(as, ir, RID_RETHI); |
3350 | if (!uselo) | 3351 | if (!uselo) |
3351 | ra_allocref(as, ir->op1, RID2RSET(RID_RET)); /* Mark call as used. */ | 3352 | ra_allocref(as, ir->op1, RID2RSET(RID_RET)); /* Mark call as used. */ |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 8330faaf..9c93a6f1 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -785,15 +785,16 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd) | |||
785 | #if LJ_TARGET_X86 | 785 | #if LJ_TARGET_X86 |
786 | ctype_cconv(ct->info) != CTCC_CDECL || | 786 | ctype_cconv(ct->info) != CTCC_CDECL || |
787 | #endif | 787 | #endif |
788 | t == IRT_CDATA || (LJ_32 && (t == IRT_I64 || t == IRT_U64))) | 788 | t == IRT_CDATA) |
789 | lj_trace_err(J, LJ_TRERR_NYICALL); | 789 | lj_trace_err(J, LJ_TRERR_NYICALL); |
790 | tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); | 790 | tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func); |
791 | if (t == IRT_FLOAT || t == IRT_U32) { | 791 | if (t == IRT_FLOAT || t == IRT_U32) { |
792 | tr = emitconv(tr, IRT_NUM, t, 0); | 792 | tr = emitconv(tr, IRT_NUM, t, 0); |
793 | } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || | 793 | } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) || |
794 | (LJ_64 && (t == IRT_I64 || t == IRT_U64))) { | 794 | (t == IRT_I64 || t == IRT_U64)) { |
795 | TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); | 795 | TRef trid = lj_ir_kint(J, ctype_cid(ct->info)); |
796 | tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); | 796 | tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr); |
797 | if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J); | ||
797 | } | 798 | } |
798 | J->base[0] = tr; | 799 | J->base[0] = tr; |
799 | J->needsnap = 1; | 800 | J->needsnap = 1; |
diff --git a/src/lj_opt_split.c b/src/lj_opt_split.c index 90b2b49c..e52ddfd4 100644 --- a/src/lj_opt_split.c +++ b/src/lj_opt_split.c | |||
@@ -256,6 +256,8 @@ static void split_ir(jit_State *J) | |||
256 | } | 256 | } |
257 | break; | 257 | break; |
258 | } | 258 | } |
259 | case IR_CALLXS: | ||
260 | goto split_call; | ||
259 | case IR_PHI: { | 261 | case IR_PHI: { |
260 | IRRef hiref2; | 262 | IRRef hiref2; |
261 | if ((irref_isk(nir->op1) && irref_isk(nir->op2)) || | 263 | if ((irref_isk(nir->op1) && irref_isk(nir->op2)) || |
@@ -285,6 +287,42 @@ static void split_ir(jit_State *J) | |||
285 | nir->op1 = nir->op2 = 0; | 287 | nir->op1 = nir->op2 = 0; |
286 | } | 288 | } |
287 | } | 289 | } |
290 | } else if (ir->o == IR_CALLXS) { | ||
291 | IRRef hiref; | ||
292 | split_call: | ||
293 | hiref = hisubst[ir->op1]; | ||
294 | if (hiref) { | ||
295 | IROpT ot = nir->ot; | ||
296 | IRRef op2 = nir->op2; | ||
297 | nir->ot = IRT(IR_CARG, IRT_NIL); | ||
298 | #if LJ_LE | ||
299 | nir->op2 = hiref; | ||
300 | #else | ||
301 | nir->op2 = nir->op1; nir->op1 = hiref; | ||
302 | #endif | ||
303 | ir->prev = nref = split_emit(J, ot, nref, op2); | ||
304 | } | ||
305 | if (irt_isint64(ir->t)) | ||
306 | hi = split_emit(J, IRTI(IR_HIOP), nref, nref); | ||
307 | } else if (ir->o == IR_CARG) { | ||
308 | IRRef hiref = hisubst[ir->op1]; | ||
309 | if (hiref) { | ||
310 | IRRef op2 = nir->op2; | ||
311 | #if LJ_LE | ||
312 | nir->op2 = hiref; | ||
313 | #else | ||
314 | nir->op2 = nir->op1; nir->op1 = hiref; | ||
315 | #endif | ||
316 | ir->prev = nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2); | ||
317 | nir = IR(nref); | ||
318 | } | ||
319 | hiref = hisubst[ir->op2]; | ||
320 | if (hiref) { | ||
321 | #if LJ_BE | ||
322 | IRRef tmp = nir->op2; nir->op2 = hiref; hiref = tmp; | ||
323 | #endif | ||
324 | ir->prev = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, hiref); | ||
325 | } | ||
288 | } else if (ir->o == IR_CNEWI) { | 326 | } else if (ir->o == IR_CNEWI) { |
289 | if (hisubst[ir->op2]) | 327 | if (hisubst[ir->op2]) |
290 | split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]); | 328 | split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]); |