aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-04-29 19:40:50 +0200
committerMike Pall <mike>2011-04-29 19:40:50 +0200
commitc77ca54564e63b7ac20a570eee84c57142d6960a (patch)
tree118392f8d4cd6ef783a7dd78f7894b8abe9309f5
parenteb7b452d5393993dc568683b05cbb7b3c4f4f5d0 (diff)
downloadluajit-c77ca54564e63b7ac20a570eee84c57142d6960a.tar.gz
luajit-c77ca54564e63b7ac20a570eee84c57142d6960a.tar.bz2
luajit-c77ca54564e63b7ac20a570eee84c57142d6960a.zip
FFI: Compile C function calls with 64 bit args/results in 32 bit mode.
-rw-r--r--doc/ext_ffi_semantics.html2
-rw-r--r--src/lj_asm.c1
-rw-r--r--src/lj_crecord.c5
-rw-r--r--src/lj_opt_split.c38
4 files changed, 42 insertions, 4 deletions
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
index d9aa27c8..b612dbc5 100644
--- a/doc/ext_ffi_semantics.html
+++ b/doc/ext_ffi_semantics.html
@@ -980,8 +980,6 @@ two.</li>
980<li>Calls to non-cdecl or vararg C&nbsp;functions.</li> 980<li>Calls to non-cdecl or vararg C&nbsp;functions.</li>
981<li>Calls to C&nbsp;functions with aggregates passed or returned by 981<li>Calls to C&nbsp;functions with aggregates passed or returned by
982value.</li> 982value.</li>
983<li>Calls to C&nbsp;functions with 64 bit arguments or return values
984on 32 bit CPUs.</li>
985<li>Calls to ctype metamethods which are not plain functions.</li> 983<li>Calls to ctype metamethods which are not plain functions.</li>
986<li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype 984<li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype
987<tt>__index</tt> tables.</li> 985<tt>__index</tt> tables.</li>
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]);