• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -----------------------------------------------------------------------
2    ffi_darwin.c
3 
4    Copyright (C) 1998 Geoffrey Keating
5    Copyright (C) 2001 John Hornkvist
6    Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
7 
8    FFI support for Darwin and AIX.
9 
10    Permission is hereby granted, free of charge, to any person obtaining
11    a copy of this software and associated documentation files (the
12    ``Software''), to deal in the Software without restriction, including
13    without limitation the rights to use, copy, modify, merge, publish,
14    distribute, sublicense, and/or sell copies of the Software, and to
15    permit persons to whom the Software is furnished to do so, subject to
16    the following conditions:
17 
18    The above copyright notice and this permission notice shall be included
19    in all copies or substantial portions of the Software.
20 
21    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
22    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
25    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
26    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
27    OTHER DEALINGS IN THE SOFTWARE.
28    ----------------------------------------------------------------------- */
29 
30 #include <ffi.h>
31 #include <ffi_common.h>
32 
33 #include <stdlib.h>
34 
35 extern void ffi_closure_ASM(void);
36 
37 enum {
38   /* The assembly depends on these exact flags.  */
39   FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7  */
40   FLAG_RETURNS_FP       = 1 << (31-29),
41   FLAG_RETURNS_64BITS   = 1 << (31-28),
42   FLAG_RETURNS_128BITS  = 1 << (31-31),
43 
44   FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
45   FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI  */
46   FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
47   FLAG_RETVAL_REFERENCE = 1 << (31- 4)
48 };
49 
50 /* About the DARWIN ABI.  */
51 enum {
52   NUM_GPR_ARG_REGISTERS = 8,
53   NUM_FPR_ARG_REGISTERS = 13
54 };
55 enum { ASM_NEEDS_REGISTERS = 4 };
56 
57 /* ffi_prep_args is called by the assembly routine once stack space
58    has been allocated for the function's arguments.
59 
60    The stack layout we want looks like this:
61 
62    |   Return address from ffi_call_DARWIN      |	higher addresses
63    |--------------------------------------------|
64    |   Previous backchain pointer	4	|	stack pointer here
65    |--------------------------------------------|<+ <<<	on entry to
66    |   Saved r28-r31			4*4	| |	ffi_call_DARWIN
67    |--------------------------------------------| |
68    |   Parameters             (at least 8*4=32) | |
69    |--------------------------------------------| |
70    |   Space for GPR2                   4       | |
71    |--------------------------------------------| |	stack	|
72    |   Reserved                       2*4       | |	grows	|
73    |--------------------------------------------| |	down	V
74    |   Space for callee's LR		4	| |
75    |--------------------------------------------| |	lower addresses
76    |   Saved CR                         4       | |
77    |--------------------------------------------| |     stack pointer here
78    |   Current backchain pointer	4	|-/	during
79    |--------------------------------------------|   <<<	ffi_call_DARWIN
80 
81    */
82 
ffi_prep_args(extended_cif * ecif,unsigned * const stack)83 void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
84 {
85   const unsigned bytes = ecif->cif->bytes;
86   const unsigned flags = ecif->cif->flags;
87 
88   /* 'stacktop' points at the previous backchain pointer.  */
89   unsigned *const stacktop = stack + (bytes / sizeof(unsigned));
90 
91   /* 'fpr_base' points at the space for fpr1, and grows upwards as
92      we use FPR registers.  */
93   double *fpr_base = (double*) (stacktop - ASM_NEEDS_REGISTERS) - NUM_FPR_ARG_REGISTERS;
94   int fparg_count = 0;
95 
96 
97   /* 'next_arg' grows up as we put parameters in it.  */
98   unsigned *next_arg = stack + 6; /* 6 reserved positions.  */
99 
100   int i = ecif->cif->nargs;
101   double double_tmp;
102   void **p_argv = ecif->avalue;
103   unsigned gprvalue;
104   ffi_type** ptr = ecif->cif->arg_types;
105   char *dest_cpy;
106   unsigned size_al = 0;
107 
108   /* Check that everything starts aligned properly.  */
109   FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0);
110   FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0);
111   FFI_ASSERT((bytes & 0xF) == 0);
112 
113   /* Deal with return values that are actually pass-by-reference.
114      Rule:
115      Return values are referenced by r3, so r4 is the first parameter.  */
116 
117   if (flags & FLAG_RETVAL_REFERENCE)
118     *next_arg++ = (unsigned)(char *)ecif->rvalue;
119 
120   /* Now for the arguments.  */
121   for (;
122        i > 0;
123        i--, ptr++, p_argv++)
124     {
125       switch ((*ptr)->type)
126 	{
127 	/* If a floating-point parameter appears before all of the general-
128 	   purpose registers are filled, the corresponding GPRs that match
129 	   the size of the floating-point parameter are skipped.  */
130 	case FFI_TYPE_FLOAT:
131 	  double_tmp = *(float *)*p_argv;
132 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
133 	    *(double *)next_arg = double_tmp;
134 	  else
135 	    *fpr_base++ = double_tmp;
136 	  next_arg++;
137 	  fparg_count++;
138 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
139 	  break;
140 
141 	case FFI_TYPE_DOUBLE:
142 	  double_tmp = *(double *)*p_argv;
143 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
144 	    *(double *)next_arg = double_tmp;
145 	  else
146 	    *fpr_base++ = double_tmp;
147 	  next_arg += 2;
148 	  fparg_count++;
149 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
150 	  break;
151 
152 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
153 
154 	case FFI_TYPE_LONGDOUBLE:
155 	  double_tmp = ((double *)*p_argv)[0];
156 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
157 	    *(double *)next_arg = double_tmp;
158 	  else
159 	    *fpr_base++ = double_tmp;
160 	  next_arg += 2;
161 	  fparg_count++;
162 	  double_tmp = ((double *)*p_argv)[1];
163 	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
164 	    *(double *)next_arg = double_tmp;
165 	  else
166 	    *fpr_base++ = double_tmp;
167 	  next_arg += 2;
168 	  fparg_count++;
169 	  FFI_ASSERT(flags & FLAG_FP_ARGUMENTS);
170 	  break;
171 #endif
172 	case FFI_TYPE_UINT64:
173 	case FFI_TYPE_SINT64:
174 	  *(long long *)next_arg = *(long long *)*p_argv;
175 	  next_arg+=2;
176 	  break;
177 	case FFI_TYPE_UINT8:
178 	  gprvalue = *(unsigned char *)*p_argv;
179 	  goto putgpr;
180 	case FFI_TYPE_SINT8:
181 	  gprvalue = *(signed char *)*p_argv;
182 	  goto putgpr;
183 	case FFI_TYPE_UINT16:
184 	  gprvalue = *(unsigned short *)*p_argv;
185 	  goto putgpr;
186 	case FFI_TYPE_SINT16:
187 	  gprvalue = *(signed short *)*p_argv;
188 	  goto putgpr;
189 
190 	case FFI_TYPE_STRUCT:
191 	  dest_cpy = (char *) next_arg;
192 
193 	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
194 	     SI 4 bytes) are aligned as if they were those modes.
195 	     Structures with 3 byte in size are padded upwards.  */
196 	  size_al = (*ptr)->size;
197 	  /* If the first member of the struct is a double, then align
198 	     the struct to double-word.
199 	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
200 	  if ((*ptr)->elements[0]->type == 3)
201 	    size_al = ALIGN((*ptr)->size, 8);
202 	  if (size_al < 3 && ecif->cif->abi == FFI_DARWIN)
203 	    dest_cpy += 4 - size_al;
204 
205 	  memcpy((char *)dest_cpy, (char *)*p_argv, size_al);
206 	  next_arg += (size_al + 3) / 4;
207 	  break;
208 
209 	case FFI_TYPE_INT:
210 	case FFI_TYPE_UINT32:
211 	case FFI_TYPE_SINT32:
212 	case FFI_TYPE_POINTER:
213 	  gprvalue = *(unsigned *)*p_argv;
214 	putgpr:
215 	  *next_arg++ = gprvalue;
216 	  break;
217 	default:
218 	  break;
219 	}
220     }
221 
222   /* Check that we didn't overrun the stack...  */
223   //FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS);
224   //FFI_ASSERT((unsigned *)fpr_base
225   //	     <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
226   //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
227 }
228 
229 /* Adjust the size of S to be correct for Darwin.
230    On Darwin, the first field of a structure has natural alignment.  */
231 
232 static void
darwin_adjust_aggregate_sizes(ffi_type * s)233 darwin_adjust_aggregate_sizes (ffi_type *s)
234 {
235   int i;
236 
237   if (s->type != FFI_TYPE_STRUCT)
238     return;
239 
240   s->size = 0;
241   for (i = 0; s->elements[i] != NULL; i++)
242     {
243       ffi_type *p;
244       int align;
245 
246       p = s->elements[i];
247       darwin_adjust_aggregate_sizes (p);
248       if (i == 0
249 	  && (p->type == FFI_TYPE_UINT64
250 	      || p->type == FFI_TYPE_SINT64
251 	      || p->type == FFI_TYPE_DOUBLE
252 	      || p->alignment == 8))
253 	align = 8;
254       else if (p->alignment == 16 || p->alignment < 4)
255 	align = p->alignment;
256       else
257 	align = 4;
258       s->size = ALIGN(s->size, align) + p->size;
259     }
260 
261   s->size = ALIGN(s->size, s->alignment);
262 
263   if (s->elements[0]->type == FFI_TYPE_UINT64
264       || s->elements[0]->type == FFI_TYPE_SINT64
265       || s->elements[0]->type == FFI_TYPE_DOUBLE
266       || s->elements[0]->alignment == 8)
267     s->alignment = s->alignment > 8 ? s->alignment : 8;
268   /* Do not add additional tail padding.  */
269 }
270 
271 /* Perform machine dependent cif processing.  */
ffi_prep_cif_machdep(ffi_cif * cif)272 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
273 {
274   /* All this is for the DARWIN ABI.  */
275   int i;
276   ffi_type **ptr;
277   unsigned bytes;
278   int fparg_count = 0, intarg_count = 0;
279   unsigned flags = 0;
280   unsigned size_al = 0;
281 
282   /* All the machine-independent calculation of cif->bytes will be wrong.
283      All the calculation of structure sizes will also be wrong.
284      Redo the calculation for DARWIN.  */
285 
286   if (cif->abi == FFI_DARWIN)
287     {
288       darwin_adjust_aggregate_sizes (cif->rtype);
289       for (i = 0; i < cif->nargs; i++)
290 	darwin_adjust_aggregate_sizes (cif->arg_types[i]);
291     }
292 
293   /* Space for the frame pointer, callee's LR, CR, etc, and for
294      the asm's temp regs.  */
295 
296   bytes = (6 + ASM_NEEDS_REGISTERS) * sizeof(long);
297 
298   /* Return value handling.  The rules are as follows:
299      - 32-bit (or less) integer values are returned in gpr3;
300      - Structures of size <= 4 bytes also returned in gpr3;
301      - 64-bit integer values and structures between 5 and 8 bytes are returned
302        in gpr3 and gpr4;
303      - Single/double FP values are returned in fpr1;
304      - Long double FP (if not equivalent to double) values are returned in
305        fpr1 and fpr2;
306      - Larger structures values are allocated space and a pointer is passed
307        as the first argument.  */
308   switch (cif->rtype->type)
309     {
310 
311 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
312     case FFI_TYPE_LONGDOUBLE:
313       flags |= FLAG_RETURNS_128BITS;
314       flags |= FLAG_RETURNS_FP;
315       break;
316 #endif
317 
318     case FFI_TYPE_DOUBLE:
319       flags |= FLAG_RETURNS_64BITS;
320       /* Fall through.  */
321     case FFI_TYPE_FLOAT:
322       flags |= FLAG_RETURNS_FP;
323       break;
324 
325     case FFI_TYPE_UINT64:
326     case FFI_TYPE_SINT64:
327       flags |= FLAG_RETURNS_64BITS;
328       break;
329 
330     case FFI_TYPE_STRUCT:
331       flags |= FLAG_RETVAL_REFERENCE;
332       flags |= FLAG_RETURNS_NOTHING;
333       intarg_count++;
334       break;
335     case FFI_TYPE_VOID:
336       flags |= FLAG_RETURNS_NOTHING;
337       break;
338 
339     default:
340       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
341       break;
342     }
343 
344   /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
345      first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
346      goes on the stack.  Structures are passed as a pointer to a copy of
347      the structure. Stuff on the stack needs to keep proper alignment.  */
348   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
349     {
350       switch ((*ptr)->type)
351 	{
352 	case FFI_TYPE_FLOAT:
353 	case FFI_TYPE_DOUBLE:
354 	  fparg_count++;
355 	  /* If this FP arg is going on the stack, it must be
356 	     8-byte-aligned.  */
357 	  if (fparg_count > NUM_FPR_ARG_REGISTERS
358 	      && intarg_count%2 != 0)
359 	    intarg_count++;
360 	  break;
361 
362 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
363 
364 	case FFI_TYPE_LONGDOUBLE:
365 	  fparg_count += 2;
366 	  /* If this FP arg is going on the stack, it must be
367 	     8-byte-aligned.  */
368 	  if (fparg_count > NUM_FPR_ARG_REGISTERS
369 	      && intarg_count%2 != 0)
370 	    intarg_count++;
371 	  intarg_count +=2;
372 	  break;
373 #endif
374 
375 	case FFI_TYPE_UINT64:
376 	case FFI_TYPE_SINT64:
377 	  /* 'long long' arguments are passed as two words, but
378 	     either both words must fit in registers or both go
379 	     on the stack.  If they go on the stack, they must
380 	     be 8-byte-aligned.  */
381 	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1
382 	      || (intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0))
383 	    intarg_count++;
384 	  intarg_count += 2;
385 	  break;
386 
387 	case FFI_TYPE_STRUCT:
388 	  size_al = (*ptr)->size;
389 	  /* If the first member of the struct is a double, then align
390 	     the struct to double-word.
391 	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
392 	  if ((*ptr)->elements[0]->type == 3)
393 	    size_al = ALIGN((*ptr)->size, 8);
394 	  intarg_count += (size_al + 3) / 4;
395 	  break;
396 
397 	default:
398 	  /* Everything else is passed as a 4-byte word in a GPR, either
399 	     the object itself or a pointer to it.  */
400 	  intarg_count++;
401 	  break;
402 	}
403     }
404 
405   if (fparg_count != 0)
406     flags |= FLAG_FP_ARGUMENTS;
407 
408   /* Space for the FPR registers, if needed.  */
409   if (fparg_count != 0)
410     bytes += NUM_FPR_ARG_REGISTERS * sizeof(double);
411 
412   /* Stack space.  */
413   if ((intarg_count + 2 * fparg_count) > NUM_GPR_ARG_REGISTERS)
414     bytes += (intarg_count + 2 * fparg_count) * sizeof(long);
415   else
416     bytes += NUM_GPR_ARG_REGISTERS * sizeof(long);
417 
418   /* The stack space allocated needs to be a multiple of 16 bytes.  */
419   bytes = (bytes + 15) & ~0xF;
420 
421   cif->flags = flags;
422   cif->bytes = bytes;
423 
424   return FFI_OK;
425 }
426 
427 extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
428 			 void (*fn)(void), void (*fn2)(void));
429 extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
430 			    void (*fn)(void), void (*fn2)(void));
431 
ffi_call(ffi_cif * cif,void (* fn)(void),void * rvalue,void ** avalue)432 void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
433 {
434   extended_cif ecif;
435 
436   ecif.cif = cif;
437   ecif.avalue = avalue;
438 
439   /* If the return value is a struct and we don't have a return
440      value address then we need to make one.  */
441 
442   if ((rvalue == NULL) &&
443       (cif->rtype->type == FFI_TYPE_STRUCT))
444     {
445       ecif.rvalue = alloca(cif->rtype->size);
446     }
447   else
448     ecif.rvalue = rvalue;
449 
450   switch (cif->abi)
451     {
452     case FFI_AIX:
453       ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
454 		   ffi_prep_args);
455       break;
456     case FFI_DARWIN:
457       ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
458 		      ffi_prep_args);
459       break;
460     default:
461       FFI_ASSERT(0);
462       break;
463     }
464 }
465 
466 static void flush_icache(char *);
467 static void flush_range(char *, int);
468 
469 /* The layout of a function descriptor.  A C function pointer really
470    points to one of these.  */
471 
472 typedef struct aix_fd_struct {
473   void *code_pointer;
474   void *toc;
475 } aix_fd;
476 
477 /* here I'd like to add the stack frame layout we use in darwin_closure.S
478    and aix_clsoure.S
479 
480    SP previous -> +---------------------------------------+ <--- child frame
481 		  | back chain to caller 4                |
482 		  +---------------------------------------+ 4
483 		  | saved CR 4                            |
484 		  +---------------------------------------+ 8
485 		  | saved LR 4                            |
486 		  +---------------------------------------+ 12
487 		  | reserved for compilers 4              |
488 		  +---------------------------------------+ 16
489 		  | reserved for binders 4                |
490 		  +---------------------------------------+ 20
491 		  | saved TOC pointer 4                   |
492 		  +---------------------------------------+ 24
493 		  | always reserved 8*4=32 (previous GPRs)|
494 		  | according to the linkage convention   |
495 		  | from AIX                              |
496 		  +---------------------------------------+ 56
497 		  | our FPR area 13*8=104                 |
498 		  | f1                                    |
499 		  | .                                     |
500 		  | f13                                   |
501 		  +---------------------------------------+ 160
502 		  | result area 8                         |
503 		  +---------------------------------------+ 168
504 		  | alignement to the next multiple of 16 |
505 SP current -->    +---------------------------------------+ 176 <- parent frame
506 		  | back chain to caller 4                |
507 		  +---------------------------------------+ 180
508 		  | saved CR 4                            |
509 		  +---------------------------------------+ 184
510 		  | saved LR 4                            |
511 		  +---------------------------------------+ 188
512 		  | reserved for compilers 4              |
513 		  +---------------------------------------+ 192
514 		  | reserved for binders 4                |
515 		  +---------------------------------------+ 196
516 		  | saved TOC pointer 4                   |
517 		  +---------------------------------------+ 200
518 		  | always reserved 8*4=32  we store our  |
519 		  | GPRs here                             |
520 		  | r3                                    |
521 		  | .                                     |
522 		  | r10                                   |
523 		  +---------------------------------------+ 232
524 		  | overflow part                         |
525 		  +---------------------------------------+ xxx
526 		  | ????                                  |
527 		  +---------------------------------------+ xxx
528 
529 */
530 ffi_status
ffi_prep_closure_loc(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)531 ffi_prep_closure_loc (ffi_closure* closure,
532 		      ffi_cif* cif,
533 		      void (*fun)(ffi_cif*, void*, void**, void*),
534 		      void *user_data,
535 		      void *codeloc)
536 {
537   unsigned int *tramp;
538   struct ffi_aix_trampoline_struct *tramp_aix;
539   aix_fd *fd;
540 
541   switch (cif->abi)
542     {
543     case FFI_DARWIN:
544 
545       FFI_ASSERT (cif->abi == FFI_DARWIN);
546 
547       tramp = (unsigned int *) &closure->tramp[0];
548       tramp[0] = 0x7c0802a6;  /*   mflr    r0  */
549       tramp[1] = 0x429f000d;  /*   bcl-    20,4*cr7+so,0x10  */
550       tramp[4] = 0x7d6802a6;  /*   mflr    r11  */
551       tramp[5] = 0x818b0000;  /*   lwz     r12,0(r11) function address  */
552       tramp[6] = 0x7c0803a6;  /*   mtlr    r0   */
553       tramp[7] = 0x7d8903a6;  /*   mtctr   r12  */
554       tramp[8] = 0x816b0004;  /*   lwz     r11,4(r11) static chain  */
555       tramp[9] = 0x4e800420;  /*   bctr  */
556       tramp[2] = (unsigned long) ffi_closure_ASM; /* function  */
557       tramp[3] = (unsigned long) codeloc; /* context  */
558 
559       closure->cif = cif;
560       closure->fun = fun;
561       closure->user_data = user_data;
562 
563       /* Flush the icache. Only necessary on Darwin.  */
564       flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
565 
566       break;
567 
568     case FFI_AIX:
569 
570       tramp_aix = (struct ffi_aix_trampoline_struct *) (closure->tramp);
571       fd = (aix_fd *)(void *)ffi_closure_ASM;
572 
573       FFI_ASSERT (cif->abi == FFI_AIX);
574 
575       tramp_aix->code_pointer = fd->code_pointer;
576       tramp_aix->toc = fd->toc;
577       tramp_aix->static_chain = codeloc;
578       closure->cif = cif;
579       closure->fun = fun;
580       closure->user_data = user_data;
581 
582     default:
583 
584       FFI_ASSERT(0);
585       break;
586     }
587   return FFI_OK;
588 }
589 
590 static void
flush_icache(char * addr)591 flush_icache(char *addr)
592 {
593 #ifndef _AIX
594   __asm__ volatile (
595 		"dcbf 0,%0\n"
596 		"\tsync\n"
597 		"\ticbi 0,%0\n"
598 		"\tsync\n"
599 		"\tisync"
600 		: : "r"(addr) : "memory");
601 #endif
602 }
603 
604 static void
flush_range(char * addr1,int size)605 flush_range(char * addr1, int size)
606 {
607 #define MIN_LINE_SIZE 32
608   int i;
609   for (i = 0; i < size; i += MIN_LINE_SIZE)
610     flush_icache(addr1+i);
611   flush_icache(addr1+size-1);
612 }
613 
614 typedef union
615 {
616   float f;
617   double d;
618 } ffi_dblfl;
619 
620 int ffi_closure_helper_DARWIN (ffi_closure*, void*,
621 			       unsigned long*, ffi_dblfl*);
622 
623 /* Basically the trampoline invokes ffi_closure_ASM, and on
624    entry, r11 holds the address of the closure.
625    After storing the registers that could possibly contain
626    parameters to be passed into the stack frame and setting
627    up space for a return value, ffi_closure_ASM invokes the
628    following helper function to do most of the work.  */
629 
ffi_closure_helper_DARWIN(ffi_closure * closure,void * rvalue,unsigned long * pgr,ffi_dblfl * pfr)630 int ffi_closure_helper_DARWIN (ffi_closure* closure, void * rvalue,
631 			       unsigned long * pgr, ffi_dblfl * pfr)
632 {
633   /* rvalue is the pointer to space for return value in closure assembly
634      pgr is the pointer to where r3-r10 are stored in ffi_closure_ASM
635      pfr is the pointer to where f1-f13 are stored in ffi_closure_ASM.  */
636 
637   typedef double ldbits[2];
638 
639   union ldu
640   {
641     ldbits lb;
642     long double ld;
643   };
644 
645   void **          avalue;
646   ffi_type **      arg_types;
647   long             i, avn;
648   long             nf;   /* number of floating registers already used.  */
649   long             ng;   /* number of general registers already used.  */
650   ffi_cif *        cif;
651   double           temp;
652   unsigned         size_al;
653   union ldu        temp_ld;
654 
655   cif = closure->cif;
656   avalue = alloca(cif->nargs * sizeof(void *));
657 
658   nf = 0;
659   ng = 0;
660 
661   /* Copy the caller's structure return value address so that the closure
662      returns the data directly to the caller.  */
663   if (cif->rtype->type == FFI_TYPE_STRUCT)
664     {
665       rvalue = (void *) *pgr;
666       pgr++;
667       ng++;
668     }
669 
670   i = 0;
671   avn = cif->nargs;
672   arg_types = cif->arg_types;
673 
674   /* Grab the addresses of the arguments from the stack frame.  */
675   while (i < avn)
676     {
677       switch (arg_types[i]->type)
678 	{
679 	case FFI_TYPE_SINT8:
680 	case FFI_TYPE_UINT8:
681 	  avalue[i] = (char *) pgr + 3;
682 	  ng++;
683 	  pgr++;
684 	  break;
685 
686 	case FFI_TYPE_SINT16:
687 	case FFI_TYPE_UINT16:
688 	  avalue[i] = (char *) pgr + 2;
689 	  ng++;
690 	  pgr++;
691 	  break;
692 
693 	case FFI_TYPE_SINT32:
694 	case FFI_TYPE_UINT32:
695 	case FFI_TYPE_POINTER:
696 	  avalue[i] = pgr;
697 	  ng++;
698 	  pgr++;
699 	  break;
700 
701 	case FFI_TYPE_STRUCT:
702 	  /* Structures that match the basic modes (QI 1 byte, HI 2 bytes,
703 	     SI 4 bytes) are aligned as if they were those modes.  */
704 	  size_al = arg_types[i]->size;
705 	  /* If the first member of the struct is a double, then align
706 	     the struct to double-word.
707 	     Type 3 is defined in include/ffi.h. #define FFI_TYPE_DOUBLE 3.  */
708 	  if (arg_types[i]->elements[0]->type == 3)
709 	    size_al = ALIGN(arg_types[i]->size, 8);
710 	  if (size_al < 3 && cif->abi == FFI_DARWIN)
711 	    avalue[i] = (void*) pgr + 4 - size_al;
712 	  else
713 	    avalue[i] = (void*) pgr;
714 	  ng += (size_al + 3) / 4;
715 	  pgr += (size_al + 3) / 4;
716 	  break;
717 
718 	case FFI_TYPE_SINT64:
719 	case FFI_TYPE_UINT64:
720 	  /* Long long ints are passed in two gpr's.  */
721 	  avalue[i] = pgr;
722 	  ng += 2;
723 	  pgr += 2;
724 	  break;
725 
726 	case FFI_TYPE_FLOAT:
727 	  /* A float value consumes a GPR.
728 	     There are 13 64bit floating point registers.  */
729 	  if (nf < NUM_FPR_ARG_REGISTERS)
730 	    {
731 	      temp = pfr->d;
732 	      pfr->f = (float)temp;
733 	      avalue[i] = pfr;
734 	      pfr++;
735 	    }
736 	  else
737 	    {
738 	      avalue[i] = pgr;
739 	    }
740 	  nf++;
741 	  ng++;
742 	  pgr++;
743 	  break;
744 
745 	case FFI_TYPE_DOUBLE:
746 	  /* A double value consumes two GPRs.
747 	     There are 13 64bit floating point registers.  */
748 	  if (nf < NUM_FPR_ARG_REGISTERS)
749 	    {
750 	      avalue[i] = pfr;
751 	      pfr++;
752 	    }
753 	  else
754 	    {
755 	      avalue[i] = pgr;
756 	    }
757 	  nf++;
758 	  ng += 2;
759 	  pgr += 2;
760 	  break;
761 
762 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
763 
764 	case FFI_TYPE_LONGDOUBLE:
765 	  /* A long double value consumes four GPRs and two FPRs.
766 	     There are 13 64bit floating point registers.  */
767 	  if (nf < NUM_FPR_ARG_REGISTERS - 1)
768 	    {
769 	      avalue[i] = pfr;
770 	      pfr += 2;
771 	    }
772 	  /* Here we have the situation where one part of the long double
773 	     is stored in fpr13 and the other part is already on the stack.
774 	     We use a union to pass the long double to avalue[i].  */
775 	  else if (nf == NUM_FPR_ARG_REGISTERS - 1)
776 	    {
777 	      memcpy (&temp_ld.lb[0], pfr, sizeof(ldbits));
778 	      memcpy (&temp_ld.lb[1], pgr + 2, sizeof(ldbits));
779 	      avalue[i] = &temp_ld.ld;
780 	    }
781 	  else
782 	    {
783 	      avalue[i] = pgr;
784 	    }
785 	  nf += 2;
786 	  ng += 4;
787 	  pgr += 4;
788 	  break;
789 #endif
790 	default:
791 	  FFI_ASSERT(0);
792 	}
793       i++;
794     }
795 
796   (closure->fun) (cif, rvalue, avalue, closure->user_data);
797 
798   /* Tell ffi_closure_ASM to perform return type promotions.  */
799   return cif->rtype->type;
800 }
801