summaryrefslogtreecommitdiff
path: root/src/lj_ccall.c
diff options
context:
space:
mode:
authorMike Pall <mike>2012-01-23 22:20:28 +0100
committerMike Pall <mike>2012-01-23 22:24:11 +0100
commit5bed11e6b4c2bbf0cbec0f00efe998289236b217 (patch)
tree5ed76367d5157df37b358a5874d34a21dc7d60b0 /src/lj_ccall.c
parent7d2774e4c5ee7c649ccb41f75bfbbb1e7f370a96 (diff)
downloadluajit2-5bed11e6b4c2bbf0cbec0f00efe998289236b217.tar.gz
MIPS: Add interpreter. Enable MIPS build rules.
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 @@
goto done; \
}
+#elif LJ_TARGET_MIPS
+/* -- MIPS calling conventions -------------------------------------------- */
+
+#define CCALL_HANDLE_STRUCTRET \
+ cc->retref = 1; /* Return all structs by reference. */ \
+ cc->gpr[ngpr++] = (GPRArg)dp;
+
+#define CCALL_HANDLE_COMPLEXRET \
+ /* Complex values are returned in 1 or 2 FPRs. */ \
+ cc->retref = 0;
+
+#define CCALL_HANDLE_COMPLEXRET2 \
+ if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPRs. */ \
+ ((float *)dp)[0] = cc->fpr[0].f; \
+ ((float *)dp)[1] = cc->fpr[1].f; \
+ } else { /* Copy complex double from FPRs. */ \
+ ((double *)dp)[0] = cc->fpr[0].d; \
+ ((double *)dp)[1] = cc->fpr[1].d; \
+ }
+
+#define CCALL_HANDLE_STRUCTARG \
+ /* Pass all structs by value in registers and/or on the stack. */
+
+#define CCALL_HANDLE_COMPLEXARG \
+ /* Pass complex by value in 2 or 4 GPRs. */
+
+#define CCALL_HANDLE_REGARG \
+ if (isfp && nfpr < CCALL_NARG_FPR && !(ct->info & CTF_VARARG)) { \
+ /* Try to pass argument in FPRs. */ \
+ dp = n == 1 ? (void *)&cc->fpr[nfpr].f : (void *)&cc->fpr[nfpr].d; \
+ nfpr++; ngpr += n; \
+ goto done; \
+ } else { /* Try to pass argument in GPRs. */ \
+ nfpr = CCALL_NARG_FPR; \
+ if ((d->info & CTF_ALIGN) > CTALIGN_PTR) \
+ ngpr = (ngpr + 1u) & ~1u; /* Align to regpair. */ \
+ if (ngpr < maxgpr) { \
+ dp = &cc->gpr[ngpr]; \
+ if (ngpr + n > maxgpr) { \
+ nsp += ngpr + n - maxgpr; /* Assumes contiguous gpr/stack fields. */ \
+ if (nsp > CCALL_MAXSTACK) goto err_nyi; /* Too many arguments. */ \
+ ngpr = maxgpr; \
+ } else { \
+ ngpr += n; \
+ } \
+ goto done; \
+ } \
+ }
+
+#define CCALL_HANDLE_RET \
+ if (ctype_isfp(ctr->info) && ctr->size == sizeof(float)) \
+ sp = (uint8_t *)&cc->fpr[0].f;
+
#else
#error "Missing calling convention definitions for this architecture"
#endif
@@ -622,13 +675,13 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
}
if (LJ_BE && ctype_isinteger_or_bool(ctr->info) && ctr->size < CTSIZE_PTR)
sp += (CTSIZE_PTR - ctr->size);
-#ifdef CCALL_HANDLE_RET
- CCALL_HANDLE_RET
-#endif
#if CCALL_NUM_FPR
if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
sp = (uint8_t *)&cc->fpr[0];
#endif
+#ifdef CCALL_HANDLE_RET
+ CCALL_HANDLE_RET
+#endif
/* No reference types end up here, so there's no need for the CTypeID. */
lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
if (ctype_isenum(ctr->info)) ctr = ctype_child(cts, ctr);