diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_ccall.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/src/lj_ccall.c b/src/lj_ccall.c index 5ab5b60d..2dda5405 100644 --- a/src/lj_ccall.c +++ b/src/lj_ccall.c | |||
@@ -418,6 +418,18 @@ | |||
418 | /* Complex values are returned in 1 or 2 FPRs. */ \ | 418 | /* Complex values are returned in 1 or 2 FPRs. */ \ |
419 | cc->retref = 0; | 419 | cc->retref = 0; |
420 | 420 | ||
421 | #if LJ_ABI_SOFTFP | ||
422 | #define CCALL_HANDLE_COMPLEXRET2 \ | ||
423 | if (ctr->size == 2*sizeof(float)) { /* Copy complex float from GPRs. */ \ | ||
424 | ((intptr_t *)dp)[0] = cc->gpr[0]; \ | ||
425 | ((intptr_t *)dp)[1] = cc->gpr[1]; \ | ||
426 | } else { /* Copy complex double from GPRs. */ \ | ||
427 | ((intptr_t *)dp)[0] = cc->gpr[0]; \ | ||
428 | ((intptr_t *)dp)[1] = cc->gpr[1]; \ | ||
429 | ((intptr_t *)dp)[2] = cc->gpr[2]; \ | ||
430 | ((intptr_t *)dp)[3] = cc->gpr[3]; \ | ||
431 | } | ||
432 | #else | ||
421 | #define CCALL_HANDLE_COMPLEXRET2 \ | 433 | #define CCALL_HANDLE_COMPLEXRET2 \ |
422 | if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \ | 434 | if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \ |
423 | ((float *)dp)[0] = cc->fpr[0].f; \ | 435 | ((float *)dp)[0] = cc->fpr[0].f; \ |
@@ -426,6 +438,7 @@ | |||
426 | ((double *)dp)[0] = cc->fpr[0].d; \ | 438 | ((double *)dp)[0] = cc->fpr[0].d; \ |
427 | ((double *)dp)[1] = cc->fpr[1].d; \ | 439 | ((double *)dp)[1] = cc->fpr[1].d; \ |
428 | } | 440 | } |
441 | #endif | ||
429 | 442 | ||
430 | #define CCALL_HANDLE_STRUCTARG \ | 443 | #define CCALL_HANDLE_STRUCTARG \ |
431 | /* Pass all structs by value in registers and/or on the stack. */ | 444 | /* Pass all structs by value in registers and/or on the stack. */ |
@@ -433,6 +446,22 @@ | |||
433 | #define CCALL_HANDLE_COMPLEXARG \ | 446 | #define CCALL_HANDLE_COMPLEXARG \ |
434 | /* Pass complex by value in 2 or 4 GPRs. */ | 447 | /* Pass complex by value in 2 or 4 GPRs. */ |
435 | 448 | ||
449 | #define CCALL_HANDLE_GPR \ | ||
450 | if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \ | ||
451 | ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ | ||
452 | if (ngpr < maxgpr) { \ | ||
453 | dp = &cc->gpr[ngpr]; \ | ||
454 | if (ngpr + n > maxgpr) { \ | ||
455 | nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ | ||
456 | if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ | ||
457 | ngpr = maxgpr; \ | ||
458 | } else { \ | ||
459 | ngpr += n; \ | ||
460 | } \ | ||
461 | goto done; \ | ||
462 | } | ||
463 | |||
464 | #if !LJ_ABI_SOFTFP /* MIPS32 hard-float */ | ||
436 | #define CCALL_HANDLE_REGARG \ | 465 | #define CCALL_HANDLE_REGARG \ |
437 | if (isfp && nfpr < CCALL_NARG_FPR && !(ct->info & CTF_VARARG)) { \ | 466 | if (isfp && nfpr < CCALL_NARG_FPR && !(ct->info & CTF_VARARG)) { \ |
438 | /* Try to pass argument in FPRs. */ \ | 467 | /* Try to pass argument in FPRs. */ \ |
@@ -441,24 +470,18 @@ | |||
441 | goto done; \ | 470 | goto done; \ |
442 | } else { /* Try to pass argument in GPRs. */ \ | 471 | } else { /* Try to pass argument in GPRs. */ \ |
443 | nfpr = CCALL_NARG_FPR; \ | 472 | nfpr = CCALL_NARG_FPR; \ |
444 | if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \ | 473 | CCALL_HANDLE_GPR \ |
445 | ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ | ||
446 | if (ngpr < maxgpr) { \ | ||
447 | dp = &cc->gpr[ngpr]; \ | ||
448 | if (ngpr + n > maxgpr) { \ | ||
449 | nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \ | ||
450 | if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \ | ||
451 | ngpr = maxgpr; \ | ||
452 | } else { \ | ||
453 | ngpr += n; \ | ||
454 | } \ | ||
455 | goto done; \ | ||
456 | } \ | ||
457 | } | 474 | } |
475 | #else /* MIPS32 soft-float */ | ||
476 | #define CCALL_HANDLE_REGARG CCALL_HANDLE_GPR | ||
477 | #endif | ||
458 | 478 | ||
479 | #if !LJ_ABI_SOFTFP | ||
480 | /* On MIPS64 soft-float, position of float return values is endian-dependant. */ | ||
459 | #define CCALL_HANDLE_RET \ | 481 | #define CCALL_HANDLE_RET \ |
460 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | 482 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ |
461 | sp = (uint8_t *)&cc->fpr[0].f; | 483 | sp = (uint8_t *)&cc->fpr[0].f; |
484 | #endif | ||
462 | 485 | ||
463 | #else | 486 | #else |
464 | #error "Missing calling convention definitions for this architecture" | 487 | #error "Missing calling convention definitions for this architecture" |