Refresh config.guess and config.sub
[libffi.git] / patches / aarch64
1 Index: libffi/README
2 ===================================================================
3 --- libffi.orig/README
4 +++ libffi/README
5 @@ -51,6 +51,7 @@ tested:
6  |-----------------+------------------|
7  | Architecture    | Operating System |
8  |-----------------+------------------|
9 +| AArch64         | Linux            |
10  | Alpha           | Linux            |
11  | Alpha           | Tru64            |
12  | ARM             | Linux            |
13 @@ -152,6 +153,7 @@ See the ChangeLog files for details.
14  3.0.12 XXX-XX-XX
15         Add Blackfin support.
16         Add TILE-Gx/TILEPro support.
17 +       Add AArch64 support.
18  
19  3.0.11 Apr-11-12
20          Lots of build fixes.
21 @@ -323,6 +325,7 @@ Thorup.
22  Major processor architecture ports were contributed by the following
23  developers:
24  
25 +aarch64                Marcus Shawcroft, James Greenhalgh
26  alpha          Richard Henderson
27  arm            Raffaele Sena
28  blackfin        Alexandre Keunecke I. de Mendonca
29 Index: libffi/src/aarch64/ffi.c
30 ===================================================================
31 --- /dev/null
32 +++ libffi/src/aarch64/ffi.c
33 @@ -0,0 +1,1076 @@
34 +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
35 +
36 +Permission is hereby granted, free of charge, to any person obtaining
37 +a copy of this software and associated documentation files (the
38 +``Software''), to deal in the Software without restriction, including
39 +without limitation the rights to use, copy, modify, merge, publish,
40 +distribute, sublicense, and/or sell copies of the Software, and to
41 +permit persons to whom the Software is furnished to do so, subject to
42 +the following conditions:
43 +
44 +The above copyright notice and this permission notice shall be
45 +included in all copies or substantial portions of the Software.
46 +
47 +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
48 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
51 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
52 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
53 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
54 +
55 +#include <stdio.h>
56 +
57 +#include <ffi.h>
58 +#include <ffi_common.h>
59 +
60 +#include <stdlib.h>
61 +
62 +/* Stack alignment requirement in bytes */
63 +#define AARCH64_STACK_ALIGN 16
64 +
65 +#define N_X_ARG_REG 8
66 +#define N_V_ARG_REG 8
67 +
68 +#define AARCH64_FFI_WITH_V (1 << AARCH64_FFI_WITH_V_BIT)
69 +
70 +union _d
71 +{
72 +  UINT64 d;
73 +  UINT32 s[2];
74 +};
75 +
76 +struct call_context
77 +{
78 +  UINT64 x [AARCH64_N_XREG];
79 +  struct
80 +  {
81 +    union _d d[2];
82 +  } v [AARCH64_N_VREG];
83 +};
84 +
85 +static void *
86 +get_x_addr (struct call_context *context, unsigned n)
87 +{
88 +  return &context->x[n];
89 +}
90 +
91 +static void *
92 +get_s_addr (struct call_context *context, unsigned n)
93 +{
94 +#if defined __AARCH64EB__
95 +  return &context->v[n].d[1].s[1];
96 +#else
97 +  return &context->v[n].d[0].s[0];
98 +#endif
99 +}
100 +
101 +static void *
102 +get_d_addr (struct call_context *context, unsigned n)
103 +{
104 +#if defined __AARCH64EB__
105 +  return &context->v[n].d[1];
106 +#else
107 +  return &context->v[n].d[0];
108 +#endif
109 +}
110 +
111 +static void *
112 +get_v_addr (struct call_context *context, unsigned n)
113 +{
114 +  return &context->v[n];
115 +}
116 +
117 +/* Return the memory location at which a basic type would reside
118 +   were it to have been stored in register n.  */
119 +
120 +static void *
121 +get_basic_type_addr (unsigned short type, struct call_context *context,
122 +                    unsigned n)
123 +{
124 +  switch (type)
125 +    {
126 +    case FFI_TYPE_FLOAT:
127 +      return get_s_addr (context, n);
128 +    case FFI_TYPE_DOUBLE:
129 +      return get_d_addr (context, n);
130 +    case FFI_TYPE_LONGDOUBLE:
131 +      return get_v_addr (context, n);
132 +    case FFI_TYPE_UINT8:
133 +    case FFI_TYPE_SINT8:
134 +    case FFI_TYPE_UINT16:
135 +    case FFI_TYPE_SINT16:
136 +    case FFI_TYPE_UINT32:
137 +    case FFI_TYPE_SINT32:
138 +    case FFI_TYPE_INT:
139 +    case FFI_TYPE_POINTER:
140 +    case FFI_TYPE_UINT64:
141 +    case FFI_TYPE_SINT64:
142 +      return get_x_addr (context, n);
143 +    default:
144 +      FFI_ASSERT (0);
145 +      return NULL;
146 +    }
147 +}
148 +
149 +/* Return the alignment width for each of the basic types.  */
150 +
151 +static size_t
152 +get_basic_type_alignment (unsigned short type)
153 +{
154 +  switch (type)
155 +    {
156 +    case FFI_TYPE_FLOAT:
157 +    case FFI_TYPE_DOUBLE:
158 +      return sizeof (UINT64);
159 +    case FFI_TYPE_LONGDOUBLE:
160 +      return sizeof (long double);
161 +    case FFI_TYPE_UINT8:
162 +    case FFI_TYPE_SINT8:
163 +    case FFI_TYPE_UINT16:
164 +    case FFI_TYPE_SINT16:
165 +    case FFI_TYPE_UINT32:
166 +    case FFI_TYPE_INT:
167 +    case FFI_TYPE_SINT32:
168 +    case FFI_TYPE_POINTER:
169 +    case FFI_TYPE_UINT64:
170 +    case FFI_TYPE_SINT64:
171 +      return sizeof (UINT64);
172 +
173 +    default:
174 +      FFI_ASSERT (0);
175 +      return 0;
176 +    }
177 +}
178 +
179 +/* Return the size in bytes for each of the basic types.  */
180 +
181 +static size_t
182 +get_basic_type_size (unsigned short type)
183 +{
184 +  switch (type)
185 +    {
186 +    case FFI_TYPE_FLOAT:
187 +      return sizeof (UINT32);
188 +    case FFI_TYPE_DOUBLE:
189 +      return sizeof (UINT64);
190 +    case FFI_TYPE_LONGDOUBLE:
191 +      return sizeof (long double);
192 +    case FFI_TYPE_UINT8:
193 +      return sizeof (UINT8);
194 +    case FFI_TYPE_SINT8:
195 +      return sizeof (SINT8);
196 +    case FFI_TYPE_UINT16:
197 +      return sizeof (UINT16);
198 +    case FFI_TYPE_SINT16:
199 +      return sizeof (SINT16);
200 +    case FFI_TYPE_UINT32:
201 +      return sizeof (UINT32);
202 +    case FFI_TYPE_INT:
203 +    case FFI_TYPE_SINT32:
204 +      return sizeof (SINT32);
205 +    case FFI_TYPE_POINTER:
206 +    case FFI_TYPE_UINT64:
207 +      return sizeof (UINT64);
208 +    case FFI_TYPE_SINT64:
209 +      return sizeof (SINT64);
210 +
211 +    default:
212 +      FFI_ASSERT (0);
213 +      return 0;
214 +    }
215 +}
216 +
217 +extern void
218 +ffi_call_SYSV (unsigned (*)(struct call_context *context, unsigned char *,
219 +                           extended_cif *),
220 +               struct call_context *context,
221 +               extended_cif *,
222 +               unsigned,
223 +               void (*fn)(void));
224 +
225 +extern void
226 +ffi_closure_SYSV (ffi_closure *);
227 +
228 +/* Test for an FFI floating point representation.  */
229 +
230 +static unsigned
231 +is_floating_type (unsigned short type)
232 +{
233 +  return (type == FFI_TYPE_FLOAT || type == FFI_TYPE_DOUBLE
234 +         || type == FFI_TYPE_LONGDOUBLE);
235 +}
236 +
237 +/* Test for a homogeneous structure.  */
238 +
239 +static unsigned short
240 +get_homogeneous_type (ffi_type *ty)
241 +{
242 +  if (ty->type == FFI_TYPE_STRUCT && ty->elements)
243 +    {
244 +      unsigned i;
245 +      unsigned short candidate_type
246 +       = get_homogeneous_type (ty->elements[0]);
247 +      for (i =1; ty->elements[i]; i++)
248 +       {
249 +         unsigned short iteration_type = 0;
250 +         /* If we have a nested struct, we must find its homogeneous type.
251 +            If that fits with our candidate type, we are still
252 +            homogeneous.  */
253 +         if (ty->elements[i]->type == FFI_TYPE_STRUCT
254 +             && ty->elements[i]->elements)
255 +           {
256 +             iteration_type = get_homogeneous_type (ty->elements[i]);
257 +           }
258 +         else
259 +           {
260 +             iteration_type = ty->elements[i]->type;
261 +           }
262 +
263 +         /* If we are not homogeneous, return FFI_TYPE_STRUCT.  */
264 +         if (candidate_type != iteration_type)
265 +           return FFI_TYPE_STRUCT;
266 +       }
267 +      return candidate_type;
268 +    }
269 +
270 +  /* Base case, we have no more levels of nesting, so we
271 +     are a basic type, and so, trivially homogeneous in that type.  */
272 +  return ty->type;
273 +}
274 +
275 +/* Determine the number of elements within a STRUCT.
276 +
277 +   Note, we must handle nested structs.
278 +
279 +   If ty is not a STRUCT this function will return 0.  */
280 +
281 +static unsigned
282 +element_count (ffi_type *ty)
283 +{
284 +  if (ty->type == FFI_TYPE_STRUCT && ty->elements)
285 +    {
286 +      unsigned n;
287 +      unsigned elems = 0;
288 +      for (n = 0; ty->elements[n]; n++)
289 +       {
290 +         if (ty->elements[n]->type == FFI_TYPE_STRUCT
291 +             && ty->elements[n]->elements)
292 +           elems += element_count (ty->elements[n]);
293 +         else
294 +           elems++;
295 +       }
296 +      return elems;
297 +    }
298 +  return 0;
299 +}
300 +
301 +/* Test for a homogeneous floating point aggregate.
302 +
303 +   A homogeneous floating point aggregate is a homogeneous aggregate of
304 +   a half- single- or double- precision floating point type with one
305 +   to four elements.  Note that this includes nested structs of the
306 +   basic type.  */
307 +
308 +static int
309 +is_hfa (ffi_type *ty)
310 +{
311 +  if (ty->type == FFI_TYPE_STRUCT
312 +      && ty->elements[0]
313 +      && is_floating_type (get_homogeneous_type (ty)))
314 +    {
315 +      unsigned n = element_count (ty);
316 +      return n >= 1 && n <= 4;
317 +    }
318 +  return 0;
319 +}
320 +
321 +/* Test if an ffi_type is a candidate for passing in a register.
322 +
323 +   This test does not check that sufficient registers of the
324 +   appropriate class are actually available, merely that IFF
325 +   sufficient registers are available then the argument will be passed
326 +   in register(s).
327 +
328 +   Note that an ffi_type that is deemed to be a register candidate
329 +   will always be returned in registers.
330 +
331 +   Returns 1 if a register candidate else 0.  */
332 +
333 +static int
334 +is_register_candidate (ffi_type *ty)
335 +{
336 +  switch (ty->type)
337 +    {
338 +    case FFI_TYPE_VOID:
339 +    case FFI_TYPE_FLOAT:
340 +    case FFI_TYPE_DOUBLE:
341 +    case FFI_TYPE_LONGDOUBLE:
342 +    case FFI_TYPE_UINT8:
343 +    case FFI_TYPE_UINT16:
344 +    case FFI_TYPE_UINT32:
345 +    case FFI_TYPE_UINT64:
346 +    case FFI_TYPE_POINTER:
347 +    case FFI_TYPE_SINT8:
348 +    case FFI_TYPE_SINT16:
349 +    case FFI_TYPE_SINT32:
350 +    case FFI_TYPE_INT:
351 +    case FFI_TYPE_SINT64:
352 +      return 1;
353 +
354 +    case FFI_TYPE_STRUCT:
355 +      if (is_hfa (ty))
356 +        {
357 +          return 1;
358 +        }
359 +      else if (ty->size > 16)
360 +        {
361 +          /* Too large. Will be replaced with a pointer to memory. The
362 +             pointer MAY be passed in a register, but the value will
363 +             not. This test specifically fails since the argument will
364 +             never be passed by value in registers. */
365 +          return 0;
366 +        }
367 +      else
368 +        {
369 +          /* Might be passed in registers depending on the number of
370 +             registers required. */
371 +          return (ty->size + 7) / 8 < N_X_ARG_REG;
372 +        }
373 +      break;
374 +
375 +    default:
376 +      FFI_ASSERT (0);
377 +      break;
378 +    }
379 +
380 +  return 0;
381 +}
382 +
383 +/* Test if an ffi_type argument or result is a candidate for a vector
384 +   register.  */
385 +
386 +static int
387 +is_v_register_candidate (ffi_type *ty)
388 +{
389 +  return is_floating_type (ty->type)
390 +          || (ty->type == FFI_TYPE_STRUCT && is_hfa (ty));
391 +}
392 +
393 +/* Representation of the procedure call argument marshalling
394 +   state.
395 +
396 +   The terse state variable names match the names used in the AARCH64
397 +   PCS. */
398 +
399 +struct arg_state
400 +{
401 +  unsigned ngrn;                /* Next general-purpose register number. */
402 +  unsigned nsrn;                /* Next vector register number. */
403 +  unsigned nsaa;                /* Next stack offset. */
404 +};
405 +
406 +/* Initialize a procedure call argument marshalling state.  */
407 +static void
408 +arg_init (struct arg_state *state, unsigned call_frame_size)
409 +{
410 +  state->ngrn = 0;
411 +  state->nsrn = 0;
412 +  state->nsaa = 0;
413 +}
414 +
415 +/* Return the number of available consecutive core argument
416 +   registers.  */
417 +
418 +static unsigned
419 +available_x (struct arg_state *state)
420 +{
421 +  return N_X_ARG_REG - state->ngrn;
422 +}
423 +
424 +/* Return the number of available consecutive vector argument
425 +   registers.  */
426 +
427 +static unsigned
428 +available_v (struct arg_state *state)
429 +{
430 +  return N_V_ARG_REG - state->nsrn;
431 +}
432 +
433 +static void *
434 +allocate_to_x (struct call_context *context, struct arg_state *state)
435 +{
436 +  FFI_ASSERT (state->ngrn < N_X_ARG_REG)
437 +  return get_x_addr (context, (state->ngrn)++);
438 +}
439 +
440 +static void *
441 +allocate_to_s (struct call_context *context, struct arg_state *state)
442 +{
443 +  FFI_ASSERT (state->nsrn < N_V_ARG_REG)
444 +  return get_s_addr (context, (state->nsrn)++);
445 +}
446 +
447 +static void *
448 +allocate_to_d (struct call_context *context, struct arg_state *state)
449 +{
450 +  FFI_ASSERT (state->nsrn < N_V_ARG_REG)
451 +  return get_d_addr (context, (state->nsrn)++);
452 +}
453 +
454 +static void *
455 +allocate_to_v (struct call_context *context, struct arg_state *state)
456 +{
457 +  FFI_ASSERT (state->nsrn < N_V_ARG_REG)
458 +  return get_v_addr (context, (state->nsrn)++);
459 +}
460 +
461 +/* Allocate an aligned slot on the stack and return a pointer to it.  */
462 +static void *
463 +allocate_to_stack (struct arg_state *state, void *stack, unsigned alignment,
464 +                  unsigned size)
465 +{
466 +  void *allocation;
467 +
468 +  /* Round up the NSAA to the larger of 8 or the natural
469 +     alignment of the argument's type.  */
470 +  state->nsaa = ALIGN (state->nsaa, alignment);
471 +  state->nsaa = ALIGN (state->nsaa, alignment);
472 +  state->nsaa = ALIGN (state->nsaa, 8);
473 +
474 +  allocation = stack + state->nsaa;
475 +
476 +  state->nsaa += size;
477 +  return allocation;
478 +}
479 +
480 +static void
481 +copy_basic_type (void *dest, void *source, unsigned short type)
482 +{
483 +  /* This is neccessary to ensure that basic types are copied
484 +     sign extended to 64-bits as libffi expects.  */
485 +  switch (type)
486 +    {
487 +    case FFI_TYPE_FLOAT:
488 +      *(float *) dest = *(float *) source;
489 +      break;
490 +    case FFI_TYPE_DOUBLE:
491 +      *(double *) dest = *(double *) source;
492 +      break;
493 +    case FFI_TYPE_LONGDOUBLE:
494 +      *(long double *) dest = *(long double *) source;
495 +      break;
496 +    case FFI_TYPE_UINT8:
497 +      *(ffi_arg *) dest = *(UINT8 *) source;
498 +      break;
499 +    case FFI_TYPE_SINT8:
500 +      *(ffi_sarg *) dest = *(SINT8 *) source;
501 +      break;
502 +    case FFI_TYPE_UINT16:
503 +      *(ffi_arg *) dest = *(UINT16 *) source;
504 +      break;
505 +    case FFI_TYPE_SINT16:
506 +      *(ffi_sarg *) dest = *(SINT16 *) source;
507 +      break;
508 +    case FFI_TYPE_UINT32:
509 +      *(ffi_arg *) dest = *(UINT32 *) source;
510 +      break;
511 +    case FFI_TYPE_INT:
512 +    case FFI_TYPE_SINT32:
513 +      *(ffi_sarg *) dest = *(SINT32 *) source;
514 +      break;
515 +    case FFI_TYPE_POINTER:
516 +    case FFI_TYPE_UINT64:
517 +      *(ffi_arg *) dest = *(UINT64 *) source;
518 +      break;
519 +    case FFI_TYPE_SINT64:
520 +      *(ffi_sarg *) dest = *(SINT64 *) source;
521 +      break;
522 +
523 +    default:
524 +      FFI_ASSERT (0);
525 +    }
526 +}
527 +
528 +static void
529 +copy_hfa_to_reg_or_stack (void *memory,
530 +                         ffi_type *ty,
531 +                         struct call_context *context,
532 +                         unsigned char *stack,
533 +                         struct arg_state *state)
534 +{
535 +  unsigned elems = element_count (ty);
536 +  if (available_v (state) < elems)
537 +    {
538 +      /* There are insufficient V registers. Further V register allocations
539 +        are prevented, the NSAA is adjusted (by allocate_to_stack ())
540 +        and the argument is copied to memory at the adjusted NSAA.  */
541 +      state->nsrn = N_V_ARG_REG;
542 +      memcpy (allocate_to_stack (state, stack, ty->alignment, ty->size),
543 +             memory,
544 +             ty->size);
545 +    }
546 +  else
547 +    {
548 +      int i;
549 +      unsigned short type = get_homogeneous_type (ty);
550 +      unsigned elems = element_count (ty);
551 +      for (i = 0; i < elems; i++)
552 +       {
553 +         void *reg = allocate_to_v (context, state);
554 +         copy_basic_type (reg, memory, type);
555 +         memory += get_basic_type_size (type);
556 +       }
557 +    }
558 +}
559 +
560 +/* Either allocate an appropriate register for the argument type, or if
561 +   none are available, allocate a stack slot and return a pointer
562 +   to the allocated space.  */
563 +
564 +static void *
565 +allocate_to_register_or_stack (struct call_context *context,
566 +                              unsigned char *stack,
567 +                              struct arg_state *state,
568 +                              unsigned short type)
569 +{
570 +  size_t alignment = get_basic_type_alignment (type);
571 +  size_t size = alignment;
572 +  switch (type)
573 +    {
574 +    case FFI_TYPE_FLOAT:
575 +      /* This is the only case for which the allocated stack size
576 +        should not match the alignment of the type.  */
577 +      size = sizeof (UINT32);
578 +      /* Fall through.  */
579 +    case FFI_TYPE_DOUBLE:
580 +      if (state->nsrn < N_V_ARG_REG)
581 +       return allocate_to_d (context, state);
582 +      state->nsrn = N_V_ARG_REG;
583 +      break;
584 +    case FFI_TYPE_LONGDOUBLE:
585 +      if (state->nsrn < N_V_ARG_REG)
586 +       return allocate_to_v (context, state);
587 +      state->nsrn = N_V_ARG_REG;
588 +      break;
589 +    case FFI_TYPE_UINT8:
590 +    case FFI_TYPE_SINT8:
591 +    case FFI_TYPE_UINT16:
592 +    case FFI_TYPE_SINT16:
593 +    case FFI_TYPE_UINT32:
594 +    case FFI_TYPE_SINT32:
595 +    case FFI_TYPE_INT:
596 +    case FFI_TYPE_POINTER:
597 +    case FFI_TYPE_UINT64:
598 +    case FFI_TYPE_SINT64:
599 +      if (state->ngrn < N_X_ARG_REG)
600 +       return allocate_to_x (context, state);
601 +      state->ngrn = N_X_ARG_REG;
602 +      break;
603 +    default:
604 +      FFI_ASSERT (0);
605 +    }
606 +
607 +    return allocate_to_stack (state, stack, alignment, size);
608 +}
609 +
610 +/* Copy a value to an appropriate register, or if none are
611 +   available, to the stack.  */
612 +
613 +static void
614 +copy_to_register_or_stack (struct call_context *context,
615 +                          unsigned char *stack,
616 +                          struct arg_state *state,
617 +                          void *value,
618 +                          unsigned short type)
619 +{
620 +  copy_basic_type (
621 +         allocate_to_register_or_stack (context, stack, state, type),
622 +         value,
623 +         type);
624 +}
625 +
626 +/* Marshall the arguments from FFI representation to procedure call
627 +   context and stack.  */
628 +
629 +static unsigned
630 +aarch64_prep_args (struct call_context *context, unsigned char *stack,
631 +                  extended_cif *ecif)
632 +{
633 +  int i;
634 +  struct arg_state state;
635 +
636 +  arg_init (&state, ALIGN(ecif->cif->bytes, 16));
637 +
638 +  for (i = 0; i < ecif->cif->nargs; i++)
639 +    {
640 +      ffi_type *ty = ecif->cif->arg_types[i];
641 +      switch (ty->type)
642 +       {
643 +       case FFI_TYPE_VOID:
644 +         FFI_ASSERT (0);
645 +         break;
646 +
647 +       /* If the argument is a basic type the argument is allocated to an
648 +          appropriate register, or if none are available, to the stack.  */
649 +       case FFI_TYPE_FLOAT:
650 +       case FFI_TYPE_DOUBLE:
651 +       case FFI_TYPE_LONGDOUBLE:
652 +       case FFI_TYPE_UINT8:
653 +       case FFI_TYPE_SINT8:
654 +       case FFI_TYPE_UINT16:
655 +       case FFI_TYPE_SINT16:
656 +       case FFI_TYPE_UINT32:
657 +       case FFI_TYPE_INT:
658 +       case FFI_TYPE_SINT32:
659 +       case FFI_TYPE_POINTER:
660 +       case FFI_TYPE_UINT64:
661 +       case FFI_TYPE_SINT64:
662 +         copy_to_register_or_stack (context, stack, &state,
663 +                                    ecif->avalue[i], ty->type);
664 +         break;
665 +
666 +       case FFI_TYPE_STRUCT:
667 +         if (is_hfa (ty))
668 +           {
669 +             copy_hfa_to_reg_or_stack (ecif->avalue[i], ty, context,
670 +                                       stack, &state);
671 +           }
672 +         else if (ty->size > 16)
673 +           {
674 +             /* If the argument is a composite type that is larger than 16
675 +                bytes, then the argument has been copied to memory, and
676 +                the argument is replaced by a pointer to the copy.  */
677 +
678 +             copy_to_register_or_stack (context, stack, &state,
679 +                                        &(ecif->avalue[i]), FFI_TYPE_POINTER);
680 +           }
681 +         else if (available_x (&state) >= (ty->size + 7) / 8)
682 +           {
683 +             /* If the argument is a composite type and the size in
684 +                double-words is not more than the number of available
685 +                X registers, then the argument is copied into consecutive
686 +                X registers.  */
687 +             int j;
688 +             for (j = 0; j < (ty->size + 7) / 8; j++)
689 +               {
690 +                 memcpy (allocate_to_x (context, &state),
691 +                         &(((UINT64 *) ecif->avalue[i])[j]),
692 +                         sizeof (UINT64));
693 +               }
694 +           }
695 +         else
696 +           {
697 +             /* Otherwise, there are insufficient X registers. Further X
698 +                register allocations are prevented, the NSAA is adjusted
699 +                (by allocate_to_stack ()) and the argument is copied to
700 +                memory at the adjusted NSAA.  */
701 +             state.ngrn = N_X_ARG_REG;
702 +
703 +             memcpy (allocate_to_stack (&state, stack, ty->alignment,
704 +                                        ty->size), ecif->avalue + i, ty->size);
705 +           }
706 +         break;
707 +
708 +       default:
709 +         FFI_ASSERT (0);
710 +         break;
711 +       }
712 +    }
713 +
714 +  return ecif->cif->aarch64_flags;
715 +}
716 +
717 +ffi_status
718 +ffi_prep_cif_machdep (ffi_cif *cif)
719 +{
720 +  /* Round the stack up to a multiple of the stack alignment requirement. */
721 +  cif->bytes =
722 +    (cif->bytes + (AARCH64_STACK_ALIGN - 1)) & ~ (AARCH64_STACK_ALIGN - 1);
723 +
724 +  /* Initialize our flags. We are interested if this CIF will touch a
725 +     vector register, if so we will enable context save and load to
726 +     those registers, otherwise not. This is intended to be friendly
727 +     to lazy float context switching in the kernel.  */
728 +  cif->aarch64_flags = 0;
729 +
730 +  if (is_v_register_candidate (cif->rtype))
731 +    {
732 +      cif->aarch64_flags |= AARCH64_FFI_WITH_V;
733 +    }
734 +  else
735 +    {
736 +      int i;
737 +      for (i = 0; i < cif->nargs; i++)
738 +        if (is_v_register_candidate (cif->arg_types[i]))
739 +          {
740 +            cif->aarch64_flags |= AARCH64_FFI_WITH_V;
741 +            break;
742 +          }
743 +    }
744 +
745 +  return FFI_OK;
746 +}
747 +
748 +/* Call a function with the provided arguments and capture the return
749 +   value.  */
750 +void
751 +ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
752 +{
753 +  extended_cif ecif;
754 +
755 +  ecif.cif = cif;
756 +  ecif.avalue = avalue;
757 +  ecif.rvalue = rvalue;
758 +
759 +  switch (cif->abi)
760 +    {
761 +    case FFI_SYSV:
762 +      {
763 +        struct call_context context;
764 +       unsigned stack_bytes;
765 +
766 +       /* Figure out the total amount of stack space we need, the
767 +          above call frame space needs to be 16 bytes aligned to
768 +          ensure correct alignment of the first object inserted in
769 +          that space hence the ALIGN applied to cif->bytes.*/
770 +       stack_bytes = ALIGN(cif->bytes, 16);
771 +
772 +       memset (&context, 0, sizeof (context));
773 +        if (is_register_candidate (cif->rtype))
774 +          {
775 +            ffi_call_SYSV (aarch64_prep_args, &context, &ecif, stack_bytes, fn);
776 +            switch (cif->rtype->type)
777 +              {
778 +              case FFI_TYPE_VOID:
779 +              case FFI_TYPE_FLOAT:
780 +              case FFI_TYPE_DOUBLE:
781 +              case FFI_TYPE_LONGDOUBLE:
782 +              case FFI_TYPE_UINT8:
783 +              case FFI_TYPE_SINT8:
784 +              case FFI_TYPE_UINT16:
785 +              case FFI_TYPE_SINT16:
786 +              case FFI_TYPE_UINT32:
787 +              case FFI_TYPE_SINT32:
788 +              case FFI_TYPE_POINTER:
789 +              case FFI_TYPE_UINT64:
790 +              case FFI_TYPE_INT:
791 +              case FFI_TYPE_SINT64:
792 +               {
793 +                 void *addr = get_basic_type_addr (cif->rtype->type,
794 +                                                   &context, 0);
795 +                 copy_basic_type (rvalue, addr, cif->rtype->type);
796 +                 break;
797 +               }
798 +
799 +              case FFI_TYPE_STRUCT:
800 +                if (is_hfa (cif->rtype))
801 +                 {
802 +                   int j;
803 +                   unsigned short type = get_homogeneous_type (cif->rtype);
804 +                   unsigned elems = element_count (cif->rtype);
805 +                   for (j = 0; j < elems; j++)
806 +                     {
807 +                       void *reg = get_basic_type_addr (type, &context, j);
808 +                       copy_basic_type (rvalue, reg, type);
809 +                       rvalue += get_basic_type_size (type);
810 +                     }
811 +                 }
812 +                else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
813 +                  {
814 +                    unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64));
815 +                    memcpy (rvalue, get_x_addr (&context, 0), size);
816 +                  }
817 +                else
818 +                  {
819 +                    FFI_ASSERT (0);
820 +                  }
821 +                break;
822 +
823 +              default:
824 +                FFI_ASSERT (0);
825 +                break;
826 +              }
827 +          }
828 +        else
829 +          {
830 +            memcpy (get_x_addr (&context, 8), &rvalue, sizeof (UINT64));
831 +            ffi_call_SYSV (aarch64_prep_args, &context, &ecif,
832 +                          stack_bytes, fn);
833 +          }
834 +        break;
835 +      }
836 +
837 +    default:
838 +      FFI_ASSERT (0);
839 +      break;
840 +    }
841 +}
842 +
843 +static unsigned char trampoline [] =
844 +{ 0x70, 0x00, 0x00, 0x58,      /* ldr  x16, 1f */
845 +  0x91, 0x00, 0x00, 0x10,      /* adr  x17, 2f */
846 +  0x00, 0x02, 0x1f, 0xd6       /* br   x16     */
847 +};
848 +
849 +/* Build a trampoline.  */
850 +
851 +#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,FLAGS)                       \
852 +  ({unsigned char *__tramp = (unsigned char*)(TRAMP);                  \
853 +    UINT64  __fun = (UINT64)(FUN);                                     \
854 +    UINT64  __ctx = (UINT64)(CTX);                                     \
855 +    UINT64  __flags = (UINT64)(FLAGS);                                 \
856 +    memcpy (__tramp, trampoline, sizeof (trampoline));                 \
857 +    memcpy (__tramp + 12, &__fun, sizeof (__fun));                     \
858 +    memcpy (__tramp + 20, &__ctx, sizeof (__ctx));                     \
859 +    memcpy (__tramp + 28, &__flags, sizeof (__flags));                 \
860 +    __clear_cache(__tramp, __tramp + FFI_TRAMPOLINE_SIZE);             \
861 +  })
862 +
863 +ffi_status
864 +ffi_prep_closure_loc (ffi_closure* closure,
865 +                      ffi_cif* cif,
866 +                      void (*fun)(ffi_cif*,void*,void**,void*),
867 +                      void *user_data,
868 +                      void *codeloc)
869 +{
870 +  if (cif->abi != FFI_SYSV)
871 +    return FFI_BAD_ABI;
872 +
873 +  FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, codeloc,
874 +                      cif->aarch64_flags);
875 +
876 +  closure->cif  = cif;
877 +  closure->user_data = user_data;
878 +  closure->fun  = fun;
879 +
880 +  return FFI_OK;
881 +}
882 +
883 +/* Primary handler to setup and invoke a function within a closure.
884 +
885 +   A closure when invoked enters via the assembler wrapper
886 +   ffi_closure_SYSV(). The wrapper allocates a call context on the
887 +   stack, saves the interesting registers (from the perspective of
888 +   the calling convention) into the context then passes control to
889 +   ffi_closure_SYSV_inner() passing the saved context and a pointer to
890 +   the stack at the point ffi_closure_SYSV() was invoked.
891 +
892 +   On the return path the assembler wrapper will reload call context
893 +   regsiters.
894 +
895 +   ffi_closure_SYSV_inner() marshalls the call context into ffi value
896 +   desriptors, invokes the wrapped function, then marshalls the return
897 +   value back into the call context.  */
898 +
899 +void
900 +ffi_closure_SYSV_inner (ffi_closure *closure, struct call_context *context,
901 +                       void *stack)
902 +{
903 +  ffi_cif *cif = closure->cif;
904 +  void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
905 +  void *rvalue = NULL;
906 +  int i;
907 +  struct arg_state state;
908 +
909 +  arg_init (&state, ALIGN(cif->bytes, 16));
910 +
911 +  for (i = 0; i < cif->nargs; i++)
912 +    {
913 +      ffi_type *ty = cif->arg_types[i];
914 +
915 +      switch (ty->type)
916 +       {
917 +       case FFI_TYPE_VOID:
918 +         FFI_ASSERT (0);
919 +         break;
920 +
921 +       case FFI_TYPE_UINT8:
922 +       case FFI_TYPE_SINT8:
923 +       case FFI_TYPE_UINT16:
924 +       case FFI_TYPE_SINT16:
925 +       case FFI_TYPE_UINT32:
926 +       case FFI_TYPE_SINT32:
927 +       case FFI_TYPE_INT:
928 +       case FFI_TYPE_POINTER:
929 +       case FFI_TYPE_UINT64:
930 +       case FFI_TYPE_SINT64:
931 +       case  FFI_TYPE_FLOAT:
932 +       case  FFI_TYPE_DOUBLE:
933 +       case  FFI_TYPE_LONGDOUBLE:
934 +         avalue[i] = allocate_to_register_or_stack (context, stack,
935 +                                                    &state, ty->type);
936 +         break;
937 +
938 +       case FFI_TYPE_STRUCT:
939 +         if (is_hfa (ty))
940 +           {
941 +             unsigned n = element_count (ty);
942 +             if (available_v (&state) < n)
943 +               {
944 +                 state.nsrn = N_V_ARG_REG;
945 +                 avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
946 +                                                ty->size);
947 +               }
948 +             else
949 +               {
950 +                 switch (get_homogeneous_type (ty))
951 +                   {
952 +                   case FFI_TYPE_FLOAT:
953 +                     {
954 +                       /* Eeek! We need a pointer to the structure,
955 +                          however the homogeneous float elements are
956 +                          being passed in individual S registers,
957 +                          therefore the structure is not represented as
958 +                          a contiguous sequence of bytes in our saved
959 +                          register context. We need to fake up a copy
960 +                          of the structure layed out in memory
961 +                          correctly. The fake can be tossed once the
962 +                          closure function has returned hence alloca()
963 +                          is sufficient. */
964 +                       int j;
965 +                       UINT32 *p = avalue[i] = alloca (ty->size);
966 +                       for (j = 0; j < element_count (ty); j++)
967 +                         memcpy (&p[j],
968 +                                 allocate_to_s (context, &state),
969 +                                 sizeof (*p));
970 +                       break;
971 +                     }
972 +
973 +                   case FFI_TYPE_DOUBLE:
974 +                     {
975 +                       /* Eeek! We need a pointer to the structure,
976 +                          however the homogeneous float elements are
977 +                          being passed in individual S registers,
978 +                          therefore the structure is not represented as
979 +                          a contiguous sequence of bytes in our saved
980 +                          register context. We need to fake up a copy
981 +                          of the structure layed out in memory
982 +                          correctly. The fake can be tossed once the
983 +                          closure function has returned hence alloca()
984 +                          is sufficient. */
985 +                       int j;
986 +                       UINT64 *p = avalue[i] = alloca (ty->size);
987 +                       for (j = 0; j < element_count (ty); j++)
988 +                         memcpy (&p[j],
989 +                                 allocate_to_d (context, &state),
990 +                                 sizeof (*p));
991 +                       break;
992 +                     }
993 +
994 +                   case FFI_TYPE_LONGDOUBLE:
995 +                         memcpy (&avalue[i],
996 +                                 allocate_to_v (context, &state),
997 +                                 sizeof (*avalue));
998 +                     break;
999 +
1000 +                   default:
1001 +                     FFI_ASSERT (0);
1002 +                     break;
1003 +                   }
1004 +               }
1005 +           }
1006 +         else if (ty->size > 16)
1007 +           {
1008 +             /* Replace Composite type of size greater than 16 with a
1009 +                pointer.  */
1010 +             memcpy (&avalue[i],
1011 +                     allocate_to_register_or_stack (context, stack,
1012 +                                                    &state, FFI_TYPE_POINTER),
1013 +                     sizeof (avalue[i]));
1014 +           }
1015 +         else if (available_x (&state) >= (ty->size + 7) / 8)
1016 +           {
1017 +             avalue[i] = get_x_addr (context, state.ngrn);
1018 +             state.ngrn += (ty->size + 7) / 8;
1019 +           }
1020 +         else
1021 +           {
1022 +             state.ngrn = N_X_ARG_REG;
1023 +
1024 +             avalue[i] = allocate_to_stack (&state, stack, ty->alignment,
1025 +                                            ty->size);
1026 +           }
1027 +         break;
1028 +
1029 +       default:
1030 +         FFI_ASSERT (0);
1031 +         break;
1032 +       }
1033 +    }
1034 +
1035 +  /* Figure out where the return value will be passed, either in
1036 +     registers or in a memory block allocated by the caller and passed
1037 +     in x8.  */
1038 +
1039 +  if (is_register_candidate (cif->rtype))
1040 +    {
1041 +      /* Register candidates are *always* returned in registers. */
1042 +
1043 +      /* Allocate a scratchpad for the return value, we will let the
1044 +         callee scrible the result into the scratch pad then move the
1045 +         contents into the appropriate return value location for the
1046 +         call convention.  */
1047 +      rvalue = alloca (cif->rtype->size);
1048 +      (closure->fun) (cif, rvalue, avalue, closure->user_data);
1049 +
1050 +      /* Copy the return value into the call context so that it is returned
1051 +         as expected to our caller.  */
1052 +      switch (cif->rtype->type)
1053 +        {
1054 +        case FFI_TYPE_VOID:
1055 +          break;
1056 +
1057 +        case FFI_TYPE_UINT8:
1058 +        case FFI_TYPE_UINT16:
1059 +        case FFI_TYPE_UINT32:
1060 +        case FFI_TYPE_POINTER:
1061 +        case FFI_TYPE_UINT64:
1062 +        case FFI_TYPE_SINT8:
1063 +        case FFI_TYPE_SINT16:
1064 +        case FFI_TYPE_INT:
1065 +        case FFI_TYPE_SINT32:
1066 +        case FFI_TYPE_SINT64:
1067 +        case FFI_TYPE_FLOAT:
1068 +        case FFI_TYPE_DOUBLE:
1069 +        case FFI_TYPE_LONGDOUBLE:
1070 +         {
1071 +           void *addr = get_basic_type_addr (cif->rtype->type, context, 0);
1072 +           copy_basic_type (addr, rvalue, cif->rtype->type);
1073 +            break;
1074 +         }
1075 +        case FFI_TYPE_STRUCT:
1076 +          if (is_hfa (cif->rtype))
1077 +           {
1078 +             int i;
1079 +             unsigned short type = get_homogeneous_type (cif->rtype);
1080 +             unsigned elems = element_count (cif->rtype);
1081 +             for (i = 0; i < elems; i++)
1082 +               {
1083 +                 void *reg = get_basic_type_addr (type, context, i);
1084 +                 copy_basic_type (reg, rvalue, type);
1085 +                 rvalue += get_basic_type_size (type);
1086 +               }
1087 +           }
1088 +          else if ((cif->rtype->size + 7) / 8 < N_X_ARG_REG)
1089 +            {
1090 +              unsigned size = ALIGN (cif->rtype->size, sizeof (UINT64)) ;
1091 +              memcpy (get_x_addr (context, 0), rvalue, size);
1092 +            }
1093 +          else
1094 +            {
1095 +              FFI_ASSERT (0);
1096 +            }
1097 +          break;
1098 +        default:
1099 +          FFI_ASSERT (0);
1100 +          break;
1101 +        }
1102 +    }
1103 +  else
1104 +    {
1105 +      memcpy (&rvalue, get_x_addr (context, 8), sizeof (UINT64));
1106 +      (closure->fun) (cif, rvalue, avalue, closure->user_data);
1107 +    }
1108 +}
1109 +
1110 Index: libffi/src/aarch64/ffitarget.h
1111 ===================================================================
1112 --- /dev/null
1113 +++ libffi/src/aarch64/ffitarget.h
1114 @@ -0,0 +1,59 @@
1115 +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
1116 +
1117 +Permission is hereby granted, free of charge, to any person obtaining
1118 +a copy of this software and associated documentation files (the
1119 +``Software''), to deal in the Software without restriction, including
1120 +without limitation the rights to use, copy, modify, merge, publish,
1121 +distribute, sublicense, and/or sell copies of the Software, and to
1122 +permit persons to whom the Software is furnished to do so, subject to
1123 +the following conditions:
1124 +
1125 +The above copyright notice and this permission notice shall be
1126 +included in all copies or substantial portions of the Software.
1127 +
1128 +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
1129 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1130 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1131 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1132 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1133 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1134 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
1135 +
1136 +#ifndef LIBFFI_TARGET_H
1137 +#define LIBFFI_TARGET_H
1138 +
1139 +#ifndef LIBFFI_H
1140 +#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
1141 +#endif
1142 +
1143 +#ifndef LIBFFI_ASM
1144 +typedef unsigned long ffi_arg;
1145 +typedef signed long ffi_sarg;
1146 +
1147 +typedef enum ffi_abi
1148 +  {
1149 +    FFI_FIRST_ABI = 0,
1150 +    FFI_SYSV,
1151 +    FFI_LAST_ABI,
1152 +    FFI_DEFAULT_ABI = FFI_SYSV
1153 +  } ffi_abi;
1154 +#endif
1155 +
1156 +/* ---- Definitions for closures ----------------------------------------- */
1157 +
1158 +#define FFI_CLOSURES 1
1159 +#define FFI_TRAMPOLINE_SIZE 36
1160 +#define FFI_NATIVE_RAW_API 0
1161 +
1162 +/* ---- Internal ---- */
1163 +
1164 +
1165 +#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_flags
1166 +
1167 +#define AARCH64_FFI_WITH_V_BIT 0
1168 +
1169 +#define AARCH64_N_XREG 32
1170 +#define AARCH64_N_VREG 32
1171 +#define AARCH64_CALL_CONTEXT_SIZE (AARCH64_N_XREG * 8 + AARCH64_N_VREG * 16)
1172 +
1173 +#endif
1174 Index: libffi/src/aarch64/sysv.S
1175 ===================================================================
1176 --- /dev/null
1177 +++ libffi/src/aarch64/sysv.S
1178 @@ -0,0 +1,307 @@
1179 +/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
1180 +
1181 +Permission is hereby granted, free of charge, to any person obtaining
1182 +a copy of this software and associated documentation files (the
1183 +``Software''), to deal in the Software without restriction, including
1184 +without limitation the rights to use, copy, modify, merge, publish,
1185 +distribute, sublicense, and/or sell copies of the Software, and to
1186 +permit persons to whom the Software is furnished to do so, subject to
1187 +the following conditions:
1188 +
1189 +The above copyright notice and this permission notice shall be
1190 +included in all copies or substantial portions of the Software.
1191 +
1192 +THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
1193 +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1194 +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
1195 +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
1196 +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1197 +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1198 +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
1199 +
1200 +#define LIBFFI_ASM
1201 +#include <fficonfig.h>
1202 +#include <ffi.h>
1203 +
1204 +#define cfi_adjust_cfa_offset(off)     .cfi_adjust_cfa_offset off
1205 +#define cfi_rel_offset(reg, off)       .cfi_rel_offset reg, off
1206 +#define cfi_restore(reg)               .cfi_restore reg
1207 +#define cfi_def_cfa_register(reg)      .cfi_def_cfa_register reg
1208 +
1209 +        .text
1210 +        .globl ffi_call_SYSV
1211 +        .type ffi_call_SYSV, #function
1212 +
1213 +/* ffi_call_SYSV()
1214 +
1215 +   Create a stack frame, setup an argument context, call the callee
1216 +   and extract the result.
1217 +
1218 +   The maximum required argument stack size is provided,
1219 +   ffi_call_SYSV() allocates that stack space then calls the
1220 +   prepare_fn to populate register context and stack.  The
1221 +   argument passing registers are loaded from the register
1222 +   context and the callee called, on return the register passing
1223 +   register are saved back to the context.  Our caller will
1224 +   extract the return value from the final state of the saved
1225 +   register context.
1226 +
1227 +   Prototype:
1228 +
1229 +   extern unsigned
1230 +   ffi_call_SYSV (void (*)(struct call_context *context, unsigned char *,
1231 +                          extended_cif *),
1232 +                  struct call_context *context,
1233 +                  extended_cif *,
1234 +                  unsigned required_stack_size,
1235 +                  void (*fn)(void));
1236 +
1237 +   Therefore on entry we have:
1238 +
1239 +   x0 prepare_fn
1240 +   x1 &context
1241 +   x2 &ecif
1242 +   x3 bytes
1243 +   x4 fn
1244 +
1245 +   This function uses the following stack frame layout:
1246 +
1247 +   ==
1248 +                saved x30(lr)
1249 +   x29(fp)->    saved x29(fp)
1250 +                saved x24
1251 +                saved x23
1252 +                saved x22
1253 +   sp'    ->    saved x21
1254 +                ...
1255 +   sp     ->    (constructed callee stack arguments)
1256 +   ==
1257 +
1258 +   Voila! */
1259 +
1260 +#define ffi_call_SYSV_FS (8 * 4)
1261 +
1262 +        .cfi_startproc
1263 +ffi_call_SYSV:
1264 +        stp     x29, x30, [sp, #-16]!
1265 +       cfi_adjust_cfa_offset (16)
1266 +        cfi_rel_offset (x29, 0)
1267 +        cfi_rel_offset (x30, 8)
1268 +
1269 +        mov     x29, sp
1270 +       cfi_def_cfa_register (x29)
1271 +        sub     sp, sp, #ffi_call_SYSV_FS
1272 +
1273 +        stp     x21, x22, [sp, 0]
1274 +        cfi_rel_offset (x21, 0 - ffi_call_SYSV_FS)
1275 +        cfi_rel_offset (x22, 8 - ffi_call_SYSV_FS)
1276 +
1277 +        stp     x23, x24, [sp, 16]
1278 +        cfi_rel_offset (x23, 16 - ffi_call_SYSV_FS)
1279 +        cfi_rel_offset (x24, 24 - ffi_call_SYSV_FS)
1280 +
1281 +        mov     x21, x1
1282 +        mov     x22, x2
1283 +        mov     x24, x4
1284 +
1285 +        /* Allocate the stack space for the actual arguments, many
1286 +           arguments will be passed in registers, but we assume
1287 +           worst case and allocate sufficient stack for ALL of
1288 +           the arguments.  */
1289 +        sub     sp, sp, x3
1290 +
1291 +        /* unsigned (*prepare_fn) (struct call_context *context,
1292 +                                  unsigned char *stack, extended_cif *ecif);
1293 +        */
1294 +        mov     x23, x0
1295 +        mov     x0, x1
1296 +        mov     x1, sp
1297 +        /* x2 already in place */
1298 +        blr     x23
1299 +
1300 +        /* Preserve the flags returned.  */
1301 +        mov     x23, x0
1302 +
1303 +        /* Figure out if we should touch the vector registers.  */
1304 +        tbz     x23, #AARCH64_FFI_WITH_V_BIT, 1f
1305 +
1306 +        /* Load the vector argument passing registers.  */
1307 +        ldp     q0, q1, [x21, #8*32 +  0]
1308 +        ldp     q2, q3, [x21, #8*32 + 32]
1309 +        ldp     q4, q5, [x21, #8*32 + 64]
1310 +        ldp     q6, q7, [x21, #8*32 + 96]
1311 +1:
1312 +        /* Load the core argument passing registers.  */
1313 +        ldp     x0, x1, [x21,  #0]
1314 +        ldp     x2, x3, [x21, #16]
1315 +        ldp     x4, x5, [x21, #32]
1316 +        ldp     x6, x7, [x21, #48]
1317 +
1318 +        /* Don't forget x8 which may be holding the address of a return buffer.
1319 +        */
1320 +        ldr     x8,     [x21, #8*8]
1321 +
1322 +        blr     x24
1323 +
1324 +        /* Save the core argument passing registers.  */
1325 +        stp     x0, x1, [x21,  #0]
1326 +        stp     x2, x3, [x21, #16]
1327 +        stp     x4, x5, [x21, #32]
1328 +        stp     x6, x7, [x21, #48]
1329 +
1330 +        /* Note nothing useful ever comes back in x8!  */
1331 +
1332 +        /* Figure out if we should touch the vector registers.  */
1333 +        tbz     x23, #AARCH64_FFI_WITH_V_BIT, 1f
1334 +
1335 +        /* Save the vector argument passing registers.  */
1336 +        stp     q0, q1, [x21, #8*32 + 0]
1337 +        stp     q2, q3, [x21, #8*32 + 32]
1338 +        stp     q4, q5, [x21, #8*32 + 64]
1339 +        stp     q6, q7, [x21, #8*32 + 96]
1340 +1:
1341 +        /* All done, unwind our stack frame.  */
1342 +        ldp     x21, x22, [x29,  # - ffi_call_SYSV_FS]
1343 +        cfi_restore (x21)
1344 +        cfi_restore (x22)
1345 +
1346 +        ldp     x23, x24, [x29,  # - ffi_call_SYSV_FS + 16]
1347 +        cfi_restore (x23)
1348 +        cfi_restore (x24)
1349 +
1350 +        mov     sp, x29
1351 +       cfi_def_cfa_register (sp)
1352 +
1353 +        ldp     x29, x30, [sp], #16
1354 +       cfi_adjust_cfa_offset (-16)
1355 +        cfi_restore (x29)
1356 +        cfi_restore (x30)
1357 +
1358 +        ret
1359 +
1360 +        .cfi_endproc
1361 +        .size ffi_call_SYSV, .-ffi_call_SYSV
1362 +
1363 +#define ffi_closure_SYSV_FS (8 * 2 + AARCH64_CALL_CONTEXT_SIZE)
1364 +
1365 +/* ffi_closure_SYSV
1366 +
1367 +   Closure invocation glue. This is the low level code invoked directly by
1368 +   the closure trampoline to setup and call a closure.
1369 +
1370 +   On entry x17 points to a struct trampoline_data, x16 has been clobbered
1371 +   all other registers are preserved.
1372 +
1373 +   We allocate a call context and save the argument passing registers,
1374 +   then invoked the generic C ffi_closure_SYSV_inner() function to do all
1375 +   the real work, on return we load the result passing registers back from
1376 +   the call context.
1377 +
1378 +   On entry
1379 +
1380 +   extern void
1381 +   ffi_closure_SYSV (struct trampoline_data *);
1382 +
1383 +   struct trampoline_data
1384 +   {
1385 +        UINT64 *ffi_closure;
1386 +        UINT64 flags;
1387 +   };
1388 +
1389 +   This function uses the following stack frame layout:
1390 +
1391 +   ==
1392 +                saved x30(lr)
1393 +   x29(fp)->    saved x29(fp)
1394 +                saved x22
1395 +                saved x21
1396 +                ...
1397 +   sp     ->    call_context
1398 +   ==
1399 +
1400 +   Voila!  */
1401 +
1402 +        .text
1403 +        .globl ffi_closure_SYSV
1404 +        .cfi_startproc
1405 +ffi_closure_SYSV:
1406 +        stp     x29, x30, [sp, #-16]!
1407 +       cfi_adjust_cfa_offset (16)
1408 +        cfi_rel_offset (x29, 0)
1409 +        cfi_rel_offset (x30, 8)
1410 +
1411 +        mov     x29, sp
1412 +
1413 +        sub     sp, sp, #ffi_closure_SYSV_FS
1414 +       cfi_adjust_cfa_offset (ffi_closure_SYSV_FS)
1415 +
1416 +        stp     x21, x22, [x29, #-16]
1417 +        cfi_rel_offset (x21, 0)
1418 +        cfi_rel_offset (x22, 8)
1419 +
1420 +        /* Load x21 with &call_context.  */
1421 +        mov     x21, sp
1422 +        /* Preserve our struct trampoline_data *  */
1423 +        mov     x22, x17
1424 +
1425 +        /* Save the rest of the argument passing registers.  */
1426 +        stp     x0, x1, [x21, #0]
1427 +        stp     x2, x3, [x21, #16]
1428 +        stp     x4, x5, [x21, #32]
1429 +        stp     x6, x7, [x21, #48]
1430 +        /* Don't forget we may have been given a result scratch pad address.
1431 +        */
1432 +        str     x8,     [x21, #64]
1433 +
1434 +        /* Figure out if we should touch the vector registers.  */
1435 +        ldr     x0, [x22, #8]
1436 +        tbz     x0, #AARCH64_FFI_WITH_V_BIT, 1f
1437 +
1438 +        /* Save the argument passing vector registers.  */
1439 +        stp     q0, q1, [x21, #8*32 + 0]
1440 +        stp     q2, q3, [x21, #8*32 + 32]
1441 +        stp     q4, q5, [x21, #8*32 + 64]
1442 +        stp     q6, q7, [x21, #8*32 + 96]
1443 +1:
1444 +        /* Load &ffi_closure..  */
1445 +        ldr     x0, [x22, #0]
1446 +        mov     x1, x21
1447 +        /* Compute the location of the stack at the point that the
1448 +           trampoline was called.  */
1449 +        add     x2, x29, #16
1450 +
1451 +        bl      ffi_closure_SYSV_inner
1452 +
1453 +        /* Figure out if we should touch the vector registers.  */
1454 +        ldr     x0, [x22, #8]
1455 +        tbz     x0, #AARCH64_FFI_WITH_V_BIT, 1f
1456 +
1457 +        /* Load the result passing vector registers.  */
1458 +        ldp     q0, q1, [x21, #8*32 + 0]
1459 +        ldp     q2, q3, [x21, #8*32 + 32]
1460 +        ldp     q4, q5, [x21, #8*32 + 64]
1461 +        ldp     q6, q7, [x21, #8*32 + 96]
1462 +1:
1463 +        /* Load the result passing core registers.  */
1464 +        ldp     x0, x1, [x21,  #0]
1465 +        ldp     x2, x3, [x21, #16]
1466 +        ldp     x4, x5, [x21, #32]
1467 +        ldp     x6, x7, [x21, #48]
1468 +        /* Note nothing usefull is returned in x8.  */
1469 +
1470 +        /* We are done, unwind our frame.  */
1471 +        ldp     x21, x22, [x29,  #-16]
1472 +        cfi_restore (x21)
1473 +        cfi_restore (x22)
1474 +
1475 +        mov     sp, x29
1476 +       cfi_adjust_cfa_offset (-ffi_closure_SYSV_FS)
1477 +
1478 +        ldp     x29, x30, [sp], #16
1479 +       cfi_adjust_cfa_offset (-16)
1480 +        cfi_restore (x29)
1481 +        cfi_restore (x30)
1482 +
1483 +        ret
1484 +        .cfi_endproc
1485 +        .size ffi_closure_SYSV, .-ffi_closure_SYSV
1486 Index: libffi/testsuite/lib/libffi.exp
1487 ===================================================================
1488 --- libffi.orig/testsuite/lib/libffi.exp
1489 +++ libffi/testsuite/lib/libffi.exp
1490 @@ -203,6 +203,10 @@ proc libffi_target_compile { source dest
1491  
1492      lappend options "libs= -lffi"
1493  
1494 +    if { [string match "aarch64*-*-linux*" $target_triplet] } {
1495 +       lappend options "libs= -lpthread"
1496 +    }
1497 +
1498      verbose "options: $options"
1499      return [target_compile $source $dest $type $options]
1500  }
1501 Index: libffi/testsuite/libffi.call/cls_struct_va1.c
1502 ===================================================================
1503 --- /dev/null
1504 +++ libffi/testsuite/libffi.call/cls_struct_va1.c
1505 @@ -0,0 +1,114 @@
1506 +/* Area:               ffi_call, closure_call
1507 +   Purpose:            Test doubles passed in variable argument lists.
1508 +   Limitations:        none.
1509 +   PR:                 none.
1510 +   Originator: Blake Chaffin 6/6/2007   */
1511 +
1512 +/* { dg-do run } */
1513 +/* { dg-output "" { xfail avr32*-*-* } } */
1514 +#include "ffitest.h"
1515 +
1516 +struct small_tag
1517 +{
1518 +  unsigned char a;
1519 +  unsigned char b;
1520 +};
1521 +
1522 +struct large_tag
1523 +{
1524 +  unsigned a;
1525 +  unsigned b;
1526 +  unsigned c;
1527 +  unsigned d;
1528 +  unsigned e;
1529 +};
1530 +
1531 +static void
1532 +test_fn (ffi_cif* cif __UNUSED__, void* resp,
1533 +        void** args, void* userdata __UNUSED__)
1534 +{
1535 +  int n = *(int*)args[0];
1536 +  struct small_tag s1 = * (struct small_tag *) args[1];
1537 +  struct large_tag l1 = * (struct large_tag *) args[2];
1538 +  struct small_tag s2 = * (struct small_tag *) args[3];
1539 +
1540 +  printf ("%d %d %d %d %d %d %d %d %d %d\n", n, s1.a, s1.b,
1541 +         l1.a, l1.b, l1.c, l1.d, l1.e,
1542 +         s2.a, s2.b);
1543 +  * (int*) resp = 42;
1544 +}
1545 +
1546 +int
1547 +main (void)
1548 +{
1549 +  ffi_cif cif;
1550 +  void *code;
1551 +  ffi_closure *pcl = ffi_closure_alloc (sizeof (ffi_closure), &code);
1552 +  ffi_type* arg_types[5];
1553 +
1554 +  ffi_arg res = 0;
1555 +
1556 +  ffi_type s_type;
1557 +  ffi_type *s_type_elements[3];
1558 +
1559 +  ffi_type l_type;
1560 +  ffi_type *l_type_elements[6];
1561 +
1562 +  struct small_tag s1;
1563 +  struct small_tag s2;
1564 +  struct large_tag l1;
1565 +
1566 +  int si;
1567 +
1568 +  s_type.size = 0;
1569 +  s_type.alignment = 0;
1570 +  s_type.type = FFI_TYPE_STRUCT;
1571 +  s_type.elements = s_type_elements;
1572 +
1573 +  s_type_elements[0] = &ffi_type_uchar;
1574 +  s_type_elements[1] = &ffi_type_uchar;
1575 +  s_type_elements[2] = NULL;
1576 +
1577 +  l_type.size = 0;
1578 +  l_type.alignment = 0;
1579 +  l_type.type = FFI_TYPE_STRUCT;
1580 +  l_type.elements = l_type_elements;
1581 +
1582 +  l_type_elements[0] = &ffi_type_uint;
1583 +  l_type_elements[1] = &ffi_type_uint;
1584 +  l_type_elements[2] = &ffi_type_uint;
1585 +  l_type_elements[3] = &ffi_type_uint;
1586 +  l_type_elements[4] = &ffi_type_uint;
1587 +  l_type_elements[5] = NULL;
1588 +
1589 +  arg_types[0] = &ffi_type_sint;
1590 +  arg_types[1] = &s_type;
1591 +  arg_types[2] = &l_type;
1592 +  arg_types[3] = &s_type;
1593 +  arg_types[4] = NULL;
1594 +
1595 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint,
1596 +                        arg_types) == FFI_OK);
1597 +
1598 +  si = 4;
1599 +  s1.a = 5;
1600 +  s1.b = 6;
1601 +
1602 +  s2.a = 20;
1603 +  s2.b = 21;
1604 +
1605 +  l1.a = 10;
1606 +  l1.b = 11;
1607 +  l1.c = 12;
1608 +  l1.d = 13;
1609 +  l1.e = 14;
1610 +
1611 +  CHECK(ffi_prep_closure_loc(pcl, &cif, test_fn, NULL, code) == FFI_OK);
1612 +
1613 +  res = ((int (*)(int, ...))(code))(si, s1, l1, s2);
1614 +  // { dg-output "4 5 6 10 11 12 13 14 20 21" }
1615 +  printf("res: %d\n", (int) res);
1616 +  // { dg-output "\nres: 42" }
1617 +
1618 +  exit(0);
1619 +}
1620 Index: libffi/testsuite/libffi.call/cls_uchar_va.c
1621 ===================================================================
1622 --- /dev/null
1623 +++ libffi/testsuite/libffi.call/cls_uchar_va.c
1624 @@ -0,0 +1,44 @@
1625 +/* Area:       closure_call
1626 +   Purpose:    Test anonymous unsigned char argument.
1627 +   Limitations:        none.
1628 +   PR:         none.
1629 +   Originator: ARM Ltd. */
1630 +
1631 +/* { dg-do run } */
1632 +#include "ffitest.h"
1633 +
1634 +typedef unsigned char T;
1635 +
1636 +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
1637 +                        void* userdata __UNUSED__)
1638 + {
1639 +   *(T *)resp = *(T *)args[0];
1640 +
1641 +   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
1642 + }
1643 +
1644 +typedef T (*cls_ret_T)(T, ...);
1645 +
1646 +int main (void)
1647 +{
1648 +  ffi_cif cif;
1649 +  void *code;
1650 +  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
1651 +  ffi_type * cl_arg_types[3];
1652 +  T res;
1653 +
1654 +  cl_arg_types[0] = &ffi_type_uchar;
1655 +  cl_arg_types[1] = &ffi_type_uchar;
1656 +  cl_arg_types[2] = NULL;
1657 +
1658 +  /* Initialize the cif */
1659 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
1660 +                        &ffi_type_uchar, cl_arg_types) == FFI_OK);
1661 +
1662 +  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
1663 +  res = ((((cls_ret_T)code)(67, 4)));
1664 +  /* { dg-output "67: 67 4" } */
1665 +  printf("res: %d\n", res);
1666 +  /* { dg-output "\nres: 67" } */
1667 +  exit(0);
1668 +}
1669 Index: libffi/testsuite/libffi.call/cls_uint_va.c
1670 ===================================================================
1671 --- /dev/null
1672 +++ libffi/testsuite/libffi.call/cls_uint_va.c
1673 @@ -0,0 +1,45 @@
1674 +/* Area:       closure_call
1675 +   Purpose:    Test anonymous unsigned int argument.
1676 +   Limitations:        none.
1677 +   PR:         none.
1678 +   Originator: ARM Ltd. */
1679 +
1680 +/* { dg-do run } */
1681 +
1682 +#include "ffitest.h"
1683 +
1684 +typedef unsigned int T;
1685 +
1686 +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
1687 +                        void* userdata __UNUSED__)
1688 + {
1689 +   *(T *)resp = *(T *)args[0];
1690 +
1691 +   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
1692 + }
1693 +
1694 +typedef T (*cls_ret_T)(T, ...);
1695 +
1696 +int main (void)
1697 +{
1698 +  ffi_cif cif;
1699 +  void *code;
1700 +  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
1701 +  ffi_type * cl_arg_types[3];
1702 +  T res;
1703 +
1704 +  cl_arg_types[0] = &ffi_type_uint;
1705 +  cl_arg_types[1] = &ffi_type_uint;
1706 +  cl_arg_types[2] = NULL;
1707 +
1708 +  /* Initialize the cif */
1709 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
1710 +                        &ffi_type_uint, cl_arg_types) == FFI_OK);
1711 +
1712 +  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
1713 +  res = ((((cls_ret_T)code)(67, 4)));
1714 +  /* { dg-output "67: 67 4" } */
1715 +  printf("res: %d\n", res);
1716 +  /* { dg-output "\nres: 67" } */
1717 +  exit(0);
1718 +}
1719 Index: libffi/testsuite/libffi.call/cls_ulong_va.c
1720 ===================================================================
1721 --- /dev/null
1722 +++ libffi/testsuite/libffi.call/cls_ulong_va.c
1723 @@ -0,0 +1,45 @@
1724 +/* Area:       closure_call
1725 +   Purpose:    Test anonymous unsigned long argument.
1726 +   Limitations:        none.
1727 +   PR:         none.
1728 +   Originator: ARM Ltd. */
1729 +
1730 +/* { dg-do run } */
1731 +
1732 +#include "ffitest.h"
1733 +
1734 +typedef unsigned long T;
1735 +
1736 +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
1737 +                        void* userdata __UNUSED__)
1738 + {
1739 +   *(T *)resp = *(T *)args[0];
1740 +
1741 +   printf("%ld: %ld %ld\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
1742 + }
1743 +
1744 +typedef T (*cls_ret_T)(T, ...);
1745 +
1746 +int main (void)
1747 +{
1748 +  ffi_cif cif;
1749 +  void *code;
1750 +  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
1751 +  ffi_type * cl_arg_types[3];
1752 +  T res;
1753 +
1754 +  cl_arg_types[0] = &ffi_type_ulong;
1755 +  cl_arg_types[1] = &ffi_type_ulong;
1756 +  cl_arg_types[2] = NULL;
1757 +
1758 +  /* Initialize the cif */
1759 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
1760 +                        &ffi_type_ulong, cl_arg_types) == FFI_OK);
1761 +
1762 +  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
1763 +  res = ((((cls_ret_T)code)(67, 4)));
1764 +  /* { dg-output "67: 67 4" } */
1765 +  printf("res: %ld\n", res);
1766 +  /* { dg-output "\nres: 67" } */
1767 +  exit(0);
1768 +}
1769 Index: libffi/testsuite/libffi.call/cls_ushort_va.c
1770 ===================================================================
1771 --- /dev/null
1772 +++ libffi/testsuite/libffi.call/cls_ushort_va.c
1773 @@ -0,0 +1,44 @@
1774 +/* Area:       closure_call
1775 +   Purpose:    Test anonymous unsigned short argument.
1776 +   Limitations:        none.
1777 +   PR:         none.
1778 +   Originator: ARM Ltd. */
1779 +
1780 +/* { dg-do run } */
1781 +#include "ffitest.h"
1782 +
1783 +typedef unsigned short T;
1784 +
1785 +static void cls_ret_T_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
1786 +                        void* userdata __UNUSED__)
1787 + {
1788 +   *(T *)resp = *(T *)args[0];
1789 +
1790 +   printf("%d: %d %d\n", *(T *)resp, *(T *)args[0], *(T *)args[1]);
1791 + }
1792 +
1793 +typedef T (*cls_ret_T)(T, ...);
1794 +
1795 +int main (void)
1796 +{
1797 +  ffi_cif cif;
1798 +  void *code;
1799 +  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
1800 +  ffi_type * cl_arg_types[3];
1801 +  T res;
1802 +
1803 +  cl_arg_types[0] = &ffi_type_ushort;
1804 +  cl_arg_types[1] = &ffi_type_ushort;
1805 +  cl_arg_types[2] = NULL;
1806 +
1807 +  /* Initialize the cif */
1808 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 2,
1809 +                        &ffi_type_ushort, cl_arg_types) == FFI_OK);
1810 +
1811 +  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ret_T_fn, NULL, code)  == FFI_OK);
1812 +  res = ((((cls_ret_T)code)(67, 4)));
1813 +  /* { dg-output "67: 67 4" } */
1814 +  printf("res: %d\n", res);
1815 +  /* { dg-output "\nres: 67" } */
1816 +  exit(0);
1817 +}
1818 Index: libffi/testsuite/libffi.call/nested_struct11.c
1819 ===================================================================
1820 --- /dev/null
1821 +++ libffi/testsuite/libffi.call/nested_struct11.c
1822 @@ -0,0 +1,121 @@
1823 +/* Area:       ffi_call, closure_call
1824 +   Purpose:    Check parameter passing with nested structs
1825 +               of a single type.  This tests the special cases
1826 +               for homogenous floating-point aggregates in the
1827 +               AArch64 PCS.
1828 +   Limitations:        none.
1829 +   PR:         none.
1830 +   Originator:  ARM Ltd.  */
1831 +
1832 +/* { dg-do run } */
1833 +#include "ffitest.h"
1834 +
1835 +typedef struct A {
1836 +  float a_x;
1837 +  float a_y;
1838 +} A;
1839 +
1840 +typedef struct B {
1841 +  float b_x;
1842 +  float b_y;
1843 +} B;
1844 +
1845 +typedef struct C {
1846 +  A a;
1847 +  B b;
1848 +} C;
1849 +
1850 +static C C_fn (int x, int y, int z, C source, int i, int j, int k)
1851 +{
1852 +  C result;
1853 +  result.a.a_x = source.a.a_x;
1854 +  result.a.a_y = source.a.a_y;
1855 +  result.b.b_x = source.b.b_x;
1856 +  result.b.b_y = source.b.b_y;
1857 +
1858 +  printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k);
1859 +
1860 +  printf ("%.1f, %.1f, %.1f, %.1f, "
1861 +         "%.1f, %.1f, %.1f, %.1f\n",
1862 +         source.a.a_x, source.a.a_y,
1863 +         source.b.b_x, source.b.b_y,
1864 +         result.a.a_x, result.a.a_y,
1865 +         result.b.b_x, result.b.b_y);
1866 +
1867 +  return result;
1868 +}
1869 +
1870 +int main (void)
1871 +{
1872 +  ffi_cif cif;
1873 +
1874 +  ffi_type* struct_fields_source_a[3];
1875 +  ffi_type* struct_fields_source_b[3];
1876 +  ffi_type* struct_fields_source_c[3];
1877 +  ffi_type* arg_types[8];
1878 +
1879 +  ffi_type struct_type_a, struct_type_b, struct_type_c;
1880 +
1881 +  struct A source_fld_a = {1.0, 2.0};
1882 +  struct B source_fld_b = {4.0, 8.0};
1883 +  int k = 1;
1884 +
1885 +  struct C result;
1886 +  struct C source = {source_fld_a, source_fld_b};
1887 +
1888 +  struct_type_a.size = 0;
1889 +  struct_type_a.alignment = 0;
1890 +  struct_type_a.type = FFI_TYPE_STRUCT;
1891 +  struct_type_a.elements = struct_fields_source_a;
1892 +
1893 +  struct_type_b.size = 0;
1894 +  struct_type_b.alignment = 0;
1895 +  struct_type_b.type = FFI_TYPE_STRUCT;
1896 +  struct_type_b.elements = struct_fields_source_b;
1897 +
1898 +  struct_type_c.size = 0;
1899 +  struct_type_c.alignment = 0;
1900 +  struct_type_c.type = FFI_TYPE_STRUCT;
1901 +  struct_type_c.elements = struct_fields_source_c;
1902 +
1903 +  struct_fields_source_a[0] = &ffi_type_float;
1904 +  struct_fields_source_a[1] = &ffi_type_float;
1905 +  struct_fields_source_a[2] = NULL;
1906 +
1907 +  struct_fields_source_b[0] = &ffi_type_float;
1908 +  struct_fields_source_b[1] = &ffi_type_float;
1909 +  struct_fields_source_b[2] = NULL;
1910 +
1911 +  struct_fields_source_c[0] = &struct_type_a;
1912 +  struct_fields_source_c[1] = &struct_type_b;
1913 +  struct_fields_source_c[2] = NULL;
1914 +
1915 +  arg_types[0] = &ffi_type_sint32;
1916 +  arg_types[1] = &ffi_type_sint32;
1917 +  arg_types[2] = &ffi_type_sint32;
1918 +  arg_types[3] = &struct_type_c;
1919 +  arg_types[4] = &ffi_type_sint32;
1920 +  arg_types[5] = &ffi_type_sint32;
1921 +  arg_types[6] = &ffi_type_sint32;
1922 +  arg_types[7] = NULL;
1923 +
1924 +  void *args[7];
1925 +  args[0] = &k;
1926 +  args[1] = &k;
1927 +  args[2] = &k;
1928 +  args[3] = &source;
1929 +  args[4] = &k;
1930 +  args[5] = &k;
1931 +  args[6] = &k;
1932 +  CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c,
1933 +                      arg_types) == FFI_OK);
1934 +
1935 +  ffi_call (&cif, FFI_FN (C_fn), &result, args);
1936 +  /* { dg-output "1, 1, 1, 1, 1, 1\n" } */
1937 +  /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */
1938 +  CHECK (result.a.a_x == source.a.a_x);
1939 +  CHECK (result.a.a_y == source.a.a_y);
1940 +  CHECK (result.b.b_x == source.b.b_x);
1941 +  CHECK (result.b.b_y == source.b.b_y);
1942 +  exit (0);
1943 +}
1944 Index: libffi/testsuite/libffi.call/uninitialized.c
1945 ===================================================================
1946 --- /dev/null
1947 +++ libffi/testsuite/libffi.call/uninitialized.c
1948 @@ -0,0 +1,61 @@
1949 +/* { dg-do run } */
1950 +#include "ffitest.h"
1951 +
1952 +typedef struct
1953 +{
1954 +  unsigned char uc;
1955 +  double d;
1956 +  unsigned int ui;
1957 +} test_structure_1;
1958 +
1959 +static test_structure_1 struct1(test_structure_1 ts)
1960 +{
1961 +  ts.uc++;
1962 +  ts.d--;
1963 +  ts.ui++;
1964 +
1965 +  return ts;
1966 +}
1967 +
1968 +int main (void)
1969 +{
1970 +  ffi_cif cif;
1971 +  ffi_type *args[MAX_ARGS];
1972 +  void *values[MAX_ARGS];
1973 +  ffi_type ts1_type;
1974 +  ffi_type *ts1_type_elements[4];
1975 +
1976 +  memset(&cif, 1, sizeof(cif));
1977 +  ts1_type.size = 0;
1978 +  ts1_type.alignment = 0;
1979 +  ts1_type.type = FFI_TYPE_STRUCT;
1980 +  ts1_type.elements = ts1_type_elements;
1981 +  ts1_type_elements[0] = &ffi_type_uchar;
1982 +  ts1_type_elements[1] = &ffi_type_double;
1983 +  ts1_type_elements[2] = &ffi_type_uint;
1984 +  ts1_type_elements[3] = NULL;
1985 +
1986 +  test_structure_1 ts1_arg;
1987 +  /* This is a hack to get a properly aligned result buffer */
1988 +  test_structure_1 *ts1_result =
1989 +    (test_structure_1 *) malloc (sizeof(test_structure_1));
1990 +
1991 +  args[0] = &ts1_type;
1992 +  values[0] = &ts1_arg;
1993 +
1994 +  /* Initialize the cif */
1995 +  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
1996 +                    &ts1_type, args) == FFI_OK);
1997 +
1998 +  ts1_arg.uc = '\x01';
1999 +  ts1_arg.d = 3.14159;
2000 +  ts1_arg.ui = 555;
2001 +
2002 +  ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
2003 +
2004 +  CHECK(ts1_result->ui == 556);
2005 +  CHECK(ts1_result->d == 3.14159 - 1);
2006 +
2007 +  free (ts1_result);
2008 +  exit(0);
2009 +}
2010 Index: libffi/testsuite/libffi.call/va_1.c
2011 ===================================================================
2012 --- /dev/null
2013 +++ libffi/testsuite/libffi.call/va_1.c
2014 @@ -0,0 +1,196 @@
2015 +/* Area:               ffi_call
2016 +   Purpose:            Test passing struct in variable argument lists.
2017 +   Limitations:        none.
2018 +   PR:                 none.
2019 +   Originator:         ARM Ltd. */
2020 +
2021 +/* { dg-do run } */
2022 +/* { dg-output "" { xfail avr32*-*-* x86_64-*-*-* } } */
2023 +
2024 +#include "ffitest.h"
2025 +#include <stdarg.h>
2026 +
2027 +struct small_tag
2028 +{
2029 +  unsigned char a;
2030 +  unsigned char b;
2031 +};
2032 +
2033 +struct large_tag
2034 +{
2035 +  unsigned a;
2036 +  unsigned b;
2037 +  unsigned c;
2038 +  unsigned d;
2039 +  unsigned e;
2040 +};
2041 +
2042 +static int
2043 +test_fn (int n, ...)
2044 +{
2045 +  va_list ap;
2046 +  struct small_tag s1;
2047 +  struct small_tag s2;
2048 +  struct large_tag l;
2049 +  unsigned char uc;
2050 +  signed char sc;
2051 +  unsigned short us;
2052 +  signed short ss;
2053 +  unsigned int ui;
2054 +  signed int si;
2055 +  unsigned long ul;
2056 +  signed long sl;
2057 +  float f;
2058 +  double d;
2059 +
2060 +  va_start (ap, n);
2061 +  s1 = va_arg (ap, struct small_tag);
2062 +  l = va_arg (ap, struct large_tag);
2063 +  s2 = va_arg (ap, struct small_tag);
2064 +
2065 +  uc = va_arg (ap, unsigned);
2066 +  sc = va_arg (ap, signed);
2067 +
2068 +  us = va_arg (ap, unsigned);
2069 +  ss = va_arg (ap, signed);
2070 +
2071 +  ui = va_arg (ap, unsigned int);
2072 +  si = va_arg (ap, signed int);
2073 +
2074 +  ul = va_arg (ap, unsigned long);
2075 +  sl = va_arg (ap, signed long);
2076 +
2077 +  f = va_arg (ap, double);     /* C standard promotes float->double
2078 +                                  when anonymous */
2079 +  d = va_arg (ap, double);
2080 +
2081 +  printf ("%u %u %u %u %u %u %u %u %u uc=%u sc=%d %u %d %u %d %lu %ld %f %f\n",
2082 +         s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
2083 +         s2.a, s2.b,
2084 +         uc, sc,
2085 +         us, ss,
2086 +         ui, si,
2087 +         ul, sl,
2088 +         f, d);
2089 +  va_end (ap);
2090 +  return n + 1;
2091 +}
2092 +
2093 +int
2094 +main (void)
2095 +{
2096 +  ffi_cif cif;
2097 +  void* args[15];
2098 +  ffi_type* arg_types[15];
2099 +
2100 +  ffi_type s_type;
2101 +  ffi_type *s_type_elements[3];
2102 +
2103 +  ffi_type l_type;
2104 +  ffi_type *l_type_elements[6];
2105 +
2106 +  struct small_tag s1;
2107 +  struct small_tag s2;
2108 +  struct large_tag l1;
2109 +
2110 +  int n;
2111 +  int res;
2112 +
2113 +  unsigned char uc;
2114 +  signed char sc;
2115 +  unsigned short us;
2116 +  signed short ss;
2117 +  unsigned int ui;
2118 +  signed int si;
2119 +  unsigned long ul;
2120 +  signed long sl;
2121 +  double d1;
2122 +  double f1;
2123 +
2124 +  s_type.size = 0;
2125 +  s_type.alignment = 0;
2126 +  s_type.type = FFI_TYPE_STRUCT;
2127 +  s_type.elements = s_type_elements;
2128 +
2129 +  s_type_elements[0] = &ffi_type_uchar;
2130 +  s_type_elements[1] = &ffi_type_uchar;
2131 +  s_type_elements[2] = NULL;
2132 +
2133 +  l_type.size = 0;
2134 +  l_type.alignment = 0;
2135 +  l_type.type = FFI_TYPE_STRUCT;
2136 +  l_type.elements = l_type_elements;
2137 +
2138 +  l_type_elements[0] = &ffi_type_uint;
2139 +  l_type_elements[1] = &ffi_type_uint;
2140 +  l_type_elements[2] = &ffi_type_uint;
2141 +  l_type_elements[3] = &ffi_type_uint;
2142 +  l_type_elements[4] = &ffi_type_uint;
2143 +  l_type_elements[5] = NULL;
2144 +
2145 +  arg_types[0] = &ffi_type_sint;
2146 +  arg_types[1] = &s_type;
2147 +  arg_types[2] = &l_type;
2148 +  arg_types[3] = &s_type;
2149 +  arg_types[4] = &ffi_type_uint;
2150 +  arg_types[5] = &ffi_type_sint;
2151 +  arg_types[6] = &ffi_type_uint;
2152 +  arg_types[7] = &ffi_type_sint;
2153 +  arg_types[8] = &ffi_type_uint;
2154 +  arg_types[9] = &ffi_type_sint;
2155 +  arg_types[10] = &ffi_type_ulong;
2156 +  arg_types[11] = &ffi_type_slong;
2157 +  arg_types[12] = &ffi_type_double;
2158 +  arg_types[13] = &ffi_type_double;
2159 +  arg_types[14] = NULL;
2160 +
2161 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 14, &ffi_type_sint, arg_types) == FFI_OK);
2162 +
2163 +  s1.a = 5;
2164 +  s1.b = 6;
2165 +
2166 +  l1.a = 10;
2167 +  l1.b = 11;
2168 +  l1.c = 12;
2169 +  l1.d = 13;
2170 +  l1.e = 14;
2171 +
2172 +  s2.a = 7;
2173 +  s2.b = 8;
2174 +
2175 +  n = 41;
2176 +
2177 +  uc = 9;
2178 +  sc = 10;
2179 +  us = 11;
2180 +  ss = 12;
2181 +  ui = 13;
2182 +  si = 14;
2183 +  ul = 15;
2184 +  sl = 16;
2185 +  f1 = 2.12;
2186 +  d1 = 3.13;
2187 +
2188 +  args[0] = &n;
2189 +  args[1] = &s1;
2190 +  args[2] = &l1;
2191 +  args[3] = &s2;
2192 +  args[4] = &uc;
2193 +  args[5] = &sc;
2194 +  args[6] = &us;
2195 +  args[7] = &ss;
2196 +  args[8] = &ui;
2197 +  args[9] = &si;
2198 +  args[10] = &ul;
2199 +  args[11] = &sl;
2200 +  args[12] = &f1;
2201 +  args[13] = &d1;
2202 +  args[14] = NULL;
2203 +
2204 +  ffi_call(&cif, FFI_FN(test_fn), &res, args);
2205 +  /* { dg-output "5 6 10 11 12 13 14 7 8 uc=9 sc=10 11 12 13 14 15 16 2.120000 3.130000" } */
2206 +  printf("res: %d\n", (int) res);
2207 +  /* { dg-output "\nres: 42" } */
2208 +
2209 +  return 0;
2210 +}
2211 Index: libffi/testsuite/libffi.call/va_struct1.c
2212 ===================================================================
2213 --- /dev/null
2214 +++ libffi/testsuite/libffi.call/va_struct1.c
2215 @@ -0,0 +1,121 @@
2216 +/* Area:               ffi_call
2217 +   Purpose:            Test passing struct in variable argument lists.
2218 +   Limitations:        none.
2219 +   PR:                 none.
2220 +   Originator: ARM Ltd. */
2221 +
2222 +/* { dg-do run } */
2223 +/* { dg-output "" { xfail avr32*-*-* } } */
2224 +
2225 +#include "ffitest.h"
2226 +#include <stdarg.h>
2227 +
2228 +struct small_tag
2229 +{
2230 +  unsigned char a;
2231 +  unsigned char b;
2232 +};
2233 +
2234 +struct large_tag
2235 +{
2236 +  unsigned a;
2237 +  unsigned b;
2238 +  unsigned c;
2239 +  unsigned d;
2240 +  unsigned e;
2241 +};
2242 +
2243 +static int
2244 +test_fn (int n, ...)
2245 +{
2246 +  va_list ap;
2247 +  struct small_tag s1;
2248 +  struct small_tag s2;
2249 +  struct large_tag l;
2250 +
2251 +  va_start (ap, n);
2252 +  s1 = va_arg (ap, struct small_tag);
2253 +  l = va_arg (ap, struct large_tag);
2254 +  s2 = va_arg (ap, struct small_tag);
2255 +  printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
2256 +         s2.a, s2.b);
2257 +  va_end (ap);
2258 +  return n + 1;
2259 +}
2260 +
2261 +int
2262 +main (void)
2263 +{
2264 +  ffi_cif cif;
2265 +  void* args[5];
2266 +  ffi_type* arg_types[5];
2267 +
2268 +  ffi_type s_type;
2269 +  ffi_type *s_type_elements[3];
2270 +
2271 +  ffi_type l_type;
2272 +  ffi_type *l_type_elements[6];
2273 +
2274 +  struct small_tag s1;
2275 +  struct small_tag s2;
2276 +  struct large_tag l1;
2277 +
2278 +  int n;
2279 +  int res;
2280 +
2281 +  s_type.size = 0;
2282 +  s_type.alignment = 0;
2283 +  s_type.type = FFI_TYPE_STRUCT;
2284 +  s_type.elements = s_type_elements;
2285 +
2286 +  s_type_elements[0] = &ffi_type_uchar;
2287 +  s_type_elements[1] = &ffi_type_uchar;
2288 +  s_type_elements[2] = NULL;
2289 +
2290 +  l_type.size = 0;
2291 +  l_type.alignment = 0;
2292 +  l_type.type = FFI_TYPE_STRUCT;
2293 +  l_type.elements = l_type_elements;
2294 +
2295 +  l_type_elements[0] = &ffi_type_uint;
2296 +  l_type_elements[1] = &ffi_type_uint;
2297 +  l_type_elements[2] = &ffi_type_uint;
2298 +  l_type_elements[3] = &ffi_type_uint;
2299 +  l_type_elements[4] = &ffi_type_uint;
2300 +  l_type_elements[5] = NULL;
2301 +
2302 +  arg_types[0] = &ffi_type_sint;
2303 +  arg_types[1] = &s_type;
2304 +  arg_types[2] = &l_type;
2305 +  arg_types[3] = &s_type;
2306 +  arg_types[4] = NULL;
2307 +
2308 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &ffi_type_sint, arg_types) == FFI_OK);
2309 +
2310 +  s1.a = 5;
2311 +  s1.b = 6;
2312 +
2313 +  l1.a = 10;
2314 +  l1.b = 11;
2315 +  l1.c = 12;
2316 +  l1.d = 13;
2317 +  l1.e = 14;
2318 +
2319 +  s2.a = 7;
2320 +  s2.b = 8;
2321 +
2322 +  n = 41;
2323 +
2324 +  args[0] = &n;
2325 +  args[1] = &s1;
2326 +  args[2] = &l1;
2327 +  args[3] = &s2;
2328 +  args[4] = NULL;
2329 +
2330 +  ffi_call(&cif, FFI_FN(test_fn), &res, args);
2331 +  /* { dg-output "5 6 10 11 12 13 14 7 8" } */
2332 +  printf("res: %d\n", (int) res);
2333 +  /* { dg-output "\nres: 42" } */
2334 +
2335 +  return 0;
2336 +}
2337 Index: libffi/testsuite/libffi.call/va_struct2.c
2338 ===================================================================
2339 --- /dev/null
2340 +++ libffi/testsuite/libffi.call/va_struct2.c
2341 @@ -0,0 +1,123 @@
2342 +/* Area:               ffi_call
2343 +   Purpose:            Test passing struct in variable argument lists.
2344 +   Limitations:        none.
2345 +   PR:                 none.
2346 +   Originator: ARM Ltd. */
2347 +
2348 +/* { dg-do run } */
2349 +/* { dg-output "" { xfail avr32*-*-* } } */
2350 +
2351 +#include "ffitest.h"
2352 +#include <stdarg.h>
2353 +
2354 +struct small_tag
2355 +{
2356 +  unsigned char a;
2357 +  unsigned char b;
2358 +};
2359 +
2360 +struct large_tag
2361 +{
2362 +  unsigned a;
2363 +  unsigned b;
2364 +  unsigned c;
2365 +  unsigned d;
2366 +  unsigned e;
2367 +};
2368 +
2369 +static struct small_tag
2370 +test_fn (int n, ...)
2371 +{
2372 +  va_list ap;
2373 +  struct small_tag s1;
2374 +  struct small_tag s2;
2375 +  struct large_tag l;
2376 +
2377 +  va_start (ap, n);
2378 +  s1 = va_arg (ap, struct small_tag);
2379 +  l = va_arg (ap, struct large_tag);
2380 +  s2 = va_arg (ap, struct small_tag);
2381 +  printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
2382 +         s2.a, s2.b);
2383 +  va_end (ap);
2384 +  s1.a += s2.a;
2385 +  s1.b += s2.b;
2386 +  return s1;
2387 +}
2388 +
2389 +int
2390 +main (void)
2391 +{
2392 +  ffi_cif cif;
2393 +  void* args[5];
2394 +  ffi_type* arg_types[5];
2395 +
2396 +  ffi_type s_type;
2397 +  ffi_type *s_type_elements[3];
2398 +
2399 +  ffi_type l_type;
2400 +  ffi_type *l_type_elements[6];
2401 +
2402 +  struct small_tag s1;
2403 +  struct small_tag s2;
2404 +  struct large_tag l1;
2405 +
2406 +  int n;
2407 +  struct small_tag res;
2408 +
2409 +  s_type.size = 0;
2410 +  s_type.alignment = 0;
2411 +  s_type.type = FFI_TYPE_STRUCT;
2412 +  s_type.elements = s_type_elements;
2413 +
2414 +  s_type_elements[0] = &ffi_type_uchar;
2415 +  s_type_elements[1] = &ffi_type_uchar;
2416 +  s_type_elements[2] = NULL;
2417 +
2418 +  l_type.size = 0;
2419 +  l_type.alignment = 0;
2420 +  l_type.type = FFI_TYPE_STRUCT;
2421 +  l_type.elements = l_type_elements;
2422 +
2423 +  l_type_elements[0] = &ffi_type_uint;
2424 +  l_type_elements[1] = &ffi_type_uint;
2425 +  l_type_elements[2] = &ffi_type_uint;
2426 +  l_type_elements[3] = &ffi_type_uint;
2427 +  l_type_elements[4] = &ffi_type_uint;
2428 +  l_type_elements[5] = NULL;
2429 +
2430 +  arg_types[0] = &ffi_type_sint;
2431 +  arg_types[1] = &s_type;
2432 +  arg_types[2] = &l_type;
2433 +  arg_types[3] = &s_type;
2434 +  arg_types[4] = NULL;
2435 +
2436 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &s_type, arg_types) == FFI_OK);
2437 +
2438 +  s1.a = 5;
2439 +  s1.b = 6;
2440 +
2441 +  l1.a = 10;
2442 +  l1.b = 11;
2443 +  l1.c = 12;
2444 +  l1.d = 13;
2445 +  l1.e = 14;
2446 +
2447 +  s2.a = 7;
2448 +  s2.b = 8;
2449 +
2450 +  n = 41;
2451 +
2452 +  args[0] = &n;
2453 +  args[1] = &s1;
2454 +  args[2] = &l1;
2455 +  args[3] = &s2;
2456 +  args[4] = NULL;
2457 +
2458 +  ffi_call(&cif, FFI_FN(test_fn), &res, args);
2459 +  /* { dg-output "5 6 10 11 12 13 14 7 8" } */
2460 +  printf("res: %d %d\n", res.a, res.b);
2461 +  /* { dg-output "\nres: 12 14" } */
2462 +
2463 +  return 0;
2464 +}
2465 Index: libffi/testsuite/libffi.call/va_struct3.c
2466 ===================================================================
2467 --- /dev/null
2468 +++ libffi/testsuite/libffi.call/va_struct3.c
2469 @@ -0,0 +1,125 @@
2470 +/* Area:               ffi_call
2471 +   Purpose:            Test passing struct in variable argument lists.
2472 +   Limitations:        none.
2473 +   PR:                 none.
2474 +   Originator: ARM Ltd. */
2475 +
2476 +/* { dg-do run } */
2477 +/* { dg-output "" { xfail avr32*-*-* } } */
2478 +
2479 +#include "ffitest.h"
2480 +#include <stdarg.h>
2481 +
2482 +struct small_tag
2483 +{
2484 +  unsigned char a;
2485 +  unsigned char b;
2486 +};
2487 +
2488 +struct large_tag
2489 +{
2490 +  unsigned a;
2491 +  unsigned b;
2492 +  unsigned c;
2493 +  unsigned d;
2494 +  unsigned e;
2495 +};
2496 +
2497 +static struct large_tag
2498 +test_fn (int n, ...)
2499 +{
2500 +  va_list ap;
2501 +  struct small_tag s1;
2502 +  struct small_tag s2;
2503 +  struct large_tag l;
2504 +
2505 +  va_start (ap, n);
2506 +  s1 = va_arg (ap, struct small_tag);
2507 +  l = va_arg (ap, struct large_tag);
2508 +  s2 = va_arg (ap, struct small_tag);
2509 +  printf ("%u %u %u %u %u %u %u %u %u\n", s1.a, s1.b, l.a, l.b, l.c, l.d, l.e,
2510 +         s2.a, s2.b);
2511 +  va_end (ap);
2512 +  l.a += s1.a;
2513 +  l.b += s1.b;
2514 +  l.c += s2.a;
2515 +  l.d += s2.b;
2516 +  return l;
2517 +}
2518 +
2519 +int
2520 +main (void)
2521 +{
2522 +  ffi_cif cif;
2523 +  void* args[5];
2524 +  ffi_type* arg_types[5];
2525 +
2526 +  ffi_type s_type;
2527 +  ffi_type *s_type_elements[3];
2528 +
2529 +  ffi_type l_type;
2530 +  ffi_type *l_type_elements[6];
2531 +
2532 +  struct small_tag s1;
2533 +  struct small_tag s2;
2534 +  struct large_tag l1;
2535 +
2536 +  int n;
2537 +  struct large_tag res;
2538 +
2539 +  s_type.size = 0;
2540 +  s_type.alignment = 0;
2541 +  s_type.type = FFI_TYPE_STRUCT;
2542 +  s_type.elements = s_type_elements;
2543 +
2544 +  s_type_elements[0] = &ffi_type_uchar;
2545 +  s_type_elements[1] = &ffi_type_uchar;
2546 +  s_type_elements[2] = NULL;
2547 +
2548 +  l_type.size = 0;
2549 +  l_type.alignment = 0;
2550 +  l_type.type = FFI_TYPE_STRUCT;
2551 +  l_type.elements = l_type_elements;
2552 +
2553 +  l_type_elements[0] = &ffi_type_uint;
2554 +  l_type_elements[1] = &ffi_type_uint;
2555 +  l_type_elements[2] = &ffi_type_uint;
2556 +  l_type_elements[3] = &ffi_type_uint;
2557 +  l_type_elements[4] = &ffi_type_uint;
2558 +  l_type_elements[5] = NULL;
2559 +
2560 +  arg_types[0] = &ffi_type_sint;
2561 +  arg_types[1] = &s_type;
2562 +  arg_types[2] = &l_type;
2563 +  arg_types[3] = &s_type;
2564 +  arg_types[4] = NULL;
2565 +
2566 +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK);
2567 +
2568 +  s1.a = 5;
2569 +  s1.b = 6;
2570 +
2571 +  l1.a = 10;
2572 +  l1.b = 11;
2573 +  l1.c = 12;
2574 +  l1.d = 13;
2575 +  l1.e = 14;
2576 +
2577 +  s2.a = 7;
2578 +  s2.b = 8;
2579 +
2580 +  n = 41;
2581 +
2582 +  args[0] = &n;
2583 +  args[1] = &s1;
2584 +  args[2] = &l1;
2585 +  args[3] = &s2;
2586 +  args[4] = NULL;
2587 +
2588 +  ffi_call(&cif, FFI_FN(test_fn), &res, args);
2589 +  /* { dg-output "5 6 10 11 12 13 14 7 8" } */
2590 +  printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e);
2591 +  /* { dg-output "\nres: 15 17 19 21 14" } */
2592 +
2593 +  return 0;
2594 +}
2595 Index: libffi/ChangeLog
2596 ===================================================================
2597 --- libffi.orig/ChangeLog
2598 +++ libffi/ChangeLog
2599 @@ -3,6 +3,33 @@
2600         * src/powerpc/linux64_closure.S: Add new ABI support.
2601         * src/powerpc/linux64.S: Likewise.
2602  
2603 +2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
2604 +            Marcus Shawcroft  <marcus.shawcroft at arm.com>
2605 +
2606 +        * README: Add details of aarch64 port.
2607 +        * src/aarch64/ffi.c: New.
2608 +        * src/aarch64/ffitarget.h: Likewise.
2609 +        * src/aarch64/sysv.S: Likewise.
2610 +       * Makefile.am: Support aarch64.
2611 +       * configure.ac: Support aarch64.
2612 +       * Makefile.in, configure: Rebuilt.
2613 +
2614 +2012-10-30  James Greenhalgh  <james.greenhalgh at arm.com>
2615 +            Marcus Shawcroft  <marcus.shawcroft at arm.com>
2616 +
2617 +        * testsuite/lib/libffi.exp: Add support for aarch64.
2618 +        * testsuite/libffi.call/cls_struct_va1.c: New.
2619 +        * testsuite/libffi.call/cls_uchar_va.c: Likewise.
2620 +        * testsuite/libffi.call/cls_uint_va.c: Likewise.
2621 +        * testsuite/libffi.call/cls_ulong_va.c: Liekwise.
2622 +        * testsuite/libffi.call/cls_ushort_va.c: Likewise.
2623 +        * testsuite/libffi.call/nested_struct11.c: Likewise.
2624 +        * testsuite/libffi.call/uninitialized.c: Likewise.
2625 +        * testsuite/libffi.call/va_1.c: Likewise.
2626 +        * testsuite/libffi.call/va_struct1.c: Likewise.
2627 +        * testsuite/libffi.call/va_struct2.c: Likewise.
2628 +        * testsuite/libffi.call/va_struct3.c: Likewise.
2629 +
2630  2012-10-12  Walter Lee  <walt@tilera.com>
2631  
2632          * Makefile.am: Add TILE-Gx/TILEPro support.
2633 Index: libffi/Makefile.am
2634 ===================================================================
2635 --- libffi.orig/Makefile.am
2636 +++ libffi/Makefile.am
2637 @@ -5,6 +5,7 @@ AUTOMAKE_OPTIONS = foreign subdir-object
2638  SUBDIRS = include testsuite man
2639  
2640  EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host      \
2641 +        src/aarch64/ffi.c src/aarch64/ffitarget.h                      \
2642          src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h          \
2643          src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h               \
2644          src/avr32/ffi.c src/avr32/sysv.S src/avr32/ffitarget.h         \
2645 @@ -151,6 +152,9 @@ endif
2646  if POWERPC_FREEBSD
2647  nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
2648  endif
2649 +if AARCH64
2650 +nodist_libffi_la_SOURCES += src/aarch64/sysv.S src/aarch64/ffi.c
2651 +endif
2652  if ARM
2653  nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
2654  if FFI_EXEC_TRAMPOLINE_TABLE
2655 Index: libffi/configure
2656 ===================================================================
2657 --- libffi.orig/configure
2658 +++ libffi/configure
2659 @@ -651,6 +651,8 @@ AVR32_FALSE
2660  AVR32_TRUE
2661  ARM_FALSE
2662  ARM_TRUE
2663 +AARCH64_FALSE
2664 +AARCH64_TRUE
2665  POWERPC_FREEBSD_FALSE
2666  POWERPC_FREEBSD_TRUE
2667  POWERPC_DARWIN_FALSE
2668 @@ -1481,7 +1483,7 @@ Optional Features:
2669  Optional Packages:
2670    --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
2671    --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
2672 -  --with-pic              try to use only PIC/non-PIC objects [default=use
2673 +  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
2674                            both]
2675    --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
2676    --with-sysroot=DIR Search for dependent libraries within DIR
2677 @@ -5282,6 +5284,11 @@ else
2678      lt_cv_sys_max_cmd_len=196608
2679      ;;
2680  
2681 +  os2*)
2682 +    # The test takes a long time on OS/2.
2683 +    lt_cv_sys_max_cmd_len=8192
2684 +    ;;
2685 +
2686    osf*)
2687      # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
2688      # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
2689 @@ -5321,7 +5328,7 @@ else
2690        # If test is not a shell built-in, we'll probably end up computing a
2691        # maximum length that is only half of the actual maximum length, but
2692        # we can't tell.
2693 -      while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
2694 +      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
2695                  = "X$teststring$teststring"; } >/dev/null 2>&1 &&
2696               test $i != 17 # 1/2 MB should be enough
2697        do
2698 @@ -5750,7 +5757,7 @@ irix5* | irix6* | nonstopux*)
2699    lt_cv_deplibs_check_method=pass_all
2700    ;;
2701  
2702 -# This must be Linux ELF.
2703 +# This must be glibc/ELF.
2704  linux* | k*bsd*-gnu | kopensolaris*-gnu)
2705    lt_cv_deplibs_check_method=pass_all
2706    ;;
2707 @@ -6391,13 +6398,13 @@ old_postuninstall_cmds=
2708  if test -n "$RANLIB"; then
2709    case $host_os in
2710    openbsd*)
2711 -    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
2712 +    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
2713      ;;
2714    *)
2715 -    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
2716 +    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
2717      ;;
2718    esac
2719 -  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
2720 +  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
2721  fi
2722  
2723  case $host_os in
2724 @@ -6544,6 +6551,7 @@ for ac_symprfx in "" "_"; do
2725      # which start with @ or ?.
2726      lt_cv_sys_global_symbol_pipe="$AWK '"\
2727  "     {last_section=section; section=\$ 3};"\
2728 +"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
2729  "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
2730  "     \$ 0!~/External *\|/{next};"\
2731  "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
2732 @@ -6932,7 +6940,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
2733      CFLAGS="$SAVE_CFLAGS"
2734    fi
2735    ;;
2736 -sparc*-*solaris*)
2737 +*-*solaris*)
2738    # Find out which ABI we are using.
2739    echo 'int i;' > conftest.$ac_ext
2740    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
2741 @@ -6943,7 +6951,20 @@ sparc*-*solaris*)
2742      case `/usr/bin/file conftest.o` in
2743      *64-bit*)
2744        case $lt_cv_prog_gnu_ld in
2745 -      yes*) LD="${LD-ld} -m elf64_sparc" ;;
2746 +      yes*)
2747 +        case $host in
2748 +        i?86-*-solaris*)
2749 +          LD="${LD-ld} -m elf_x86_64"
2750 +          ;;
2751 +        sparc*-*-solaris*)
2752 +          LD="${LD-ld} -m elf64_sparc"
2753 +          ;;
2754 +        esac
2755 +        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
2756 +        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
2757 +          LD="${LD-ld}_sol2"
2758 +        fi
2759 +        ;;
2760        *)
2761         if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
2762           LD="${LD-ld} -64"
2763 @@ -7583,7 +7604,13 @@ else
2764         $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
2765           -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
2766          _lt_result=$?
2767 -       if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
2768 +       # If there is a non-empty error log, and "single_module"
2769 +       # appears in it, assume the flag caused a linker warning
2770 +        if test -s conftest.err && $GREP single_module conftest.err; then
2771 +         cat conftest.err >&5
2772 +       # Otherwise, if the output was created with a 0 exit code from
2773 +       # the compiler, it worked.
2774 +       elif test -f libconftest.dylib && test $_lt_result -eq 0; then
2775           lt_cv_apple_cc_single_mod=yes
2776         else
2777           cat conftest.err >&5
2778 @@ -7594,6 +7621,7 @@ else
2779  fi
2780  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
2781  $as_echo "$lt_cv_apple_cc_single_mod" >&6; }
2782 +
2783      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
2784  $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
2785  if ${lt_cv_ld_exported_symbols_list+:} false; then :
2786 @@ -7626,6 +7654,7 @@ rm -f core conftest.err conftest.$ac_obj
2787  fi
2788  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
2789  $as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
2790 +
2791      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
2792  $as_echo_n "checking for -force_load linker flag... " >&6; }
2793  if ${lt_cv_ld_force_load+:} false; then :
2794 @@ -7647,7 +7676,9 @@ _LT_EOF
2795        echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
2796        $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
2797        _lt_result=$?
2798 -      if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
2799 +      if test -s conftest.err && $GREP force_load conftest.err; then
2800 +       cat conftest.err >&5
2801 +      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
2802         lt_cv_ld_force_load=yes
2803        else
2804         cat conftest.err >&5
2805 @@ -8052,7 +8083,22 @@ fi
2806  
2807  # Check whether --with-pic was given.
2808  if test "${with_pic+set}" = set; then :
2809 -  withval=$with_pic; pic_mode="$withval"
2810 +  withval=$with_pic; lt_p=${PACKAGE-default}
2811 +    case $withval in
2812 +    yes|no) pic_mode=$withval ;;
2813 +    *)
2814 +      pic_mode=default
2815 +      # Look at the argument we got.  We use all the common list separators.
2816 +      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
2817 +      for lt_pkg in $withval; do
2818 +       IFS="$lt_save_ifs"
2819 +       if test "X$lt_pkg" = "X$lt_p"; then
2820 +         pic_mode=yes
2821 +       fi
2822 +      done
2823 +      IFS="$lt_save_ifs"
2824 +      ;;
2825 +    esac
2826  else
2827    pic_mode=default
2828  fi
2829 @@ -8130,6 +8176,10 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtoo
2830  
2831  
2832  
2833 +
2834 +
2835 +
2836 +
2837  test -z "$LN_S" && LN_S="ln -s"
2838  
2839  
2840 @@ -8419,10 +8469,6 @@ _lt_linker_boilerplate=`cat conftest.err
2841  $RM -r conftest*
2842  
2843  
2844 -## CAVEAT EMPTOR:
2845 -## There is no encapsulation within the following macros, do not change
2846 -## the running order or otherwise move them around unless you know exactly
2847 -## what you are doing...
2848  if test -n "$compiler"; then
2849  
2850  lt_prog_compiler_no_builtin_flag=
2851 @@ -8589,7 +8635,9 @@ lt_prog_compiler_static=
2852      case $cc_basename in
2853      nvcc*) # Cuda Compiler Driver 2.2
2854        lt_prog_compiler_wl='-Xlinker '
2855 -      lt_prog_compiler_pic='-Xcompiler -fPIC'
2856 +      if test -n "$lt_prog_compiler_pic"; then
2857 +        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
2858 +      fi
2859        ;;
2860      esac
2861    else
2862 @@ -8680,18 +8728,33 @@ lt_prog_compiler_static=
2863         ;;
2864        *)
2865         case `$CC -V 2>&1 | sed 5q` in
2866 -       *Sun\ F* | *Sun*Fortran*)
2867 +       *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
2868           # Sun Fortran 8.3 passes all unrecognized flags to the linker
2869           lt_prog_compiler_pic='-KPIC'
2870           lt_prog_compiler_static='-Bstatic'
2871           lt_prog_compiler_wl=''
2872           ;;
2873 +       *Sun\ F* | *Sun*Fortran*)
2874 +         lt_prog_compiler_pic='-KPIC'
2875 +         lt_prog_compiler_static='-Bstatic'
2876 +         lt_prog_compiler_wl='-Qoption ld '
2877 +         ;;
2878         *Sun\ C*)
2879           # Sun C 5.9
2880           lt_prog_compiler_pic='-KPIC'
2881           lt_prog_compiler_static='-Bstatic'
2882           lt_prog_compiler_wl='-Wl,'
2883           ;;
2884 +        *Intel*\ [CF]*Compiler*)
2885 +         lt_prog_compiler_wl='-Wl,'
2886 +         lt_prog_compiler_pic='-fPIC'
2887 +         lt_prog_compiler_static='-static'
2888 +         ;;
2889 +       *Portland\ Group*)
2890 +         lt_prog_compiler_wl='-Wl,'
2891 +         lt_prog_compiler_pic='-fpic'
2892 +         lt_prog_compiler_static='-Bstatic'
2893 +         ;;
2894         esac
2895         ;;
2896        esac
2897 @@ -9053,7 +9116,6 @@ $as_echo_n "checking whether the $compil
2898    hardcode_direct=no
2899    hardcode_direct_absolute=no
2900    hardcode_libdir_flag_spec=
2901 -  hardcode_libdir_flag_spec_ld=
2902    hardcode_libdir_separator=
2903    hardcode_minus_L=no
2904    hardcode_shlibpath_var=unsupported
2905 @@ -9303,8 +9365,7 @@ _LT_EOF
2906         xlf* | bgf* | bgxlf* | mpixlf*)
2907           # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
2908           whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
2909 -         hardcode_libdir_flag_spec=
2910 -         hardcode_libdir_flag_spec_ld='-rpath $libdir'
2911 +         hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
2912           archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
2913           if test "x$supports_anon_versioning" = xyes; then
2914             archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
2915 @@ -9683,6 +9744,7 @@ fi
2916         # The linker will not automatically build a static lib if we build a DLL.
2917         # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
2918         enable_shared_with_static_runtimes=yes
2919 +       exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
2920         export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
2921         # Don't use ranlib
2922         old_postinstall_cmds='chmod 644 $oldlib'
2923 @@ -9728,6 +9790,7 @@ fi
2924    hardcode_shlibpath_var=unsupported
2925    if test "$lt_cv_ld_force_load" = "yes"; then
2926      whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
2927 +
2928    else
2929      whole_archive_flag_spec=''
2930    fi
2931 @@ -9756,10 +9819,6 @@ fi
2932        hardcode_shlibpath_var=no
2933        ;;
2934  
2935 -    freebsd1*)
2936 -      ld_shlibs=no
2937 -      ;;
2938 -
2939      # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
2940      # support.  Future versions do this automatically, but an explicit c++rt0.o
2941      # does not break anything, and helps significantly (at the cost of a little
2942 @@ -9772,7 +9831,7 @@ fi
2943        ;;
2944  
2945      # Unfortunately, older versions of FreeBSD 2 do not have this feature.
2946 -    freebsd2*)
2947 +    freebsd2.*)
2948        archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
2949        hardcode_direct=yes
2950        hardcode_minus_L=yes
2951 @@ -9811,7 +9870,6 @@ fi
2952        fi
2953        if test "$with_gnu_ld" = no; then
2954         hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
2955 -       hardcode_libdir_flag_spec_ld='+b $libdir'
2956         hardcode_libdir_separator=:
2957         hardcode_direct=yes
2958         hardcode_direct_absolute=yes
2959 @@ -10435,11 +10493,6 @@ esac
2960  
2961  
2962  
2963 -
2964 -
2965 -
2966 -
2967 -
2968    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
2969  $as_echo_n "checking dynamic linker characteristics... " >&6; }
2970  
2971 @@ -10529,7 +10582,7 @@ need_version=unknown
2972  
2973  case $host_os in
2974  aix3*)
2975 -  version_type=linux
2976 +  version_type=linux # correct to gnu/linux during the next big refactor
2977    library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
2978    shlibpath_var=LIBPATH
2979  
2980 @@ -10538,7 +10591,7 @@ aix3*)
2981    ;;
2982  
2983  aix[4-9]*)
2984 -  version_type=linux
2985 +  version_type=linux # correct to gnu/linux during the next big refactor
2986    need_lib_prefix=no
2987    need_version=no
2988    hardcode_into_libs=yes
2989 @@ -10603,7 +10656,7 @@ beos*)
2990    ;;
2991  
2992  bsdi[45]*)
2993 -  version_type=linux
2994 +  version_type=linux # correct to gnu/linux during the next big refactor
2995    need_version=no
2996    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
2997    soname_spec='${libname}${release}${shared_ext}$major'
2998 @@ -10742,7 +10795,7 @@ darwin* | rhapsody*)
2999    ;;
3000  
3001  dgux*)
3002 -  version_type=linux
3003 +  version_type=linux # correct to gnu/linux during the next big refactor
3004    need_lib_prefix=no
3005    need_version=no
3006    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
3007 @@ -10750,10 +10803,6 @@ dgux*)
3008    shlibpath_var=LD_LIBRARY_PATH
3009    ;;
3010  
3011 -freebsd1*)
3012 -  dynamic_linker=no
3013 -  ;;
3014 -
3015  freebsd* | dragonfly*)
3016    # DragonFly does not have aout.  When/if they implement a new
3017    # versioning mechanism, adjust this.
3018 @@ -10761,7 +10810,7 @@ freebsd* | dragonfly*)
3019      objformat=`/usr/bin/objformat`
3020    else
3021      case $host_os in
3022 -    freebsd[123]*) objformat=aout ;;
3023 +    freebsd[23].*) objformat=aout ;;
3024      *) objformat=elf ;;
3025      esac
3026    fi
3027 @@ -10779,7 +10828,7 @@ freebsd* | dragonfly*)
3028    esac
3029    shlibpath_var=LD_LIBRARY_PATH
3030    case $host_os in
3031 -  freebsd2*)
3032 +  freebsd2.*)
3033      shlibpath_overrides_runpath=yes
3034      ;;
3035    freebsd3.[01]* | freebsdelf3.[01]*)
3036 @@ -10799,17 +10848,18 @@ freebsd* | dragonfly*)
3037    ;;
3038  
3039  gnu*)
3040 -  version_type=linux
3041 +  version_type=linux # correct to gnu/linux during the next big refactor
3042    need_lib_prefix=no
3043    need_version=no
3044    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
3045    soname_spec='${libname}${release}${shared_ext}$major'
3046    shlibpath_var=LD_LIBRARY_PATH
3047 +  shlibpath_overrides_runpath=no
3048    hardcode_into_libs=yes
3049    ;;
3050  
3051  haiku*)
3052 -  version_type=linux
3053 +  version_type=linux # correct to gnu/linux during the next big refactor
3054    need_lib_prefix=no
3055    need_version=no
3056    dynamic_linker="$host_os runtime_loader"
3057 @@ -10870,7 +10920,7 @@ hpux9* | hpux10* | hpux11*)
3058    ;;
3059  
3060  interix[3-9]*)
3061 -  version_type=linux
3062 +  version_type=linux # correct to gnu/linux during the next big refactor
3063    need_lib_prefix=no
3064    need_version=no
3065    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
3066 @@ -10886,7 +10936,7 @@ irix5* | irix6* | nonstopux*)
3067      nonstopux*) version_type=nonstopux ;;
3068      *)
3069         if test "$lt_cv_prog_gnu_ld" = yes; then
3070 -               version_type=linux
3071 +               version_type=linux # correct to gnu/linux during the next big refactor
3072         else
3073                 version_type=irix
3074         fi ;;
3075 @@ -10923,9 +10973,9 @@ linux*oldld* | linux*aout* | linux*coff*
3076    dynamic_linker=no
3077    ;;
3078  
3079 -# This must be Linux ELF.
3080 +# This must be glibc/ELF.
3081  linux* | k*bsd*-gnu | kopensolaris*-gnu)
3082 -  version_type=linux
3083 +  version_type=linux # correct to gnu/linux during the next big refactor
3084    need_lib_prefix=no
3085    need_version=no
3086    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
3087 @@ -10973,10 +11023,14 @@ fi
3088    # before this can be enabled.
3089    hardcode_into_libs=yes
3090  
3091 +  # Add ABI-specific directories to the system library path.
3092 +  sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
3093 +
3094    # Append ld.so.conf contents to the search path
3095    if test -f /etc/ld.so.conf; then
3096      lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
3097 -    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
3098 +    sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
3099 +
3100    fi
3101  
3102    # We used to test for /lib/ld.so.1 and disable shared libraries on
3103 @@ -11007,7 +11061,7 @@ netbsd*)
3104    ;;
3105  
3106  newsos6)
3107 -  version_type=linux
3108 +  version_type=linux # correct to gnu/linux during the next big refactor
3109    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
3110    shlibpath_var=LD_LIBRARY_PATH
3111    shlibpath_overrides_runpath=yes
3112 @@ -11076,7 +11130,7 @@ rdos*)
3113    ;;
3114  
3115  solaris*)
3116 -  version_type=linux
3117 +  version_type=linux # correct to gnu/linux during the next big refactor
3118    need_lib_prefix=no
3119    need_version=no
3120    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
3121 @@ -11101,7 +11155,7 @@ sunos4*)
3122    ;;
3123  
3124  sysv4 | sysv4.3*)
3125 -  version_type=linux
3126 +  version_type=linux # correct to gnu/linux during the next big refactor
3127    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
3128    soname_spec='${libname}${release}${shared_ext}$major'
3129    shlibpath_var=LD_LIBRARY_PATH
3130 @@ -11125,7 +11179,7 @@ sysv4 | sysv4.3*)
3131  
3132  sysv4*MP*)
3133    if test -d /usr/nec ;then
3134 -    version_type=linux
3135 +    version_type=linux # correct to gnu/linux during the next big refactor
3136      library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
3137      soname_spec='$libname${shared_ext}.$major'
3138      shlibpath_var=LD_LIBRARY_PATH
3139 @@ -11156,7 +11210,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware*
3140  
3141  tpf*)
3142    # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
3143 -  version_type=linux
3144 +  version_type=linux # correct to gnu/linux during the next big refactor
3145    need_lib_prefix=no
3146    need_version=no
3147    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
3148 @@ -11166,7 +11220,7 @@ tpf*)
3149    ;;
3150  
3151  uts4*)
3152 -  version_type=linux
3153 +  version_type=linux # correct to gnu/linux during the next big refactor
3154    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
3155    soname_spec='${libname}${release}${shared_ext}$major'
3156    shlibpath_var=LD_LIBRARY_PATH
3157 @@ -11948,6 +12002,8 @@ CC="$lt_save_CC"
3158  
3159  
3160  
3161 +
3162 +
3163          ac_config_commands="$ac_config_commands libtool"
3164  
3165  
3166 @@ -13161,6 +13217,10 @@ fi
3167  
3168  TARGETDIR="unknown"
3169  case "$host" in
3170 +  aarch64*-*-*)
3171 +       TARGET=AARCH64; TARGETDIR=aarch64
3172 +       ;;
3173 +
3174    alpha*-*-*)
3175         TARGET=ALPHA; TARGETDIR=alpha;
3176         # Support 128-bit long double, changeable via command-line switch.
3177 @@ -13464,6 +13524,14 @@ else
3178    POWERPC_FREEBSD_FALSE=
3179  fi
3180  
3181 + if test x$TARGET = xAARCH64; then
3182 +  AARCH64_TRUE=
3183 +  AARCH64_FALSE='#'
3184 +else
3185 +  AARCH64_TRUE='#'
3186 +  AARCH64_FALSE=
3187 +fi
3188 +
3189   if test x$TARGET = xARM; then
3190    ARM_TRUE=
3191    ARM_FALSE='#'
3192 @@ -14191,40 +14259,7 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUI
3193   esac
3194  
3195  
3196 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler .cfi pseudo-op support" >&5
3197 -$as_echo_n "checking assembler .cfi pseudo-op support... " >&6; }
3198 -if ${gcc_cv_as_cfi_pseudo_op+:} false; then :
3199 -  $as_echo_n "(cached) " >&6
3200 -else
3201 -
3202 -    gcc_cv_as_cfi_pseudo_op=unknown
3203 -    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
3204 -/* end confdefs.h.  */
3205 -asm (".cfi_startproc\n\t.cfi_endproc");
3206 -int
3207 -main ()
3208 -{
3209 -
3210 -  ;
3211 -  return 0;
3212 -}
3213 -_ACEOF
3214 -if ac_fn_c_try_compile "$LINENO"; then :
3215 -  gcc_cv_as_cfi_pseudo_op=yes
3216 -else
3217 -  gcc_cv_as_cfi_pseudo_op=no
3218 -fi
3219 -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
3220 -
3221 -fi
3222 -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_cfi_pseudo_op" >&5
3223 -$as_echo "$gcc_cv_as_cfi_pseudo_op" >&6; }
3224 - if test "x$gcc_cv_as_cfi_pseudo_op" = xyes; then
3225 -
3226 -$as_echo "#define HAVE_AS_CFI_PSEUDO_OP 1" >>confdefs.h
3227 -
3228 - fi
3229 -
3230 +GCC_AS_CFI_PSEUDO_OP
3231  
3232  if test x$TARGET = xSPARC; then
3233      { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler and linker support unaligned pc related relocs" >&5
3234 @@ -14860,6 +14895,10 @@ if test -z "${POWERPC_FREEBSD_TRUE}" &&
3235    as_fn_error $? "conditional \"POWERPC_FREEBSD\" was never defined.
3236  Usually this means the macro was only invoked conditionally." "$LINENO" 5
3237  fi
3238 +if test -z "${AARCH64_TRUE}" && test -z "${AARCH64_FALSE}"; then
3239 +  as_fn_error $? "conditional \"AARCH64\" was never defined.
3240 +Usually this means the macro was only invoked conditionally." "$LINENO" 5
3241 +fi
3242  if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then
3243    as_fn_error $? "conditional \"ARM\" was never defined.
3244  Usually this means the macro was only invoked conditionally." "$LINENO" 5
3245 @@ -15541,6 +15580,7 @@ pic_mode='`$ECHO "$pic_mode" | $SED "$de
3246  enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
3247  SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
3248  ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
3249 +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
3250  host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
3251  host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
3252  host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
3253 @@ -15623,7 +15663,6 @@ with_gnu_ld='`$ECHO "$with_gnu_ld" | $SE
3254  allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
3255  no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
3256  hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
3257 -hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
3258  hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
3259  hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
3260  hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
3261 @@ -15679,6 +15718,7 @@ _LTECHO_EOF'
3262  # Quote evaled strings.
3263  for var in SHELL \
3264  ECHO \
3265 +PATH_SEPARATOR \
3266  SED \
3267  GREP \
3268  EGREP \
3269 @@ -15729,7 +15769,6 @@ with_gnu_ld \
3270  allow_undefined_flag \
3271  no_undefined_flag \
3272  hardcode_libdir_flag_spec \
3273 -hardcode_libdir_flag_spec_ld \
3274  hardcode_libdir_separator \
3275  exclude_expsyms \
3276  include_expsyms \
3277 @@ -16711,8 +16750,8 @@ $as_echo X"$file" |
3278  # NOTE: Changes made to this file will be lost: look at ltmain.sh.
3279  #
3280  #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
3281 -#                 2006, 2007, 2008, 2009, 2010 Free Software Foundation,
3282 -#                 Inc.
3283 +#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
3284 +#                 Foundation, Inc.
3285  #   Written by Gordon Matzigkeit, 1996
3286  #
3287  #   This file is part of GNU Libtool.
3288 @@ -16766,6 +16805,9 @@ SHELL=$lt_SHELL
3289  # An echo program that protects backslashes.
3290  ECHO=$lt_ECHO
3291  
3292 +# The PATH separator for the build system.
3293 +PATH_SEPARATOR=$lt_PATH_SEPARATOR
3294 +
3295  # The host system.
3296  host_alias=$host_alias
3297  host=$host
3298 @@ -17067,10 +17109,6 @@ no_undefined_flag=$lt_no_undefined_flag
3299  # This must work even if \$libdir does not exist
3300  hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
3301  
3302 -# If ld is used when linking, flag to hardcode \$libdir into a binary
3303 -# during linking.  This must work even if \$libdir does not exist.
3304 -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
3305 -
3306  # Whether we need a single "-rpath" flag with a separated argument.
3307  hardcode_libdir_separator=$lt_hardcode_libdir_separator
3308  
3309 Index: libffi/configure.ac
3310 ===================================================================
3311 --- libffi.orig/configure.ac
3312 +++ libffi/configure.ac
3313 @@ -53,6 +53,10 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcd
3314  
3315  TARGETDIR="unknown"
3316  case "$host" in
3317 +  aarch64*-*-*)
3318 +       TARGET=AARCH64; TARGETDIR=aarch64
3319 +       ;;
3320 +
3321    alpha*-*-*)
3322         TARGET=ALPHA; TARGETDIR=alpha;
3323         # Support 128-bit long double, changeable via command-line switch.
3324 @@ -237,6 +241,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET =
3325  AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
3326  AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
3327  AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
3328 +AM_CONDITIONAL(AARCH64, test x$TARGET = xAARCH64)
3329  AM_CONDITIONAL(ARM, test x$TARGET = xARM)
3330  AM_CONDITIONAL(AVR32, test x$TARGET = xAVR32)
3331  AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
3332 Index: libffi/config.guess
3333 ===================================================================
3334 --- libffi.orig/config.guess
3335 +++ libffi/config.guess
3336 @@ -2,9 +2,9 @@
3337  # Attempt to guess a canonical system name.
3338  #   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
3339  #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3340 -#   2011 Free Software Foundation, Inc.
3341 +#   2011, 2012 Free Software Foundation, Inc.
3342  
3343 -timestamp='2011-06-03'
3344 +timestamp='2012-09-25'
3345  
3346  # This file is free software; you can redistribute it and/or modify it
3347  # under the terms of the GNU General Public License as published by
3348 @@ -17,9 +17,7 @@ timestamp='2011-06-03'
3349  # General Public License for more details.
3350  #
3351  # You should have received a copy of the GNU General Public License
3352 -# along with this program; if not, write to the Free Software
3353 -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
3354 -# 02110-1301, USA.
3355 +# along with this program; if not, see <http://www.gnu.org/licenses/>.
3356  #
3357  # As a special exception to the GNU General Public License, if you
3358  # distribute this file as part of a program that contains a
3359 @@ -57,8 +55,8 @@ GNU config.guess ($timestamp)
3360  
3361  Originally written by Per Bothner.
3362  Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3363 -2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
3364 -Software Foundation, Inc.
3365 +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3366 +Free Software Foundation, Inc.
3367  
3368  This is free software; see the source for copying conditions.  There is NO
3369  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
3370 @@ -145,7 +143,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` |
3371  case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
3372      *:NetBSD:*:*)
3373         # NetBSD (nbsd) targets should (where applicable) match one or
3374 -       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
3375 +       # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
3376         # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
3377         # switched to ELF, *-*-netbsd* would select the old
3378         # object file format.  This provides both forward
3379 @@ -202,6 +200,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
3380         # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
3381         echo "${machine}-${os}${release}"
3382         exit ;;
3383 +    *:Bitrig:*:*)
3384 +       UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
3385 +       echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
3386 +       exit ;;
3387      *:OpenBSD:*:*)
3388         UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
3389         echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
3390 @@ -304,7 +306,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:$
3391      arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
3392         echo arm-acorn-riscix${UNAME_RELEASE}
3393         exit ;;
3394 -    arm:riscos:*:*|arm:RISCOS:*:*)
3395 +    arm*:riscos:*:*|arm*:RISCOS:*:*)
3396         echo arm-unknown-riscos
3397         exit ;;
3398      SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
3399 @@ -792,21 +794,26 @@ EOF
3400         echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
3401         exit ;;
3402      *:FreeBSD:*:*)
3403 -       case ${UNAME_MACHINE} in
3404 -           pc98)
3405 -               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
3406 +       UNAME_PROCESSOR=`/usr/bin/uname -p`
3407 +       case ${UNAME_PROCESSOR} in
3408             amd64)
3409                 echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
3410             *)
3411 -               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
3412 +               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
3413         esac
3414         exit ;;
3415      i*:CYGWIN*:*)
3416         echo ${UNAME_MACHINE}-pc-cygwin
3417         exit ;;
3418 +    *:MINGW64*:*)
3419 +       echo ${UNAME_MACHINE}-pc-mingw64
3420 +       exit ;;
3421      *:MINGW*:*)
3422         echo ${UNAME_MACHINE}-pc-mingw32
3423         exit ;;
3424 +    i*:MSYS*:*)
3425 +       echo ${UNAME_MACHINE}-pc-msys
3426 +       exit ;;
3427      i*:windows32*:*)
3428         # uname -m includes "-pc" on this system.
3429         echo ${UNAME_MACHINE}-mingw32
3430 @@ -861,6 +868,13 @@ EOF
3431      i*86:Minix:*:*)
3432         echo ${UNAME_MACHINE}-pc-minix
3433         exit ;;
3434 +    aarch64:Linux:*:*)
3435 +       echo ${UNAME_MACHINE}-unknown-linux-gnu
3436 +       exit ;;
3437 +    aarch64_be:Linux:*:*)
3438 +       UNAME_MACHINE=aarch64_be
3439 +       echo ${UNAME_MACHINE}-unknown-linux-gnu
3440 +       exit ;;
3441      alpha:Linux:*:*)
3442         case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
3443           EV5)   UNAME_MACHINE=alphaev5 ;;
3444 @@ -895,13 +909,16 @@ EOF
3445         echo ${UNAME_MACHINE}-unknown-linux-gnu
3446         exit ;;
3447      cris:Linux:*:*)
3448 -       echo cris-axis-linux-gnu
3449 +       echo ${UNAME_MACHINE}-axis-linux-gnu
3450         exit ;;
3451      crisv32:Linux:*:*)
3452 -       echo crisv32-axis-linux-gnu
3453 +       echo ${UNAME_MACHINE}-axis-linux-gnu
3454         exit ;;
3455      frv:Linux:*:*)
3456 -       echo frv-unknown-linux-gnu
3457 +       echo ${UNAME_MACHINE}-unknown-linux-gnu
3458 +       exit ;;
3459 +    hexagon:Linux:*:*)
3460 +       echo ${UNAME_MACHINE}-unknown-linux-gnu
3461         exit ;;
3462      i*86:Linux:*:*)
3463         LIBC=gnu
3464 @@ -943,7 +960,7 @@ EOF
3465         test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
3466         ;;
3467      or32:Linux:*:*)
3468 -       echo or32-unknown-linux-gnu
3469 +       echo ${UNAME_MACHINE}-unknown-linux-gnu
3470         exit ;;
3471      padre:Linux:*:*)
3472         echo sparc-unknown-linux-gnu
3473 @@ -984,7 +1001,7 @@ EOF
3474         echo ${UNAME_MACHINE}-dec-linux-gnu
3475         exit ;;
3476      x86_64:Linux:*:*)
3477 -       echo x86_64-unknown-linux-gnu
3478 +       echo ${UNAME_MACHINE}-unknown-linux-gnu
3479         exit ;;
3480      xtensa*:Linux:*:*)
3481         echo ${UNAME_MACHINE}-unknown-linux-gnu
3482 @@ -1191,6 +1208,9 @@ EOF
3483      BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
3484         echo i586-pc-haiku
3485         exit ;;
3486 +    x86_64:Haiku:*:*)
3487 +       echo x86_64-unknown-haiku
3488 +       exit ;;
3489      SX-4:SUPER-UX:*:*)
3490         echo sx4-nec-superux${UNAME_RELEASE}
3491         exit ;;
3492 @@ -1246,7 +1266,7 @@ EOF
3493      NEO-?:NONSTOP_KERNEL:*:*)
3494         echo neo-tandem-nsk${UNAME_RELEASE}
3495         exit ;;
3496 -    NSE-?:NONSTOP_KERNEL:*:*)
3497 +    NSE-*:NONSTOP_KERNEL:*:*)
3498         echo nse-tandem-nsk${UNAME_RELEASE}
3499         exit ;;
3500      NSR-?:NONSTOP_KERNEL:*:*)
3501 @@ -1315,11 +1335,11 @@ EOF
3502      i*86:AROS:*:*)
3503         echo ${UNAME_MACHINE}-pc-aros
3504         exit ;;
3505 +    x86_64:VMkernel:*:*)
3506 +       echo ${UNAME_MACHINE}-unknown-esx
3507 +       exit ;;
3508  esac
3509  
3510 -#echo '(No uname command or uname output not recognized.)' 1>&2
3511 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
3512 -
3513  eval $set_cc_for_build
3514  cat >$dummy.c <<EOF
3515  #ifdef _SEQUENT_
3516 Index: libffi/config.sub
3517 ===================================================================
3518 --- libffi.orig/config.sub
3519 +++ libffi/config.sub
3520 @@ -4,7 +4,7 @@
3521  #   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
3522  #   2011, 2012 Free Software Foundation, Inc.
3523  
3524 -timestamp='2012-04-18'
3525 +timestamp='2012-10-10'
3526  
3527  # This file is (in principle) common to ALL GNU software.
3528  # The presence of a machine in this file suggests that SOME GNU software
3529 @@ -123,7 +123,7 @@ esac
3530  maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
3531  case $maybe_os in
3532    nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
3533 -  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
3534 +  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
3535    knetbsd*-gnu* | netbsd*-gnu* | \
3536    kopensolaris*-gnu* | \
3537    storm-chaos* | os2-emx* | rtmk-nova*)
3538 @@ -156,7 +156,7 @@ case $os in
3539         -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
3540         -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
3541         -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
3542 -       -apple | -axis | -knuth | -cray | -microblaze)
3543 +       -apple | -axis | -knuth | -cray | -microblaze*)
3544                 os=
3545                 basic_machine=$1
3546                 ;;
3547 @@ -259,8 +259,10 @@ case $basic_machine in
3548         | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
3549         | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
3550         | am33_2.0 \
3551 -       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
3552 -        | be32 | be64 \
3553 +       | arc \
3554 +       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
3555 +       | avr | avr32 \
3556 +       | be32 | be64 \
3557         | bfin \
3558         | c4x | clipper \
3559         | d10v | d30v | dlx | dsp16xx \
3560 @@ -273,7 +275,7 @@ case $basic_machine in
3561         | le32 | le64 \
3562         | lm32 \
3563         | m32c | m32r | m32rle | m68000 | m68k | m88k \
3564 -       | maxq | mb | microblaze | mcore | mep | metag \
3565 +       | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
3566         | mips | mipsbe | mipseb | mipsel | mipsle \
3567         | mips16 \
3568         | mips64 | mips64el \
3569 @@ -389,7 +391,8 @@ case $basic_machine in
3570         | lm32-* \
3571         | m32c-* | m32r-* | m32rle-* \
3572         | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
3573 -       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
3574 +       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
3575 +       | microblaze-* | microblazeel-* \
3576         | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
3577         | mips16-* \
3578         | mips64-* | mips64el-* \
3579 @@ -788,9 +791,13 @@ case $basic_machine in
3580                 basic_machine=ns32k-utek
3581                 os=-sysv
3582                 ;;
3583 -       microblaze)
3584 +       microblaze*)
3585                 basic_machine=microblaze-xilinx
3586                 ;;
3587 +       mingw64)
3588 +               basic_machine=x86_64-pc
3589 +               os=-mingw64
3590 +               ;;
3591         mingw32)
3592                 basic_machine=i386-pc
3593                 os=-mingw32
3594 @@ -1352,15 +1359,15 @@ case $os in
3595               | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
3596               | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
3597               | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
3598 -             | -openbsd* | -solidbsd* \
3599 +             | -bitrig* | -openbsd* | -solidbsd* \
3600               | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
3601               | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
3602               | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
3603               | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
3604               | -chorusos* | -chorusrdb* | -cegcc* \
3605               | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
3606 -             | -mingw32* | -linux-gnu* | -linux-android* \
3607 -             | -linux-newlib* | -linux-uclibc* \
3608 +             | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
3609 +             | -linux-newlib* | -linux-musl* | -linux-uclibc* \
3610               | -uxpv* | -beos* | -mpeix* | -udk* \
3611               | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
3612               | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
3613 @@ -1543,6 +1550,9 @@ case $basic_machine in
3614         c4x-* | tic4x-*)
3615                 os=-coff
3616                 ;;
3617 +       hexagon-*)
3618 +               os=-elf
3619 +               ;;
3620         tic54x-*)
3621                 os=-coff
3622                 ;;