1/*
2** FFI C call handling.
3** Copyright (C) 2005-2014 Mike Pall. See Copyright Notice in luajit.h
4*/
5
6#ifndef _LJ_CCALL_H
7#define _LJ_CCALL_H
8
9#include "lj_obj.h"
10#include "lj_ctype.h"
11
12#if LJ_HASFFI
13
14/* -- C calling conventions ----------------------------------------------- */
15
16#if LJ_TARGET_X86ORX64
17
18#if LJ_TARGET_X86
19#define CCALL_NARG_GPR 2 /* For fastcall arguments. */
20#define CCALL_NARG_FPR 0
21#define CCALL_NRET_GPR 2
22#define CCALL_NRET_FPR 1 /* For FP results on x87 stack. */
23#define CCALL_ALIGN_STACKARG 0 /* Don't align argument on stack. */
24#elif LJ_ABI_WIN
25#define CCALL_NARG_GPR 4
26#define CCALL_NARG_FPR 4
27#define CCALL_NRET_GPR 1
28#define CCALL_NRET_FPR 1
29#define CCALL_SPS_EXTRA 4
30#else
31#define CCALL_NARG_GPR 6
32#define CCALL_NARG_FPR 8
33#define CCALL_NRET_GPR 2
34#define CCALL_NRET_FPR 2
35#define CCALL_VECTOR_REG 1 /* Pass vectors in registers. */
36#endif
37
38#define CCALL_SPS_FREE 1
39#define CCALL_ALIGN_CALLSTATE 16
40
41typedef LJ_ALIGN(16) union FPRArg {
42 double d[2];
43 float f[4];
44 uint8_t b[16];
45 uint16_t s[8];
46 int i[4];
47 int64_t l[2];
48} FPRArg;
49
50typedef intptr_t GPRArg;
51
52#elif LJ_TARGET_ARM
53
54#define CCALL_NARG_GPR 4
55#define CCALL_NRET_GPR 2 /* For softfp double. */
56#if LJ_ABI_SOFTFP
57#define CCALL_NARG_FPR 0
58#define CCALL_NRET_FPR 0
59#else
60#define CCALL_NARG_FPR 8
61#define CCALL_NRET_FPR 4
62#endif
63#define CCALL_SPS_FREE 0
64
65typedef intptr_t GPRArg;
66typedef union FPRArg {
67 double d;
68 float f[2];
69} FPRArg;
70
71#elif LJ_TARGET_PPC
72
73#define CCALL_NARG_GPR 8
74#define CCALL_NARG_FPR 8
75#define CCALL_NRET_GPR 4 /* For complex double. */
76#define CCALL_NRET_FPR 1
77#define CCALL_SPS_EXTRA 4
78#define CCALL_SPS_FREE 0
79
80typedef intptr_t GPRArg;
81typedef double FPRArg;
82
83#elif LJ_TARGET_PPCSPE
84
85#define CCALL_NARG_GPR 8
86#define CCALL_NARG_FPR 0
87#define CCALL_NRET_GPR 4 /* For softfp complex double. */
88#define CCALL_NRET_FPR 0
89#define CCALL_SPS_FREE 0 /* NYI */
90
91typedef intptr_t GPRArg;
92
93#elif LJ_TARGET_MIPS
94
95#define CCALL_NARG_GPR 4
96#define CCALL_NARG_FPR 2
97#define CCALL_NRET_GPR 2
98#define CCALL_NRET_FPR 2
99#define CCALL_SPS_EXTRA 7
100#define CCALL_SPS_FREE 1
101
102typedef intptr_t GPRArg;
103typedef union FPRArg {
104 double d;
105 struct { LJ_ENDIAN_LOHI(float f; , float g;) };
106} FPRArg;
107
108#else
109#error "Missing calling convention definitions for this architecture"
110#endif
111
112#ifndef CCALL_SPS_EXTRA
113#define CCALL_SPS_EXTRA 0
114#endif
115#ifndef CCALL_VECTOR_REG
116#define CCALL_VECTOR_REG 0
117#endif
118#ifndef CCALL_ALIGN_STACKARG
119#define CCALL_ALIGN_STACKARG 1
120#endif
121#ifndef CCALL_ALIGN_CALLSTATE
122#define CCALL_ALIGN_CALLSTATE 8
123#endif
124
125#define CCALL_NUM_GPR \
126 (CCALL_NARG_GPR > CCALL_NRET_GPR ? CCALL_NARG_GPR : CCALL_NRET_GPR)
127#define CCALL_NUM_FPR \
128 (CCALL_NARG_FPR > CCALL_NRET_FPR ? CCALL_NARG_FPR : CCALL_NRET_FPR)
129
130/* Check against constants in lj_ctype.h. */
131LJ_STATIC_ASSERT(CCALL_NUM_GPR <= CCALL_MAX_GPR);
132LJ_STATIC_ASSERT(CCALL_NUM_FPR <= CCALL_MAX_FPR);
133
134#define CCALL_MAXSTACK 32
135
136/* -- C call state -------------------------------------------------------- */
137
138typedef LJ_ALIGN(CCALL_ALIGN_CALLSTATE) struct CCallState {
139 void (*func)(void); /* Pointer to called function. */
140 uint32_t spadj; /* Stack pointer adjustment. */
141 uint8_t nsp; /* Number of stack slots. */
142 uint8_t retref; /* Return value by reference. */
143#if LJ_TARGET_X64
144 uint8_t ngpr; /* Number of arguments in GPRs. */
145 uint8_t nfpr; /* Number of arguments in FPRs. */
146#elif LJ_TARGET_X86
147 uint8_t resx87; /* Result on x87 stack: 1:float, 2:double. */
148#elif LJ_TARGET_PPC
149 uint8_t nfpr; /* Number of arguments in FPRs. */
150#endif
151#if LJ_32
152 int32_t align1;
153#endif
154#if CCALL_NUM_FPR
155 FPRArg fpr[CCALL_NUM_FPR]; /* Arguments/results in FPRs. */
156#endif
157 GPRArg gpr[CCALL_NUM_GPR]; /* Arguments/results in GPRs. */
158 GPRArg stack[CCALL_MAXSTACK]; /* Stack slots. */
159} CCallState;
160
161/* -- C call handling ----------------------------------------------------- */
162
163/* Really belongs to lj_vm.h. */
164LJ_ASMF void LJ_FASTCALL lj_vm_ffi_call(CCallState *cc);
165
166LJ_FUNC CTypeID lj_ccall_ctid_vararg(CTState *cts, cTValue *o);
167LJ_FUNC int lj_ccall_func(lua_State *L, GCcdata *cd);
168
169#endif
170
171#endif
172