diff options
Diffstat (limited to 'src/lj_ccall.c')
-rw-r--r-- | src/lj_ccall.c | 53 |
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]; |