d3e09bc60e7cf109b327b1b8b96c67d944b84af8
[libffi.git] / patches / variadic
1 Index: libffi/include/ffi.h.in
2 ===================================================================
3 --- libffi.orig/include/ffi.h.in
4 +++ libffi/include/ffi.h.in
5 @@ -207,6 +207,15 @@ typedef struct {
6  #endif
7  } ffi_cif;
8  
9 +/* Used internally, but overridden by some architectures */
10 +ffi_status ffi_prep_cif_core(ffi_cif *cif,
11 +                            ffi_abi abi,
12 +                            unsigned int isvariadic,
13 +                            unsigned int nfixedargs,
14 +                            unsigned int ntotalargs,
15 +                            ffi_type *rtype,
16 +                            ffi_type **atypes);
17 +
18  /* ---- Definitions for the raw API -------------------------------------- */
19  
20  #ifndef FFI_SIZEOF_ARG
21 @@ -384,6 +393,13 @@ ffi_status ffi_prep_cif(ffi_cif *cif,
22                         ffi_type *rtype,
23                         ffi_type **atypes);
24  
25 +ffi_status ffi_prep_cif_var(ffi_cif *cif,
26 +                           ffi_abi abi,
27 +                           unsigned int nfixedargs,
28 +                           unsigned int ntotalargs,
29 +                           ffi_type *rtype,
30 +                           ffi_type **atypes);
31 +
32  void ffi_call(ffi_cif *cif,
33               void (*fn)(void),
34               void *rvalue,
35 Index: libffi/include/ffi_common.h
36 ===================================================================
37 --- libffi.orig/include/ffi_common.h
38 +++ libffi/include/ffi_common.h
39 @@ -75,6 +75,8 @@ void ffi_type_test(ffi_type *a, char *fi
40  
41  /* Perform machine dependent cif processing */
42  ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
43 +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
44 +        unsigned int nfixedargs, unsigned int ntotalargs);
45  
46  /* Extended cif, used in callback from assembly routine */
47  typedef struct
48 Index: libffi/man/Makefile.am
49 ===================================================================
50 --- libffi.orig/man/Makefile.am
51 +++ libffi/man/Makefile.am
52 @@ -2,7 +2,7 @@
53  
54  AUTOMAKE_OPTIONS=foreign
55  
56 -EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3
57 +EXTRA_DIST = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
58  
59 -man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3
60 +man_MANS = ffi.3 ffi_call.3 ffi_prep_cif.3 ffi_prep_cif_var.3
61  
62 Index: libffi/man/ffi.3
63 ===================================================================
64 --- libffi.orig/man/ffi.3
65 +++ libffi/man/ffi.3
66 @@ -16,6 +16,15 @@ libffi, -lffi
67  .Fa "ffi_type **atypes"
68  .Fc
69  .Ft void
70 +.Fo ffi_prep_cif_var
71 +.Fa "ffi_cif *cif"
72 +.Fa "ffi_abi abi"
73 +.Fa "unsigned int nfixedargs"
74 +.Fa "unsigned int ntotalargs"
75 +.Fa "ffi_type *rtype"
76 +.Fa "ffi_type **atypes"
77 +.Fc
78 +.Ft void
79  .Fo ffi_call
80  .Fa "ffi_cif *cif"
81  .Fa "void (*fn)(void)"
82 @@ -28,4 +37,5 @@ generate a call to another function at r
83  the called function's interface at compile time.
84  .Sh SEE ALSO
85  .Xr ffi_prep_cif 3 ,
86 +.Xr ffi_prep_cif_var 3 ,
87  .Xr ffi_call 3
88 Index: libffi/man/ffi_prep_cif.3
89 ===================================================================
90 --- libffi.orig/man/ffi_prep_cif.3
91 +++ libffi/man/ffi_prep_cif.3
92 @@ -37,7 +37,9 @@ structs that describe the data type, siz
93  points to an
94  .Nm ffi_type
95  that describes the data type, size and alignment of the
96 -return value.
97 +return value. Note that to call a variadic function
98 +.Nm ffi_prep_cif_var
99 +must be used instead.
100  .Sh RETURN VALUES
101  Upon successful completion,
102  .Nm ffi_prep_cif
103 @@ -63,4 +65,6 @@ defined in
104  .
105  .Sh SEE ALSO
106  .Xr ffi 3 ,
107 -.Xr ffi_call 3 
108 +.Xr ffi_call 3 ,
109 +.Xr ffi_prep_cif_var 3
110 +
111 Index: libffi/man/ffi_prep_cif_var.3
112 ===================================================================
113 --- /dev/null
114 +++ libffi/man/ffi_prep_cif_var.3
115 @@ -0,0 +1,73 @@
116 +.Dd January 25, 2011
117 +.Dt ffi_prep_cif_var 3
118 +.Sh NAME
119 +.Nm ffi_prep_cif_var
120 +.Nd Prepare a
121 +.Nm ffi_cif
122 +structure for use with
123 +.Nm ffi_call
124 +for variadic functions.
125 +.Sh SYNOPSIS
126 +.In ffi.h
127 +.Ft ffi_status
128 +.Fo ffi_prep_cif_var
129 +.Fa "ffi_cif *cif"
130 +.Fa "ffi_abi abi"
131 +.Fa "unsigned int nfixedargs"
132 +.Fa "unsigned int ntotalargs"
133 +.Fa "ffi_type *rtype"
134 +.Fa "ffi_type **atypes"
135 +.Fc
136 +.Sh DESCRIPTION
137 +The
138 +.Nm ffi_prep_cif_var
139 +function prepares a
140 +.Nm ffi_cif
141 +structure for use with
142 +.Nm ffi_call
143 +for variadic functions.
144 +.Fa abi
145 +specifies a set of calling conventions to use.
146 +.Fa atypes
147 +is an array of
148 +.Fa ntotalargs
149 +pointers to
150 +.Nm ffi_type
151 +structs that describe the data type, size and alignment of each argument.
152 +.Fa rtype
153 +points to an
154 +.Nm ffi_type
155 +that describes the data type, size and alignment of the
156 +return value.
157 +.Fa nfixedargs
158 +must contain the number of fixed (non-variadic) arguments.
159 +Note that to call a non-variadic function
160 +.Nm ffi_prep_cif
161 +must be used.
162 +.Sh RETURN VALUES
163 +Upon successful completion,
164 +.Nm ffi_prep_cif_var
165 +returns
166 +.Nm FFI_OK .
167 +It will return
168 +.Nm FFI_BAD_TYPEDEF
169 +if
170 +.Fa cif
171 +is
172 +.Nm NULL
173 +or
174 +.Fa atypes
175 +or
176 +.Fa rtype
177 +is malformed. If
178 +.Fa abi
179 +does not refer to a valid ABI,
180 +.Nm FFI_BAD_ABI
181 +will be returned. Available ABIs are
182 +defined in
183 +.Nm <ffitarget.h>
184 +.
185 +.Sh SEE ALSO
186 +.Xr ffi 3 ,
187 +.Xr ffi_call 3 ,
188 +.Xr ffi_prep_cif 3
189 Index: libffi/src/arm/ffi.c
190 ===================================================================
191 --- libffi.orig/src/arm/ffi.c
192 +++ libffi/src/arm/ffi.c
193 @@ -196,6 +196,18 @@ ffi_status ffi_prep_cif_machdep(ffi_cif
194    return FFI_OK;
195  }
196  
197 +/* Perform machine dependent cif processing for variadic calls */
198 +ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
199 +                                   unsigned int nfixedargs,
200 +                                   unsigned int ntotalargs)
201 +{
202 +  /* VFP variadic calls actually use the SYSV ABI */
203 +  if (cif->abi == FFI_VFP)
204 +       cif->abi = FFI_SYSV;
205 +
206 +  return ffi_prep_cif_machdep(cif);
207 +}
208 +
209  /* Prototypes for assembly functions, in sysv.S */
210  extern void ffi_call_SYSV (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
211  extern void ffi_call_VFP (void (*fn)(void), extended_cif *, unsigned, unsigned, unsigned *);
212 Index: libffi/src/arm/ffitarget.h
213 ===================================================================
214 --- libffi.orig/src/arm/ffitarget.h
215 +++ libffi/src/arm/ffitarget.h
216 @@ -55,6 +55,8 @@ typedef enum ffi_abi {
217  #define FFI_TYPE_STRUCT_VFP_FLOAT  (FFI_TYPE_LAST + 1)
218  #define FFI_TYPE_STRUCT_VFP_DOUBLE (FFI_TYPE_LAST + 2)
219  
220 +#define FFI_TARGET_SPECIFIC_VARIADIC
221 +
222  /* ---- Definitions for closures ----------------------------------------- */
223  
224  #define FFI_CLOSURES 1
225 @@ -62,4 +64,3 @@ typedef enum ffi_abi {
226  #define FFI_NATIVE_RAW_API 0
227  
228  #endif
229 -
230 Index: libffi/src/cris/ffi.c
231 ===================================================================
232 --- libffi.orig/src/cris/ffi.c
233 +++ libffi/src/cris/ffi.c
234 @@ -153,21 +153,24 @@ ffi_prep_args (char *stack, extended_cif
235    return (struct_count);
236  }
237  
238 -ffi_status
239 -ffi_prep_cif (ffi_cif * cif,
240 -             ffi_abi abi, unsigned int nargs,
241 -             ffi_type * rtype, ffi_type ** atypes)
242 +ffi_status FFI_HIDDEN
243 +ffi_prep_cif_core (ffi_cif * cif,
244 +                  ffi_abi abi, unsigned int isvariadic,
245 +                  unsigned int nfixedargs, unsigned int ntotalargs,
246 +                  ffi_type * rtype, ffi_type ** atypes)
247  {
248    unsigned bytes = 0;
249    unsigned int i;
250    ffi_type **ptr;
251  
252    FFI_ASSERT (cif != NULL);
253 +  FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
254 +  FFI_ASSERT(nfixedargs <= ntotalargs);
255    FFI_ASSERT (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI);
256  
257    cif->abi = abi;
258    cif->arg_types = atypes;
259 -  cif->nargs = nargs;
260 +  cif->nargs = ntotalargs;
261    cif->rtype = rtype;
262  
263    cif->flags = 0;
264 Index: libffi/src/prep_cif.c
265 ===================================================================
266 --- libffi.orig/src/prep_cif.c
267 +++ libffi/src/prep_cif.c
268 @@ -90,20 +90,33 @@ static ffi_status initialize_aggregate(f
269  /* Perform machine independent ffi_cif preparation, then call
270     machine dependent routine. */
271  
272 -ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
273 -                       ffi_type *rtype, ffi_type **atypes)
274 +/* For non variadic functions isvariadic should be 0 and
275 +   nfixedargs==ntotalargs.
276 +
277 +   For variadic calls, isvariadic should be 1 and nfixedargs
278 +   and ntotalargs set as appropriate. nfixedargs must always be >=1 */
279 +
280 +
281 +ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
282 +                            unsigned int isvariadic,
283 +                             unsigned int nfixedargs,
284 +                             unsigned int ntotalargs,
285 +                            ffi_type *rtype, ffi_type **atypes)
286  {
287    unsigned bytes = 0;
288    unsigned int i;
289    ffi_type **ptr;
290  
291    FFI_ASSERT(cif != NULL);
292 +  FFI_ASSERT((!isvariadic) || (nfixedargs >= 1));
293 +  FFI_ASSERT(nfixedargs <= ntotalargs);
294 +
295    if (! (abi > FFI_FIRST_ABI && abi < FFI_LAST_ABI))
296      return FFI_BAD_ABI;
297  
298    cif->abi = abi;
299    cif->arg_types = atypes;
300 -  cif->nargs = nargs;
301 +  cif->nargs = ntotalargs;
302    cif->rtype = rtype;
303  
304    cif->flags = 0;
305 @@ -159,10 +172,31 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ff
306    cif->bytes = bytes;
307  
308    /* Perform machine dependent cif processing */
309 +#ifdef FFI_TARGET_SPECIFIC_VARIADIC
310 +  if (isvariadic)
311 +       return ffi_prep_cif_machdep_var(cif, nfixedargs, ntotalargs);
312 +#endif
313 +
314    return ffi_prep_cif_machdep(cif);
315  }
316  #endif /* not __CRIS__ */
317  
318 +ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
319 +                            ffi_type *rtype, ffi_type **atypes)
320 +{
321 +  return ffi_prep_cif_core(cif, abi, 0, nargs, nargs, rtype, atypes);
322 +}
323 +
324 +ffi_status ffi_prep_cif_var(ffi_cif *cif,
325 +                            ffi_abi abi,
326 +                            unsigned int nfixedargs,
327 +                            unsigned int ntotalargs,
328 +                            ffi_type *rtype,
329 +                            ffi_type **atypes)
330 +{
331 +  return ffi_prep_cif_core(cif, abi, 1, nfixedargs, ntotalargs, rtype, atypes);
332 +}
333 +
334  #if FFI_CLOSURES
335  
336  ffi_status
337 Index: libffi/testsuite/libffi.call/cls_double_va.c
338 ===================================================================
339 --- libffi.orig/testsuite/libffi.call/cls_double_va.c
340 +++ libffi/testsuite/libffi.call/cls_double_va.c
341 @@ -37,7 +37,8 @@ int main (void)
342         arg_types[1] = &ffi_type_double;
343         arg_types[2] = NULL;
344  
345 -       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
346 +       /* This printf call is variadic */
347 +       CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
348                 arg_types) == FFI_OK);
349  
350         args[0] = &format;
351 @@ -49,6 +50,9 @@ int main (void)
352         printf("res: %d\n", (int) res);
353         // { dg-output "\nres: 4" }
354  
355 +       /* The call to cls_double_va_fn is static, so have to use a normal prep_cif */
356 +       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint, arg_types) == FFI_OK);
357 +
358         CHECK(ffi_prep_closure_loc(pcl, &cif, cls_double_va_fn, NULL, code) == FFI_OK);
359  
360         res     = ((int(*)(char*, double))(code))(format, doubleArg);
361 Index: libffi/testsuite/libffi.call/cls_longdouble_va.c
362 ===================================================================
363 --- libffi.orig/testsuite/libffi.call/cls_longdouble_va.c
364 +++ libffi/testsuite/libffi.call/cls_longdouble_va.c
365 @@ -37,7 +37,8 @@ int main (void)
366         arg_types[1] = &ffi_type_longdouble;
367         arg_types[2] = NULL;
368  
369 -       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
370 +       /* This printf call is variadic */
371 +       CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2, &ffi_type_sint,
372                 arg_types) == FFI_OK);
373  
374         args[0] = &format;
375 @@ -49,6 +50,10 @@ int main (void)
376         printf("res: %d\n", (int) res);
377         // { dg-output "\nres: 4" }
378  
379 +       /* The call to cls_longdouble_va_fn is static, so have to use a normal prep_cif */
380 +       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
381 +               arg_types) == FFI_OK);
382 +
383         CHECK(ffi_prep_closure_loc(pcl, &cif, cls_longdouble_va_fn, NULL, code) == FFI_OK);
384  
385         res     = ((int(*)(char*, long double))(code))(format, ldArg);
386 Index: libffi/testsuite/libffi.call/float_va.c
387 ===================================================================
388 --- /dev/null
389 +++ libffi/testsuite/libffi.call/float_va.c
390 @@ -0,0 +1,107 @@
391 +/* Area:        fp and variadics
392 +   Purpose:     check fp inputs and returns work on variadics, even the fixed params
393 +   Limitations: None
394 +   PR:          none
395 +   Originator:  <david.gilbert@linaro.org> 2011-01-25
396 +
397 +   Intended to stress the difference in ABI on ARM vfp
398 +*/
399 +
400 +/* { dg-do run } */
401 +
402 +#include <stdarg.h>
403 +
404 +#include "ffitest.h"
405 +
406 +/* prints out all the parameters, and returns the sum of them all.
407 + * 'x' is the number of variadic parameters all of which are double in this test
408 + */
409 +double float_va_fn(unsigned int x, double y,...)
410 +{
411 +  double total=0.0;
412 +  va_list ap;
413 +  unsigned int i;
414 +
415 +  total+=(double)x;
416 +  total+=y;
417 +
418 +  printf("%u: %.1lf :", x, y);
419 +
420 +  va_start(ap, y);
421 +  for(i=0;i<x;i++)
422 +  {
423 +    double arg=va_arg(ap, double);
424 +    total+=arg;
425 +    printf(" %d:%.1lf ", i, arg);
426 +  }
427 +  va_end(ap);
428 +
429 +  printf(" total: %.1lf\n", total);
430 +
431 +  return total;
432 +}
433 +
434 +int main (void)
435 +{
436 +  ffi_cif    cif;
437 +
438 +  ffi_type    *arg_types[5];
439 +  void        *values[5];
440 +  double        doubles[5];
441 +  unsigned int firstarg;
442 +  double        resfp;
443 +
444 +  /* First test, pass float_va_fn(0,2.0) - note there are no actual
445 +   * variadic parameters, but it's declared variadic so the ABI may be
446 +   * different. */
447 +  /* Call it statically and then via ffi */
448 +  resfp=float_va_fn(0,2.0);
449 +  // { dg-output "0: 2.0 : total: 2.0" }
450 +  printf("compiled: %.1lf\n", resfp);
451 +  // { dg-output "\ncompiled: 2.0" }
452 +
453 +  arg_types[0] = &ffi_type_uint;
454 +  arg_types[1] = &ffi_type_double;
455 +  arg_types[2] = NULL;
456 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 2,
457 +        &ffi_type_double, arg_types) == FFI_OK);
458 +
459 +  firstarg = 0;
460 +  doubles[0] = 2.0;
461 +  values[0] = &firstarg;
462 +  values[1] = &doubles[0];
463 +  ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
464 +  // { dg-output "\n0: 2.0 : total: 2.0" }
465 +  printf("ffi: %.1lf\n", resfp);
466 +  // { dg-output "\nffi: 2.0" }
467 +
468 +  /* Second test, float_va_fn(2,2.0,3.0,4.0), now with variadic params */
469 +  /* Call it statically and then via ffi */
470 +  resfp=float_va_fn(2,2.0,3.0,4.0);
471 +  // { dg-output "\n2: 2.0 : 0:3.0  1:4.0  total: 11.0" }
472 +  printf("compiled: %.1lf\n", resfp);
473 +  // { dg-output "\ncompiled: 11.0" }
474 +
475 +  arg_types[0] = &ffi_type_uint;
476 +  arg_types[1] = &ffi_type_double;
477 +  arg_types[2] = &ffi_type_double;
478 +  arg_types[3] = &ffi_type_double;
479 +  arg_types[4] = NULL;
480 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 2, 4,
481 +        &ffi_type_double, arg_types) == FFI_OK);
482 +
483 +  firstarg = 2;
484 +  doubles[0] = 2.0;
485 +  doubles[1] = 3.0;
486 +  doubles[2] = 4.0;
487 +  values[0] = &firstarg;
488 +  values[1] = &doubles[0];
489 +  values[2] = &doubles[1];
490 +  values[3] = &doubles[2];
491 +  ffi_call(&cif, FFI_FN(float_va_fn), &resfp, values);
492 +  // { dg-output "\n2: 2.0 : 0:3.0  1:4.0  total: 11.0" }
493 +  printf("ffi: %.1lf\n", resfp);
494 +  // { dg-output "\nffi: 11.0" }
495 +
496 +  exit(0);
497 +}
498 Index: libffi/doc/libffi.texi
499 ===================================================================
500 --- libffi.orig/doc/libffi.texi
501 +++ libffi/doc/libffi.texi
502 @@ -19,7 +19,7 @@
503  This manual is for Libffi, a portable foreign-function interface
504  library.
505  
506 -Copyright @copyright{} 2008, 2010 Red Hat, Inc.
507 +Copyright @copyright{} 2008, 2010, 2011 Red Hat, Inc.
508  
509  @quotation
510  Permission is granted to copy, distribute and/or modify this document
511 @@ -133,8 +133,6 @@ This initializes @var{cif} according to
512  you want.  @ref{Multiple ABIs} for more information.
513  
514  @var{nargs} is the number of arguments that this function accepts.
515 -@samp{libffi} does not yet handle varargs functions; see @ref{Missing
516 -Features} for more information.
517  
518  @var{rtype} is a pointer to an @code{ffi_type} structure that
519  describes the return type of the function.  @xref{Types}.
520 @@ -150,6 +148,30 @@ objects is incorrect; or @code{FFI_BAD_A
521  is invalid.
522  @end defun
523  
524 +If the function being called is variadic (varargs) then
525 +@code{ffi_prep_cif_var} must be used instead of @code{ffi_prep_cif}.
526 +
527 +@findex ffi_prep_cif_var
528 +@defun ffi_status ffi_prep_cif_var (ffi_cif *@var{cif}, ffi_abi var{abi}, unsigned int @var{nfixedargs}, unsigned int var{ntotalargs}, ffi_type *@var{rtype}, ffi_type **@var{argtypes})
529 +This initializes @var{cif} according to the given parameters for
530 +a call to a variadic function.  In general it's operation is the
531 +same as for @code{ffi_prep_cif} except that:
532 +
533 +@var{nfixedargs} is the number of fixed arguments, prior to any
534 +variadic arguments.  It must be greater than zero.
535 +
536 +@var{ntotalargs} the total number of arguments, including variadic
537 +and fixed arguments.
538 +
539 +Note that, different cif's must be prepped for calls to the same
540 +function when different numbers of arguments are passed.
541 +
542 +Also note that a call to @code{ffi_prep_cif_var} with
543 +@var{nfixedargs}=@var{nototalargs} is NOT equivalent to a call to
544 +@code{ffi_prep_cif}.
545 +
546 +@end defun
547 +
548  
549  To call a function using an initialized @code{ffi_cif}, use the
550  @code{ffi_call} function:
551 @@ -572,9 +594,7 @@ support for these.
552  
553  @itemize @bullet
554  @item
555 -There is no support for calling varargs functions.  This may work on
556 -some platforms, depending on how the ABI is defined, but it is not
557 -reliable.
558 +Variadic closures.
559  
560  @item
561  There is no support for bit fields in structures.
562 @@ -591,6 +611,8 @@ The ``raw'' API is undocumented.
563  @c anything else?
564  @end itemize
565  
566 +Note that variadic support is very new and tested on a relatively
567 +small number of platforms.
568  
569  @node Index
570  @unnumbered Index
571 Index: libffi/ChangeLog
572 ===================================================================
573 --- libffi.orig/ChangeLog
574 +++ libffi/ChangeLog
575 @@ -41,6 +41,17 @@
576  
577         * configure: Regenerate.
578  
579 +2011-11-12  David Gilbert <david.gilbert@linaro.org>
580 +
581 +       * doc/libffi.texi, include/ffi.h.in, include/ffi_common.h,
582 +       man/Makefile.am, man/ffi.3, man/ffi_prep_cif.3,
583 +       man/ffi_prep_cif_var.3, src/arm/ffi.c, src/arm/ffitarget.h,
584 +       src/cris/ffi.c, src/prep_cif.c,
585 +       testsuite/libffi.call/cls_double_va.c,
586 +       testsuite/libffi.call/cls_longdouble_va.c,
587 +       testsuite/libffi.call/float_va.c: Many changes to support variadic
588 +       function calls.
589 +
590  2011-11-12  Kyle Moffett <Kyle.D.Moffett@boeing.com>
591  
592         * src/powerpc/ffi.c, src/powerpc/ffitarget.h,