1*1fd5a2e1SPrashanth Swaminathan /* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan ffi.c
3*1fd5a2e1SPrashanth Swaminathan
4*1fd5a2e1SPrashanth Swaminathan m68k Foreign Function Interface
5*1fd5a2e1SPrashanth Swaminathan ----------------------------------------------------------------------- */
6*1fd5a2e1SPrashanth Swaminathan
7*1fd5a2e1SPrashanth Swaminathan #include <ffi.h>
8*1fd5a2e1SPrashanth Swaminathan #include <ffi_common.h>
9*1fd5a2e1SPrashanth Swaminathan
10*1fd5a2e1SPrashanth Swaminathan #include <stdlib.h>
11*1fd5a2e1SPrashanth Swaminathan #include <unistd.h>
12*1fd5a2e1SPrashanth Swaminathan #ifdef __rtems__
13*1fd5a2e1SPrashanth Swaminathan void rtems_cache_flush_multiple_data_lines( const void *, size_t );
14*1fd5a2e1SPrashanth Swaminathan #else
15*1fd5a2e1SPrashanth Swaminathan #include <sys/syscall.h>
16*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
17*1fd5a2e1SPrashanth Swaminathan #include <mint/mintbind.h>
18*1fd5a2e1SPrashanth Swaminathan #include <mint/ssystem.h>
19*1fd5a2e1SPrashanth Swaminathan #else
20*1fd5a2e1SPrashanth Swaminathan #include <asm/cachectl.h>
21*1fd5a2e1SPrashanth Swaminathan #endif
22*1fd5a2e1SPrashanth Swaminathan #endif
23*1fd5a2e1SPrashanth Swaminathan
24*1fd5a2e1SPrashanth Swaminathan void ffi_call_SYSV (extended_cif *,
25*1fd5a2e1SPrashanth Swaminathan unsigned, unsigned,
26*1fd5a2e1SPrashanth Swaminathan void *, void (*fn) ());
27*1fd5a2e1SPrashanth Swaminathan void *ffi_prep_args (void *stack, extended_cif *ecif);
28*1fd5a2e1SPrashanth Swaminathan void ffi_closure_SYSV (ffi_closure *);
29*1fd5a2e1SPrashanth Swaminathan void ffi_closure_struct_SYSV (ffi_closure *);
30*1fd5a2e1SPrashanth Swaminathan unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
31*1fd5a2e1SPrashanth Swaminathan void *resp, void *args);
32*1fd5a2e1SPrashanth Swaminathan
33*1fd5a2e1SPrashanth Swaminathan /* ffi_prep_args is called by the assembly routine once stack space has
34*1fd5a2e1SPrashanth Swaminathan been allocated for the function's arguments. */
35*1fd5a2e1SPrashanth Swaminathan
36*1fd5a2e1SPrashanth Swaminathan void *
ffi_prep_args(void * stack,extended_cif * ecif)37*1fd5a2e1SPrashanth Swaminathan ffi_prep_args (void *stack, extended_cif *ecif)
38*1fd5a2e1SPrashanth Swaminathan {
39*1fd5a2e1SPrashanth Swaminathan unsigned int i;
40*1fd5a2e1SPrashanth Swaminathan void **p_argv;
41*1fd5a2e1SPrashanth Swaminathan char *argp;
42*1fd5a2e1SPrashanth Swaminathan ffi_type **p_arg;
43*1fd5a2e1SPrashanth Swaminathan void *struct_value_ptr;
44*1fd5a2e1SPrashanth Swaminathan
45*1fd5a2e1SPrashanth Swaminathan argp = stack;
46*1fd5a2e1SPrashanth Swaminathan
47*1fd5a2e1SPrashanth Swaminathan if (
48*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
49*1fd5a2e1SPrashanth Swaminathan (ecif->cif->rtype->type == FFI_TYPE_LONGDOUBLE) ||
50*1fd5a2e1SPrashanth Swaminathan #endif
51*1fd5a2e1SPrashanth Swaminathan (((ecif->cif->rtype->type == FFI_TYPE_STRUCT)
52*1fd5a2e1SPrashanth Swaminathan && !ecif->cif->flags)))
53*1fd5a2e1SPrashanth Swaminathan struct_value_ptr = ecif->rvalue;
54*1fd5a2e1SPrashanth Swaminathan else
55*1fd5a2e1SPrashanth Swaminathan struct_value_ptr = NULL;
56*1fd5a2e1SPrashanth Swaminathan
57*1fd5a2e1SPrashanth Swaminathan p_argv = ecif->avalue;
58*1fd5a2e1SPrashanth Swaminathan
59*1fd5a2e1SPrashanth Swaminathan for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
60*1fd5a2e1SPrashanth Swaminathan i != 0;
61*1fd5a2e1SPrashanth Swaminathan i--, p_arg++)
62*1fd5a2e1SPrashanth Swaminathan {
63*1fd5a2e1SPrashanth Swaminathan size_t z = (*p_arg)->size;
64*1fd5a2e1SPrashanth Swaminathan int type = (*p_arg)->type;
65*1fd5a2e1SPrashanth Swaminathan
66*1fd5a2e1SPrashanth Swaminathan if (z < sizeof (int))
67*1fd5a2e1SPrashanth Swaminathan {
68*1fd5a2e1SPrashanth Swaminathan switch (type)
69*1fd5a2e1SPrashanth Swaminathan {
70*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_SINT8:
71*1fd5a2e1SPrashanth Swaminathan *(signed int *) argp = (signed int) *(SINT8 *) *p_argv;
72*1fd5a2e1SPrashanth Swaminathan break;
73*1fd5a2e1SPrashanth Swaminathan
74*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_UINT8:
75*1fd5a2e1SPrashanth Swaminathan *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv;
76*1fd5a2e1SPrashanth Swaminathan break;
77*1fd5a2e1SPrashanth Swaminathan
78*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_SINT16:
79*1fd5a2e1SPrashanth Swaminathan *(signed int *) argp = (signed int) *(SINT16 *) *p_argv;
80*1fd5a2e1SPrashanth Swaminathan break;
81*1fd5a2e1SPrashanth Swaminathan
82*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_UINT16:
83*1fd5a2e1SPrashanth Swaminathan *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv;
84*1fd5a2e1SPrashanth Swaminathan break;
85*1fd5a2e1SPrashanth Swaminathan
86*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_STRUCT:
87*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
88*1fd5a2e1SPrashanth Swaminathan if (z == 1 || z == 2)
89*1fd5a2e1SPrashanth Swaminathan memcpy (argp + 2, *p_argv, z);
90*1fd5a2e1SPrashanth Swaminathan else
91*1fd5a2e1SPrashanth Swaminathan memcpy (argp, *p_argv, z);
92*1fd5a2e1SPrashanth Swaminathan #else
93*1fd5a2e1SPrashanth Swaminathan memcpy (argp + sizeof (int) - z, *p_argv, z);
94*1fd5a2e1SPrashanth Swaminathan #endif
95*1fd5a2e1SPrashanth Swaminathan break;
96*1fd5a2e1SPrashanth Swaminathan
97*1fd5a2e1SPrashanth Swaminathan default:
98*1fd5a2e1SPrashanth Swaminathan FFI_ASSERT (0);
99*1fd5a2e1SPrashanth Swaminathan }
100*1fd5a2e1SPrashanth Swaminathan z = sizeof (int);
101*1fd5a2e1SPrashanth Swaminathan }
102*1fd5a2e1SPrashanth Swaminathan else
103*1fd5a2e1SPrashanth Swaminathan {
104*1fd5a2e1SPrashanth Swaminathan memcpy (argp, *p_argv, z);
105*1fd5a2e1SPrashanth Swaminathan
106*1fd5a2e1SPrashanth Swaminathan /* Align if necessary. */
107*1fd5a2e1SPrashanth Swaminathan if ((sizeof(int) - 1) & z)
108*1fd5a2e1SPrashanth Swaminathan z = FFI_ALIGN(z, sizeof(int));
109*1fd5a2e1SPrashanth Swaminathan }
110*1fd5a2e1SPrashanth Swaminathan
111*1fd5a2e1SPrashanth Swaminathan p_argv++;
112*1fd5a2e1SPrashanth Swaminathan argp += z;
113*1fd5a2e1SPrashanth Swaminathan }
114*1fd5a2e1SPrashanth Swaminathan
115*1fd5a2e1SPrashanth Swaminathan return struct_value_ptr;
116*1fd5a2e1SPrashanth Swaminathan }
117*1fd5a2e1SPrashanth Swaminathan
118*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_INT 1
119*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_DINT 2
120*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_FLOAT 4
121*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_DOUBLE 8
122*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_LDOUBLE 16
123*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_POINTER 32
124*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_STRUCT1 64
125*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_STRUCT2 128
126*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_SINT8 256
127*1fd5a2e1SPrashanth Swaminathan #define CIF_FLAGS_SINT16 512
128*1fd5a2e1SPrashanth Swaminathan
129*1fd5a2e1SPrashanth Swaminathan /* Perform machine dependent cif processing */
130*1fd5a2e1SPrashanth Swaminathan ffi_status
ffi_prep_cif_machdep(ffi_cif * cif)131*1fd5a2e1SPrashanth Swaminathan ffi_prep_cif_machdep (ffi_cif *cif)
132*1fd5a2e1SPrashanth Swaminathan {
133*1fd5a2e1SPrashanth Swaminathan /* Set the return type flag */
134*1fd5a2e1SPrashanth Swaminathan switch (cif->rtype->type)
135*1fd5a2e1SPrashanth Swaminathan {
136*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_VOID:
137*1fd5a2e1SPrashanth Swaminathan cif->flags = 0;
138*1fd5a2e1SPrashanth Swaminathan break;
139*1fd5a2e1SPrashanth Swaminathan
140*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_STRUCT:
141*1fd5a2e1SPrashanth Swaminathan if (cif->rtype->elements[0]->type == FFI_TYPE_STRUCT &&
142*1fd5a2e1SPrashanth Swaminathan cif->rtype->elements[1])
143*1fd5a2e1SPrashanth Swaminathan {
144*1fd5a2e1SPrashanth Swaminathan cif->flags = 0;
145*1fd5a2e1SPrashanth Swaminathan break;
146*1fd5a2e1SPrashanth Swaminathan }
147*1fd5a2e1SPrashanth Swaminathan
148*1fd5a2e1SPrashanth Swaminathan switch (cif->rtype->size)
149*1fd5a2e1SPrashanth Swaminathan {
150*1fd5a2e1SPrashanth Swaminathan case 1:
151*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
152*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_STRUCT2;
153*1fd5a2e1SPrashanth Swaminathan #else
154*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_STRUCT1;
155*1fd5a2e1SPrashanth Swaminathan #endif
156*1fd5a2e1SPrashanth Swaminathan break;
157*1fd5a2e1SPrashanth Swaminathan case 2:
158*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_STRUCT2;
159*1fd5a2e1SPrashanth Swaminathan break;
160*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
161*1fd5a2e1SPrashanth Swaminathan case 3:
162*1fd5a2e1SPrashanth Swaminathan #endif
163*1fd5a2e1SPrashanth Swaminathan case 4:
164*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_INT;
165*1fd5a2e1SPrashanth Swaminathan break;
166*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
167*1fd5a2e1SPrashanth Swaminathan case 7:
168*1fd5a2e1SPrashanth Swaminathan #endif
169*1fd5a2e1SPrashanth Swaminathan case 8:
170*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_DINT;
171*1fd5a2e1SPrashanth Swaminathan break;
172*1fd5a2e1SPrashanth Swaminathan default:
173*1fd5a2e1SPrashanth Swaminathan cif->flags = 0;
174*1fd5a2e1SPrashanth Swaminathan break;
175*1fd5a2e1SPrashanth Swaminathan }
176*1fd5a2e1SPrashanth Swaminathan break;
177*1fd5a2e1SPrashanth Swaminathan
178*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_FLOAT:
179*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_FLOAT;
180*1fd5a2e1SPrashanth Swaminathan break;
181*1fd5a2e1SPrashanth Swaminathan
182*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_DOUBLE:
183*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_DOUBLE;
184*1fd5a2e1SPrashanth Swaminathan break;
185*1fd5a2e1SPrashanth Swaminathan
186*1fd5a2e1SPrashanth Swaminathan #if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
187*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_LONGDOUBLE:
188*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
189*1fd5a2e1SPrashanth Swaminathan cif->flags = 0;
190*1fd5a2e1SPrashanth Swaminathan #else
191*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_LDOUBLE;
192*1fd5a2e1SPrashanth Swaminathan #endif
193*1fd5a2e1SPrashanth Swaminathan break;
194*1fd5a2e1SPrashanth Swaminathan #endif
195*1fd5a2e1SPrashanth Swaminathan
196*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_POINTER:
197*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_POINTER;
198*1fd5a2e1SPrashanth Swaminathan break;
199*1fd5a2e1SPrashanth Swaminathan
200*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_SINT64:
201*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_UINT64:
202*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_DINT;
203*1fd5a2e1SPrashanth Swaminathan break;
204*1fd5a2e1SPrashanth Swaminathan
205*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_SINT16:
206*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_SINT16;
207*1fd5a2e1SPrashanth Swaminathan break;
208*1fd5a2e1SPrashanth Swaminathan
209*1fd5a2e1SPrashanth Swaminathan case FFI_TYPE_SINT8:
210*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_SINT8;
211*1fd5a2e1SPrashanth Swaminathan break;
212*1fd5a2e1SPrashanth Swaminathan
213*1fd5a2e1SPrashanth Swaminathan default:
214*1fd5a2e1SPrashanth Swaminathan cif->flags = CIF_FLAGS_INT;
215*1fd5a2e1SPrashanth Swaminathan break;
216*1fd5a2e1SPrashanth Swaminathan }
217*1fd5a2e1SPrashanth Swaminathan
218*1fd5a2e1SPrashanth Swaminathan return FFI_OK;
219*1fd5a2e1SPrashanth Swaminathan }
220*1fd5a2e1SPrashanth Swaminathan
221*1fd5a2e1SPrashanth Swaminathan void
ffi_call(ffi_cif * cif,void (* fn)(),void * rvalue,void ** avalue)222*1fd5a2e1SPrashanth Swaminathan ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
223*1fd5a2e1SPrashanth Swaminathan {
224*1fd5a2e1SPrashanth Swaminathan extended_cif ecif;
225*1fd5a2e1SPrashanth Swaminathan
226*1fd5a2e1SPrashanth Swaminathan ecif.cif = cif;
227*1fd5a2e1SPrashanth Swaminathan ecif.avalue = avalue;
228*1fd5a2e1SPrashanth Swaminathan
229*1fd5a2e1SPrashanth Swaminathan /* If the return value is a struct and we don't have a return value
230*1fd5a2e1SPrashanth Swaminathan address then we need to make one. */
231*1fd5a2e1SPrashanth Swaminathan
232*1fd5a2e1SPrashanth Swaminathan if (rvalue == NULL
233*1fd5a2e1SPrashanth Swaminathan && cif->rtype->type == FFI_TYPE_STRUCT
234*1fd5a2e1SPrashanth Swaminathan && cif->rtype->size > 8)
235*1fd5a2e1SPrashanth Swaminathan ecif.rvalue = alloca (cif->rtype->size);
236*1fd5a2e1SPrashanth Swaminathan else
237*1fd5a2e1SPrashanth Swaminathan ecif.rvalue = rvalue;
238*1fd5a2e1SPrashanth Swaminathan
239*1fd5a2e1SPrashanth Swaminathan switch (cif->abi)
240*1fd5a2e1SPrashanth Swaminathan {
241*1fd5a2e1SPrashanth Swaminathan case FFI_SYSV:
242*1fd5a2e1SPrashanth Swaminathan ffi_call_SYSV (&ecif, cif->bytes, cif->flags,
243*1fd5a2e1SPrashanth Swaminathan ecif.rvalue, fn);
244*1fd5a2e1SPrashanth Swaminathan break;
245*1fd5a2e1SPrashanth Swaminathan
246*1fd5a2e1SPrashanth Swaminathan default:
247*1fd5a2e1SPrashanth Swaminathan FFI_ASSERT (0);
248*1fd5a2e1SPrashanth Swaminathan break;
249*1fd5a2e1SPrashanth Swaminathan }
250*1fd5a2e1SPrashanth Swaminathan }
251*1fd5a2e1SPrashanth Swaminathan
252*1fd5a2e1SPrashanth Swaminathan static void
ffi_prep_incoming_args_SYSV(char * stack,void ** avalue,ffi_cif * cif)253*1fd5a2e1SPrashanth Swaminathan ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
254*1fd5a2e1SPrashanth Swaminathan {
255*1fd5a2e1SPrashanth Swaminathan unsigned int i;
256*1fd5a2e1SPrashanth Swaminathan void **p_argv;
257*1fd5a2e1SPrashanth Swaminathan char *argp;
258*1fd5a2e1SPrashanth Swaminathan ffi_type **p_arg;
259*1fd5a2e1SPrashanth Swaminathan
260*1fd5a2e1SPrashanth Swaminathan argp = stack;
261*1fd5a2e1SPrashanth Swaminathan p_argv = avalue;
262*1fd5a2e1SPrashanth Swaminathan
263*1fd5a2e1SPrashanth Swaminathan for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
264*1fd5a2e1SPrashanth Swaminathan {
265*1fd5a2e1SPrashanth Swaminathan size_t z;
266*1fd5a2e1SPrashanth Swaminathan
267*1fd5a2e1SPrashanth Swaminathan z = (*p_arg)->size;
268*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
269*1fd5a2e1SPrashanth Swaminathan if (cif->flags &&
270*1fd5a2e1SPrashanth Swaminathan cif->rtype->type == FFI_TYPE_STRUCT &&
271*1fd5a2e1SPrashanth Swaminathan (z == 1 || z == 2))
272*1fd5a2e1SPrashanth Swaminathan {
273*1fd5a2e1SPrashanth Swaminathan *p_argv = (void *) (argp + 2);
274*1fd5a2e1SPrashanth Swaminathan
275*1fd5a2e1SPrashanth Swaminathan z = 4;
276*1fd5a2e1SPrashanth Swaminathan }
277*1fd5a2e1SPrashanth Swaminathan else
278*1fd5a2e1SPrashanth Swaminathan if (cif->flags &&
279*1fd5a2e1SPrashanth Swaminathan cif->rtype->type == FFI_TYPE_STRUCT &&
280*1fd5a2e1SPrashanth Swaminathan (z == 3 || z == 4))
281*1fd5a2e1SPrashanth Swaminathan {
282*1fd5a2e1SPrashanth Swaminathan *p_argv = (void *) (argp);
283*1fd5a2e1SPrashanth Swaminathan
284*1fd5a2e1SPrashanth Swaminathan z = 4;
285*1fd5a2e1SPrashanth Swaminathan }
286*1fd5a2e1SPrashanth Swaminathan else
287*1fd5a2e1SPrashanth Swaminathan #endif
288*1fd5a2e1SPrashanth Swaminathan if (z <= 4)
289*1fd5a2e1SPrashanth Swaminathan {
290*1fd5a2e1SPrashanth Swaminathan *p_argv = (void *) (argp + 4 - z);
291*1fd5a2e1SPrashanth Swaminathan
292*1fd5a2e1SPrashanth Swaminathan z = 4;
293*1fd5a2e1SPrashanth Swaminathan }
294*1fd5a2e1SPrashanth Swaminathan else
295*1fd5a2e1SPrashanth Swaminathan {
296*1fd5a2e1SPrashanth Swaminathan *p_argv = (void *) argp;
297*1fd5a2e1SPrashanth Swaminathan
298*1fd5a2e1SPrashanth Swaminathan /* Align if necessary */
299*1fd5a2e1SPrashanth Swaminathan if ((sizeof(int) - 1) & z)
300*1fd5a2e1SPrashanth Swaminathan z = FFI_ALIGN(z, sizeof(int));
301*1fd5a2e1SPrashanth Swaminathan }
302*1fd5a2e1SPrashanth Swaminathan
303*1fd5a2e1SPrashanth Swaminathan p_argv++;
304*1fd5a2e1SPrashanth Swaminathan argp += z;
305*1fd5a2e1SPrashanth Swaminathan }
306*1fd5a2e1SPrashanth Swaminathan }
307*1fd5a2e1SPrashanth Swaminathan
308*1fd5a2e1SPrashanth Swaminathan unsigned int
ffi_closure_SYSV_inner(ffi_closure * closure,void * resp,void * args)309*1fd5a2e1SPrashanth Swaminathan ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
310*1fd5a2e1SPrashanth Swaminathan {
311*1fd5a2e1SPrashanth Swaminathan ffi_cif *cif;
312*1fd5a2e1SPrashanth Swaminathan void **arg_area;
313*1fd5a2e1SPrashanth Swaminathan
314*1fd5a2e1SPrashanth Swaminathan cif = closure->cif;
315*1fd5a2e1SPrashanth Swaminathan arg_area = (void**) alloca (cif->nargs * sizeof (void *));
316*1fd5a2e1SPrashanth Swaminathan
317*1fd5a2e1SPrashanth Swaminathan ffi_prep_incoming_args_SYSV(args, arg_area, cif);
318*1fd5a2e1SPrashanth Swaminathan
319*1fd5a2e1SPrashanth Swaminathan (closure->fun) (cif, resp, arg_area, closure->user_data);
320*1fd5a2e1SPrashanth Swaminathan
321*1fd5a2e1SPrashanth Swaminathan return cif->flags;
322*1fd5a2e1SPrashanth Swaminathan }
323*1fd5a2e1SPrashanth Swaminathan
324*1fd5a2e1SPrashanth Swaminathan ffi_status
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)325*1fd5a2e1SPrashanth Swaminathan ffi_prep_closure_loc (ffi_closure* closure,
326*1fd5a2e1SPrashanth Swaminathan ffi_cif* cif,
327*1fd5a2e1SPrashanth Swaminathan void (*fun)(ffi_cif*,void*,void**,void*),
328*1fd5a2e1SPrashanth Swaminathan void *user_data,
329*1fd5a2e1SPrashanth Swaminathan void *codeloc)
330*1fd5a2e1SPrashanth Swaminathan {
331*1fd5a2e1SPrashanth Swaminathan if (cif->abi != FFI_SYSV)
332*1fd5a2e1SPrashanth Swaminathan return FFI_BAD_ABI;
333*1fd5a2e1SPrashanth Swaminathan
334*1fd5a2e1SPrashanth Swaminathan *(unsigned short *)closure->tramp = 0x207c;
335*1fd5a2e1SPrashanth Swaminathan *(void **)(closure->tramp + 2) = codeloc;
336*1fd5a2e1SPrashanth Swaminathan *(unsigned short *)(closure->tramp + 6) = 0x4ef9;
337*1fd5a2e1SPrashanth Swaminathan
338*1fd5a2e1SPrashanth Swaminathan if (
339*1fd5a2e1SPrashanth Swaminathan #ifdef __MINT__
340*1fd5a2e1SPrashanth Swaminathan (cif->rtype->type == FFI_TYPE_LONGDOUBLE) ||
341*1fd5a2e1SPrashanth Swaminathan #endif
342*1fd5a2e1SPrashanth Swaminathan (((cif->rtype->type == FFI_TYPE_STRUCT)
343*1fd5a2e1SPrashanth Swaminathan && !cif->flags)))
344*1fd5a2e1SPrashanth Swaminathan *(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
345*1fd5a2e1SPrashanth Swaminathan else
346*1fd5a2e1SPrashanth Swaminathan *(void **)(closure->tramp + 8) = ffi_closure_SYSV;
347*1fd5a2e1SPrashanth Swaminathan
348*1fd5a2e1SPrashanth Swaminathan #ifdef __rtems__
349*1fd5a2e1SPrashanth Swaminathan rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
350*1fd5a2e1SPrashanth Swaminathan #elif defined(__MINT__)
351*1fd5a2e1SPrashanth Swaminathan Ssystem(S_FLUSHCACHE, codeloc, FFI_TRAMPOLINE_SIZE);
352*1fd5a2e1SPrashanth Swaminathan #else
353*1fd5a2e1SPrashanth Swaminathan syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
354*1fd5a2e1SPrashanth Swaminathan FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
355*1fd5a2e1SPrashanth Swaminathan #endif
356*1fd5a2e1SPrashanth Swaminathan
357*1fd5a2e1SPrashanth Swaminathan closure->cif = cif;
358*1fd5a2e1SPrashanth Swaminathan closure->user_data = user_data;
359*1fd5a2e1SPrashanth Swaminathan closure->fun = fun;
360*1fd5a2e1SPrashanth Swaminathan
361*1fd5a2e1SPrashanth Swaminathan return FFI_OK;
362*1fd5a2e1SPrashanth Swaminathan }
363