diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_ccallback.c | 70 |
1 files changed, 60 insertions, 10 deletions
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c index 43c29e41..2ca6406c 100644 --- a/src/lj_ccallback.c +++ b/src/lj_ccallback.c | |||
@@ -63,9 +63,13 @@ static MSize CALLBACK_OFS2SLOT(MSize ofs) | |||
63 | 63 | ||
64 | #define CALLBACK_MCODE_HEAD 24 | 64 | #define CALLBACK_MCODE_HEAD 24 |
65 | 65 | ||
66 | #elif LJ_TARGET_MIPS | 66 | #elif LJ_TARGET_MIPS32 |
67 | 67 | ||
68 | #define CALLBACK_MCODE_HEAD 24 | 68 | #define CALLBACK_MCODE_HEAD 20 |
69 | |||
70 | #elif LJ_TARGET_MIPS64 | ||
71 | |||
72 | #define CALLBACK_MCODE_HEAD 52 | ||
69 | 73 | ||
70 | #else | 74 | #else |
71 | 75 | ||
@@ -206,14 +210,27 @@ static void callback_mcode_init(global_State *g, uint32_t *page) | |||
206 | static void callback_mcode_init(global_State *g, uint32_t *page) | 210 | static void callback_mcode_init(global_State *g, uint32_t *page) |
207 | { | 211 | { |
208 | uint32_t *p = page; | 212 | uint32_t *p = page; |
209 | void *target = (void *)lj_vm_ffi_callback; | 213 | uintptr_t target = (uintptr_t)(void *)lj_vm_ffi_callback; |
214 | uintptr_t ug = (uintptr_t)(void *)g; | ||
210 | MSize slot; | 215 | MSize slot; |
211 | *p++ = MIPSI_SW | MIPSF_T(RID_R1)|MIPSF_S(RID_SP) | 0; | 216 | #if LJ_TARGET_MIPS32 |
212 | *p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (u32ptr(target) >> 16); | 217 | *p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (target >> 16); |
213 | *p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (u32ptr(g) >> 16); | 218 | *p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (ug >> 16); |
214 | *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) |(u32ptr(target)&0xffff); | 219 | #else |
220 | *p++ = MIPSI_LUI | MIPSF_T(RID_R3) | (target >> 48); | ||
221 | *p++ = MIPSI_LUI | MIPSF_T(RID_R2) | (ug >> 48); | ||
222 | *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) | ((target >> 32) & 0xffff); | ||
223 | *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | ((ug >> 32) & 0xffff); | ||
224 | *p++ = MIPSI_DSLL | MIPSF_D(RID_R3)|MIPSF_T(RID_R3) | MIPSF_A(16); | ||
225 | *p++ = MIPSI_DSLL | MIPSF_D(RID_R2)|MIPSF_T(RID_R2) | MIPSF_A(16); | ||
226 | *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) | ((target >> 16) & 0xffff); | ||
227 | *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | ((ug >> 16) & 0xffff); | ||
228 | *p++ = MIPSI_DSLL | MIPSF_D(RID_R3)|MIPSF_T(RID_R3) | MIPSF_A(16); | ||
229 | *p++ = MIPSI_DSLL | MIPSF_D(RID_R2)|MIPSF_T(RID_R2) | MIPSF_A(16); | ||
230 | #endif | ||
231 | *p++ = MIPSI_ORI | MIPSF_T(RID_R3)|MIPSF_S(RID_R3) | (target & 0xffff); | ||
215 | *p++ = MIPSI_JR | MIPSF_S(RID_R3); | 232 | *p++ = MIPSI_JR | MIPSF_S(RID_R3); |
216 | *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | (u32ptr(g)&0xffff); | 233 | *p++ = MIPSI_ORI | MIPSF_T(RID_R2)|MIPSF_S(RID_R2) | (ug & 0xffff); |
217 | for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { | 234 | for (slot = 0; slot < CALLBACK_MAX_SLOT; slot++) { |
218 | *p = MIPSI_B | ((page-p-1) & 0x0000ffffu); | 235 | *p = MIPSI_B | ((page-p-1) & 0x0000ffffu); |
219 | p++; | 236 | p++; |
@@ -425,7 +442,7 @@ void lj_ccallback_mcode_free(CTState *cts) | |||
425 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | 442 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ |
426 | *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */ | 443 | *(double *)dp = *(float *)dp; /* FPRs always hold doubles. */ |
427 | 444 | ||
428 | #elif LJ_TARGET_MIPS | 445 | #elif LJ_TARGET_MIPS32 |
429 | 446 | ||
430 | #define CALLBACK_HANDLE_GPR \ | 447 | #define CALLBACK_HANDLE_GPR \ |
431 | if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ | 448 | if (n > 1) ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \ |
@@ -455,6 +472,29 @@ void lj_ccallback_mcode_free(CTState *cts) | |||
455 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | 472 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ |
456 | ((float *)dp)[1] = *(float *)dp; | 473 | ((float *)dp)[1] = *(float *)dp; |
457 | 474 | ||
475 | #elif LJ_TARGET_MIPS64 | ||
476 | |||
477 | #if !LJ_ABI_SOFTFP /* MIPS64 hard-float */ | ||
478 | #define CALLBACK_HANDLE_REGARG \ | ||
479 | if (ngpr + n <= maxgpr) { \ | ||
480 | sp = isfp ? (void*) &cts->cb.fpr[ngpr] : (void*) &cts->cb.gpr[ngpr]; \ | ||
481 | ngpr += n; \ | ||
482 | goto done; \ | ||
483 | } | ||
484 | #else /* MIPS64 soft-float */ | ||
485 | #define CALLBACK_HANDLE_REGARG \ | ||
486 | if (ngpr + n <= maxgpr) { \ | ||
487 | UNUSED(isfp); \ | ||
488 | sp = (void*) &cts->cb.gpr[ngpr]; \ | ||
489 | ngpr += n; \ | ||
490 | goto done; \ | ||
491 | } | ||
492 | #endif | ||
493 | |||
494 | #define CALLBACK_HANDLE_RET \ | ||
495 | if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \ | ||
496 | ((float *)dp)[1] = *(float *)dp; | ||
497 | |||
458 | #else | 498 | #else |
459 | #error "Missing calling convention definitions for this architecture" | 499 | #error "Missing calling convention definitions for this architecture" |
460 | #endif | 500 | #endif |
@@ -542,7 +582,11 @@ static void callback_conv_args(CTState *cts, lua_State *L) | |||
542 | nsp += n; | 582 | nsp += n; |
543 | 583 | ||
544 | done: | 584 | done: |
545 | if (LJ_BE && cta->size < CTSIZE_PTR) | 585 | if (LJ_BE && cta->size < CTSIZE_PTR |
586 | #if LJ_TARGET_MIPS64 | ||
587 | && !(isfp && nsp) | ||
588 | #endif | ||
589 | ) | ||
546 | sp = (void *)((uint8_t *)sp + CTSIZE_PTR-cta->size); | 590 | sp = (void *)((uint8_t *)sp + CTSIZE_PTR-cta->size); |
547 | gcsteps += lj_cconv_tv_ct(cts, cta, 0, o++, sp); | 591 | gcsteps += lj_cconv_tv_ct(cts, cta, 0, o++, sp); |
548 | } | 592 | } |
@@ -593,6 +637,12 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o) | |||
593 | *(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp : | 637 | *(int32_t *)dp = ctr->size == 1 ? (int32_t)*(int8_t *)dp : |
594 | (int32_t)*(int16_t *)dp; | 638 | (int32_t)*(int16_t *)dp; |
595 | } | 639 | } |
640 | #if LJ_TARGET_MIPS64 | ||
641 | /* Always sign-extend results to 64 bits. Even a soft-fp 'float'. */ | ||
642 | if (ctr->size <= 4 && | ||
643 | (LJ_ABI_SOFTFP || ctype_isinteger_or_bool(ctr->info))) | ||
644 | *(int64_t *)dp = (int64_t)*(int32_t *)dp; | ||
645 | #endif | ||
596 | #if LJ_TARGET_X86 | 646 | #if LJ_TARGET_X86 |
597 | if (ctype_isfp(ctr->info)) | 647 | if (ctype_isfp(ctr->info)) |
598 | cts->cb.gpr[2] = ctr->size == sizeof(float) ? 1 : 2; | 648 | cts->cb.gpr[2] = ctr->size == sizeof(float) ? 1 : 2; |