mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
FFI: Fix calling conventions for 32 bit OSX and iOS simulator.
OSX uses -freg-struct-return, which returns small structs in regs. Thanks to Adriano Bertucci.
This commit is contained in:
parent
1a5fd521b8
commit
5dabdb2e70
@ -32,6 +32,26 @@
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
#if LJ_TARGET_OSX
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_STRUCTRET \
|
||||||
|
/* Return structs of size 1, 2, 4 or 8 in registers. */ \
|
||||||
|
cc->retref = !(sz == 1 || sz == 2 || sz == 4 || sz == 8); \
|
||||||
|
if (cc->retref) { \
|
||||||
|
if (ngpr < maxgpr) \
|
||||||
|
cc->gpr[ngpr++] = (GPRArg)dp; \
|
||||||
|
else \
|
||||||
|
cc->stack[nsp++] = (GPRArg)dp; \
|
||||||
|
} else { /* Struct with single FP field ends up in FPR. */ \
|
||||||
|
cc->resx87 = ccall_classify_struct(cts, ctr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CCALL_HANDLE_STRUCTRET2 \
|
||||||
|
if (cc->resx87) sp = (uint8_t *)&cc->fpr[0]; \
|
||||||
|
memcpy(dp, sp, ctr->size);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
#define CCALL_HANDLE_STRUCTRET \
|
#define CCALL_HANDLE_STRUCTRET \
|
||||||
cc->retref = 1; /* Return all structs by reference (in reg or on stack). */ \
|
cc->retref = 1; /* Return all structs by reference (in reg or on stack). */ \
|
||||||
if (ngpr < maxgpr) \
|
if (ngpr < maxgpr) \
|
||||||
@ -39,6 +59,8 @@
|
|||||||
else \
|
else \
|
||||||
cc->stack[nsp++] = (GPRArg)dp;
|
cc->stack[nsp++] = (GPRArg)dp;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CCALL_HANDLE_COMPLEXRET \
|
#define CCALL_HANDLE_COMPLEXRET \
|
||||||
/* Return complex float in GPRs and complex double by reference. */ \
|
/* Return complex float in GPRs and complex double by reference. */ \
|
||||||
cc->retref = (sz > 8); \
|
cc->retref = (sz > 8); \
|
||||||
@ -414,6 +436,42 @@
|
|||||||
memcpy(dp, sp, ctr->size); /* Copy struct return value from GPRs. */
|
memcpy(dp, sp, ctr->size); /* Copy struct return value from GPRs. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* -- x86 OSX ABI struct classification ----------------------------------- */
|
||||||
|
|
||||||
|
#if LJ_TARGET_X86 && LJ_TARGET_OSX
|
||||||
|
|
||||||
|
/* Check for struct with single FP field. */
|
||||||
|
static int ccall_classify_struct(CTState *cts, CType *ct)
|
||||||
|
{
|
||||||
|
CTSize sz = ct->size;
|
||||||
|
if (!(sz == sizeof(float) || sz == sizeof(double))) return 0;
|
||||||
|
if ((ct->info & CTF_UNION)) return 0;
|
||||||
|
while (ct->sib) {
|
||||||
|
ct = ctype_get(cts, ct->sib);
|
||||||
|
if (ctype_isfield(ct->info)) {
|
||||||
|
CType *sct = ctype_rawchild(cts, ct);
|
||||||
|
if (ctype_isfp(sct->info)) {
|
||||||
|
if (sct->size == sz)
|
||||||
|
return (sz >> 2); /* Return 1 for float or 2 for double. */
|
||||||
|
} else if (ctype_isstruct(sct->info)) {
|
||||||
|
if (sct->size)
|
||||||
|
return ccall_classify_struct(cts, sct);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (ctype_isbitfield(ct->info)) {
|
||||||
|
break;
|
||||||
|
} else if (ctype_isxattrib(ct->info, CTA_SUBTYPE)) {
|
||||||
|
CType *sct = ctype_rawchild(cts, ct);
|
||||||
|
if (sct->size)
|
||||||
|
return ccall_classify_struct(cts, sct);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* -- x64 struct classification ------------------------------------------- */
|
/* -- x64 struct classification ------------------------------------------- */
|
||||||
|
|
||||||
#if LJ_TARGET_X64 && !LJ_ABI_WIN
|
#if LJ_TARGET_X64 && !LJ_ABI_WIN
|
||||||
|
Loading…
Reference in New Issue
Block a user