diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_ccallback.c | 58 |
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 | ||
75 | static void callback_mcode_init(global_State *g, uint8_t *page) | 82 | static 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 | ||
114 | static 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) |