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 | |
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.
-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)) \ |