1*1fd5a2e1SPrashanth Swaminathan /* Area: ffi_call
2*1fd5a2e1SPrashanth Swaminathan Purpose: Test passing struct in variable argument lists.
3*1fd5a2e1SPrashanth Swaminathan Limitations: none.
4*1fd5a2e1SPrashanth Swaminathan PR: none.
5*1fd5a2e1SPrashanth Swaminathan Originator: ARM Ltd. */
6*1fd5a2e1SPrashanth Swaminathan
7*1fd5a2e1SPrashanth Swaminathan /* { dg-do run } */
8*1fd5a2e1SPrashanth Swaminathan /* { dg-output "" { xfail avr32*-*-* } } */
9*1fd5a2e1SPrashanth Swaminathan
10*1fd5a2e1SPrashanth Swaminathan #include "ffitest.h"
11*1fd5a2e1SPrashanth Swaminathan #include <stdarg.h>
12*1fd5a2e1SPrashanth Swaminathan
13*1fd5a2e1SPrashanth Swaminathan struct small_tag
14*1fd5a2e1SPrashanth Swaminathan {
15*1fd5a2e1SPrashanth Swaminathan unsigned char a;
16*1fd5a2e1SPrashanth Swaminathan unsigned char b;
17*1fd5a2e1SPrashanth Swaminathan };
18*1fd5a2e1SPrashanth Swaminathan
19*1fd5a2e1SPrashanth Swaminathan struct large_tag
20*1fd5a2e1SPrashanth Swaminathan {
21*1fd5a2e1SPrashanth Swaminathan unsigned a;
22*1fd5a2e1SPrashanth Swaminathan unsigned b;
23*1fd5a2e1SPrashanth Swaminathan unsigned c;
24*1fd5a2e1SPrashanth Swaminathan unsigned d;
25*1fd5a2e1SPrashanth Swaminathan unsigned e;
26*1fd5a2e1SPrashanth Swaminathan };
27*1fd5a2e1SPrashanth Swaminathan
28*1fd5a2e1SPrashanth Swaminathan static struct large_tag
test_fn(int n,...)29*1fd5a2e1SPrashanth Swaminathan test_fn (int n, ...)
30*1fd5a2e1SPrashanth Swaminathan {
31*1fd5a2e1SPrashanth Swaminathan va_list ap;
32*1fd5a2e1SPrashanth Swaminathan struct small_tag s1;
33*1fd5a2e1SPrashanth Swaminathan struct small_tag s2;
34*1fd5a2e1SPrashanth Swaminathan struct large_tag l;
35*1fd5a2e1SPrashanth Swaminathan
36*1fd5a2e1SPrashanth Swaminathan va_start (ap, n);
37*1fd5a2e1SPrashanth Swaminathan s1 = va_arg (ap, struct small_tag);
38*1fd5a2e1SPrashanth Swaminathan l = va_arg (ap, struct large_tag);
39*1fd5a2e1SPrashanth Swaminathan s2 = va_arg (ap, struct small_tag);
40*1fd5a2e1SPrashanth Swaminathan 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,
41*1fd5a2e1SPrashanth Swaminathan s2.a, s2.b);
42*1fd5a2e1SPrashanth Swaminathan va_end (ap);
43*1fd5a2e1SPrashanth Swaminathan l.a += s1.a;
44*1fd5a2e1SPrashanth Swaminathan l.b += s1.b;
45*1fd5a2e1SPrashanth Swaminathan l.c += s2.a;
46*1fd5a2e1SPrashanth Swaminathan l.d += s2.b;
47*1fd5a2e1SPrashanth Swaminathan return l;
48*1fd5a2e1SPrashanth Swaminathan }
49*1fd5a2e1SPrashanth Swaminathan
50*1fd5a2e1SPrashanth Swaminathan int
main(void)51*1fd5a2e1SPrashanth Swaminathan main (void)
52*1fd5a2e1SPrashanth Swaminathan {
53*1fd5a2e1SPrashanth Swaminathan ffi_cif cif;
54*1fd5a2e1SPrashanth Swaminathan void* args[5];
55*1fd5a2e1SPrashanth Swaminathan ffi_type* arg_types[5];
56*1fd5a2e1SPrashanth Swaminathan
57*1fd5a2e1SPrashanth Swaminathan ffi_type s_type;
58*1fd5a2e1SPrashanth Swaminathan ffi_type *s_type_elements[3];
59*1fd5a2e1SPrashanth Swaminathan
60*1fd5a2e1SPrashanth Swaminathan ffi_type l_type;
61*1fd5a2e1SPrashanth Swaminathan ffi_type *l_type_elements[6];
62*1fd5a2e1SPrashanth Swaminathan
63*1fd5a2e1SPrashanth Swaminathan struct small_tag s1;
64*1fd5a2e1SPrashanth Swaminathan struct small_tag s2;
65*1fd5a2e1SPrashanth Swaminathan struct large_tag l1;
66*1fd5a2e1SPrashanth Swaminathan
67*1fd5a2e1SPrashanth Swaminathan int n;
68*1fd5a2e1SPrashanth Swaminathan struct large_tag res;
69*1fd5a2e1SPrashanth Swaminathan
70*1fd5a2e1SPrashanth Swaminathan s_type.size = 0;
71*1fd5a2e1SPrashanth Swaminathan s_type.alignment = 0;
72*1fd5a2e1SPrashanth Swaminathan s_type.type = FFI_TYPE_STRUCT;
73*1fd5a2e1SPrashanth Swaminathan s_type.elements = s_type_elements;
74*1fd5a2e1SPrashanth Swaminathan
75*1fd5a2e1SPrashanth Swaminathan s_type_elements[0] = &ffi_type_uchar;
76*1fd5a2e1SPrashanth Swaminathan s_type_elements[1] = &ffi_type_uchar;
77*1fd5a2e1SPrashanth Swaminathan s_type_elements[2] = NULL;
78*1fd5a2e1SPrashanth Swaminathan
79*1fd5a2e1SPrashanth Swaminathan l_type.size = 0;
80*1fd5a2e1SPrashanth Swaminathan l_type.alignment = 0;
81*1fd5a2e1SPrashanth Swaminathan l_type.type = FFI_TYPE_STRUCT;
82*1fd5a2e1SPrashanth Swaminathan l_type.elements = l_type_elements;
83*1fd5a2e1SPrashanth Swaminathan
84*1fd5a2e1SPrashanth Swaminathan l_type_elements[0] = &ffi_type_uint;
85*1fd5a2e1SPrashanth Swaminathan l_type_elements[1] = &ffi_type_uint;
86*1fd5a2e1SPrashanth Swaminathan l_type_elements[2] = &ffi_type_uint;
87*1fd5a2e1SPrashanth Swaminathan l_type_elements[3] = &ffi_type_uint;
88*1fd5a2e1SPrashanth Swaminathan l_type_elements[4] = &ffi_type_uint;
89*1fd5a2e1SPrashanth Swaminathan l_type_elements[5] = NULL;
90*1fd5a2e1SPrashanth Swaminathan
91*1fd5a2e1SPrashanth Swaminathan arg_types[0] = &ffi_type_sint;
92*1fd5a2e1SPrashanth Swaminathan arg_types[1] = &s_type;
93*1fd5a2e1SPrashanth Swaminathan arg_types[2] = &l_type;
94*1fd5a2e1SPrashanth Swaminathan arg_types[3] = &s_type;
95*1fd5a2e1SPrashanth Swaminathan arg_types[4] = NULL;
96*1fd5a2e1SPrashanth Swaminathan
97*1fd5a2e1SPrashanth Swaminathan CHECK(ffi_prep_cif_var(&cif, FFI_DEFAULT_ABI, 1, 4, &l_type, arg_types) == FFI_OK);
98*1fd5a2e1SPrashanth Swaminathan
99*1fd5a2e1SPrashanth Swaminathan s1.a = 5;
100*1fd5a2e1SPrashanth Swaminathan s1.b = 6;
101*1fd5a2e1SPrashanth Swaminathan
102*1fd5a2e1SPrashanth Swaminathan l1.a = 10;
103*1fd5a2e1SPrashanth Swaminathan l1.b = 11;
104*1fd5a2e1SPrashanth Swaminathan l1.c = 12;
105*1fd5a2e1SPrashanth Swaminathan l1.d = 13;
106*1fd5a2e1SPrashanth Swaminathan l1.e = 14;
107*1fd5a2e1SPrashanth Swaminathan
108*1fd5a2e1SPrashanth Swaminathan s2.a = 7;
109*1fd5a2e1SPrashanth Swaminathan s2.b = 8;
110*1fd5a2e1SPrashanth Swaminathan
111*1fd5a2e1SPrashanth Swaminathan n = 41;
112*1fd5a2e1SPrashanth Swaminathan
113*1fd5a2e1SPrashanth Swaminathan args[0] = &n;
114*1fd5a2e1SPrashanth Swaminathan args[1] = &s1;
115*1fd5a2e1SPrashanth Swaminathan args[2] = &l1;
116*1fd5a2e1SPrashanth Swaminathan args[3] = &s2;
117*1fd5a2e1SPrashanth Swaminathan args[4] = NULL;
118*1fd5a2e1SPrashanth Swaminathan
119*1fd5a2e1SPrashanth Swaminathan ffi_call(&cif, FFI_FN(test_fn), &res, args);
120*1fd5a2e1SPrashanth Swaminathan /* { dg-output "5 6 10 11 12 13 14 7 8" } */
121*1fd5a2e1SPrashanth Swaminathan printf("res: %d %d %d %d %d\n", res.a, res.b, res.c, res.d, res.e);
122*1fd5a2e1SPrashanth Swaminathan /* { dg-output "\nres: 15 17 19 21 14" } */
123*1fd5a2e1SPrashanth Swaminathan
124*1fd5a2e1SPrashanth Swaminathan return 0;
125*1fd5a2e1SPrashanth Swaminathan }
126