1a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* Area:	ffi_call, closure_call
2a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project   Purpose:	Check structure passing with different structure size.
3a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project		Contains structs as parameter of the struct itself.
4a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project   Limitations:	none.
5a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project   PR:		none.
6a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project   Originator:	<andreast@gcc.gnu.org> 20030828	 */
7a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
8a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project/* { dg-do run } */
9a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#include "ffitest.h"
10a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
11a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projecttypedef struct cls_struct_16byte1 {
12a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  double a;
13a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  float b;
14a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  int c;
15a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} cls_struct_16byte1;
16a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
17a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projecttypedef struct cls_struct_16byte2 {
18a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  int ii;
19a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  double dd;
20a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  float ff;
21a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} cls_struct_16byte2;
22a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
23a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projecttypedef struct cls_struct_combined {
24a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_16byte1 d;
25a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_16byte2 e;
26a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project} cls_struct_combined;
27a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
28a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectcls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
29a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project					   struct cls_struct_16byte2 b1,
30a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project					   struct cls_struct_combined b2,
31a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project					   struct cls_struct_16byte1 b3)
32a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{
33a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_combined result;
34a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
35a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  result.d.a = b0.a + b1.dd + b2.d.a;
36a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  result.d.b = b0.b + b1.ff + b2.d.b;
37a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  result.d.c = b0.c + b1.ii + b2.d.c;
38a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  result.e.ii = b0.c + b1.ii + b2.e.ii;
39a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  result.e.dd = b0.a + b1.dd + b2.e.dd;
40a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  result.e.ff = b0.b + b1.ff + b2.e.ff;
41a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
42a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  printf("%g %g %d %d %g %g %g %g %d %d %g %g %g %g %d: %g %g %d %d %g %g\n",
43a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 b0.a, b0.b, b0.c,
44a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 b1.ii, b1.dd, b1.ff,
45a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 b2.d.a, b2.d.b, b2.d.c,
46a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 b2.e.ii, b2.e.dd, b2.e.ff,
47a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 b3.a, b3.b, b3.c,
48a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 result.d.a, result.d.b, result.d.c,
49a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	 result.e.ii, result.e.dd, result.e.ff);
50a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
51a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  return result;
52a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project}
53a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
54a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectstatic void
55a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectcls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
56a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project		       void* userdata __UNUSED__)
57a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{
58a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_16byte1 b0;
59a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_16byte2 b1;
60a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_combined b2;
61a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_16byte1 b3;
62a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
63a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  b0 = *(struct cls_struct_16byte1*)(args[0]);
64a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  b1 = *(struct cls_struct_16byte2*)(args[1]);
65a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  b2 = *(struct cls_struct_combined*)(args[2]);
66a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  b3 = *(struct cls_struct_16byte1*)(args[3]);
67a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
68a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
69a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2, b3);
70a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project}
71a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
72a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Projectint main (void)
73a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project{
74a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_cif cif;
75a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifndef USING_MMAP
76a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  static ffi_closure cl;
77a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif
78a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_closure *pcl;
79a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  void* args_dbl[5];
80a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_type* cls_struct_fields[5];
81a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_type* cls_struct_fields1[5];
82a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_type* cls_struct_fields2[5];
83a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
84a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_type* dbl_arg_types[5];
85a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
86a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#ifdef USING_MMAP
87a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  pcl = allocate_mmap (sizeof(ffi_closure));
88a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#else
89a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  pcl = &cl;
90a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project#endif
91a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
92a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type.size = 0;
93a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type.alignment = 0;
94a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type.type = FFI_TYPE_STRUCT;
95a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type.elements = cls_struct_fields;
96a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
97a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type1.size = 0;
98a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type1.alignment = 0;
99a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type1.type = FFI_TYPE_STRUCT;
100a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type1.elements = cls_struct_fields1;
101a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
102a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type2.size = 0;
103a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type2.alignment = 0;
104a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type2.type = FFI_TYPE_STRUCT;
105a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_type2.elements = cls_struct_fields2;
106a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
107a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
108a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
109a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
110a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project				      {3, 1.0, 8.0}};
111a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_16byte1 h_dbl = { 3.0, 2.0, 4};
112a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  struct cls_struct_combined res_dbl;
113a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
114a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields[0] = &ffi_type_double;
115a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields[1] = &ffi_type_float;
116a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields[2] = &ffi_type_sint;
117a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields[3] = NULL;
118a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
119a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields1[0] = &ffi_type_sint;
120a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields1[1] = &ffi_type_double;
121a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields1[2] = &ffi_type_float;
122a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields1[3] = NULL;
123a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
124a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields2[0] = &cls_struct_type;
125a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields2[1] = &cls_struct_type1;
126a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  cls_struct_fields2[2] = NULL;
127a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
128a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
129a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  dbl_arg_types[0] = &cls_struct_type;
130a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  dbl_arg_types[1] = &cls_struct_type1;
131a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  dbl_arg_types[2] = &cls_struct_type2;
132a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  dbl_arg_types[3] = &cls_struct_type;
133a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  dbl_arg_types[4] = NULL;
134a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
135a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &cls_struct_type2,
136a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project		     dbl_arg_types) == FFI_OK);
137a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
138a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  args_dbl[0] = &e_dbl;
139a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  args_dbl[1] = &f_dbl;
140a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  args_dbl[2] = &g_dbl;
141a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  args_dbl[3] = &h_dbl;
142a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  args_dbl[4] = NULL;
143a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
144a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
145a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
146a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
147a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
148a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
149a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
150a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
151a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
152a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
153a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK(ffi_prep_closure(pcl, &cif, cls_struct_combined_gn, NULL) == FFI_OK);
154a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project
155a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
156a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project				     cls_struct_16byte2,
157a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project				     cls_struct_combined,
158a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project				     cls_struct_16byte1))
159a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project	     (pcl))(e_dbl, f_dbl, g_dbl, h_dbl);
160a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8 3 2 4: 15 10 13 10 12 13" } */
161a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
162a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
163a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
164a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
165a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
166a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
167a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  //  CHECK( 1 == 0);
168a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project  exit(0);
169a89495f48f185779ff7d9d64ce6e6b037c9ded87The Android Open Source Project}
170