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.c59
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);