1/* -----------------------------------------------------------------------
2   ffi.c - Copyright (c) 1998 Geoffrey Keating
3   Copyright (C) 2007 Free Software Foundation, Inc
4   Copyright (C) 2008 Red Hat, Inc
5
6   PowerPC Foreign Function Interface
7
8   Permission is hereby granted, free of charge, to any person obtaining
9   a copy of this software and associated documentation files (the
10   ``Software''), to deal in the Software without restriction, including
11   without limitation the rights to use, copy, modify, merge, publish,
12   distribute, sublicense, and/or sell copies of the Software, and to
13   permit persons to whom the Software is furnished to do so, subject to
14   the following conditions:
15
16   The above copyright notice and this permission notice shall be included
17   in all copies or substantial portions of the Software.
18
19   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
20   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
23   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25   OTHER DEALINGS IN THE SOFTWARE.
26   ----------------------------------------------------------------------- */
27
28#include <ffi.h>
29#include <ffi_common.h>
30
31#include <stdlib.h>
32#include <stdio.h>
33
34
35extern void ffi_closure_SYSV (void);
36extern void FFI_HIDDEN ffi_closure_LINUX64 (void);
37
38enum {
39  /* The assembly depends on these exact flags.  */
40  FLAG_RETURNS_SMST	= 1 << (31-31), /* Used for FFI_SYSV small structs.  */
41  FLAG_RETURNS_NOTHING  = 1 << (31-30), /* These go in cr7 */
42  FLAG_RETURNS_FP       = 1 << (31-29),
43  FLAG_RETURNS_64BITS   = 1 << (31-28),
44
45  FLAG_RETURNS_128BITS  = 1 << (31-27), /* cr6  */
46
47  FLAG_ARG_NEEDS_COPY   = 1 << (31- 7),
48  FLAG_FP_ARGUMENTS     = 1 << (31- 6), /* cr1.eq; specified by ABI */
49  FLAG_4_GPR_ARGUMENTS  = 1 << (31- 5),
50  FLAG_RETVAL_REFERENCE = 1 << (31- 4)
51};
52
53/* About the SYSV ABI.  */
54unsigned int NUM_GPR_ARG_REGISTERS = 8;
55#ifndef __NO_FPRS__
56unsigned int NUM_FPR_ARG_REGISTERS = 8;
57#else
58unsigned int NUM_FPR_ARG_REGISTERS = 0;
59#endif
60
61enum { ASM_NEEDS_REGISTERS = 4 };
62
63/* ffi_prep_args_SYSV is called by the assembly routine once stack space
64   has been allocated for the function's arguments.
65
66   The stack layout we want looks like this:
67
68   |   Return address from ffi_call_SYSV 4bytes	|	higher addresses
69   |--------------------------------------------|
70   |   Previous backchain pointer	4	|       stack pointer here
71   |--------------------------------------------|<+ <<<	on entry to
72   |   Saved r28-r31			4*4	| |	ffi_call_SYSV
73   |--------------------------------------------| |
74   |   GPR registers r3-r10		8*4	| |	ffi_call_SYSV
75   |--------------------------------------------| |
76   |   FPR registers f1-f8 (optional)	8*8	| |
77   |--------------------------------------------| |	stack	|
78   |   Space for copied structures		| |	grows	|
79   |--------------------------------------------| |	down    V
80   |   Parameters that didn't fit in registers  | |
81   |--------------------------------------------| |	lower addresses
82   |   Space for callee's LR		4	| |
83   |--------------------------------------------| |	stack pointer here
84   |   Current backchain pointer	4	|-/	during
85   |--------------------------------------------|   <<<	ffi_call_SYSV
86
87*/
88
89void
90ffi_prep_args_SYSV (extended_cif *ecif, unsigned *const stack)
91{
92  const unsigned bytes = ecif->cif->bytes;
93  const unsigned flags = ecif->cif->flags;
94
95  typedef union {
96    char *c;
97    unsigned *u;
98    long long *ll;
99    float *f;
100    double *d;
101  } valp;
102
103  /* 'stacktop' points at the previous backchain pointer.  */
104  valp stacktop;
105
106  /* 'gpr_base' points at the space for gpr3, and grows upwards as
107     we use GPR registers.  */
108  valp gpr_base;
109  int intarg_count;
110
111  /* 'fpr_base' points at the space for fpr1, and grows upwards as
112     we use FPR registers.  */
113  valp fpr_base;
114  int fparg_count;
115
116  /* 'copy_space' grows down as we put structures in it.  It should
117     stay 16-byte aligned.  */
118  valp copy_space;
119
120  /* 'next_arg' grows up as we put parameters in it.  */
121  valp next_arg;
122
123  int i, ii MAYBE_UNUSED;
124  ffi_type **ptr;
125  double double_tmp;
126  union {
127    void **v;
128    char **c;
129    signed char **sc;
130    unsigned char **uc;
131    signed short **ss;
132    unsigned short **us;
133    unsigned int **ui;
134    long long **ll;
135    float **f;
136    double **d;
137  } p_argv;
138  size_t struct_copy_size;
139  unsigned gprvalue;
140
141  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
142    NUM_FPR_ARG_REGISTERS = 0;
143
144  stacktop.c = (char *) stack + bytes;
145  gpr_base.u = stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS;
146  intarg_count = 0;
147  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS;
148  fparg_count = 0;
149  copy_space.c = ((flags & FLAG_FP_ARGUMENTS) ? fpr_base.c : gpr_base.c);
150  next_arg.u = stack + 2;
151
152  /* Check that everything starts aligned properly.  */
153  FFI_ASSERT (((unsigned) (char *) stack & 0xF) == 0);
154  FFI_ASSERT (((unsigned) copy_space.c & 0xF) == 0);
155  FFI_ASSERT (((unsigned) stacktop.c & 0xF) == 0);
156  FFI_ASSERT ((bytes & 0xF) == 0);
157  FFI_ASSERT (copy_space.c >= next_arg.c);
158
159  /* Deal with return values that are actually pass-by-reference.  */
160  if (flags & FLAG_RETVAL_REFERENCE)
161    {
162      *gpr_base.u++ = (unsigned long) (char *) ecif->rvalue;
163      intarg_count++;
164    }
165
166  /* Now for the arguments.  */
167  p_argv.v = ecif->avalue;
168  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
169       i > 0;
170       i--, ptr++, p_argv.v++)
171    {
172      switch ((*ptr)->type)
173	{
174	case FFI_TYPE_FLOAT:
175	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
176	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
177	    goto soft_float_prep;
178	  double_tmp = **p_argv.f;
179	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
180	    {
181	      *next_arg.f = (float) double_tmp;
182	      next_arg.u += 1;
183	    }
184	  else
185	    *fpr_base.d++ = double_tmp;
186	  fparg_count++;
187	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
188	  break;
189
190	case FFI_TYPE_DOUBLE:
191	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
192	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
193	    goto soft_double_prep;
194	  double_tmp = **p_argv.d;
195
196	  if (fparg_count >= NUM_FPR_ARG_REGISTERS)
197	    {
198	      if (intarg_count >= NUM_GPR_ARG_REGISTERS
199		  && intarg_count % 2 != 0)
200		{
201		  intarg_count++;
202		  next_arg.u++;
203		}
204	      *next_arg.d = double_tmp;
205	      next_arg.u += 2;
206	    }
207	  else
208	    *fpr_base.d++ = double_tmp;
209	  fparg_count++;
210	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
211	  break;
212
213#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
214	case FFI_TYPE_LONGDOUBLE:
215	  if ((ecif->cif->abi != FFI_LINUX)
216		&& (ecif->cif->abi != FFI_LINUX_SOFT_FLOAT))
217	    goto do_struct;
218	  /* The soft float ABI for long doubles works like this,
219	     a long double is passed in four consecutive gprs if available.
220	     A maximum of 2 long doubles can be passed in gprs.
221	     If we do not have 4 gprs left, the long double is passed on the
222	     stack, 4-byte aligned.  */
223	  if (ecif->cif->abi == FFI_LINUX_SOFT_FLOAT)
224	    {
225	      unsigned int int_tmp = (*p_argv.ui)[0];
226	      if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3)
227		{
228		  if (intarg_count < NUM_GPR_ARG_REGISTERS)
229		    intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
230		  *next_arg.u = int_tmp;
231		  next_arg.u++;
232		  for (ii = 1; ii < 4; ii++)
233		    {
234		      int_tmp = (*p_argv.ui)[ii];
235		      *next_arg.u = int_tmp;
236		      next_arg.u++;
237		    }
238		}
239	      else
240		{
241		  *gpr_base.u++ = int_tmp;
242		  for (ii = 1; ii < 4; ii++)
243		    {
244		      int_tmp = (*p_argv.ui)[ii];
245		      *gpr_base.u++ = int_tmp;
246		    }
247		}
248	      intarg_count +=4;
249	    }
250	  else
251	    {
252	      double_tmp = (*p_argv.d)[0];
253
254	      if (fparg_count >= NUM_FPR_ARG_REGISTERS - 1)
255		{
256		  if (intarg_count >= NUM_GPR_ARG_REGISTERS
257		      && intarg_count % 2 != 0)
258		    {
259		      intarg_count++;
260		      next_arg.u++;
261		    }
262		  *next_arg.d = double_tmp;
263		  next_arg.u += 2;
264		  double_tmp = (*p_argv.d)[1];
265		  *next_arg.d = double_tmp;
266		  next_arg.u += 2;
267		}
268	      else
269		{
270		  *fpr_base.d++ = double_tmp;
271		  double_tmp = (*p_argv.d)[1];
272		  *fpr_base.d++ = double_tmp;
273		}
274
275	      fparg_count += 2;
276	      FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
277	    }
278	  break;
279#endif
280
281	case FFI_TYPE_UINT64:
282	case FFI_TYPE_SINT64:
283	soft_double_prep:
284	  if (intarg_count == NUM_GPR_ARG_REGISTERS-1)
285	    intarg_count++;
286	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
287	    {
288	      if (intarg_count % 2 != 0)
289		{
290		  intarg_count++;
291		  next_arg.u++;
292		}
293	      *next_arg.ll = **p_argv.ll;
294	      next_arg.u += 2;
295	    }
296	  else
297	    {
298	      /* whoops: abi states only certain register pairs
299	       * can be used for passing long long int
300	       * specifically (r3,r4), (r5,r6), (r7,r8),
301	       * (r9,r10) and if next arg is long long but
302	       * not correct starting register of pair then skip
303	       * until the proper starting register
304	       */
305	      if (intarg_count % 2 != 0)
306		{
307		  intarg_count ++;
308		  gpr_base.u++;
309		}
310	      *gpr_base.ll++ = **p_argv.ll;
311	    }
312	  intarg_count += 2;
313	  break;
314
315	case FFI_TYPE_STRUCT:
316#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
317	do_struct:
318#endif
319	  struct_copy_size = ((*ptr)->size + 15) & ~0xF;
320	  copy_space.c -= struct_copy_size;
321	  memcpy (copy_space.c, *p_argv.c, (*ptr)->size);
322
323	  gprvalue = (unsigned long) copy_space.c;
324
325	  FFI_ASSERT (copy_space.c > next_arg.c);
326	  FFI_ASSERT (flags & FLAG_ARG_NEEDS_COPY);
327	  goto putgpr;
328
329	case FFI_TYPE_UINT8:
330	  gprvalue = **p_argv.uc;
331	  goto putgpr;
332	case FFI_TYPE_SINT8:
333	  gprvalue = **p_argv.sc;
334	  goto putgpr;
335	case FFI_TYPE_UINT16:
336	  gprvalue = **p_argv.us;
337	  goto putgpr;
338	case FFI_TYPE_SINT16:
339	  gprvalue = **p_argv.ss;
340	  goto putgpr;
341
342	case FFI_TYPE_INT:
343	case FFI_TYPE_UINT32:
344	case FFI_TYPE_SINT32:
345	case FFI_TYPE_POINTER:
346	soft_float_prep:
347
348	  gprvalue = **p_argv.ui;
349
350	putgpr:
351	  if (intarg_count >= NUM_GPR_ARG_REGISTERS)
352	    *next_arg.u++ = gprvalue;
353	  else
354	    *gpr_base.u++ = gprvalue;
355	  intarg_count++;
356	  break;
357	}
358    }
359
360  /* Check that we didn't overrun the stack...  */
361  FFI_ASSERT (copy_space.c >= next_arg.c);
362  FFI_ASSERT (gpr_base.u <= stacktop.u - ASM_NEEDS_REGISTERS);
363  FFI_ASSERT (fpr_base.u
364	      <= stacktop.u - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS);
365  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
366}
367
368/* About the LINUX64 ABI.  */
369enum {
370  NUM_GPR_ARG_REGISTERS64 = 8,
371  NUM_FPR_ARG_REGISTERS64 = 13
372};
373enum { ASM_NEEDS_REGISTERS64 = 4 };
374
375/* ffi_prep_args64 is called by the assembly routine once stack space
376   has been allocated for the function's arguments.
377
378   The stack layout we want looks like this:
379
380   |   Ret addr from ffi_call_LINUX64	8bytes	|	higher addresses
381   |--------------------------------------------|
382   |   CR save area			8bytes	|
383   |--------------------------------------------|
384   |   Previous backchain pointer	8	|	stack pointer here
385   |--------------------------------------------|<+ <<<	on entry to
386   |   Saved r28-r31			4*8	| |	ffi_call_LINUX64
387   |--------------------------------------------| |
388   |   GPR registers r3-r10		8*8	| |
389   |--------------------------------------------| |
390   |   FPR registers f1-f13 (optional)	13*8	| |
391   |--------------------------------------------| |
392   |   Parameter save area		        | |
393   |--------------------------------------------| |
394   |   TOC save area			8	| |
395   |--------------------------------------------| |	stack	|
396   |   Linker doubleword		8	| |	grows	|
397   |--------------------------------------------| |	down	V
398   |   Compiler doubleword		8	| |
399   |--------------------------------------------| |	lower addresses
400   |   Space for callee's LR		8	| |
401   |--------------------------------------------| |
402   |   CR save area			8	| |
403   |--------------------------------------------| |	stack pointer here
404   |   Current backchain pointer	8	|-/	during
405   |--------------------------------------------|   <<<	ffi_call_LINUX64
406
407*/
408
409void FFI_HIDDEN
410ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
411{
412  const unsigned long bytes = ecif->cif->bytes;
413  const unsigned long flags = ecif->cif->flags;
414
415  typedef union {
416    char *c;
417    unsigned long *ul;
418    float *f;
419    double *d;
420  } valp;
421
422  /* 'stacktop' points at the previous backchain pointer.  */
423  valp stacktop;
424
425  /* 'next_arg' points at the space for gpr3, and grows upwards as
426     we use GPR registers, then continues at rest.  */
427  valp gpr_base;
428  valp gpr_end;
429  valp rest;
430  valp next_arg;
431
432  /* 'fpr_base' points at the space for fpr3, and grows upwards as
433     we use FPR registers.  */
434  valp fpr_base;
435  int fparg_count;
436
437  int i, words;
438  ffi_type **ptr;
439  double double_tmp;
440  union {
441    void **v;
442    char **c;
443    signed char **sc;
444    unsigned char **uc;
445    signed short **ss;
446    unsigned short **us;
447    signed int **si;
448    unsigned int **ui;
449    unsigned long **ul;
450    float **f;
451    double **d;
452  } p_argv;
453  unsigned long gprvalue;
454
455  stacktop.c = (char *) stack + bytes;
456  gpr_base.ul = stacktop.ul - ASM_NEEDS_REGISTERS64 - NUM_GPR_ARG_REGISTERS64;
457  gpr_end.ul = gpr_base.ul + NUM_GPR_ARG_REGISTERS64;
458  rest.ul = stack + 6 + NUM_GPR_ARG_REGISTERS64;
459  fpr_base.d = gpr_base.d - NUM_FPR_ARG_REGISTERS64;
460  fparg_count = 0;
461  next_arg.ul = gpr_base.ul;
462
463  /* Check that everything starts aligned properly.  */
464  FFI_ASSERT (((unsigned long) (char *) stack & 0xF) == 0);
465  FFI_ASSERT (((unsigned long) stacktop.c & 0xF) == 0);
466  FFI_ASSERT ((bytes & 0xF) == 0);
467
468  /* Deal with return values that are actually pass-by-reference.  */
469  if (flags & FLAG_RETVAL_REFERENCE)
470    *next_arg.ul++ = (unsigned long) (char *) ecif->rvalue;
471
472  /* Now for the arguments.  */
473  p_argv.v = ecif->avalue;
474  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
475       i > 0;
476       i--, ptr++, p_argv.v++)
477    {
478      switch ((*ptr)->type)
479	{
480	case FFI_TYPE_FLOAT:
481	  double_tmp = **p_argv.f;
482	  *next_arg.f = (float) double_tmp;
483	  if (++next_arg.ul == gpr_end.ul)
484	    next_arg.ul = rest.ul;
485	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
486	    *fpr_base.d++ = double_tmp;
487	  fparg_count++;
488	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
489	  break;
490
491	case FFI_TYPE_DOUBLE:
492	  double_tmp = **p_argv.d;
493	  *next_arg.d = double_tmp;
494	  if (++next_arg.ul == gpr_end.ul)
495	    next_arg.ul = rest.ul;
496	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
497	    *fpr_base.d++ = double_tmp;
498	  fparg_count++;
499	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
500	  break;
501
502#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
503	case FFI_TYPE_LONGDOUBLE:
504	  double_tmp = (*p_argv.d)[0];
505	  *next_arg.d = double_tmp;
506	  if (++next_arg.ul == gpr_end.ul)
507	    next_arg.ul = rest.ul;
508	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
509	    *fpr_base.d++ = double_tmp;
510	  fparg_count++;
511	  double_tmp = (*p_argv.d)[1];
512	  *next_arg.d = double_tmp;
513	  if (++next_arg.ul == gpr_end.ul)
514	    next_arg.ul = rest.ul;
515	  if (fparg_count < NUM_FPR_ARG_REGISTERS64)
516	    *fpr_base.d++ = double_tmp;
517	  fparg_count++;
518	  FFI_ASSERT (__LDBL_MANT_DIG__ == 106);
519	  FFI_ASSERT (flags & FLAG_FP_ARGUMENTS);
520	  break;
521#endif
522
523	case FFI_TYPE_STRUCT:
524	  words = ((*ptr)->size + 7) / 8;
525	  if (next_arg.ul >= gpr_base.ul && next_arg.ul + words > gpr_end.ul)
526	    {
527	      size_t first = gpr_end.c - next_arg.c;
528	      memcpy (next_arg.c, *p_argv.c, first);
529	      memcpy (rest.c, *p_argv.c + first, (*ptr)->size - first);
530	      next_arg.c = rest.c + words * 8 - first;
531	    }
532	  else
533	    {
534	      char *where = next_arg.c;
535
536	      /* Structures with size less than eight bytes are passed
537		 left-padded.  */
538	      if ((*ptr)->size < 8)
539		where += 8 - (*ptr)->size;
540
541	      memcpy (where, *p_argv.c, (*ptr)->size);
542	      next_arg.ul += words;
543	      if (next_arg.ul == gpr_end.ul)
544		next_arg.ul = rest.ul;
545	    }
546	  break;
547
548	case FFI_TYPE_UINT8:
549	  gprvalue = **p_argv.uc;
550	  goto putgpr;
551	case FFI_TYPE_SINT8:
552	  gprvalue = **p_argv.sc;
553	  goto putgpr;
554	case FFI_TYPE_UINT16:
555	  gprvalue = **p_argv.us;
556	  goto putgpr;
557	case FFI_TYPE_SINT16:
558	  gprvalue = **p_argv.ss;
559	  goto putgpr;
560	case FFI_TYPE_UINT32:
561	  gprvalue = **p_argv.ui;
562	  goto putgpr;
563	case FFI_TYPE_INT:
564	case FFI_TYPE_SINT32:
565	  gprvalue = **p_argv.si;
566	  goto putgpr;
567
568	case FFI_TYPE_UINT64:
569	case FFI_TYPE_SINT64:
570	case FFI_TYPE_POINTER:
571	  gprvalue = **p_argv.ul;
572	putgpr:
573	  *next_arg.ul++ = gprvalue;
574	  if (next_arg.ul == gpr_end.ul)
575	    next_arg.ul = rest.ul;
576	  break;
577	}
578    }
579
580  FFI_ASSERT (flags & FLAG_4_GPR_ARGUMENTS
581	      || (next_arg.ul >= gpr_base.ul
582		  && next_arg.ul <= gpr_base.ul + 4));
583}
584
585
586
587/* Perform machine dependent cif processing */
588ffi_status
589ffi_prep_cif_machdep (ffi_cif *cif)
590{
591  /* All this is for the SYSV and LINUX64 ABI.  */
592  int i;
593  ffi_type **ptr;
594  unsigned bytes;
595  int fparg_count = 0, intarg_count = 0;
596  unsigned flags = 0;
597  unsigned struct_copy_size = 0;
598  unsigned type = cif->rtype->type;
599  unsigned size = cif->rtype->size;
600
601  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
602    NUM_FPR_ARG_REGISTERS = 0;
603
604  if (cif->abi != FFI_LINUX64)
605    {
606      /* All the machine-independent calculation of cif->bytes will be wrong.
607	 Redo the calculation for SYSV.  */
608
609      /* Space for the frame pointer, callee's LR, and the asm's temp regs.  */
610      bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof (int);
611
612      /* Space for the GPR registers.  */
613      bytes += NUM_GPR_ARG_REGISTERS * sizeof (int);
614    }
615  else
616    {
617      /* 64-bit ABI.  */
618
619      /* Space for backchain, CR, LR, cc/ld doubleword, TOC and the asm's temp
620	 regs.  */
621      bytes = (6 + ASM_NEEDS_REGISTERS64) * sizeof (long);
622
623      /* Space for the mandatory parm save area and general registers.  */
624      bytes += 2 * NUM_GPR_ARG_REGISTERS64 * sizeof (long);
625    }
626
627  /* Return value handling.  The rules for SYSV are as follows:
628     - 32-bit (or less) integer values are returned in gpr3;
629     - Structures of size <= 4 bytes also returned in gpr3;
630     - 64-bit integer values and structures between 5 and 8 bytes are returned
631     in gpr3 and gpr4;
632     - Single/double FP values are returned in fpr1;
633     - Larger structures are allocated space and a pointer is passed as
634     the first argument.
635     - long doubles (if not equivalent to double) are returned in
636     fpr1,fpr2 for Linux and as for large structs for SysV.
637     For LINUX64:
638     - integer values in gpr3;
639     - Structures/Unions by reference;
640     - Single/double FP values in fpr1, long double in fpr1,fpr2.
641     - soft-float float/doubles are treated as UINT32/UINT64 respectivley.
642     - soft-float long doubles are returned in gpr3-gpr6.  */
643  switch (type)
644    {
645#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
646    case FFI_TYPE_LONGDOUBLE:
647      if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX64
648	&& cif->abi != FFI_LINUX_SOFT_FLOAT)
649	goto byref;
650      flags |= FLAG_RETURNS_128BITS;
651      /* Fall through.  */
652#endif
653    case FFI_TYPE_DOUBLE:
654      flags |= FLAG_RETURNS_64BITS;
655      /* Fall through.  */
656    case FFI_TYPE_FLOAT:
657      /* With FFI_LINUX_SOFT_FLOAT no fp registers are used.  */
658      if (cif->abi != FFI_LINUX_SOFT_FLOAT)
659	flags |= FLAG_RETURNS_FP;
660      break;
661
662    case FFI_TYPE_UINT64:
663    case FFI_TYPE_SINT64:
664      flags |= FLAG_RETURNS_64BITS;
665      break;
666
667    case FFI_TYPE_STRUCT:
668      if (cif->abi == FFI_SYSV)
669	{
670	  /* The final SYSV ABI says that structures smaller or equal 8 bytes
671	     are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
672	     in memory.  */
673
674	  /* Treat structs with size <= 8 bytes.  */
675	  if (size <= 8)
676	    {
677	      flags |= FLAG_RETURNS_SMST;
678	      /* These structs are returned in r3. We pack the type and the
679		 precalculated shift value (needed in the sysv.S) into flags.
680		 The same applies for the structs returned in r3/r4.  */
681	      if (size <= 4)
682		{
683		  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1);
684		  flags |= 8 * (4 - size) << 4;
685		  break;
686		}
687	      /* These structs are returned in r3 and r4. See above.   */
688	      if  (size <= 8)
689		{
690		  flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2);
691		  flags |= 8 * (8 - size) << 4;
692		  break;
693		}
694	    }
695	}
696#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
697    byref:
698#endif
699      intarg_count++;
700      flags |= FLAG_RETVAL_REFERENCE;
701      /* Fall through.  */
702    case FFI_TYPE_VOID:
703      flags |= FLAG_RETURNS_NOTHING;
704      break;
705
706    default:
707      /* Returns 32-bit integer, or similar.  Nothing to do here.  */
708      break;
709    }
710
711  if (cif->abi != FFI_LINUX64)
712    /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the
713       first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest
714       goes on the stack.  Structures and long doubles (if not equivalent
715       to double) are passed as a pointer to a copy of the structure.
716       Stuff on the stack needs to keep proper alignment.  */
717    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
718      {
719	switch ((*ptr)->type)
720	  {
721	  case FFI_TYPE_FLOAT:
722	    /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
723	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
724	      goto soft_float_cif;
725	    fparg_count++;
726	    /* floating singles are not 8-aligned on stack */
727	    break;
728
729#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
730	  case FFI_TYPE_LONGDOUBLE:
731	    if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
732	      goto do_struct;
733	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
734	      {
735		if (intarg_count >= NUM_GPR_ARG_REGISTERS - 3
736		  || intarg_count < NUM_GPR_ARG_REGISTERS)
737		  /* A long double in FFI_LINUX_SOFT_FLOAT can use only
738		     a set of four consecutive gprs. If we have not enough,
739		     we have to adjust the intarg_count value.  */
740		  intarg_count += NUM_GPR_ARG_REGISTERS - intarg_count;
741		intarg_count += 4;
742		break;
743	      }
744	    else
745	      fparg_count++;
746	    /* Fall thru */
747#endif
748	  case FFI_TYPE_DOUBLE:
749	    /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
750	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
751	      goto soft_double_cif;
752	    fparg_count++;
753	    /* If this FP arg is going on the stack, it must be
754	       8-byte-aligned.  */
755	    if (fparg_count > NUM_FPR_ARG_REGISTERS
756		&& intarg_count >= NUM_GPR_ARG_REGISTERS
757		&& intarg_count % 2 != 0)
758	      intarg_count++;
759	    break;
760
761	  case FFI_TYPE_UINT64:
762	  case FFI_TYPE_SINT64:
763	  soft_double_cif:
764	    /* 'long long' arguments are passed as two words, but
765	       either both words must fit in registers or both go
766	       on the stack.  If they go on the stack, they must
767	       be 8-byte-aligned.
768
769	       Also, only certain register pairs can be used for
770	       passing long long int -- specifically (r3,r4), (r5,r6),
771	       (r7,r8), (r9,r10).
772	    */
773	    if (intarg_count == NUM_GPR_ARG_REGISTERS-1
774		|| intarg_count % 2 != 0)
775	      intarg_count++;
776	    intarg_count += 2;
777	    break;
778
779	  case FFI_TYPE_STRUCT:
780#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
781	  do_struct:
782#endif
783	    /* We must allocate space for a copy of these to enforce
784	       pass-by-value.  Pad the space up to a multiple of 16
785	       bytes (the maximum alignment required for anything under
786	       the SYSV ABI).  */
787	    struct_copy_size += ((*ptr)->size + 15) & ~0xF;
788	    /* Fall through (allocate space for the pointer).  */
789
790	  default:
791	  soft_float_cif:
792	    /* Everything else is passed as a 4-byte word in a GPR, either
793	       the object itself or a pointer to it.  */
794	    intarg_count++;
795	    break;
796	  }
797      }
798  else
799    for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
800      {
801	switch ((*ptr)->type)
802	  {
803#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
804	  case FFI_TYPE_LONGDOUBLE:
805	    if (cif->abi == FFI_LINUX_SOFT_FLOAT)
806	      intarg_count += 4;
807	    else
808	      {
809		fparg_count += 2;
810		intarg_count += 2;
811	      }
812	    break;
813#endif
814	  case FFI_TYPE_FLOAT:
815	  case FFI_TYPE_DOUBLE:
816	    fparg_count++;
817	    intarg_count++;
818	    break;
819
820	  case FFI_TYPE_STRUCT:
821	    intarg_count += ((*ptr)->size + 7) / 8;
822	    break;
823
824	  default:
825	    /* Everything else is passed as a 8-byte word in a GPR, either
826	       the object itself or a pointer to it.  */
827	    intarg_count++;
828	    break;
829	  }
830      }
831
832  if (fparg_count != 0)
833    flags |= FLAG_FP_ARGUMENTS;
834  if (intarg_count > 4)
835    flags |= FLAG_4_GPR_ARGUMENTS;
836  if (struct_copy_size != 0)
837    flags |= FLAG_ARG_NEEDS_COPY;
838
839  if (cif->abi != FFI_LINUX64)
840    {
841      /* Space for the FPR registers, if needed.  */
842      if (fparg_count != 0)
843	bytes += NUM_FPR_ARG_REGISTERS * sizeof (double);
844
845      /* Stack space.  */
846      if (intarg_count > NUM_GPR_ARG_REGISTERS)
847	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof (int);
848      if (fparg_count > NUM_FPR_ARG_REGISTERS)
849	bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof (double);
850    }
851  else
852    {
853      /* Space for the FPR registers, if needed.  */
854      if (fparg_count != 0)
855	bytes += NUM_FPR_ARG_REGISTERS64 * sizeof (double);
856
857      /* Stack space.  */
858      if (intarg_count > NUM_GPR_ARG_REGISTERS64)
859	bytes += (intarg_count - NUM_GPR_ARG_REGISTERS64) * sizeof (long);
860    }
861
862  /* The stack space allocated needs to be a multiple of 16 bytes.  */
863  bytes = (bytes + 15) & ~0xF;
864
865  /* Add in the space for the copied structures.  */
866  bytes += struct_copy_size;
867
868  cif->flags = flags;
869  cif->bytes = bytes;
870
871  return FFI_OK;
872}
873
874extern void ffi_call_SYSV(extended_cif *, unsigned, unsigned, unsigned *,
875			  void (*fn)(void));
876extern void FFI_HIDDEN ffi_call_LINUX64(extended_cif *, unsigned long,
877					unsigned long, unsigned long *,
878					void (*fn)(void));
879
880void
881ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
882{
883  extended_cif ecif;
884
885  ecif.cif = cif;
886  ecif.avalue = avalue;
887
888  /* If the return value is a struct and we don't have a return	*/
889  /* value address then we need to make one		        */
890
891  if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT))
892    {
893      ecif.rvalue = alloca(cif->rtype->size);
894    }
895  else
896    ecif.rvalue = rvalue;
897
898
899  switch (cif->abi)
900    {
901#ifndef POWERPC64
902    case FFI_SYSV:
903    case FFI_GCC_SYSV:
904    case FFI_LINUX:
905    case FFI_LINUX_SOFT_FLOAT:
906      ffi_call_SYSV (&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn);
907      break;
908#else
909    case FFI_LINUX64:
910      ffi_call_LINUX64 (&ecif, -(long) cif->bytes, cif->flags, ecif.rvalue, fn);
911      break;
912#endif
913    default:
914      FFI_ASSERT (0);
915      break;
916    }
917}
918
919
920#ifndef POWERPC64
921#define MIN_CACHE_LINE_SIZE 8
922
923static void
924flush_icache (char *wraddr, char *xaddr, int size)
925{
926  int i;
927  for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE)
928    __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;"
929		      : : "r" (xaddr + i), "r" (wraddr + i) : "memory");
930  __asm__ volatile ("icbi 0,%0;" "dcbf 0,%1;" "sync;" "isync;"
931		    : : "r"(xaddr + size - 1), "r"(wraddr + size - 1)
932		    : "memory");
933}
934#endif
935
936ffi_status
937ffi_prep_closure_loc (ffi_closure *closure,
938		      ffi_cif *cif,
939		      void (*fun) (ffi_cif *, void *, void **, void *),
940		      void *user_data,
941		      void *codeloc)
942{
943#ifdef POWERPC64
944  void **tramp = (void **) &closure->tramp[0];
945
946  FFI_ASSERT (cif->abi == FFI_LINUX64);
947  /* Copy function address and TOC from ffi_closure_LINUX64.  */
948  memcpy (tramp, (char *) ffi_closure_LINUX64, 16);
949  tramp[2] = codeloc;
950#else
951  unsigned int *tramp;
952
953  FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
954
955  tramp = (unsigned int *) &closure->tramp[0];
956  tramp[0] = 0x7c0802a6;  /*   mflr    r0 */
957  tramp[1] = 0x4800000d;  /*   bl      10 <trampoline_initial+0x10> */
958  tramp[4] = 0x7d6802a6;  /*   mflr    r11 */
959  tramp[5] = 0x7c0803a6;  /*   mtlr    r0 */
960  tramp[6] = 0x800b0000;  /*   lwz     r0,0(r11) */
961  tramp[7] = 0x816b0004;  /*   lwz     r11,4(r11) */
962  tramp[8] = 0x7c0903a6;  /*   mtctr   r0 */
963  tramp[9] = 0x4e800420;  /*   bctr */
964  *(void **) &tramp[2] = (void *) ffi_closure_SYSV; /* function */
965  *(void **) &tramp[3] = codeloc;                   /* context */
966
967  /* Flush the icache.  */
968  flush_icache ((char *)tramp, (char *)codeloc, FFI_TRAMPOLINE_SIZE);
969#endif
970
971  closure->cif = cif;
972  closure->fun = fun;
973  closure->user_data = user_data;
974
975  return FFI_OK;
976}
977
978typedef union
979{
980  float f;
981  double d;
982} ffi_dblfl;
983
984int ffi_closure_helper_SYSV (ffi_closure *, void *, unsigned long *,
985			     ffi_dblfl *, unsigned long *);
986
987/* Basically the trampoline invokes ffi_closure_SYSV, and on
988 * entry, r11 holds the address of the closure.
989 * After storing the registers that could possibly contain
990 * parameters to be passed into the stack frame and setting
991 * up space for a return value, ffi_closure_SYSV invokes the
992 * following helper function to do most of the work
993 */
994
995int
996ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
997			 unsigned long *pgr, ffi_dblfl *pfr,
998			 unsigned long *pst)
999{
1000  /* rvalue is the pointer to space for return value in closure assembly */
1001  /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */
1002  /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV  */
1003  /* pst is the pointer to outgoing parameter stack in original caller */
1004
1005  void **          avalue;
1006  ffi_type **      arg_types;
1007  long             i, avn;
1008  long             nf;   /* number of floating registers already used */
1009  long             ng;   /* number of general registers already used */
1010  ffi_cif *        cif;
1011  double           temp;
1012  unsigned         size;
1013
1014  cif = closure->cif;
1015  avalue = alloca (cif->nargs * sizeof (void *));
1016  size = cif->rtype->size;
1017
1018  nf = 0;
1019  ng = 0;
1020
1021  /* Copy the caller's structure return value address so that the closure
1022     returns the data directly to the caller.
1023     For FFI_SYSV the result is passed in r3/r4 if the struct size is less
1024     or equal 8 bytes.  */
1025
1026  if ((cif->rtype->type == FFI_TYPE_STRUCT
1027       && !((cif->abi == FFI_SYSV) && (size <= 8)))
1028#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1029      || (cif->rtype->type == FFI_TYPE_LONGDOUBLE
1030	  && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1031#endif
1032      )
1033    {
1034      rvalue = (void *) *pgr;
1035      ng++;
1036      pgr++;
1037    }
1038
1039  i = 0;
1040  avn = cif->nargs;
1041  arg_types = cif->arg_types;
1042
1043  /* Grab the addresses of the arguments from the stack frame.  */
1044  while (i < avn)
1045    {
1046      switch (arg_types[i]->type)
1047	{
1048	case FFI_TYPE_SINT8:
1049	case FFI_TYPE_UINT8:
1050	  /* there are 8 gpr registers used to pass values */
1051	  if (ng < 8)
1052	    {
1053	      avalue[i] = (char *) pgr + 3;
1054	      ng++;
1055	      pgr++;
1056	    }
1057	  else
1058	    {
1059	      avalue[i] = (char *) pst + 3;
1060	      pst++;
1061	    }
1062	  break;
1063
1064	case FFI_TYPE_SINT16:
1065	case FFI_TYPE_UINT16:
1066	  /* there are 8 gpr registers used to pass values */
1067	  if (ng < 8)
1068	    {
1069	      avalue[i] = (char *) pgr + 2;
1070	      ng++;
1071	      pgr++;
1072	    }
1073	  else
1074	    {
1075	      avalue[i] = (char *) pst + 2;
1076	      pst++;
1077	    }
1078	  break;
1079
1080	case FFI_TYPE_SINT32:
1081	case FFI_TYPE_UINT32:
1082	case FFI_TYPE_POINTER:
1083	soft_float_closure:
1084	  /* there are 8 gpr registers used to pass values */
1085	  if (ng < 8)
1086	    {
1087	      avalue[i] = pgr;
1088	      ng++;
1089	      pgr++;
1090	    }
1091	  else
1092	    {
1093	      avalue[i] = pst;
1094	      pst++;
1095	    }
1096	  break;
1097
1098	case FFI_TYPE_STRUCT:
1099#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1100	do_struct:
1101#endif
1102	  /* Structs are passed by reference. The address will appear in a
1103	     gpr if it is one of the first 8 arguments.  */
1104	  if (ng < 8)
1105	    {
1106	      avalue[i] = (void *) *pgr;
1107	      ng++;
1108	      pgr++;
1109	    }
1110	  else
1111	    {
1112	      avalue[i] = (void *) *pst;
1113	      pst++;
1114	    }
1115	  break;
1116
1117	case FFI_TYPE_SINT64:
1118	case FFI_TYPE_UINT64:
1119	soft_double_closure:
1120	  /* passing long long ints are complex, they must
1121	   * be passed in suitable register pairs such as
1122	   * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10)
1123	   * and if the entire pair aren't available then the outgoing
1124	   * parameter stack is used for both but an alignment of 8
1125	   * must will be kept.  So we must either look in pgr
1126	   * or pst to find the correct address for this type
1127	   * of parameter.
1128	   */
1129	  if (ng < 7)
1130	    {
1131	      if (ng & 0x01)
1132		{
1133		  /* skip r4, r6, r8 as starting points */
1134		  ng++;
1135		  pgr++;
1136		}
1137	      avalue[i] = pgr;
1138	      ng += 2;
1139	      pgr += 2;
1140	    }
1141	  else
1142	    {
1143	      if (((long) pst) & 4)
1144		pst++;
1145	      avalue[i] = pst;
1146	      pst += 2;
1147	    }
1148	  break;
1149
1150	case FFI_TYPE_FLOAT:
1151	  /* With FFI_LINUX_SOFT_FLOAT floats are handled like UINT32.  */
1152	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1153	    goto soft_float_closure;
1154	  /* unfortunately float values are stored as doubles
1155	   * in the ffi_closure_SYSV code (since we don't check
1156	   * the type in that routine).
1157	   */
1158
1159	  /* there are 8 64bit floating point registers */
1160
1161	  if (nf < 8)
1162	    {
1163	      temp = pfr->d;
1164	      pfr->f = (float) temp;
1165	      avalue[i] = pfr;
1166	      nf++;
1167	      pfr++;
1168	    }
1169	  else
1170	    {
1171	      /* FIXME? here we are really changing the values
1172	       * stored in the original calling routines outgoing
1173	       * parameter stack.  This is probably a really
1174	       * naughty thing to do but...
1175	       */
1176	      avalue[i] = pst;
1177	      pst += 1;
1178	    }
1179	  break;
1180
1181	case FFI_TYPE_DOUBLE:
1182	  /* With FFI_LINUX_SOFT_FLOAT doubles are handled like UINT64.  */
1183	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1184	    goto soft_double_closure;
1185	  /* On the outgoing stack all values are aligned to 8 */
1186	  /* there are 8 64bit floating point registers */
1187
1188	  if (nf < 8)
1189	    {
1190	      avalue[i] = pfr;
1191	      nf++;
1192	      pfr++;
1193	    }
1194	  else
1195	    {
1196	      if (((long) pst) & 4)
1197		pst++;
1198	      avalue[i] = pst;
1199	      pst += 2;
1200	    }
1201	  break;
1202
1203#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1204	case FFI_TYPE_LONGDOUBLE:
1205	  if (cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1206	    goto do_struct;
1207	  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1208	    { /* Test if for the whole long double, 4 gprs are available.
1209		 otherwise the stuff ends up on the stack.  */
1210	      if (ng < 5)
1211		{
1212		  avalue[i] = pgr;
1213		  pgr += 4;
1214		  ng += 4;
1215		}
1216	      else
1217		{
1218		  avalue[i] = pst;
1219		  pst += 4;
1220		}
1221	      break;
1222	    }
1223	  if (nf < 7)
1224	    {
1225	      avalue[i] = pfr;
1226	      pfr += 2;
1227	      nf += 2;
1228	    }
1229	  else
1230	    {
1231	      if (((long) pst) & 4)
1232		pst++;
1233	      avalue[i] = pst;
1234	      pst += 4;
1235	      nf = 8;
1236	    }
1237	  break;
1238#endif
1239
1240	default:
1241	  FFI_ASSERT (0);
1242	}
1243
1244      i++;
1245    }
1246
1247
1248  (closure->fun) (cif, rvalue, avalue, closure->user_data);
1249
1250  /* Tell ffi_closure_SYSV how to perform return type promotions.
1251     Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
1252     we have to tell ffi_closure_SYSV how to treat them.  */
1253  if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
1254      && size <= 8)
1255    return FFI_SYSV_TYPE_SMALL_STRUCT + size;
1256#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1257  else if (cif->rtype->type == FFI_TYPE_LONGDOUBLE
1258	   && cif->abi != FFI_LINUX && cif->abi != FFI_LINUX_SOFT_FLOAT)
1259    return FFI_TYPE_STRUCT;
1260#endif
1261  /* With FFI_LINUX_SOFT_FLOAT floats and doubles are handled like UINT32
1262     respectivley UINT64.  */
1263  if (cif->abi == FFI_LINUX_SOFT_FLOAT)
1264    {
1265      switch (cif->rtype->type)
1266	{
1267	case FFI_TYPE_FLOAT:
1268	  return FFI_TYPE_UINT32;
1269	  break;
1270	case FFI_TYPE_DOUBLE:
1271	  return FFI_TYPE_UINT64;
1272	  break;
1273#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1274	case FFI_TYPE_LONGDOUBLE:
1275	  return FFI_TYPE_UINT128;
1276	  break;
1277#endif
1278	default:
1279	  return cif->rtype->type;
1280	}
1281    }
1282  else
1283    {
1284      return cif->rtype->type;
1285    }
1286}
1287
1288int FFI_HIDDEN ffi_closure_helper_LINUX64 (ffi_closure *, void *,
1289					   unsigned long *, ffi_dblfl *);
1290
1291int FFI_HIDDEN
1292ffi_closure_helper_LINUX64 (ffi_closure *closure, void *rvalue,
1293			    unsigned long *pst, ffi_dblfl *pfr)
1294{
1295  /* rvalue is the pointer to space for return value in closure assembly */
1296  /* pst is the pointer to parameter save area
1297     (r3-r10 are stored into its first 8 slots by ffi_closure_LINUX64) */
1298  /* pfr is the pointer to where f1-f13 are stored in ffi_closure_LINUX64 */
1299
1300  void **avalue;
1301  ffi_type **arg_types;
1302  long i, avn;
1303  ffi_cif *cif;
1304  ffi_dblfl *end_pfr = pfr + NUM_FPR_ARG_REGISTERS64;
1305
1306  cif = closure->cif;
1307  avalue = alloca (cif->nargs * sizeof (void *));
1308
1309  /* Copy the caller's structure return value address so that the closure
1310     returns the data directly to the caller.  */
1311  if (cif->rtype->type == FFI_TYPE_STRUCT)
1312    {
1313      rvalue = (void *) *pst;
1314      pst++;
1315    }
1316
1317  i = 0;
1318  avn = cif->nargs;
1319  arg_types = cif->arg_types;
1320
1321  /* Grab the addresses of the arguments from the stack frame.  */
1322  while (i < avn)
1323    {
1324      switch (arg_types[i]->type)
1325	{
1326	case FFI_TYPE_SINT8:
1327	case FFI_TYPE_UINT8:
1328	  avalue[i] = (char *) pst + 7;
1329	  pst++;
1330	  break;
1331
1332	case FFI_TYPE_SINT16:
1333	case FFI_TYPE_UINT16:
1334	  avalue[i] = (char *) pst + 6;
1335	  pst++;
1336	  break;
1337
1338	case FFI_TYPE_SINT32:
1339	case FFI_TYPE_UINT32:
1340	  avalue[i] = (char *) pst + 4;
1341	  pst++;
1342	  break;
1343
1344	case FFI_TYPE_SINT64:
1345	case FFI_TYPE_UINT64:
1346	case FFI_TYPE_POINTER:
1347	  avalue[i] = pst;
1348	  pst++;
1349	  break;
1350
1351	case FFI_TYPE_STRUCT:
1352	  /* Structures with size less than eight bytes are passed
1353	     left-padded.  */
1354	  if (arg_types[i]->size < 8)
1355	    avalue[i] = (char *) pst + 8 - arg_types[i]->size;
1356	  else
1357	    avalue[i] = pst;
1358	  pst += (arg_types[i]->size + 7) / 8;
1359	  break;
1360
1361	case FFI_TYPE_FLOAT:
1362	  /* unfortunately float values are stored as doubles
1363	   * in the ffi_closure_LINUX64 code (since we don't check
1364	   * the type in that routine).
1365	   */
1366
1367	  /* there are 13 64bit floating point registers */
1368
1369	  if (pfr < end_pfr)
1370	    {
1371	      double temp = pfr->d;
1372	      pfr->f = (float) temp;
1373	      avalue[i] = pfr;
1374	      pfr++;
1375	    }
1376	  else
1377	    avalue[i] = pst;
1378	  pst++;
1379	  break;
1380
1381	case FFI_TYPE_DOUBLE:
1382	  /* On the outgoing stack all values are aligned to 8 */
1383	  /* there are 13 64bit floating point registers */
1384
1385	  if (pfr < end_pfr)
1386	    {
1387	      avalue[i] = pfr;
1388	      pfr++;
1389	    }
1390	  else
1391	    avalue[i] = pst;
1392	  pst++;
1393	  break;
1394
1395#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
1396	case FFI_TYPE_LONGDOUBLE:
1397	  if (pfr + 1 < end_pfr)
1398	    {
1399	      avalue[i] = pfr;
1400	      pfr += 2;
1401	    }
1402	  else
1403	    {
1404	      if (pfr < end_pfr)
1405		{
1406		  /* Passed partly in f13 and partly on the stack.
1407		     Move it all to the stack.  */
1408		  *pst = *(unsigned long *) pfr;
1409		  pfr++;
1410		}
1411	      avalue[i] = pst;
1412	    }
1413	  pst += 2;
1414	  break;
1415#endif
1416
1417	default:
1418	  FFI_ASSERT (0);
1419	}
1420
1421      i++;
1422    }
1423
1424
1425  (closure->fun) (cif, rvalue, avalue, closure->user_data);
1426
1427  /* Tell ffi_closure_LINUX64 how to perform return type promotions.  */
1428  return cif->rtype->type;
1429}
1430