mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
FFI: Add callback support for ARM.
This commit is contained in:
parent
1b0d646004
commit
03c51fc578
@ -502,22 +502,30 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| ldr CARG1, [BASE, #-16] // Get continuation.
|
| ldr CARG1, [BASE, #-16] // Get continuation.
|
||||||
| mov CARG4, BASE
|
| mov CARG4, BASE
|
||||||
| mov BASE, RB // Restore caller BASE.
|
| mov BASE, RB // Restore caller BASE.
|
||||||
| cmp CARG1, #0
|
#if LJ_HASFFI
|
||||||
|
| cmp CARG1, #1
|
||||||
|
#endif
|
||||||
| ldr PC, [CARG4, #-12] // Restore PC from [cont|PC].
|
| ldr PC, [CARG4, #-12] // Restore PC from [cont|PC].
|
||||||
| beq >1
|
|
||||||
| ldr CARG3, LFUNC:CARG3->field_pc
|
| ldr CARG3, LFUNC:CARG3->field_pc
|
||||||
| mvn INS, #~LJ_TNIL
|
| mvn INS, #~LJ_TNIL
|
||||||
| add CARG2, RA, RC
|
| add CARG2, RA, RC
|
||||||
| str INS, [CARG2, #-4] // Ensure one valid arg.
|
| str INS, [CARG2, #-4] // Ensure one valid arg.
|
||||||
|
#if LJ_HASFFI
|
||||||
|
| bls >1
|
||||||
|
#endif
|
||||||
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
||||||
| // BASE = base, RA = resultptr, CARG4 = meta base
|
| // BASE = base, RA = resultptr, CARG4 = meta base
|
||||||
| bx CARG1
|
| bx CARG1
|
||||||
|
|
|
|
||||||
|1: // Tail call from C function.
|
#if LJ_HASFFI
|
||||||
|
|1:
|
||||||
|
| beq ->cont_ffi_callback // cont = 1: return from FFI callback.
|
||||||
|
| // cont = 0: tailcall from C function.
|
||||||
| ldr CARG3, [BASE, FRAME_FUNC]
|
| ldr CARG3, [BASE, FRAME_FUNC]
|
||||||
| sub CARG4, CARG4, #16
|
| sub CARG4, CARG4, #16
|
||||||
| sub RC, CARG4, BASE
|
| sub RC, CARG4, BASE
|
||||||
| b ->vm_call_tail
|
| b ->vm_call_tail
|
||||||
|
#endif
|
||||||
|
|
|
|
||||||
|->cont_cat: // RA = resultptr, CARG4 = meta base
|
|->cont_cat: // RA = resultptr, CARG4 = meta base
|
||||||
| ldr INS, [PC, #-4]
|
| ldr INS, [PC, #-4]
|
||||||
@ -2177,6 +2185,50 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|//-- FFI helper functions -----------------------------------------------
|
|//-- FFI helper functions -----------------------------------------------
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|// Handler for callback functions.
|
||||||
|
|// Saveregs already performed. Callback slot number in [sp], g in r12.
|
||||||
|
|->vm_ffi_callback:
|
||||||
|
#if LJ_HASFFI
|
||||||
|
|.type CTSTATE, CTState, PC
|
||||||
|
| ldr CTSTATE, GL:r12->ctype_state
|
||||||
|
| add DISPATCH, r12, #GG_G2DISP
|
||||||
|
| strd CARG12, CTSTATE->cb.gpr[0]
|
||||||
|
| strd CARG34, CTSTATE->cb.gpr[2]
|
||||||
|
| ldr CARG4, [sp]
|
||||||
|
| add CARG3, sp, #CFRAME_SIZE
|
||||||
|
| mov CARG1, CTSTATE
|
||||||
|
| lsr CARG4, CARG4, #3
|
||||||
|
| str CARG3, CTSTATE->cb.stack
|
||||||
|
| mov CARG2, sp
|
||||||
|
| str CARG4, CTSTATE->cb.slot
|
||||||
|
| str CTSTATE, SAVE_PC // Any value outside of bytecode is ok.
|
||||||
|
| bl extern lj_ccallback_enter // (CTState *cts, void *cf)
|
||||||
|
| // Returns lua_State *.
|
||||||
|
| ldr BASE, L:CRET1->base
|
||||||
|
| mv_vmstate CARG2, INTERP
|
||||||
|
| ldr RC, L:CRET1->top
|
||||||
|
| mov MASKR8, #255
|
||||||
|
| ldr LFUNC:CARG3, [BASE, FRAME_FUNC]
|
||||||
|
| mov L, CRET1
|
||||||
|
| sub RC, RC, BASE
|
||||||
|
| lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
|
||||||
|
| st_vmstate CARG2
|
||||||
|
| ins_callt
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|->cont_ffi_callback: // Return from FFI callback.
|
||||||
|
#if LJ_HASFFI
|
||||||
|
| ldr CTSTATE, [DISPATCH, #DISPATCH_GL(ctype_state)]
|
||||||
|
| str BASE, L->base
|
||||||
|
| str CARG4, L->top
|
||||||
|
| str L, CTSTATE->L
|
||||||
|
| mov CARG1, CTSTATE
|
||||||
|
| mov CARG2, RA
|
||||||
|
| bl extern lj_ccallback_leave // (CTState *cts, TValue *o)
|
||||||
|
| ldrd CARG12, CTSTATE->cb.gpr[0]
|
||||||
|
| b ->vm_leave_unw
|
||||||
|
#endif
|
||||||
|
|
|
|
||||||
|->vm_ffi_call: // Call C function via FFI.
|
|->vm_ffi_call: // Call C function via FFI.
|
||||||
| // Caveat: needs special frame unwinding, see below.
|
| // Caveat: needs special frame unwinding, see below.
|
||||||
|
2373
src/buildvm_arm.h
2373
src/buildvm_arm.h
File diff suppressed because it is too large
Load Diff
@ -43,6 +43,13 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
|
|||||||
#define CALLBACK_MAX_SLOT \
|
#define CALLBACK_MAX_SLOT \
|
||||||
(((CALLBACK_MCODE_SIZE-CALLBACK_MCODE_HEAD)/(CALLBACK_MCODE_GROUP+4*32))*32)
|
(((CALLBACK_MCODE_SIZE-CALLBACK_MCODE_HEAD)/(CALLBACK_MCODE_GROUP+4*32))*32)
|
||||||
|
|
||||||
|
#elif LJ_TARGET_ARM
|
||||||
|
|
||||||
|
#define CALLBACK_MCODE_HEAD 32
|
||||||
|
#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + 8*(slot))
|
||||||
|
#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8)
|
||||||
|
#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
|
||||||
|
|
||||||
#elif LJ_TARGET_PPC
|
#elif LJ_TARGET_PPC
|
||||||
|
|
||||||
#define CALLBACK_MCODE_HEAD 24
|
#define CALLBACK_MCODE_HEAD 24
|
||||||
@ -110,6 +117,28 @@ static void callback_mcode_init(global_State *g, uint8_t *page)
|
|||||||
}
|
}
|
||||||
lua_assert(p - page <= CALLBACK_MCODE_SIZE);
|
lua_assert(p - page <= CALLBACK_MCODE_SIZE);
|
||||||
}
|
}
|
||||||
|
#elif LJ_TARGET_ARM
|
||||||
|
static void callback_mcode_init(global_State *g, uint32_t *page)
|
||||||
|
{
|
||||||
|
uint32_t *p = page;
|
||||||
|
void *target = (void *)lj_vm_ffi_callback;
|
||||||
|
MSize slot;
|
||||||
|
/* This must match with the saveregs macro in buildvm_arm.dasc. */
|
||||||
|
*p++ = ARMI_SUB|ARMF_D(RID_R12)|ARMF_N(RID_R12)|ARMF_M(RID_PC);
|
||||||
|
*p++ = ARMI_PUSH|ARMF_N(RID_SP)|RSET_RANGE(RID_R4,RID_R11+1)|RID2RSET(RID_LR);
|
||||||
|
*p++ = ARMI_SUB|ARMI_K12|ARMF_D(RID_R12)|ARMF_N(RID_R12)|CALLBACK_MCODE_HEAD;
|
||||||
|
*p++ = ARMI_STR|ARMI_LS_P|ARMI_LS_W|ARMF_D(RID_R12)|ARMF_N(RID_SP)|(CFRAME_SIZE-4*9);
|
||||||
|
*p++ = ARMI_LDR|ARMI_LS_P|ARMI_LS_U|ARMF_D(RID_R12)|ARMF_N(RID_PC);
|
||||||
|
*p++ = ARMI_LDR|ARMI_LS_P|ARMI_LS_U|ARMF_D(RID_PC)|ARMF_N(RID_PC);
|
||||||
|
*p++ = u32ptr(g);
|
||||||
|
*p++ = u32ptr(target);
|
||||||
|
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
|
||||||
|
*p++ = ARMI_MOV|ARMF_D(RID_R12)|ARMF_M(RID_PC);
|
||||||
|
*p = ARMI_B | ((page-p-2) & 0x00ffffffu);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
lua_assert(p - page <= CALLBACK_MCODE_SIZE);
|
||||||
|
}
|
||||||
#elif LJ_TARGET_PPC
|
#elif LJ_TARGET_PPC
|
||||||
static void callback_mcode_init(global_State *g, uint32_t *page)
|
static void callback_mcode_init(global_State *g, uint32_t *page)
|
||||||
{
|
{
|
||||||
@ -245,7 +274,12 @@ void lj_ccallback_mcode_free(CTState *cts)
|
|||||||
#elif LJ_TARGET_ARM
|
#elif LJ_TARGET_ARM
|
||||||
|
|
||||||
#define CALLBACK_HANDLE_REGARG \
|
#define CALLBACK_HANDLE_REGARG \
|
||||||
UNUSED(ngpr); UNUSED(maxgpr); goto done; /* NYI */
|
if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \
|
||||||
|
if (ngpr + n <= maxgpr) { \
|
||||||
|
sp = &cts->cb.gpr[ngpr]; \
|
||||||
|
ngpr += n; \
|
||||||
|
goto done; \
|
||||||
|
}
|
||||||
|
|
||||||
#elif LJ_TARGET_PPC
|
#elif LJ_TARGET_PPC
|
||||||
|
|
||||||
|
@ -161,11 +161,7 @@ ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed")
|
|||||||
ERRDEF(FFI_WRCONST, "attempt to write to constant location")
|
ERRDEF(FFI_WRCONST, "attempt to write to constant location")
|
||||||
ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
|
ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
|
||||||
ERRDEF(FFI_BADCBACK, "bad callback")
|
ERRDEF(FFI_BADCBACK, "bad callback")
|
||||||
#if LJ_TARGET_X86ORX64 || LJ_TARGET_PPC
|
|
||||||
ERRDEF(FFI_CBACKOV, "too many callbacks")
|
ERRDEF(FFI_CBACKOV, "too many callbacks")
|
||||||
#else
|
|
||||||
ERRDEF(FFI_CBACKOV, "no support for callbacks (yet)")
|
|
||||||
#endif
|
|
||||||
ERRDEF(FFI_NYIPACKBIT, "NYI: packed bit fields")
|
ERRDEF(FFI_NYIPACKBIT, "NYI: packed bit fields")
|
||||||
ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)")
|
ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)")
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,6 +139,7 @@ typedef enum ARMIns {
|
|||||||
ARMI_S = 0x000100000,
|
ARMI_S = 0x000100000,
|
||||||
ARMI_K12 = 0x02000000,
|
ARMI_K12 = 0x02000000,
|
||||||
ARMI_KNEG = 0x00200000,
|
ARMI_KNEG = 0x00200000,
|
||||||
|
ARMI_LS_W = 0x00200000,
|
||||||
ARMI_LS_U = 0x00800000,
|
ARMI_LS_U = 0x00800000,
|
||||||
ARMI_LS_P = 0x01000000,
|
ARMI_LS_P = 0x01000000,
|
||||||
ARMI_LS_R = 0x02000000,
|
ARMI_LS_R = 0x02000000,
|
||||||
@ -176,6 +177,7 @@ typedef enum ARMIns {
|
|||||||
ARMI_STRB = 0xe4400000,
|
ARMI_STRB = 0xe4400000,
|
||||||
ARMI_STRH = 0xe00000b0,
|
ARMI_STRH = 0xe00000b0,
|
||||||
ARMI_STRD = 0xe00000f0,
|
ARMI_STRD = 0xe00000f0,
|
||||||
|
ARMI_PUSH = 0xe92d0000,
|
||||||
|
|
||||||
ARMI_B = 0xea000000,
|
ARMI_B = 0xea000000,
|
||||||
ARMI_BL = 0xeb000000,
|
ARMI_BL = 0xeb000000,
|
||||||
|
Loading…
Reference in New Issue
Block a user