mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-04-22 06:43:27 +00:00
LoongArch64: Add FFI C callback handling
Co-developed-by: Qiqi Huang <huangqiqi@loongson.cn>
This commit is contained in:
parent
700f82bb79
commit
84b3306e60
@ -71,6 +71,10 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
|
|||||||
|
|
||||||
#define CALLBACK_MCODE_HEAD 52
|
#define CALLBACK_MCODE_HEAD 52
|
||||||
|
|
||||||
|
#elif LJ_TARGET_LOONGARCH64
|
||||||
|
|
||||||
|
#define CALLBACK_MCODE_HEAD 52
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Missing support for this architecture. */
|
/* Missing support for this architecture. */
|
||||||
@ -238,6 +242,33 @@ static void *callback_mcode_init(global_State *g, uint32_t *page)
|
|||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
#elif LJ_TARGET_LOONGARCH64
|
||||||
|
static void *callback_mcode_init(global_State *g, uint32_t *page)
|
||||||
|
{
|
||||||
|
uint32_t *p = page;
|
||||||
|
uintptr_t target = (uintptr_t)(void *)lj_vm_ffi_callback;
|
||||||
|
uintptr_t ug = (uintptr_t)(void *)g;
|
||||||
|
MSize slot;
|
||||||
|
*p++ = LOONGI_LU12I_W | LOONGF_D(RID_R18) | LOONGF_I20((target >> 12) & 0xfffff);
|
||||||
|
*p++ = LOONGI_LU12I_W | LOONGF_D(RID_R17) | LOONGF_I20((ug >> 12) & 0xfffff);
|
||||||
|
*p++ = LOONGI_ORI | LOONGF_D(RID_R18) | LOONGF_J(RID_R18) | LOONGF_I(target & 0xfff);
|
||||||
|
*p++ = LOONGI_ORI | LOONGF_D(RID_R17) | LOONGF_J(RID_R17) | LOONGF_I(ug & 0xfff);
|
||||||
|
*p++ = LOONGI_LU32I_D | LOONGF_D(RID_R18) | LOONGF_I20((target >> 32) & 0xfffff);
|
||||||
|
*p++ = LOONGI_LU32I_D | LOONGF_D(RID_R17) | LOONGF_I20((ug >> 32) & 0xfffff);
|
||||||
|
*p++ = LOONGI_LU52I_D | LOONGF_D(RID_R18) | LOONGF_J(RID_R18) | LOONGF_I((target >> 52) & 0xfff);
|
||||||
|
*p++ = LOONGI_LU52I_D | LOONGF_D(RID_R17) | LOONGF_J(RID_R17) | LOONGF_I((ug >> 52) & 0xfff);
|
||||||
|
*p++ = LOONGI_NOP;
|
||||||
|
*p++ = LOONGI_NOP;
|
||||||
|
*p++ = LOONGI_NOP;
|
||||||
|
*p++ = LOONGI_NOP;
|
||||||
|
*p++ = LOONGI_JIRL | LOONGF_D(RID_R0) | LOONGF_J(RID_R18) | LOONGF_I(0);
|
||||||
|
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
|
||||||
|
*p++ = LOONGI_ORI | LOONGF_D(RID_R19) | LOONGF_J(RID_R0) | LOONGF_I(slot & 0xfff);
|
||||||
|
*p = LOONGI_B | LOONGF_I((page-p) & 0xffff) | (((page-p) >> 16) & 0x3ff);
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/* Missing support for this architecture. */
|
/* Missing support for this architecture. */
|
||||||
#define callback_mcode_init(g, p) (p)
|
#define callback_mcode_init(g, p) (p)
|
||||||
@ -512,6 +543,31 @@ void lj_ccallback_mcode_free(CTState *cts)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define CALLBACK_HANDLE_RET \
|
||||||
|
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||||
|
((float *)dp)[1] = *(float *)dp;
|
||||||
|
|
||||||
|
#elif LJ_TARGET_LOONGARCH64
|
||||||
|
|
||||||
|
#define CALLBACK_HANDLE_REGARG \
|
||||||
|
if (isfp) { \
|
||||||
|
if (nfpr + n <= CCALL_NARG_FPR) { \
|
||||||
|
sp = &cts->cb.fpr[nfpr]; \
|
||||||
|
nfpr += n; \
|
||||||
|
goto done; \
|
||||||
|
} else if (ngpr + n <= maxgpr) { \
|
||||||
|
sp = &cts->cb.gpr[ngpr]; \
|
||||||
|
ngpr += n; \
|
||||||
|
goto done; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
if (ngpr + n <= maxgpr) { \
|
||||||
|
sp = &cts->cb.gpr[ngpr]; \
|
||||||
|
ngpr += n; \
|
||||||
|
goto done; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
#define CALLBACK_HANDLE_RET \
|
#define CALLBACK_HANDLE_RET \
|
||||||
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
|
||||||
((float *)dp)[1] = *(float *)dp;
|
((float *)dp)[1] = *(float *)dp;
|
||||||
@ -662,7 +718,7 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
|
|||||||
*(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp :
|
*(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp :
|
||||||
(int32_t)*(int16_t *)dp;
|
(int32_t)*(int16_t *)dp;
|
||||||
}
|
}
|
||||||
#if LJ_TARGET_MIPS64 || (LJ_TARGET_ARM64 && LJ_BE)
|
#if LJ_TARGET_MIPS64 || (LJ_TARGET_ARM64 && LJ_BE) || LJ_TARGET_LOONGARCH64
|
||||||
/* Always sign-extend results to 64 bits. Even a soft-fp 'float'. */
|
/* Always sign-extend results to 64 bits. Even a soft-fp 'float'. */
|
||||||
if (ctr->size <= 4 &&
|
if (ctr->size <= 4 &&
|
||||||
(LJ_ABI_SOFTFP || ctype_isinteger_or_bool(ctr->info)))
|
(LJ_ABI_SOFTFP || ctype_isinteger_or_bool(ctr->info)))
|
||||||
|
@ -2370,6 +2370,69 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|//-- FFI helper functions -----------------------------------------------
|
|//-- FFI helper functions -----------------------------------------------
|
||||||
|//-----------------------------------------------------------------------
|
|//-----------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
|
|// Handler for callback functions. Callback slot number in r19, g in r17.
|
||||||
|
|->vm_ffi_callback:
|
||||||
|
|.if FFI
|
||||||
|
|.type CTSTATE, CTState, PC
|
||||||
|
| saveregs
|
||||||
|
| ld.d CTSTATE, GL:r17->ctype_state
|
||||||
|
| .ADD16I DISPATCH, r17, GG_G2DISP
|
||||||
|
| st.w r19, CTSTATE->cb.slot
|
||||||
|
| st.d CARG1, CTSTATE->cb.gpr[0]
|
||||||
|
| fst.d FARG1, CTSTATE->cb.fpr[0]
|
||||||
|
| st.d CARG2, CTSTATE->cb.gpr[1]
|
||||||
|
| fst.d FARG2, CTSTATE->cb.fpr[1]
|
||||||
|
| st.d CARG3, CTSTATE->cb.gpr[2]
|
||||||
|
| fst.d FARG3, CTSTATE->cb.fpr[2]
|
||||||
|
| st.d CARG4, CTSTATE->cb.gpr[3]
|
||||||
|
| fst.d FARG4, CTSTATE->cb.fpr[3]
|
||||||
|
| st.d CARG5, CTSTATE->cb.gpr[4]
|
||||||
|
| fst.d FARG5, CTSTATE->cb.fpr[4]
|
||||||
|
| st.d CARG6, CTSTATE->cb.gpr[5]
|
||||||
|
| fst.d FARG6, CTSTATE->cb.fpr[5]
|
||||||
|
| st.d CARG7, CTSTATE->cb.gpr[6]
|
||||||
|
| fst.d FARG7, CTSTATE->cb.fpr[6]
|
||||||
|
| st.d CARG8, CTSTATE->cb.gpr[7]
|
||||||
|
| fst.d FARG8, CTSTATE->cb.fpr[7]
|
||||||
|
| addi.d TMP0, sp, CFRAME_SPACE
|
||||||
|
| st.d TMP0, CTSTATE->cb.stack
|
||||||
|
| st.d r0, SAVE_PC(sp) // Any value outside of bytecode is ok.
|
||||||
|
| or CARG1, CTSTATE, r0
|
||||||
|
| or CARG2, sp, r0
|
||||||
|
| bl extern lj_ccallback_enter // (CTState *cts, void *cf)
|
||||||
|
| // Returns lua_State *.
|
||||||
|
| ld.d BASE, L:CRET1->base
|
||||||
|
| ld.d RC, L:CRET1->top
|
||||||
|
| or L, CRET1, r0
|
||||||
|
| addu16i.d TMP3, r0, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
|
||||||
|
| ld.d LFUNC:RB, FRAME_FUNC(BASE)
|
||||||
|
| movgr2fr.w TOBIT, TMP3
|
||||||
|
| addi.d TISNIL, r0, LJ_TNIL
|
||||||
|
| addi.d TISNUM, r0, LJ_TISNUM
|
||||||
|
| li_vmstate INTERP
|
||||||
|
| sub.w RC, RC, BASE
|
||||||
|
| cleartp LFUNC:RB
|
||||||
|
| st_vmstate
|
||||||
|
| fcvt.d.s TOBIT, TOBIT
|
||||||
|
| ins_callt
|
||||||
|
|.endif
|
||||||
|
|
|
||||||
|
|->cont_ffi_callback: // Return from FFI callback.
|
||||||
|
|.if FFI
|
||||||
|
| .LDXD CTSTATE, DISPATCH, DISPATCH_GL(ctype_state)
|
||||||
|
| st.d BASE, L->base
|
||||||
|
| st.d RB, L->top
|
||||||
|
| st.d L, CTSTATE->L
|
||||||
|
| or CARG1, CTSTATE, r0
|
||||||
|
| or CARG2, RA, r0
|
||||||
|
| bl extern lj_ccallback_leave // (CTState *cts, TValue *o)
|
||||||
|
| fld.d FRET1, CTSTATE->cb.fpr[0]
|
||||||
|
| ld.d CRET1, CTSTATE->cb.gpr[0]
|
||||||
|
| fld.d FRET2, CTSTATE->cb.fpr[1]
|
||||||
|
| ld.d CRET2, CTSTATE->cb.gpr[1]
|
||||||
|
| 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.
|
||||||
|.if FFI
|
|.if FFI
|
||||||
|
Loading…
Reference in New Issue
Block a user