diff options
Diffstat (limited to 'src/lj_ccall.c')
-rw-r--r-- | src/lj_ccall.c | 59 |
1 files changed, 56 insertions, 3 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 5ed1bf5b..97ad4f02 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c | |||
@@ -290,6 +290,59 @@ | |||
290 | goto done; \ | 290 | goto done; \ |
291 | } | 291 | } |
292 | 292 | ||
293 | #elif LJ_TARGET_MIPS | ||
294 | /* -- MIPS calling conventions -------------------------------------------- */ | ||
295 | |||
296 | #define CCALL_HANDLE_STRUCTRET \ | ||
297 | cc->retref = 1; /* Return all structs by reference. */ \ | ||
298 | cc->gpr[ngpr++] = (GPRArg)dp; | ||
299 | |||
300 | #define CCALL_HANDLE_COMPLEXRET \ | ||
301 | /* Complex values are returned in 1 or 2 FPRs. */ \ | ||
302 | cc->retref = 0; | ||
303 | |||
304 | #define CCALL_HANDLE_COMPLEXRET2 \ | ||
305 | if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \ | ||
306 | ((float *)dp)[0] = cc->fpr[0].f; \ | ||
307 | ((float *)dp)[1] = cc->fpr[1].f; \ | ||
308 | } else { /* Copy complex double from FPRs. */ \ | ||
309 | ((double *)dp)[0] = cc->fpr[0].d; \ | ||
310 | ((double *)dp)[1] = cc->fpr[1].d; \ | ||
311 | } | ||
312 | |||
313 | #define CCALL_HANDLE_STRUCTARG \ | ||
314 | /* Pass all structs by value in registers and/or on the stack. */ | ||
315 | |||
316 | #define CCALL_HANDLE_COMPLEXARG \ | ||
317 | /* Pass complex by value in 2 or 4 GPRs. */ | ||
318 | |||
319 | #define CCALL_HANDLE_REGARG \ | ||
320 | if (isfp && nfpr < CCALL_NARG_FPR && !(ct->info & CTF_VARARG)) { \ | ||
321 | /* Try to pass argument in FPRs. */ \ | ||
322 | dp = n == 1 ? (void *)&cc->fpr[nfpr].f : (void *)&cc->fpr[nfpr].d; \ | ||
323 | nfpr++; ngpr += n; \ | ||
324 | goto done; \ | ||
325 | } else { /* Try to pass argument in GPRs. */ \ | ||
326 | nfpr = CCALL_NARG_FPR; \ | ||
327 | if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \ | ||
328 | ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ | ||
329 | if (ngpr < maxgpr) { \ | ||
330 | dp = &cc->gpr[ngpr]; \ | ||
331 | if (ngpr + n > maxgpr) { \ | ||
332 | nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ | ||
333 | if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ | ||
334 | ngpr = maxgpr; \ | ||
335 | } else { \ | ||
336 | ngpr += n; \ | ||
337 | } \ | ||
338 | goto done; \ | ||
339 | } \ | ||
340 | } | ||
341 | |||
342 | #define CCALL_HANDLE_RET \ | ||
343 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | ||
344 | sp = (uint8_t *)&cc->fpr[0].f; | ||
345 | |||
293 | #else | 346 | #else |
294 | #error "Missing calling convention definitions for this architecture" | 347 | #error "Missing calling convention definitions for this architecture" |
295 | #endif | 348 | #endif |
@@ -622,13 +675,13 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct, | |||
622 | } | 675 | } |
623 | if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR) | 676 | if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR) |
624 | sp += (CTSIZE_PTR - ctr->size); | 677 | sp += (CTSIZE_PTR - ctr->size); |
625 | #ifdef CCALL_HANDLE_RET | ||
626 | CCALL_HANDLE_RET | ||
627 | #endif | ||
628 | #if CCALL_NUM_FPR | 678 | #if CCALL_NUM_FPR |
629 | if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info)) | 679 | if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info)) |
630 | sp = (uint8_t *)&cc->fpr[0]; | 680 | sp = (uint8_t *)&cc->fpr[0]; |
631 | #endif | 681 | #endif |
682 | #ifdef CCALL_HANDLE_RET | ||
683 | CCALL_HANDLE_RET | ||
684 | #endif | ||
632 | /* No reference types end up here, so there's no need for the CTypeID. */ | 685 | /* No reference types end up here, so there's no need for the CTypeID. */ |
633 | lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info))); | 686 | lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info))); |
634 | if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr); | 687 | if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr); |