xref: /aosp_15_r20/external/libffi/src/m68k/ffi.c (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
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