diff options
| author | Raghuram Subramani <raghus2247@gmail.com> | 2022-06-19 19:47:51 +0530 | 
|---|---|---|
| committer | Raghuram Subramani <raghus2247@gmail.com> | 2022-06-19 19:47:51 +0530 | 
| commit | 4fd287655a72b9aea14cdac715ad5b90ed082ed2 (patch) | |
| tree | 65d393bc0e699dd12d05b29ba568e04cea666207 /circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c | |
| parent | 0150f70ce9c39e9e6dd878766c0620c85e47bed0 (diff) | |
add circuitpython code
Diffstat (limited to 'circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c')
| -rw-r--r-- | circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c | 125 | 
1 files changed, 125 insertions, 0 deletions
| diff --git a/circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c new file mode 100644 index 0000000..9a27e7f --- /dev/null +++ b/circuitpython/lib/libffi/testsuite/libffi.call/va_struct3.c @@ -0,0 +1,125 @@ +/* Area:		ffi_call +   Purpose:		Test passing struct in variable argument lists. +   Limitations:	none. +   PR:			none. +   Originator:	ARM Ltd. */ + +/* { dg-do run } */ +/* { dg-output "" { xfail avr32*-*-* } } */ + +#include "ffitest.h" +#include <stdarg.h> + +struct small_tag +{ +  unsigned char a; +  unsigned char b; +}; + +struct large_tag +{ +  unsigned a; +  unsigned b; +  unsigned c; +  unsigned d; +  unsigned e; +}; + +static struct large_tag +test_fn (int n, ...) +{ +  va_list ap; +  struct small_tag s1; +  struct small_tag s2; +  struct large_tag l; + +  va_start (ap, n); +  s1 = va_arg (ap, struct small_tag); +  l = va_arg (ap, struct large_tag); +  s2 = va_arg (ap, struct small_tag); +  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, +	  s2.a, s2.b); +  va_end (ap); +  l.a += s1.a; +  l.b += s1.b; +  l.c += s2.a; +  l.d += s2.b; +  return l; +} + +int +main (void) +{ +  ffi_cif cif; +  void* args[5]; +  ffi_type* arg_types[5]; + +  ffi_type s_type; +  ffi_type *s_type_elements[3]; + +  ffi_type l_type; +  ffi_type *l_type_elements[6]; + +  struct small_tag s1; +  struct small_tag s2; +  struct large_tag l1; + +  int n; +  struct large_tag res; + +  s_type.size = 0; +  s_type.alignment = 0; +  s_type.type = FFI_TYPE_STRUCT; +  s_type.elements = s_type_elements; + +  s_type_elements[0] = &ffi_type_uchar; +  s_type_elements[1] = &ffi_type_uchar; +  s_type_elements[2] = NULL; + +  l_type.size = 0; +  l_type.alignment = 0; +  l_type.type = FFI_TYPE_STRUCT; +  l_type.elements = l_type_elements; + +  l_type_elements[0] = &ffi_type_uint; +  l_type_elements[1] = &ffi_type_uint; +  l_type_elements[2] = &ffi_type_uint; +  l_type_elements[3] = &ffi_type_uint; +  l_type_elements[4] = &ffi_type_uint; +  l_type_elements[5] = NULL; + +  arg_types[0] = &ffi_type_sint; +  arg_types[1] = &s_type; +  arg_types[2] = &l_type; +  arg_types[3] = &s_type; +  arg_types[4] = NULL; + +  CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK); + +  s1.a = 5; +  s1.b = 6; + +  l1.a = 10; +  l1.b = 11; +  l1.c = 12; +  l1.d = 13; +  l1.e = 14; + +  s2.a = 7; +  s2.b = 8; + +  n = 41; + +  args[0] = &n; +  args[1] = &s1; +  args[2] = &l1; +  args[3] = &s2; +  args[4] = NULL; + +  ffi_call(&cif, FFI_FN(test_fn), &res, args); +  /* { dg-output "5 6 10 11 12 13 14 7 8" } */ +  printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e); +  /* { dg-output "\nres: 15 17 19 21 14" } */ + +  return 0; +} | 
