1 /* -----------------------------------------------------------------------
2    ffi_sysv.c - Copyright (C) 2013 IBM
3                 Copyright (C) 2011 Anthony Green
4                 Copyright (C) 2011 Kyle Moffett
5                 Copyright (C) 2008 Red Hat, Inc
6                 Copyright (C) 2007, 2008 Free Software Foundation, Inc
7                 Copyright (c) 1998 Geoffrey Keating
8 
9    PowerPC Foreign Function Interface
10 
11    Permission is hereby granted, free of charge, to any person obtaining
12    a copy of this software and associated documentation files (the
13    ``Software''), to deal in the Software without restriction, including
14    without limitation the rights to use, copy, modify, merge, publish,
15    distribute, sublicense, and/or sell copies of the Software, and to
16    permit persons to whom the Software is furnished to do so, subject to
17    the following conditions:
18 
19    The above copyright notice and this permission notice shall be included
20    in all copies or substantial portions of the Software.
21 
22    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
23    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
26    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28    OTHER DEALINGS IN THE SOFTWARE.
29    ----------------------------------------------------------------------- */
30 
31 #include "ffi.h"
32 
33 #ifndef POWERPC64
34 #include "ffi_common.h"
35 #include "ffi_powerpc.h"
36 
37 
38 /* About the SYSV ABI.  */
39 #define ASM_NEEDS_REGISTERS 6
40 #define NUM_GPR_ARG_REGISTERS 8
41 #define NUM_FPR_ARG_REGISTERS 8
42 
43 
44 #if HAVE_LONG_DOUBLE_VARIANT && FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
45 /* Adjust size of ffi_type_longdouble.  */
46 void FFI_HIDDEN
ffi_prep_types_sysv(ffi_abi abi)47 ffi_prep_types_sysv (ffi_abi abi)
48 {
49   if ((abi & (FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128)) == FFI_SYSV)
50     {
51       ffi_type_longdouble.size = 8;
52       ffi_type_longdouble.alignment = 8;
53     }
54   else
55     {
56       ffi_type_longdouble.size = 16;
57       ffi_type_longdouble.alignment = 16;
58     }
59 }
60 #endif
61 
62 /* Transform long double, double and float to other types as per abi.  */
63 static int
translate_float(int abi,int type)64 translate_float (int abi, int type)
65 {
66 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
67   if (type == FFI_TYPE_LONGDOUBLE
68       && (abi & FFI_SYSV_LONG_DOUBLE_128) == 0)
69     type = FFI_TYPE_DOUBLE;
70 #endif
71   if ((abi & FFI_SYSV_SOFT_FLOAT) != 0)
72     {
73       if (type == FFI_TYPE_FLOAT)
74 	type = FFI_TYPE_UINT32;
75       else if (type == FFI_TYPE_DOUBLE)
76 	type = FFI_TYPE_UINT64;
77 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
78       else if (type == FFI_TYPE_LONGDOUBLE)
79 	type = FFI_TYPE_UINT128;
80     }
81   else if ((abi & FFI_SYSV_IBM_LONG_DOUBLE) == 0)
82     {
83       if (type == FFI_TYPE_LONGDOUBLE)
84 	type = FFI_TYPE_STRUCT;
85 #endif
86     }
87   return type;
88 }
89 
90 /* Perform machine dependent cif processing */
91 static ffi_status
ffi_prep_cif_sysv_core(ffi_cif * cif)92 ffi_prep_cif_sysv_core (ffi_cif *cif)
93 {
94   ffi_type **ptr;
95   unsigned bytes;
96   unsigned i, fpr_count = 0, gpr_count = 0, stack_count = 0;
97   unsigned flags = cif->flags;
98   unsigned struct_copy_size = 0;
99   unsigned type = cif->rtype->type;
100   unsigned size = cif->rtype->size;
101 
102   /* The machine-independent calculation of cif->bytes doesn't work
103      for us.  Redo the calculation.  */
104 
105   /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
106   bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
107 
108   /* Space for the GPR registers.  */
109   bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
110 
111   /* Return value handling.  The rules for SYSV are as follows:
112      - 32-bit (or less) integer values are returned in gpr3;
113      - Structures of size <= 4 bytes also returned in gpr3;
114      - 64-bit integer values and structures between 5 and 8 bytes are returned
115      in gpr3 and gpr4;
116      - Larger structures are allocated space and a pointer is passed as
117      the first argument.
118      - Single/double FP values are returned in fpr1;
119      - long doubles (if not equivalent to double) are returned in
120      fpr1,fpr2 for Linux and as for large structs for SysV.  */
121 
122   type = translate_float (cif->abi, type);
123 
124   switch (type)
125     {
126 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
127     case FFI_TYPE_LONGDOUBLE:
128       flags |= FLAG_RETURNS_128BITS;
129       /* Fall through.  */
130 #endif
131     case FFI_TYPE_DOUBLE:
132       flags |= FLAG_RETURNS_64BITS;
133       /* Fall through.  */
134     case FFI_TYPE_FLOAT:
135       flags |= FLAG_RETURNS_FP;
136 #ifdef __NO_FPRS__
137       return FFI_BAD_ABI;
138 #endif
139       break;
140 
141     case FFI_TYPE_UINT128:
142       flags |= FLAG_RETURNS_128BITS;
143       /* Fall through.  */
144     case FFI_TYPE_UINT64:
145     case FFI_TYPE_SINT64:
146       flags |= FLAG_RETURNS_64BITS;
147       break;
148 
149     case FFI_TYPE_STRUCT:
150       /* The final SYSV ABI says that structures smaller or equal 8 bytes
151 	 are returned in r3/r4.  A draft ABI used by linux instead
152 	 returns them in memory.  */
153       if ((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)
154 	{
155 	  flags |= FLAG_RETURNS_SMST;
156 	  break;
157 	}
158       gpr_count++;
159       flags |= FLAG_RETVAL_REFERENCE;
160       /* Fall through.  */
161     case FFI_TYPE_VOID:
162       flags |= FLAG_RETURNS_NOTHING;
163       break;
164 
165     default:
166       /* Returns 32-bit integer, or similar.  Nothing to do here.  */
167       break;
168     }
169 
170   /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
171      first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
172      goes on the stack.  Structures and long doubles (if not equivalent
173      to double) are passed as a pointer to a copy of the structure.
174      Stuff on the stack needs to keep proper alignment.  */
175   for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
176     {
177       unsigned short typenum = (*ptr)->type;
178 
179       typenum = translate_float (cif->abi, typenum);
180 
181       switch (typenum)
182 	{
183 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
184 	case FFI_TYPE_LONGDOUBLE:
185 	  if (fpr_count >= NUM_FPR_ARG_REGISTERS - 1)
186 	    {
187 	      fpr_count = NUM_FPR_ARG_REGISTERS;
188 	      /* 8-byte align long doubles.  */
189 	      stack_count += stack_count & 1;
190 	      stack_count += 4;
191 	    }
192 	  else
193 	    fpr_count += 2;
194 #ifdef __NO_FPRS__
195 	  return FFI_BAD_ABI;
196 #endif
197 	  break;
198 #endif
199 
200 	case FFI_TYPE_DOUBLE:
201 	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)
202 	    {
203 	      /* 8-byte align doubles.  */
204 	      stack_count += stack_count & 1;
205 	      stack_count += 2;
206 	    }
207 	  else
208 	    fpr_count += 1;
209 #ifdef __NO_FPRS__
210 	  return FFI_BAD_ABI;
211 #endif
212 	  break;
213 
214 	case FFI_TYPE_FLOAT:
215 	  if (fpr_count >= NUM_FPR_ARG_REGISTERS)
216 	    /* Yes, we don't follow the ABI, but neither does gcc.  */
217 	    stack_count += 1;
218 	  else
219 	    fpr_count += 1;
220 #ifdef __NO_FPRS__
221 	  return FFI_BAD_ABI;
222 #endif
223 	  break;
224 
225 	case FFI_TYPE_UINT128:
226 	  /* A long double in FFI_LINUX_SOFT_FLOAT can use only a set
227 	     of four consecutive gprs. If we do not have enough, we
228 	     have to adjust the gpr_count value.  */
229 	  if (gpr_count >= NUM_GPR_ARG_REGISTERS - 3)
230 	    gpr_count = NUM_GPR_ARG_REGISTERS;
231 	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
232 	    stack_count += 4;
233 	  else
234 	    gpr_count += 4;
235 	  break;
236 
237 	case FFI_TYPE_UINT64:
238 	case FFI_TYPE_SINT64:
239 	  /* 'long long' arguments are passed as two words, but
240 	     either both words must fit in registers or both go
241 	     on the stack.  If they go on the stack, they must
242 	     be 8-byte-aligned.
243 
244 	     Also, only certain register pairs can be used for
245 	     passing long long int -- specifically (r3,r4), (r5,r6),
246 	     (r7,r8), (r9,r10).  */
247 	  gpr_count += gpr_count & 1;
248 	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
249 	    {
250 	      stack_count += stack_count & 1;
251 	      stack_count += 2;
252 	    }
253 	  else
254 	    gpr_count += 2;
255 	  break;
256 
257 	case FFI_TYPE_STRUCT:
258 	  /* We must allocate space for a copy of these to enforce
259 	     pass-by-value.  Pad the space up to a multiple of 16
260 	     bytes (the maximum alignment required for anything under
261 	     the SYSV ABI).  */
262 	  struct_copy_size += ((*ptr)->size + 15) & ~0xF;
263 	  /* Fall through (allocate space for the pointer).  */
264 
265 	case FFI_TYPE_POINTER:
266 	case FFI_TYPE_INT:
267 	case FFI_TYPE_UINT32:
268 	case FFI_TYPE_SINT32:
269 	case FFI_TYPE_UINT16:
270 	case FFI_TYPE_SINT16:
271 	case FFI_TYPE_UINT8:
272 	case FFI_TYPE_SINT8:
273 	  /* Everything else is passed as a 4-byte word in a GPR, either
274 	     the object itself or a pointer to it.  */
275 	  if (gpr_count >= NUM_GPR_ARG_REGISTERS)
276 	    stack_count += 1;
277 	  else
278 	    gpr_count += 1;
279 	  break;
280 
281 	default:
282 	  FFI_ASSERT (0);
283 	}
284     }
285 
286   if (fpr_count != 0)
287     flags |= FLAG_FP_ARGUMENTS;
288   if (gpr_count > 4)
289     flags |= FLAG_4_GPR_ARGUMENTS;
290   if (struct_copy_size != 0)
291     flags |= FLAG_ARG_NEEDS_COPY;
292 
293   /* Space for the FPR registers, if needed.  */
294   if (fpr_count != 0)
295     bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
296 
297   /* Stack space.  */
298   bytes += stack_count * sizeof (int);
299 
300   /* The stack space allocated needs to be a multiple of 16 bytes.  */
301   bytes = (bytes + 15) & ~0xF;
302 
303   /* Add in the space for the copied structures.  */
304   bytes += struct_copy_size;
305 
306   cif->flags = flags;
307   cif->bytes = bytes;
308 
309   return FFI_OK;
310 }
311 
312 ffi_status FFI_HIDDEN
ffi_prep_cif_sysv(ffi_cif * cif)313 ffi_prep_cif_sysv (ffi_cif *cif)
314 {
315   if ((cif->abi & FFI_SYSV) == 0)
316     {
317       /* This call is from old code.  Translate to new ABI values.  */
318       cif->flags |= FLAG_COMPAT;
319       switch (cif->abi)
320 	{
321 	default:
322 	  return FFI_BAD_ABI;
323 
324 	case FFI_COMPAT_SYSV:
325 	  cif->abi = FFI_SYSV | FFI_SYSV_STRUCT_RET | FFI_SYSV_LONG_DOUBLE_128;
326 	  break;
327 
328 	case FFI_COMPAT_GCC_SYSV:
329 	  cif->abi = FFI_SYSV | FFI_SYSV_LONG_DOUBLE_128;
330 	  break;
331 
332 	case FFI_COMPAT_LINUX:
333 	  cif->abi = (FFI_SYSV | FFI_SYSV_IBM_LONG_DOUBLE
334 		      | FFI_SYSV_LONG_DOUBLE_128);
335 	  break;
336 
337 	case FFI_COMPAT_LINUX_SOFT_FLOAT:
338 	  cif->abi = (FFI_SYSV | FFI_SYSV_SOFT_FLOAT | FFI_SYSV_IBM_LONG_DOUBLE
339 		      | FFI_SYSV_LONG_DOUBLE_128);
340 	  break;
341 	}
342     }
343   return ffi_prep_cif_sysv_core (cif);
344 }
345 
346 /* ffi_prep_args_SYSV is called by the assembly routine once stack space
347    has been allocated for the function's arguments.
348 
349    The stack layout we want looks like this:
350 
351    |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
352    |--------------------------------------------|
353    |   Previous backchain pointer	4	|       stack pointer here
354    |--------------------------------------------|<+ <<<	on entry to
355    |   Saved r28-r31			4*4	| |	ffi_call_SYSV
356    |--------------------------------------------| |
357    |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
358    |--------------------------------------------| |
359    |   FPR registers f1-f8 (optional)	8*8	| |
360    |--------------------------------------------| |	stack	|
361    |   Space for copied structures		| |	grows	|
362    |--------------------------------------------| |	down    V
363    |   Parameters that didn't fit in registers  | |
364    |--------------------------------------------| |	lower addresses
365    |   Space for callee's LR		4	| |
366    |--------------------------------------------| |	stack pointer here
367    |   Current backchain pointer	4	|-/	during
368    |--------------------------------------------|   <<<	ffi_call_SYSV
369 
370 */
371 
372 void FFI_HIDDEN
ffi_prep_args_SYSV(extended_cif * ecif,unsigned * const stack)373 ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
374 {
375   const unsigned bytes = ecif->cif->bytes;
376   const unsigned flags = ecif->cif->flags;
377 
378   typedef union
379   {
380     char *c;
381     unsigned *u;
382     long long *ll;
383     float *f;
384     double *d;
385   } valp;
386 
387   /* 'stacktop' points at the previous backchain pointer.  */
388   valp stacktop;
389 
390   /* 'gpr_base' points at the space for gpr3, and grows upwards as
391      we use GPR registers.  */
392   valp gpr_base;
393   valp gpr_end;
394 
395 #ifndef __NO_FPRS__
396   /* 'fpr_base' points at the space for fpr1, and grows upwards as
397      we use FPR registers.  */
398   valp fpr_base;
399   valp fpr_end;
400 #endif
401 
402   /* 'copy_space' grows down as we put structures in it.  It should
403      stay 16-byte aligned.  */
404   valp copy_space;
405 
406   /* 'next_arg' grows up as we put parameters in it.  */
407   valp next_arg;
408 
409   int i;
410   ffi_type **ptr;
411 #ifndef __NO_FPRS__
412   double double_tmp;
413 #endif
414   union
415   {
416     void **v;
417     char **c;
418     signed char **sc;
419     unsigned char **uc;
420     signed short **ss;
421     unsigned short **us;
422     unsigned int **ui;
423     long long **ll;
424     float **f;
425     double **d;
426   } p_argv;
427   size_t struct_copy_size;
428   unsigned gprvalue;
429 
430   stacktop.c = (char *) stack + bytes;
431   gpr_end.u = stacktop.u - ASM_NEEDS_REGISTERS;
432   gpr_base.u = gpr_end.u - NUM_GPR_ARG_REGISTERS;
433 #ifndef __NO_FPRS__
434   fpr_end.d = gpr_base.d;
435   fpr_base.d = fpr_end.d - NUM_FPR_ARG_REGISTERS;
436   copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
437 #else
438   copy_space.c = gpr_base.c;
439 #endif
440   next_arg.u = stack + 2;
441 
442   /* Check that everything starts aligned properly.  */
443   FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
444   FFI_ASSERT (((unsigned long) copy_space.c & 0xF) == 0);
445   FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
446   FFI_ASSERT ((bytes & 0xF) == 0);
447   FFI_ASSERT (copy_space.c >= next_arg.c);
448 
449   /* Deal with return values that are actually pass-by-reference.  */
450   if (flags & FLAG_RETVAL_REFERENCE)
451     *gpr_base.u++ = (unsigned) (char *) ecif->rvalue;
452 
453   /* Now for the arguments.  */
454   p_argv.v = ecif->avalue;
455   for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
456        i > 0;
457        i--, ptr++, p_argv.v++)
458     {
459       unsigned int typenum = (*ptr)->type;
460 
461       typenum = translate_float (ecif->cif->abi, typenum);
462 
463       /* Now test the translated value */
464       switch (typenum)
465 	{
466 #ifndef __NO_FPRS__
467 # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
468 	case FFI_TYPE_LONGDOUBLE:
469 	  double_tmp = (*p_argv.d)[0];
470 
471 	  if (fpr_base.d >= fpr_end.d - 1)
472 	    {
473 	      fpr_base.d = fpr_end.d;
474 	      if (((next_arg.u - stack) & 1) != 0)
475 		next_arg.u += 1;
476 	      *next_arg.d = double_tmp;
477 	      next_arg.u += 2;
478 	      double_tmp = (*p_argv.d)[1];
479 	      *next_arg.d = double_tmp;
480 	      next_arg.u += 2;
481 	    }
482 	  else
483 	    {
484 	      *fpr_base.d++ = double_tmp;
485 	      double_tmp = (*p_argv.d)[1];
486 	      *fpr_base.d++ = double_tmp;
487 	    }
488 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
489 	  break;
490 # endif
491 	case FFI_TYPE_DOUBLE:
492 	  double_tmp = **p_argv.d;
493 
494 	  if (fpr_base.d >= fpr_end.d)
495 	    {
496 	      if (((next_arg.u - stack) & 1) != 0)
497 		next_arg.u += 1;
498 	      *next_arg.d = double_tmp;
499 	      next_arg.u += 2;
500 	    }
501 	  else
502 	    *fpr_base.d++ = double_tmp;
503 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
504 	  break;
505 
506 	case FFI_TYPE_FLOAT:
507 	  double_tmp = **p_argv.f;
508 	  if (fpr_base.d >= fpr_end.d)
509 	    {
510 	      *next_arg.f = (float) double_tmp;
511 	      next_arg.u += 1;
512 	    }
513 	  else
514 	    *fpr_base.d++ = double_tmp;
515 	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
516 	  break;
517 #endif /* have FPRs */
518 
519 	case FFI_TYPE_UINT128:
520 	  /* The soft float ABI for long doubles works like this, a long double
521 	     is passed in four consecutive GPRs if available.  A maximum of 2
522 	     long doubles can be passed in gprs.  If we do not have 4 GPRs
523 	     left, the long double is passed on the stack, 4-byte aligned.  */
524 	  if (gpr_base.u >= gpr_end.u - 3)
525 	    {
526 	      unsigned int ii;
527 	      gpr_base.u = gpr_end.u;
528 	      for (ii = 0; ii < 4; ii++)
529 		{
530 		  unsigned int int_tmp = (*p_argv.ui)[ii];
531 		  *next_arg.u++ = int_tmp;
532 		}
533 	    }
534 	  else
535 	    {
536 	      unsigned int ii;
537 	      for (ii = 0; ii < 4; ii++)
538 		{
539 		  unsigned int int_tmp = (*p_argv.ui)[ii];
540 		  *gpr_base.u++ = int_tmp;
541 		}
542 	    }
543 	  break;
544 
545 	case FFI_TYPE_UINT64:
546 	case FFI_TYPE_SINT64:
547 	  if (gpr_base.u >= gpr_end.u - 1)
548 	    {
549 	      gpr_base.u = gpr_end.u;
550 	      if (((next_arg.u - stack) & 1) != 0)
551 		next_arg.u++;
552 	      *next_arg.ll = **p_argv.ll;
553 	      next_arg.u += 2;
554 	    }
555 	  else
556 	    {
557 	      /* The abi states only certain register pairs can be
558 		 used for passing long long int specifically (r3,r4),
559 		 (r5,r6), (r7,r8), (r9,r10).  If next arg is long long
560 		 but not correct starting register of pair then skip
561 		 until the proper starting register.  */
562 	      if (((gpr_end.u - gpr_base.u) & 1) != 0)
563 		gpr_base.u++;
564 	      *gpr_base.ll++ = **p_argv.ll;
565 	    }
566 	  break;
567 
568 	case FFI_TYPE_STRUCT:
569 	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
570 	  copy_space.c -= struct_copy_size;
571 	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
572 
573 	  gprvalue = (unsigned long) copy_space.c;
574 
575 	  FFI_ASSERT (copy_space.c > next_arg.c);
576 	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
577 	  goto putgpr;
578 
579 	case FFI_TYPE_UINT8:
580 	  gprvalue = **p_argv.uc;
581 	  goto putgpr;
582 	case FFI_TYPE_SINT8:
583 	  gprvalue = **p_argv.sc;
584 	  goto putgpr;
585 	case FFI_TYPE_UINT16:
586 	  gprvalue = **p_argv.us;
587 	  goto putgpr;
588 	case FFI_TYPE_SINT16:
589 	  gprvalue = **p_argv.ss;
590 	  goto putgpr;
591 
592 	case FFI_TYPE_INT:
593 	case FFI_TYPE_UINT32:
594 	case FFI_TYPE_SINT32:
595 	case FFI_TYPE_POINTER:
596 
597 	  gprvalue = **p_argv.ui;
598 
599 	putgpr:
600 	  if (gpr_base.u >= gpr_end.u)
601 	    *next_arg.u++ = gprvalue;
602 	  else
603 	    *gpr_base.u++ = gprvalue;
604 	  break;
605 	}
606     }
607 
608   /* Check that we didn't overrun the stack...  */
609   FFI_ASSERT (copy_space.c >= next_arg.c);
610   FFI_ASSERT (gpr_base.u <= gpr_end.u);
611 #ifndef __NO_FPRS__
612   FFI_ASSERT (fpr_base.u <= fpr_end.u);
613 #endif
614   FFI_ASSERT (((flags & FLAG_4_GPR_ARGUMENTS) != 0)
615 	      == (gpr_end.u - gpr_base.u < 4));
616 }
617 
618 #define MIN_CACHE_LINE_SIZE 8
619 
620 static void
flush_icache(char * wraddr,char * xaddr,int size)621 flush_icache (char *wraddr, char *xaddr, int size)
622 {
623   int i;
624   for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
625     __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
626 		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
627   __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
628 		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
629 		    : "memory");
630 }
631 
632 ffi_status FFI_HIDDEN
ffi_prep_closure_loc_sysv(ffi_closure * closure,ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * codeloc)633 ffi_prep_closure_loc_sysv (ffi_closure *closure,
634 			   ffi_cif *cif,
635 			   void (*fun) (ffi_cif *, void *, void **, void *),
636 			   void *user_data,
637 			   void *codeloc)
638 {
639   unsigned int *tramp;
640 
641   if (cif->abi < FFI_SYSV || cif->abi >= FFI_LAST_ABI)
642     return FFI_BAD_ABI;
643 
644   tramp = (unsigned int *) &closure->tramp[0];
645   tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
646   tramp[1] = 0x429f0005;  /*   bcl     20,31,.+4 */
647   tramp[2] = 0x7d6802a6;  /*   mflr    r11 */
648   tramp[3] = 0x7c0803a6;  /*   mtlr    r0 */
649   tramp[4] = 0x800b0018;  /*   lwz     r0,24(r11) */
650   tramp[5] = 0x816b001c;  /*   lwz     r11,28(r11) */
651   tramp[6] = 0x7c0903a6;  /*   mtctr   r0 */
652   tramp[7] = 0x4e800420;  /*   bctr */
653   *(void **) &tramp[8] = (void *) ffi_closure_SYSV; /* function */
654   *(void **) &tramp[9] = codeloc;                   /* context */
655 
656   /* Flush the icache.  */
657   flush_icache ((char *)tramp, (char *)codeloc, 8 * 4);
658 
659   closure->cif = cif;
660   closure->fun = fun;
661   closure->user_data = user_data;
662 
663   return FFI_OK;
664 }
665 
666 /* Basically the trampoline invokes ffi_closure_SYSV, and on
667    entry, r11 holds the address of the closure.
668    After storing the registers that could possibly contain
669    parameters to be passed into the stack frame and setting
670    up space for a return value, ffi_closure_SYSV invokes the
671    following helper function to do most of the work.  */
672 
673 int
ffi_closure_helper_SYSV(ffi_cif * cif,void (* fun)(ffi_cif *,void *,void **,void *),void * user_data,void * rvalue,unsigned long * pgr,ffi_dblfl * pfr,unsigned long * pst)674 ffi_closure_helper_SYSV (ffi_cif *cif,
675 			 void (*fun) (ffi_cif *, void *, void **, void *),
676 			 void *user_data,
677 			 void *rvalue,
678 			 unsigned long *pgr,
679 			 ffi_dblfl *pfr,
680 			 unsigned long *pst)
681 {
682   /* rvalue is the pointer to space for return value in closure assembly */
683   /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
684   /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
685   /* pst is the pointer to outgoing parameter stack in original caller */
686 
687   void **          avalue;
688   ffi_type **      arg_types;
689   long             i, avn;
690 #ifndef __NO_FPRS__
691   long             nf = 0;   /* number of floating registers already used */
692 #endif
693   long             ng = 0;   /* number of general registers already used */
694 
695   unsigned       size     = cif->rtype->size;
696   unsigned short rtypenum = cif->rtype->type;
697 
698   avalue = alloca (cif->nargs * sizeof (void *));
699 
700   /* First translate for softfloat/nonlinux */
701   rtypenum = translate_float (cif->abi, rtypenum);
702 
703   /* Copy the caller's structure return value address so that the closure
704      returns the data directly to the caller.
705      For FFI_SYSV the result is passed in r3/r4 if the struct size is less
706      or equal 8 bytes.  */
707   if (rtypenum == FFI_TYPE_STRUCT
708       && !((cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8))
709     {
710       rvalue = (void *) *pgr;
711       ng++;
712       pgr++;
713     }
714 
715   i = 0;
716   avn = cif->nargs;
717   arg_types = cif->arg_types;
718 
719   /* Grab the addresses of the arguments from the stack frame.  */
720   while (i < avn) {
721     unsigned short typenum = arg_types[i]->type;
722 
723     /* We may need to handle some values depending on ABI.  */
724     typenum = translate_float (cif->abi, typenum);
725 
726     switch (typenum)
727       {
728 #ifndef __NO_FPRS__
729       case FFI_TYPE_FLOAT:
730 	/* Unfortunately float values are stored as doubles
731 	   in the ffi_closure_SYSV code (since we don't check
732 	   the type in that routine).  */
733 	if (nf < NUM_FPR_ARG_REGISTERS)
734 	  {
735 	    /* FIXME? here we are really changing the values
736 	       stored in the original calling routines outgoing
737 	       parameter stack.  This is probably a really
738 	       naughty thing to do but...  */
739 	    double temp = pfr->d;
740 	    pfr->f = (float) temp;
741 	    avalue[i] = pfr;
742 	    nf++;
743 	    pfr++;
744 	  }
745 	else
746 	  {
747 	    avalue[i] = pst;
748 	    pst += 1;
749 	  }
750 	break;
751 
752       case FFI_TYPE_DOUBLE:
753 	if (nf < NUM_FPR_ARG_REGISTERS)
754 	  {
755 	    avalue[i] = pfr;
756 	    nf++;
757 	    pfr++;
758 	  }
759 	else
760 	  {
761 	    if (((long) pst) & 4)
762 	      pst++;
763 	    avalue[i] = pst;
764 	    pst += 2;
765 	  }
766 	break;
767 
768 # if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
769       case FFI_TYPE_LONGDOUBLE:
770 	if (nf < NUM_FPR_ARG_REGISTERS - 1)
771 	  {
772 	    avalue[i] = pfr;
773 	    pfr += 2;
774 	    nf += 2;
775 	  }
776 	else
777 	  {
778 	    if (((long) pst) & 4)
779 	      pst++;
780 	    avalue[i] = pst;
781 	    pst += 4;
782 	    nf = 8;
783 	  }
784 	break;
785 # endif
786 #endif
787 
788       case FFI_TYPE_UINT128:
789 	/* Test if for the whole long double, 4 gprs are available.
790 	   otherwise the stuff ends up on the stack.  */
791 	if (ng < NUM_GPR_ARG_REGISTERS - 3)
792 	  {
793 	    avalue[i] = pgr;
794 	    pgr += 4;
795 	    ng += 4;
796 	  }
797 	else
798 	  {
799 	    avalue[i] = pst;
800 	    pst += 4;
801 	    ng = 8+4;
802 	  }
803 	break;
804 
805       case FFI_TYPE_SINT8:
806       case FFI_TYPE_UINT8:
807 #ifndef __LITTLE_ENDIAN__
808 	if (ng < NUM_GPR_ARG_REGISTERS)
809 	  {
810 	    avalue[i] = (char *) pgr + 3;
811 	    ng++;
812 	    pgr++;
813 	  }
814 	else
815 	  {
816 	    avalue[i] = (char *) pst + 3;
817 	    pst++;
818 	  }
819 	break;
820 #endif
821 
822       case FFI_TYPE_SINT16:
823       case FFI_TYPE_UINT16:
824 #ifndef __LITTLE_ENDIAN__
825 	if (ng < NUM_GPR_ARG_REGISTERS)
826 	  {
827 	    avalue[i] = (char *) pgr + 2;
828 	    ng++;
829 	    pgr++;
830 	  }
831 	else
832 	  {
833 	    avalue[i] = (char *) pst + 2;
834 	    pst++;
835 	  }
836 	break;
837 #endif
838 
839       case FFI_TYPE_SINT32:
840       case FFI_TYPE_UINT32:
841       case FFI_TYPE_POINTER:
842 	if (ng < NUM_GPR_ARG_REGISTERS)
843 	  {
844 	    avalue[i] = pgr;
845 	    ng++;
846 	    pgr++;
847 	  }
848 	else
849 	  {
850 	    avalue[i] = pst;
851 	    pst++;
852 	  }
853 	break;
854 
855       case FFI_TYPE_STRUCT:
856 	/* Structs are passed by reference. The address will appear in a
857 	   gpr if it is one of the first 8 arguments.  */
858 	if (ng < NUM_GPR_ARG_REGISTERS)
859 	  {
860 	    avalue[i] = (void *) *pgr;
861 	    ng++;
862 	    pgr++;
863 	  }
864 	else
865 	  {
866 	    avalue[i] = (void *) *pst;
867 	    pst++;
868 	  }
869 	break;
870 
871       case FFI_TYPE_SINT64:
872       case FFI_TYPE_UINT64:
873 	/* Passing long long ints are complex, they must
874 	   be passed in suitable register pairs such as
875 	   (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
876 	   and if the entire pair aren't available then the outgoing
877 	   parameter stack is used for both but an alignment of 8
878 	   must will be kept.  So we must either look in pgr
879 	   or pst to find the correct address for this type
880 	   of parameter.  */
881 	if (ng < NUM_GPR_ARG_REGISTERS - 1)
882 	  {
883 	    if (ng & 1)
884 	      {
885 		/* skip r4, r6, r8 as starting points */
886 		ng++;
887 		pgr++;
888 	      }
889 	    avalue[i] = pgr;
890 	    ng += 2;
891 	    pgr += 2;
892 	  }
893 	else
894 	  {
895 	    if (((long) pst) & 4)
896 	      pst++;
897 	    avalue[i] = pst;
898 	    pst += 2;
899 	    ng = NUM_GPR_ARG_REGISTERS;
900 	  }
901 	break;
902 
903       default:
904 	FFI_ASSERT (0);
905       }
906 
907     i++;
908   }
909 
910   (*fun) (cif, rvalue, avalue, user_data);
911 
912   /* Tell ffi_closure_SYSV how to perform return type promotions.
913      Because the FFI_SYSV ABI returns the structures <= 8 bytes in
914      r3/r4 we have to tell ffi_closure_SYSV how to treat them.  We
915      combine the base type FFI_SYSV_TYPE_SMALL_STRUCT with the size of
916      the struct less one.  We never have a struct with size zero.
917      See the comment in ffitarget.h about ordering.  */
918   if (rtypenum == FFI_TYPE_STRUCT
919       && (cif->abi & FFI_SYSV_STRUCT_RET) != 0 && size <= 8)
920     return FFI_SYSV_TYPE_SMALL_STRUCT - 1 + size;
921   return rtypenum;
922 }
923 #endif
924