]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
FFI: Compile C function calls with 64 bit args/results in 32 bit mode.
authorMike Pall <mike>
Fri, 29 Apr 2011 17:40:50 +0000 (19:40 +0200)
committerMike Pall <mike>
Fri, 29 Apr 2011 17:40:50 +0000 (19:40 +0200)
doc/ext_ffi_semantics.html
src/lj_asm.c
src/lj_crecord.c
src/lj_opt_split.c

index d9aa27c8403ea5be57d8d5c5f64e716b64e98b8c..b612dbc5beeb908aa7997629102f72fdd16cc48a 100644 (file)
@@ -980,8 +980,6 @@ two.</li>
 <li>Calls to non-cdecl or vararg C&nbsp;functions.</li>
 <li>Calls to C&nbsp;functions with aggregates passed or returned by
 value.</li>
-<li>Calls to C&nbsp;functions with 64 bit arguments or return values
-on 32 bit CPUs.</li>
 <li>Calls to ctype metamethods which are not plain functions.</li>
 <li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype
 <tt>__index</tt> tables.</li>
index d5e74185c0a000fc52d090c73c4f895750021d14..46142f5c423a8eda4ef9d46dd9ac5e6b2dd23d8e 100644 (file)
@@ -3346,6 +3346,7 @@ static void asm_hiop(ASMState *as, IRIns *ir)
     break;
     }
   case IR_CALLN:
+  case IR_CALLXS:
     ra_destreg(as, ir, RID_RETHI);
     if (!uselo)
       ra_allocref(as, ir->op1, RID2RSET(RID_RET));  /* Mark call as used. */
index 8330faaf1aacf1a3dcd81997f05613c83d81b54c..9c93a6f1fe5ebac57772f30be63fe85d03d37fce 100644 (file)
@@ -785,15 +785,16 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
 #if LJ_TARGET_X86
        ctype_cconv(ct->info) != CTCC_CDECL ||
 #endif
-       t == IRT_CDATA || (LJ_32 && (t == IRT_I64 || t == IRT_U64)))
+       t == IRT_CDATA)
       lj_trace_err(J, LJ_TRERR_NYICALL);
     tr = emitir(IRT(IR_CALLXS, t), crec_call_args(J, rd, cts, ct), func);
     if (t == IRT_FLOAT || t == IRT_U32) {
       tr = emitconv(tr, IRT_NUM, t, 0);
     } else if (t == IRT_PTR || (LJ_64 && t == IRT_P32) ||
-              (LJ_64 && (t == IRT_I64 || t == IRT_U64))) {
+              (t == IRT_I64 || t == IRT_U64)) {
       TRef trid = lj_ir_kint(J, ctype_cid(ct->info));
       tr = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, tr);
+      if (t == IRT_I64 || t == IRT_U64) lj_needsplit(J);
     }
     J->base[0] = tr;
     J->needsnap = 1;
index 90b2b49c8301451359733937f3e93b172335dc8b..e52ddfd4ca0cb9c1b583d20bd076b5a1f289bada 100644 (file)
@@ -256,6 +256,8 @@ static void split_ir(jit_State *J)
        }
        break;
        }
+      case IR_CALLXS:
+       goto split_call;
       case IR_PHI: {
        IRRef hiref2;
        if ((irref_isk(nir->op1) && irref_isk(nir->op2)) ||
@@ -285,6 +287,42 @@ static void split_ir(jit_State *J)
          nir->op1 = nir->op2 = 0;
        }
       }
+    } else if (ir->o == IR_CALLXS) {
+      IRRef hiref;
+    split_call:
+      hiref = hisubst[ir->op1];
+      if (hiref) {
+       IROpT ot = nir->ot;
+       IRRef op2 = nir->op2;
+       nir->ot = IRT(IR_CARG, IRT_NIL);
+#if LJ_LE
+       nir->op2 = hiref;
+#else
+       nir->op2 = nir->op1; nir->op1 = hiref;
+#endif
+       ir->prev = nref = split_emit(J, ot, nref, op2);
+      }
+      if (irt_isint64(ir->t))
+       hi = split_emit(J, IRTI(IR_HIOP), nref, nref);
+    } else if (ir->o == IR_CARG) {
+      IRRef hiref = hisubst[ir->op1];
+      if (hiref) {
+       IRRef op2 = nir->op2;
+#if LJ_LE
+       nir->op2 = hiref;
+#else
+       nir->op2 = nir->op1; nir->op1 = hiref;
+#endif
+       ir->prev = nref = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, op2);
+       nir = IR(nref);
+      }
+      hiref = hisubst[ir->op2];
+      if (hiref) {
+#if LJ_BE
+       IRRef tmp = nir->op2; nir->op2 = hiref; hiref = tmp;
+#endif
+       ir->prev = split_emit(J, IRT(IR_CARG, IRT_NIL), nref, hiref);
+      }
     } else if (ir->o == IR_CNEWI) {
       if (hisubst[ir->op2])
        split_emit(J, IRT(IR_HIOP, IRT_NIL), nref, hisubst[ir->op2]);