mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-12 09:24:07 +00:00
FFI: Fix C calls with complex values on x64.
This commit is contained in:
parent
a54843bb51
commit
8d858bfefa
@ -44,9 +44,9 @@
|
|||||||
|
|
||||||
#define CCALL_HANDLE_REGARG \
|
#define CCALL_HANDLE_REGARG \
|
||||||
if (isfp) { /* Try to pass argument in FPRs. */ \
|
if (isfp) { /* Try to pass argument in FPRs. */ \
|
||||||
if (nfpr + isfp <= CCALL_NARG_FPR) { \
|
if (nfpr + n <= CCALL_NARG_FPR) { \
|
||||||
dp = &cc->fpr[nfpr]; \
|
dp = &cc->fpr[nfpr]; \
|
||||||
nfpr += isfp; \
|
nfpr += n; \
|
||||||
goto done; \
|
goto done; \
|
||||||
} \
|
} \
|
||||||
} else { /* Try to pass argument in GPRs. */ \
|
} else { /* Try to pass argument in GPRs. */ \
|
||||||
@ -272,6 +272,13 @@ static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
|
|||||||
else
|
else
|
||||||
cc->fpr[ngpr-1].l[0] = cc->gpr[ngpr-1];
|
cc->fpr[ngpr-1].l[0] = cc->gpr[ngpr-1];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if LJ_TARGET_X64 && !LJ_ABI_WIN
|
||||||
|
if (isfp == 2 && n == 2 &&
|
||||||
|
(uint8_t *)dp == (uint8_t *)&cc->fpr[nfpr-2]) {
|
||||||
|
cc->fpr[nfpr-1].d[0] = cc->fpr[nfpr-2].d[1];
|
||||||
|
cc->fpr[nfpr-2].d[1] = 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
|
if (fid) lj_err_caller(L, LJ_ERR_FFI_NUMARG); /* Too few arguments. */
|
||||||
@ -309,20 +316,20 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
|
|||||||
/* Return cdata object which is already on top of stack. */
|
/* Return cdata object which is already on top of stack. */
|
||||||
#if !CCALL_COMPLEX_RETREF || !CCALL_COMPLEXF_RETREF
|
#if !CCALL_COMPLEX_RETREF || !CCALL_COMPLEXF_RETREF
|
||||||
void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */
|
void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */
|
||||||
#if CCALL_COMPLEX_RETREF && !CCALL_COMPLEXF_RETREF
|
#if !CCALL_NUM_FPR
|
||||||
|
memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
|
||||||
|
#elif CCALL_COMPLEX_RETREF && !CCALL_COMPLEXF_RETREF
|
||||||
if (ctr->size == 2*sizeof(float))
|
if (ctr->size == 2*sizeof(float))
|
||||||
memcpy(dp, sp, ctr->size); /* Copy complex float from GPRs. */
|
*(int64_t *)dp = *(int64_t *)sp; /* Copy complex float from GPRs. */
|
||||||
#elif CCALL_NUM_FPR
|
#elif LJ_TARGET_X64
|
||||||
/* Copy non-contiguous re/im part from FPRs to cdata object. */
|
if (ctr->size == 2*sizeof(float)) { /* Copy complex float from FPR. */
|
||||||
if (ctr->size == 2*sizeof(float)) {
|
*(int64_t *)dp = cc->fpr[0].l[0];
|
||||||
((float *)dp)[0] = cc->fpr[0].f[0];
|
} else { /* Copy non-contiguous complex double from FPRs. */
|
||||||
((float *)dp)[1] = cc->fpr[1].f[0];
|
((int64_t *)dp)[0] = cc->fpr[0].l[0];
|
||||||
} else {
|
((int64_t *)dp)[1] = cc->fpr[1].l[0];
|
||||||
((double *)dp)[0] = cc->fpr[0].d[0];
|
|
||||||
((double *)dp)[1] = cc->fpr[1].d[0];
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
|
#error "missing definition for handling of complex return values"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return 1; /* One GC step. */
|
return 1; /* One GC step. */
|
||||||
|
Loading…
Reference in New Issue
Block a user