aboutsummaryrefslogtreecommitdiff
path: root/src/lj_ccall.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_ccall.c')
-rw-r--r--src/lj_ccall.c53
1 files changed, 52 insertions, 1 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 6a163b0e..183e471c 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -205,6 +205,54 @@
205 goto done; \ 205 goto done; \
206 } 206 }
207 207
208#elif LJ_TARGET_PPC
209/* -- PPC calling conventions --------------------------------------------- */
210
211#define CCALL_HANDLE_STRUCTRET \
212 cc->retref = 1; /* Return all structs by reference. */ \
213 cc->gpr[ngpr++] = (GPRArg)dp;
214
215#define CCALL_HANDLE_COMPLEXRET \
216 /* Complex values are returned in 2 or 4 GPRs. */ \
217 cc->retref = 0;
218
219#define CCALL_HANDLE_COMPLEXRET2 \
220 memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
221
222#define CCALL_HANDLE_STRUCTARG \
223 rp = cdataptr(lj_cdata_new(cts, did, sz)); \
224 sz = CTSIZE_PTR; /* Pass all structs by reference. */
225
226#define CCALL_HANDLE_COMPLEXARG \
227 /* Pass complex by value in 2 or 4 GPRs. */
228
229#define CCALL_HANDLE_REGARG \
230 if (isfp) { /* Try to pass argument in FPRs. */ \
231 if (nfpr + 1 <= CCALL_NARG_FPR) { \
232 dp = &cc->fpr[nfpr]; \
233 nfpr += 1; \
234 d = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */ \
235 goto done; \
236 } \
237 } else { /* Try to pass argument in GPRs. */ \
238 if (n > 1) { \
239 lua_assert(n == 2 || n == 4); /* int64_t or complex (float). */ \
240 if (ctype_isinteger(d->info)) \
241 ngpr = (ngpr + 1u) & ~1u; /* Align int64_t to regpair. */ \
242 else if (ngpr + n > maxgpr) \
243 ngpr = maxgpr; /* Prevent reordering. */ \
244 } \
245 if (ngpr + n <= maxgpr) { \
246 dp = &cc->gpr[ngpr]; \
247 ngpr += n; \
248 goto done; \
249 } \
250 }
251
252#define CCALL_HANDLE_RET \
253 if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
254 ctr = ctype_get(cts, CTID_DOUBLE); /* FPRs always hold doubles. */
255
208#elif LJ_TARGET_PPCSPE 256#elif LJ_TARGET_PPCSPE
209/* -- PPC/SPE calling conventions ----------------------------------------- */ 257/* -- PPC/SPE calling conventions ----------------------------------------- */
210 258
@@ -530,7 +578,7 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
530 } 578 }
531 if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */ 579 if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
532 580
533#if LJ_TARGET_X64 581#if LJ_TARGET_X64 || LJ_TARGET_PPC || LJ_TARGET_PPCSPE
534 cc->nfpr = nfpr; /* Required for vararg functions. */ 582 cc->nfpr = nfpr; /* Required for vararg functions. */
535#endif 583#endif
536 cc->nsp = nsp; 584 cc->nsp = nsp;
@@ -565,6 +613,9 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
565 CCALL_HANDLE_COMPLEXRET2 613 CCALL_HANDLE_COMPLEXRET2
566 return 1; /* One GC step. */ 614 return 1; /* One GC step. */
567 } 615 }
616#ifdef CCALL_HANDLE_RET
617 CCALL_HANDLE_RET
618#endif
568#if CCALL_NUM_FPR 619#if CCALL_NUM_FPR
569 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info)) 620 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
570 sp = &cc->fpr[0]; 621 sp = &cc->fpr[0];