|
|->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
|
|//-----------------------------------------------------------------------
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:
#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
} \
}
+#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 ----------------------------------------- */
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
#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;