mirror of https://github.com/odrling/Aegisub
172 lines
4.0 KiB
C
172 lines
4.0 KiB
C
/*
|
|
** FFI C call handling.
|
|
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
|
*/
|
|
|
|
#ifndef _LJ_CCALL_H
|
|
#define _LJ_CCALL_H
|
|
|
|
#include "lj_obj.h"
|
|
#include "lj_ctype.h"
|
|
|
|
#if LJ_HASFFI
|
|
|
|
/* -- C calling conventions ----------------------------------------------- */
|
|
|
|
#if LJ_TARGET_X86ORX64
|
|
|
|
#if LJ_TARGET_X86
|
|
#define CCALL_NARG_GPR 2 /* For fastcall arguments. */
|
|
#define CCALL_NARG_FPR 0
|
|
#define CCALL_NRET_GPR 2
|
|
#define CCALL_NRET_FPR 1 /* For FP results on x87 stack. */
|
|
#define CCALL_ALIGN_STACKARG 0 /* Don't align argument on stack. */
|
|
#elif LJ_ABI_WIN
|
|
#define CCALL_NARG_GPR 4
|
|
#define CCALL_NARG_FPR 4
|
|
#define CCALL_NRET_GPR 1
|
|
#define CCALL_NRET_FPR 1
|
|
#define CCALL_SPS_EXTRA 4
|
|
#else
|
|
#define CCALL_NARG_GPR 6
|
|
#define CCALL_NARG_FPR 8
|
|
#define CCALL_NRET_GPR 2
|
|
#define CCALL_NRET_FPR 2
|
|
#define CCALL_VECTOR_REG 1 /* Pass vectors in registers. */
|
|
#endif
|
|
|
|
#define CCALL_SPS_FREE 1
|
|
#define CCALL_ALIGN_CALLSTATE 16
|
|
|
|
typedef LJ_ALIGN(16) union FPRArg {
|
|
double d[2];
|
|
float f[4];
|
|
uint8_t b[16];
|
|
uint16_t s[8];
|
|
int i[4];
|
|
int64_t l[2];
|
|
} FPRArg;
|
|
|
|
typedef intptr_t GPRArg;
|
|
|
|
#elif LJ_TARGET_ARM
|
|
|
|
#define CCALL_NARG_GPR 4
|
|
#define CCALL_NRET_GPR 2 /* For softfp double. */
|
|
#if LJ_ABI_SOFTFP
|
|
#define CCALL_NARG_FPR 0
|
|
#define CCALL_NRET_FPR 0
|
|
#else
|
|
#define CCALL_NARG_FPR 8
|
|
#define CCALL_NRET_FPR 4
|
|
#endif
|
|
#define CCALL_SPS_FREE 0
|
|
|
|
typedef intptr_t GPRArg;
|
|
typedef union FPRArg {
|
|
double d;
|
|
float f[2];
|
|
} FPRArg;
|
|
|
|
#elif LJ_TARGET_PPC
|
|
|
|
#define CCALL_NARG_GPR 8
|
|
#define CCALL_NARG_FPR 8
|
|
#define CCALL_NRET_GPR 4 /* For complex double. */
|
|
#define CCALL_NRET_FPR 1
|
|
#define CCALL_SPS_EXTRA 4
|
|
#define CCALL_SPS_FREE 0
|
|
|
|
typedef intptr_t GPRArg;
|
|
typedef double FPRArg;
|
|
|
|
#elif LJ_TARGET_PPCSPE
|
|
|
|
#define CCALL_NARG_GPR 8
|
|
#define CCALL_NARG_FPR 0
|
|
#define CCALL_NRET_GPR 4 /* For softfp complex double. */
|
|
#define CCALL_NRET_FPR 0
|
|
#define CCALL_SPS_FREE 0 /* NYI */
|
|
|
|
typedef intptr_t GPRArg;
|
|
|
|
#elif LJ_TARGET_MIPS
|
|
|
|
#define CCALL_NARG_GPR 4
|
|
#define CCALL_NARG_FPR 2
|
|
#define CCALL_NRET_GPR 2
|
|
#define CCALL_NRET_FPR 2
|
|
#define CCALL_SPS_EXTRA 7
|
|
#define CCALL_SPS_FREE 1
|
|
|
|
typedef intptr_t GPRArg;
|
|
typedef union FPRArg {
|
|
double d;
|
|
struct { LJ_ENDIAN_LOHI(float f; , float g;) };
|
|
} FPRArg;
|
|
|
|
#else
|
|
#error "Missing calling convention definitions for this architecture"
|
|
#endif
|
|
|
|
#ifndef CCALL_SPS_EXTRA
|
|
#define CCALL_SPS_EXTRA 0
|
|
#endif
|
|
#ifndef CCALL_VECTOR_REG
|
|
#define CCALL_VECTOR_REG 0
|
|
#endif
|
|
#ifndef CCALL_ALIGN_STACKARG
|
|
#define CCALL_ALIGN_STACKARG 1
|
|
#endif
|
|
#ifndef CCALL_ALIGN_CALLSTATE
|
|
#define CCALL_ALIGN_CALLSTATE 8
|
|
#endif
|
|
|
|
#define CCALL_NUM_GPR \
|
|
(CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
|
|
#define CCALL_NUM_FPR \
|
|
(CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
|
|
|
|
/* Check against constants in lj_ctype.h. */
|
|
LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
|
|
LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
|
|
|
|
#define CCALL_MAXSTACK 32
|
|
|
|
/* -- C call state -------------------------------------------------------- */
|
|
|
|
typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
|
|
void (*func)(void); /* Pointer to called function. */
|
|
uint32_t spadj; /* Stack pointer adjustment. */
|
|
uint8_t nsp; /* Number of stack slots. */
|
|
uint8_t retref; /* Return value by reference. */
|
|
#if LJ_TARGET_X64
|
|
uint8_t ngpr; /* Number of arguments in GPRs. */
|
|
uint8_t nfpr; /* Number of arguments in FPRs. */
|
|
#elif LJ_TARGET_X86
|
|
uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
|
|
#elif LJ_TARGET_PPC
|
|
uint8_t nfpr; /* Number of arguments in FPRs. */
|
|
#endif
|
|
#if LJ_32
|
|
int32_t align1;
|
|
#endif
|
|
#if CCALL_NUM_FPR
|
|
FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
|
|
#endif
|
|
GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
|
|
GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
|
|
} CCallState;
|
|
|
|
/* -- C call handling ----------------------------------------------------- */
|
|
|
|
/* Really belongs to lj_vm.h. */
|
|
LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
|
|
|
|
LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
|
|
LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
|
|
|
|
#endif
|
|
|
|
#endif
|