diff options
| author | Mike Pall <mike> | 2011-04-29 19:40:50 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-04-29 19:40:50 +0200 |
| commit | c77ca54564e63b7ac20a570eee84c57142d6960a (patch) | |
| tree | 118392f8d4cd6ef783a7dd78f7894b8abe9309f5 /src | |
| parent | eb7b452d5393993dc568683b05cbb7b3c4f4f5d0 (diff) | |
| download | luajit-c77ca54564e63b7ac20a570eee84c57142d6960a.tar.gz luajit-c77ca54564e63b7ac20a570eee84c57142d6960a.tar.bz2 luajit-c77ca54564e63b7ac20a570eee84c57142d6960a.zip | |
FFI: Compile C function calls with 64 bit args/results in 32 bit mode.
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]); |
