]>
Commit | Line | Data |
---|---|---|
b47b5e08 AT |
1 | /* Area: ffi_call, closure_call |
2 | Purpose: Check structure passing with different structure size. | |
3 | Contains structs as parameter of the struct itself. | |
4 | Sample taken from Alan Modras patch to src/prep_cif.c. | |
5 | Limitations: none. | |
6 | PR: none. | |
7 | Originator: <andreast@gcc.gnu.org> 20051010 */ | |
8 | ||
1a4878f7 | 9 | /* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* powerpc*-*-darwin* } } */ |
b47b5e08 AT |
10 | #include "ffitest.h" |
11 | ||
12 | typedef struct A { | |
13 | double a; | |
14 | unsigned char b; | |
15 | } A; | |
16 | ||
17 | typedef struct B { | |
18 | struct A x; | |
19 | unsigned char y; | |
20 | } B; | |
21 | ||
22 | typedef struct C { | |
23 | long d; | |
24 | unsigned char e; | |
25 | } C; | |
26 | ||
27 | static B B_fn(struct A b2, struct B b3, struct C b4) | |
28 | { | |
29 | struct B result; | |
30 | ||
31 | result.x.a = b2.a + b3.x.a + b4.d; | |
32 | result.x.b = b2.b + b3.x.b + b3.y + b4.e; | |
33 | result.y = b2.b + b3.x.b + b4.e; | |
34 | ||
35 | printf("%d %d %d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, | |
36 | (int)b3.x.a, b3.x.b, b3.y, (int)b4.d, b4.e, | |
37 | (int)result.x.a, result.x.b, result.y); | |
38 | ||
39 | return result; | |
40 | } | |
41 | ||
42 | static void | |
43 | B_gn(ffi_cif* cif __attribute__((unused)), void* resp, void** args, | |
44 | void* userdata __attribute__((unused))) | |
45 | { | |
46 | struct A b0; | |
47 | struct B b1; | |
48 | struct C b2; | |
49 | ||
50 | b0 = *(struct A*)(args[0]); | |
51 | b1 = *(struct B*)(args[1]); | |
52 | b2 = *(struct C*)(args[2]); | |
53 | ||
54 | *(B*)resp = B_fn(b0, b1, b2); | |
55 | } | |
56 | ||
57 | int main (void) | |
58 | { | |
59 | ffi_cif cif; | |
60 | #ifndef USING_MMAP | |
61 | static ffi_closure cl; | |
62 | #endif | |
63 | ffi_closure *pcl; | |
64 | void* args_dbl[4]; | |
65 | ffi_type* cls_struct_fields[3]; | |
66 | ffi_type* cls_struct_fields1[3]; | |
67 | ffi_type* cls_struct_fields2[3]; | |
68 | ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2; | |
69 | ffi_type* dbl_arg_types[4]; | |
70 | ||
71 | #ifdef USING_MMAP | |
72 | pcl = allocate_mmap (sizeof(ffi_closure)); | |
73 | #else | |
74 | pcl = &cl; | |
75 | #endif | |
76 | ||
77 | cls_struct_type.size = 0; | |
78 | cls_struct_type.alignment = 0; | |
79 | cls_struct_type.type = FFI_TYPE_STRUCT; | |
80 | cls_struct_type.elements = cls_struct_fields; | |
81 | ||
82 | cls_struct_type1.size = 0; | |
83 | cls_struct_type1.alignment = 0; | |
84 | cls_struct_type1.type = FFI_TYPE_STRUCT; | |
85 | cls_struct_type1.elements = cls_struct_fields1; | |
86 | ||
87 | cls_struct_type2.size = 0; | |
88 | cls_struct_type2.alignment = 0; | |
89 | cls_struct_type2.type = FFI_TYPE_STRUCT; | |
90 | cls_struct_type2.elements = cls_struct_fields2; | |
91 | ||
92 | struct A e_dbl = { 1.0, 7}; | |
93 | struct B f_dbl = {{12.0 , 127}, 99}; | |
94 | struct C g_dbl = { 2, 9}; | |
95 | ||
96 | struct B res_dbl; | |
97 | ||
98 | cls_struct_fields[0] = &ffi_type_double; | |
99 | cls_struct_fields[1] = &ffi_type_uchar; | |
100 | cls_struct_fields[2] = NULL; | |
101 | ||
102 | cls_struct_fields1[0] = &cls_struct_type; | |
103 | cls_struct_fields1[1] = &ffi_type_uchar; | |
104 | cls_struct_fields1[2] = NULL; | |
105 | ||
106 | cls_struct_fields2[0] = &ffi_type_mylong; | |
107 | cls_struct_fields2[1] = &ffi_type_uchar; | |
108 | cls_struct_fields2[2] = NULL; | |
109 | ||
110 | ||
111 | dbl_arg_types[0] = &cls_struct_type; | |
112 | dbl_arg_types[1] = &cls_struct_type1; | |
113 | dbl_arg_types[2] = &cls_struct_type2; | |
114 | dbl_arg_types[3] = NULL; | |
115 | ||
116 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type1, | |
117 | dbl_arg_types) == FFI_OK); | |
118 | ||
119 | args_dbl[0] = &e_dbl; | |
120 | args_dbl[1] = &f_dbl; | |
121 | args_dbl[2] = &g_dbl; | |
122 | args_dbl[3] = NULL; | |
123 | ||
124 | ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); | |
125 | /* { dg-output "1 7 12 127 99 2 9: 15 242 143" } */ | |
126 | CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); | |
127 | CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); | |
128 | CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); | |
129 | ||
130 | CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK); | |
131 | ||
132 | res_dbl = ((B(*)(A, B, C))(pcl))(e_dbl, f_dbl, g_dbl); | |
133 | /* { dg-output "\n1 7 12 127 99 2 9: 15 242 143" } */ | |
134 | CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a + g_dbl.d)); | |
135 | CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y + g_dbl.e)); | |
136 | CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b + g_dbl.e)); | |
137 | ||
138 | exit(0); | |
139 | } |