summaryrefslogtreecommitdiff
path: root/src/lj_ccallback.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_ccallback.c58
1 files changed, 52 insertions, 6 deletions
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c
index e104c484..c0668e41 100644
--- a/src/lj_ccallback.c
+++ b/src/lj_ccallback.c
@@ -43,6 +43,13 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs)
43#define CALLBACK_MAX_SLOT \ 43#define CALLBACK_MAX_SLOT \
44 (((CALLBACK_MCODE_SIZE-CALLBACK_MCODE_HEAD)/(CALLBACK_MCODE_GROUP+4*32))*32) 44 (((CALLBACK_MCODE_SIZE-CALLBACK_MCODE_HEAD)/(CALLBACK_MCODE_GROUP+4*32))*32)
45 45
46#elif LJ_TARGET_PPC
47
48#define CALLBACK_MCODE_HEAD 24
49#define CALLBACK_SLOT2OFS(slot) (CALLBACK_MCODE_HEAD + 8*(slot))
50#define CALLBACK_OFS2SLOT(ofs) (((ofs)-CALLBACK_MCODE_HEAD)/8)
51#define CALLBACK_MAX_SLOT (CALLBACK_OFS2SLOT(CALLBACK_MCODE_SIZE))
52
46#else 53#else
47 54
48/* Missing support for this architecture. */ 55/* Missing support for this architecture. */
@@ -70,8 +77,8 @@ MSize lj_ccallback_ptr2slot(CTState *cts, void *p)
70 return ~0u; /* Not a known callback function pointer. */ 77 return ~0u; /* Not a known callback function pointer. */
71} 78}
72 79
73#if LJ_TARGET_X86ORX64
74/* Initialize machine code for callback function pointers. */ 80/* Initialize machine code for callback function pointers. */
81#if LJ_TARGET_X86ORX64
75static void callback_mcode_init(global_State *g, uint8_t *page) 82static void callback_mcode_init(global_State *g, uint8_t *page)
76{ 83{
77 uint8_t *p = page; 84 uint8_t *p = page;
@@ -103,6 +110,25 @@ static void callback_mcode_init(global_State *g, uint8_t *page)
103 } 110 }
104 lua_assert(p - page <= CALLBACK_MCODE_SIZE); 111 lua_assert(p - page <= CALLBACK_MCODE_SIZE);
105} 112}
113#elif LJ_TARGET_PPC
114static void callback_mcode_init(global_State *g, uint32_t *page)
115{
116 uint32_t *p = page;
117 void *target = (void *)lj_vm_ffi_callback;
118 MSize slot;
119 *p++ = PPCI_LIS | PPCF_T(RID_TMP) | (u32ptr(target) >> 16);
120 *p++ = PPCI_LIS | PPCF_T(RID_R12) | (u32ptr(g) >> 16);
121 *p++ = PPCI_ORI | PPCF_A(RID_TMP)|PPCF_T(RID_TMP) | (u32ptr(target) & 0xffff);
122 *p++ = PPCI_ORI | PPCF_A(RID_R12)|PPCF_T(RID_R12) | (u32ptr(g) & 0xffff);
123 *p++ = PPCI_MTCTR | PPCF_T(RID_TMP);
124 *p++ = PPCI_BCTR;
125 for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) {
126 *p++ = PPCI_LI | PPCF_T(RID_R11) | slot;
127 *p = PPCI_B | (((page-p) & 0x00ffffffu) << 2);
128 p++;
129 }
130 lua_assert(p - page <= CALLBACK_MCODE_SIZE);
131}
106#else 132#else
107/* Missing support for this architecture. */ 133/* Missing support for this architecture. */
108#define callback_mcode_init(g, p) UNUSED(p) 134#define callback_mcode_init(g, p) UNUSED(p)
@@ -224,8 +250,28 @@ void lj_ccallback_mcode_free(CTState *cts)
224#elif LJ_TARGET_PPC 250#elif LJ_TARGET_PPC
225 251
226#define CALLBACK_HANDLE_REGARG \ 252#define CALLBACK_HANDLE_REGARG \
227 UNUSED(ngpr); UNUSED(nfpr); UNUSED(maxgpr); goto done; /* NYI */ 253 if (isfp) { \
228#define CALLBACK_HANDLE_RET /* NYI */ 254 if (nfpr + 1 <= CCALL_NARG_FPR) { \
255 sp = &cts->cb.fpr[nfpr]; \
256 nfpr += 1; \
257 cta = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
258 goto done; \
259 } \
260 } else { /* Try to pass argument in GPRs. */ \
261 if (n > 1) { \
262 lua_assert(ctype_isinteger(cta->info) && n == 2); /* int64_t. */ \
263 ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
264 } \
265 if (ngpr + n <= maxgpr) { \
266 sp = &cts->cb.gpr[ngpr]; \
267 ngpr += n; \
268 goto done; \
269 } \
270 }
271
272#define CALLBACK_HANDLE_RET \
273 if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
274 *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */
229 275
230#else 276#else
231#error "Missing calling convention definitions for this architecture" 277#error "Missing calling convention definitions for this architecture"
@@ -327,14 +373,14 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
327#endif 373#endif
328 if (!ctype_isvoid(ctr->info)) { 374 if (!ctype_isvoid(ctr->info)) {
329 uint8_t *dp = (uint8_t *)&cts->cb.gpr[0]; 375 uint8_t *dp = (uint8_t *)&cts->cb.gpr[0];
330#ifdef CALLBACK_HANDLE_RET
331 CALLBACK_HANDLE_RET
332#endif
333#if CCALL_NUM_FPR 376#if CCALL_NUM_FPR
334 if (ctype_isfp(ctr->info)) 377 if (ctype_isfp(ctr->info))
335 dp = (uint8_t *)&cts->cb.fpr[0]; 378 dp = (uint8_t *)&cts->cb.fpr[0];
336#endif 379#endif
337 lj_cconv_ct_tv(cts, ctr, dp, o, 0); 380 lj_cconv_ct_tv(cts, ctr, dp, o, 0);
381#ifdef CALLBACK_HANDLE_RET
382 CALLBACK_HANDLE_RET
383#endif
338 /* Extend returned integers to (at least) 32 bits. */ 384 /* Extend returned integers to (at least) 32 bits. */
339 if (ctype_isinteger_or_bool(ctr->info) && ctr->size < 4) { 385 if (ctype_isinteger_or_bool(ctr->info) && ctr->size < 4) {
340 if (ctr->info & CTF_UNSIGNED) 386 if (ctr->info & CTF_UNSIGNED)