]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
ARM: Add partial support for FFI.
authorMike Pall <mike>
Sat, 16 Apr 2011 21:28:51 +0000 (23:28 +0200)
committerMike Pall <mike>
Sat, 16 Apr 2011 21:28:51 +0000 (23:28 +0200)
src/buildvm_arm.dasc
src/lj_arch.h
src/lj_ccall.c
src/lj_ccall.h

index 3e3fb23c1055e9d76fbf84e2700554436de9ae07..c12b4da8f89a5d29af7e76337a9ec3d060615728 100644 (file)
@@ -1873,7 +1873,32 @@ static void build_subroutines(BuildCtx *ctx)
   |
   |->vm_ffi_call:
 #if LJ_HASFFI
-  |  NYI
+  |  .type CCSTATE, CCallState, r4
+  |  push {CCSTATE, r5, r11, lr}
+  |  mov CCSTATE, CARG1
+  |  ldr CARG1, CCSTATE:CARG1->spadj
+  |   ldrb CARG2, CCSTATE->nsp
+  |    add CARG3, CCSTATE, #offsetof(CCallState, stack)
+  |  mov r11, sp
+  |  sub sp, sp, CARG1                 // Readjust stack.
+  |   subs CARG2, CARG2, #1
+  |    ldr RB, CCSTATE->func
+  |   bmi >2
+  |1:  // Copy stack slots.
+  |  ldr CARG4, [CARG3, CARG2, lsl #2]
+  |  str CARG4, [sp, CARG2, lsl #2]
+  |  subs CARG2, CARG2, #1
+  |  bpl <1
+  |2:
+  |  ldr CARG1, CCSTATE->gpr[0]
+  |  ldr CARG2, CCSTATE->gpr[1]
+  |  ldr CARG3, CCSTATE->gpr[2]
+  |  ldr CARG4, CCSTATE->gpr[3]
+  |  blx RB
+  |  mov sp, r11
+  |  str CRET1, CCSTATE->gpr[0]
+  |  str CRET2, CCSTATE->gpr[1]
+  |  pop {CCSTATE, r5, r11, pc}
 #endif
   |
   |//-----------------------------------------------------------------------
@@ -2340,7 +2365,14 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
     break;
   case BC_KCDATA:
 #if LJ_HASFFI
-    |  NYI
+    |  // RA = dst*8, RC = cdata_const (~)
+    |  mvn RC, RC
+    |   ins_next1
+    |  ldr CARG1, [KBASE, RC, lsl #2]
+    |  mvn CARG2, #~LJ_TCDATA
+    |   ins_next2
+    |  strd CARG12, [BASE, RA]
+    |   ins_next3
 #endif
     break;
   case BC_KSHORT:
index 5e866fe41899a3f0d8ebf0a13300001372f6e67a..ca5b0df4a670443b4c7d94a5939f7632ed70e00a 100644 (file)
 #define LJ_TARGET_MASKSHIFT    0
 #define LJ_TARGET_MASKROT      1
 #define LJ_ARCH_DUALNUM                2
-#define LJ_ARCH_NOFFI          1
+#define LJ_ARCH_NOFFI          1       /* NYI: comparisons, calls. */
 #define LJ_ARCH_NOJIT          1
 
 #elif LUAJIT_TARGET == LUAJIT_ARCH_PPC
index 85d8af9c668671db9da4f4fd90573a177e4eeaf8..da7b47382ae588ccd178cb506eb1d7e10ec1c75e 100644 (file)
     } \
   }
 
+#elif LJ_TARGET_ARM
+/* -- ARM calling conventions --------------------------------------------- */
+
+#define CCALL_HANDLE_STRUCTRET \
+  /* Return structs of size <= 4 in a GPR. */ \
+  cc->retref = !(sz <= 4); \
+  if (cc->retref) cc->gpr[ngpr++] = (GPRArg)dp;
+
+#define CCALL_HANDLE_COMPLEXRET \
+  cc->retref = 1;  /* Return all complex values by reference. */ \
+  cc->gpr[ngpr++] = (GPRArg)dp;
+
+#define CCALL_HANDLE_COMPLEXRET2 \
+  UNUSED(dp); /* Nothing to do. */
+
+#define CCALL_HANDLE_STRUCTARG \
+  /* Pass all structs by value in registers and/or on the stack. */
+
+#define CCALL_HANDLE_COMPLEXARG \
+  /* Pass complex by value in 2 or 4 GPRs. */
+
+/* ARM has a softfp ABI. */
+#define CCALL_HANDLE_REGARG \
+  if ((d->info & CTF_ALIGN) > CTALIGN_PTR) { \
+    if (ngpr < maxgpr) \
+      ngpr = (ngpr + 1u) & ~1u;  /* Align to regpair. */ \
+    else \
+      nsp = (nsp + 1u) & ~1u;  /* Align argument on stack. */ \
+  } \
+  if (ngpr < maxgpr) { \
+    dp = &cc->gpr[ngpr]; \
+    if (ngpr + n > maxgpr) { \
+      nsp += ngpr + n - maxgpr;  /* Assumes contiguous gpr/stack fields. */ \
+      if (nsp > CCALL_MAXSTACK) goto err_nyi;  /* Too many arguments. */ \
+      ngpr = maxgpr; \
+    } else { \
+      ngpr += n; \
+    } \
+    goto done; \
+  }
+
 #elif LJ_TARGET_PPCSPE
 /* -- PPC/SPE calling conventions ----------------------------------------- */
 
index 83e2403db37cac4b5acc08d70aa6a464b313053a..d097978109991c83ff1f8344d9749530f4dcd3e4 100644 (file)
@@ -47,6 +47,16 @@ typedef LJ_ALIGN(16) union FPRArg {
 
 typedef intptr_t GPRArg;
 
+#elif LJ_TARGET_ARM
+
+#define CCALL_NARG_GPR         4
+#define CCALL_NARG_FPR         0
+#define CCALL_NRET_GPR         2       /* For softfp double. */
+#define CCALL_NRET_FPR         0
+#define CCALL_SPS_FREE         0       /* NYI */
+
+typedef intptr_t GPRArg;
+
 #elif LJ_TARGET_PPCSPE
 
 #define CCALL_NARG_GPR         8
@@ -91,10 +101,10 @@ typedef struct CCallState {
 #elif LJ_TARGET_X86
   uint8_t resx87;              /* Result on x87 stack: 1:float, 2:double. */
 #endif
-  GPRArg gpr[CCALL_NUM_GPR];   /* Arguments/results in GPRs. */
 #if CCALL_NUM_FPR
   FPRArg fpr[CCALL_NUM_FPR];   /* Arguments/results in FPRs. */
 #endif
+  GPRArg gpr[CCALL_NUM_GPR];   /* Arguments/results in GPRs. */
   GPRArg stack[CCALL_MAXSTACK];        /* Stack slots. */
 } CCallState;