diff options
| author | Mike Pall <mike> | 2015-12-18 21:38:03 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2015-12-18 21:38:03 +0100 |
| commit | 0345f361531c756367257eb2f147c707e1710218 (patch) | |
| tree | 65dfb35f899caab0dc1f21eed8a0988e1ff2dcab /src | |
| parent | 3f5c72421e282a2a4d8614064f13097678b80be1 (diff) | |
| download | luajit-0345f361531c756367257eb2f147c707e1710218.tar.gz luajit-0345f361531c756367257eb2f147c707e1710218.tar.bz2 luajit-0345f361531c756367257eb2f147c707e1710218.zip | |
MIPS soft-float, part 2: Add soft-float FFI support.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_ccall.c | 49 | ||||
| -rw-r--r-- | src/lj_ccall.h | 4 | ||||
| -rw-r--r-- | src/lj_ccallback.c | 21 |
3 files changed, 53 insertions, 21 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" |
diff --git a/src/lj_ccall.h b/src/lj_ccall.h index 91983fee..8b0e796b 100644 --- a/src/lj_ccall.h +++ b/src/lj_ccall.h | |||
| @@ -98,9 +98,9 @@ typedef double FPRArg; | |||
| 98 | #elif LJ_TARGET_MIPS | 98 | #elif LJ_TARGET_MIPS |
| 99 | 99 | ||
| 100 | #define CCALL_NARG_GPR 4 | 100 | #define CCALL_NARG_GPR 4 |
| 101 | #define CCALL_NARG_FPR 2 | 101 | #define CCALL_NARG_FPR (LJ_ABI_SOFTFP ? 0 : 2) |
| 102 | #define CCALL_NRET_GPR 2 | 102 | #define CCALL_NRET_GPR 2 |
| 103 | #define CCALL_NRET_FPR 2 | 103 | #define CCALL_NRET_FPR (LJ_ABI_SOFTFP ? 0 : 2) |
| 104 | #define CCALL_SPS_EXTRA 7 | 104 | #define CCALL_SPS_EXTRA 7 |
| 105 | #define CCALL_SPS_FREE 1 | 105 | #define CCALL_SPS_FREE 1 |
| 106 | 106 | ||
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 065c329f..539c9e3d 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c | |||
| @@ -427,6 +427,15 @@ void lj_ccallback_mcode_free(CTState *cts) | |||
| 427 | 427 | ||
| 428 | #elif LJ_TARGET_MIPS | 428 | #elif LJ_TARGET_MIPS |
| 429 | 429 | ||
| 430 | #define CALLBACK_HANDLE_GPR \ | ||
| 431 | if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ | ||
| 432 | if (ngpr + n <= maxgpr) { \ | ||
| 433 | sp = &cts->cb.gpr[ngpr]; \ | ||
| 434 | ngpr += n; \ | ||
| 435 | goto done; \ | ||
| 436 | } | ||
| 437 | |||
| 438 | #if !LJ_ABI_SOFTFP /* MIPS32 hard-float */ | ||
| 430 | #define CALLBACK_HANDLE_REGARG \ | 439 | #define CALLBACK_HANDLE_REGARG \ |
| 431 | if (isfp && nfpr < CCALL_NARG_FPR) { /* Try to pass argument in FPRs. */ \ | 440 | if (isfp && nfpr < CCALL_NARG_FPR) { /* Try to pass argument in FPRs. */ \ |
| 432 | sp = (void *)((uint8_t *)&cts->cb.fpr[nfpr] + ((LJ_BE && n==1) ? 4 : 0)); \ | 441 | sp = (void *)((uint8_t *)&cts->cb.fpr[nfpr] + ((LJ_BE && n==1) ? 4 : 0)); \ |
| @@ -434,13 +443,13 @@ void lj_ccallback_mcode_free(CTState *cts) | |||
| 434 | goto done; \ | 443 | goto done; \ |
| 435 | } else { /* Try to pass argument in GPRs. */ \ | 444 | } else { /* Try to pass argument in GPRs. */ \ |
| 436 | nfpr = CCALL_NARG_FPR; \ | 445 | nfpr = CCALL_NARG_FPR; \ |
| 437 | if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ | 446 | CALLBACK_HANDLE_GPR \ |
| 438 | if (ngpr + n <= maxgpr) { \ | ||
| 439 | sp = &cts->cb.gpr[ngpr]; \ | ||
| 440 | ngpr += n; \ | ||
| 441 | goto done; \ | ||
| 442 | } \ | ||
| 443 | } | 447 | } |
| 448 | #else /* MIPS32 soft-float */ | ||
| 449 | #define CALLBACK_HANDLE_REGARG \ | ||
| 450 | CALLBACK_HANDLE_GPR \ | ||
| 451 | UNUSED(isfp); | ||
| 452 | #endif | ||
| 444 | 453 | ||
| 445 | #define CALLBACK_HANDLE_RET \ | 454 | #define CALLBACK_HANDLE_RET \ |
| 446 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | 455 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ |
