PPC64: Add ffi support

This commit is contained in:
Gustavo Serra Scalet 2015-06-02 15:15:37 -03:00 committed by Gustavo Serra Scalet
parent 04c444e533
commit 069296bba0
4 changed files with 66 additions and 1 deletions

View File

@ -380,6 +380,37 @@
#define CCALL_HANDLE_COMPLEXARG \ #define CCALL_HANDLE_COMPLEXARG \
/* Pass complex by value in 2 or 4 GPRs. */ /* Pass complex by value in 2 or 4 GPRs. */
#if LJ_ARCH_PPC64
#define CCALL_HANDLE_REGARG \
if (isva) { /* only GPRs will be used on C ellipsis operator */ \
goto gpr; \
} \
else { \
if (isfp) { /* Try to pass argument in FPRs. */ \
if (nfpr + 1 <= CCALL_NARG_FPR) { \
dp = &cc->fpr[nfpr]; \
nfpr += 1; \
ngpr += 1; /* align GPRs */ \
d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
goto done; \
} \
} else { /* Try to pass argument in GPRs. */ \
gpr: \
if (n > 1) { \
lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
if (ctype_isinteger(d->info)) \
ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
else if (ngpr + n > maxgpr) \
ngpr = maxgpr; /* Prevent reordering. */ \
} \
if (ngpr + n <= maxgpr) { \
dp = &cc->gpr[ngpr]; \
ngpr += n; \
goto done; \
} \
} \
}
#else /* 32 bits */
#define CCALL_HANDLE_REGARG \ #define CCALL_HANDLE_REGARG \
if (isfp) { /* Try to pass argument in FPRs. */ \ if (isfp) { /* Try to pass argument in FPRs. */ \
if (nfpr + 1 <= CCALL_NARG_FPR) { \ if (nfpr + 1 <= CCALL_NARG_FPR) { \
@ -402,6 +433,7 @@
goto done; \ goto done; \
} \ } \
} }
#endif
#define CCALL_HANDLE_RET \ #define CCALL_HANDLE_RET \
if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \

View File

@ -85,12 +85,21 @@ typedef union FPRArg {
#elif LJ_TARGET_PPC #elif LJ_TARGET_PPC
#if LJ_ARCH_PPC64
#define CCALL_NARG_GPR 8
#define CCALL_NARG_FPR 8
#define CCALL_NRET_GPR 4 /* For complex double. */
#define CCALL_NRET_FPR 1
#define CCALL_SPS_EXTRA 14
#define CCALL_SPS_FREE 0
#else
#define CCALL_NARG_GPR 8 #define CCALL_NARG_GPR 8
#define CCALL_NARG_FPR 8 #define CCALL_NARG_FPR 8
#define CCALL_NRET_GPR 4 /* For complex double. */ #define CCALL_NRET_GPR 4 /* For complex double. */
#define CCALL_NRET_FPR 1 #define CCALL_NRET_FPR 1
#define CCALL_SPS_EXTRA 4 #define CCALL_SPS_EXTRA 4
#define CCALL_SPS_FREE 0 #define CCALL_SPS_FREE 0
#endif
typedef intptr_t GPRArg; typedef intptr_t GPRArg;
typedef double FPRArg; typedef double FPRArg;

View File

@ -61,7 +61,11 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
#elif LJ_TARGET_PPC #elif LJ_TARGET_PPC
#if LJ_ARCH_PPC64
#define CALLBACK_MCODE_HEAD 40
#else /* PPC 32bits */
#define CALLBACK_MCODE_HEAD 24 #define CALLBACK_MCODE_HEAD 24
#endif
#elif LJ_TARGET_MIPS #elif LJ_TARGET_MIPS
@ -189,10 +193,21 @@ static void callback_mcode_init(global_State *g, uint32_t *page)
uint32_t *p = page; uint32_t *p = page;
void *target = (void *)lj_vm_ffi_callback; void *target = (void *)lj_vm_ffi_callback;
MSize slot; MSize slot;
#if LJ_ARCH_PPC64
*p++ = PPCI_LI | PPCF_T(RID_TMP) | ((((intptr_t)target) >> 32) & 0xffff);
*p++ = PPCI_LI | PPCF_T(RID_R12) | ((((intptr_t)g) >> 32) & 0xffff);
*p++ = PPCI_RLDICR | PPCF_T(RID_TMP) | PPCF_A(RID_TMP) | PPCF_SH(32) | PPCF_M6(63-32); /* sldi */
*p++ = PPCI_RLDICR | PPCF_T(RID_R12) | PPCF_A(RID_R12) | PPCF_SH(32) | PPCF_M6(63-32); /* sldi */
*p++ = PPCI_ORIS | PPCF_A(RID_TMP) | PPCF_T(RID_TMP) | ((((intptr_t)target) >> 16) & 0xffff);
*p++ = PPCI_ORIS | PPCF_A(RID_R12) | PPCF_T(RID_R12) | ((((intptr_t)g) >> 16) & 0xffff);
*p++ = PPCI_ORI | PPCF_A(RID_TMP) | PPCF_T(RID_TMP) | (((intptr_t)target) & 0xffff);
*p++ = PPCI_ORI | PPCF_A(RID_R12) | PPCF_T(RID_R12) | (((intptr_t)g) & 0xffff);
#else /* PPC 32bits */
*p++ = PPCI_LIS | PPCF_T(RID_TMP) | (u32ptr(target) >> 16); *p++ = PPCI_LIS | PPCF_T(RID_TMP) | (u32ptr(target) >> 16);
*p++ = PPCI_LIS | PPCF_T(RID_R12) | (u32ptr(g) >> 16); *p++ = PPCI_LIS | PPCF_T(RID_R12) | (u32ptr(g) >> 16);
*p++ = PPCI_ORI | PPCF_A(RID_TMP)|PPCF_T(RID_TMP) | (u32ptr(target) & 0xffff); *p++ = PPCI_ORI | PPCF_A(RID_TMP)|PPCF_T(RID_TMP) | (u32ptr(target) & 0xffff);
*p++ = PPCI_ORI | PPCF_A(RID_R12)|PPCF_T(RID_R12) | (u32ptr(g) & 0xffff); *p++ = PPCI_ORI | PPCF_A(RID_R12)|PPCF_T(RID_R12) | (u32ptr(g) & 0xffff);
#endif
*p++ = PPCI_MTCTR | PPCF_T(RID_TMP); *p++ = PPCI_MTCTR | PPCF_T(RID_TMP);
*p++ = PPCI_BCTR; *p++ = PPCI_BCTR;
for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {

View File

@ -1,5 +1,5 @@
/* /*
** Definitions for PPC CPUs. ** Definitions for PPC/PPC64 CPUs.
** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h
*/ */
@ -131,6 +131,8 @@ static LJ_AINLINE uint32_t *exitstub_trace_addr_(uint32_t *p, uint32_t exitno)
#define PPCF_C(r) ((r) << 6) #define PPCF_C(r) ((r) << 6)
#define PPCF_MB(n) ((n) << 6) #define PPCF_MB(n) ((n) << 6)
#define PPCF_ME(n) ((n) << 1) #define PPCF_ME(n) ((n) << 1)
#define PPCF_SH(n) ((((n) & 31) << (11+1)) | (((n) & 32) >> (5-1)))
#define PPCF_M6(n) ((((n) & 31) << (5+1)) | (((n) & 32) << (11-5)))
#define PPCF_Y 0x00200000 #define PPCF_Y 0x00200000
#define PPCF_DOT 0x00000001 #define PPCF_DOT 0x00000001
@ -200,6 +202,13 @@ typedef enum PPCIns {
PPCI_RLWINM = 0x54000000, PPCI_RLWINM = 0x54000000,
PPCI_RLWIMI = 0x50000000, PPCI_RLWIMI = 0x50000000,
PPCI_RLDICL = 0x78000000,
PPCI_RLDICR = 0x78000004,
PPCI_RLDIC = 0x78000008,
PPCI_RLDIMI = 0x7800000c,
PPCI_RLDCL = 0x78000010,
PPCI_RLDCR = 0x78000012,
PPCI_B = 0x48000000, PPCI_B = 0x48000000,
PPCI_BL = 0x48000001, PPCI_BL = 0x48000001,
PPCI_BC = 0x40800000, PPCI_BC = 0x40800000,