]>
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 | ||
9 | /* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ | |
10 | #include "ffitest.h" | |
11 | ||
12 | typedef struct A { | |
13 | long 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 | static B B_fn(struct A b2, struct B b3) | |
23 | { | |
24 | struct B result; | |
25 | ||
26 | result.x.a = b2.a + b3.x.a; | |
27 | result.x.b = b2.b + b3.x.b + b3.y; | |
28 | result.y = b2.b + b3.x.b; | |
29 | ||
30 | printf("%d %d %d %d %d: %d %d %d\n", (int)b2.a, b2.b, | |
31 | (int)b3.x.a, b3.x.b, b3.y, | |
32 | (int)result.x.a, result.x.b, result.y); | |
33 | ||
34 | return result; | |
35 | } | |
36 | ||
37 | static void | |
9fdeb13b AT |
38 | B_gn(ffi_cif* cif __UNUSED__, void* resp, void** args, |
39 | void* userdata __UNUSED__) | |
b47b5e08 AT |
40 | { |
41 | struct A b0; | |
42 | struct B b1; | |
43 | ||
44 | b0 = *(struct A*)(args[0]); | |
45 | b1 = *(struct B*)(args[1]); | |
46 | ||
47 | *(B*)resp = B_fn(b0, b1); | |
48 | } | |
49 | ||
50 | int main (void) | |
51 | { | |
52 | ffi_cif cif; | |
53 | #ifndef USING_MMAP | |
54 | static ffi_closure cl; | |
55 | #endif | |
56 | ffi_closure *pcl; | |
57 | void* args_dbl[3]; | |
58 | ffi_type* cls_struct_fields[3]; | |
59 | ffi_type* cls_struct_fields1[3]; | |
60 | ffi_type cls_struct_type, cls_struct_type1; | |
61 | ffi_type* dbl_arg_types[3]; | |
62 | ||
63 | #ifdef USING_MMAP | |
64 | pcl = allocate_mmap (sizeof(ffi_closure)); | |
65 | #else | |
66 | pcl = &cl; | |
67 | #endif | |
68 | ||
69 | cls_struct_type.size = 0; | |
70 | cls_struct_type.alignment = 0; | |
71 | cls_struct_type.type = FFI_TYPE_STRUCT; | |
72 | cls_struct_type.elements = cls_struct_fields; | |
73 | ||
74 | cls_struct_type1.size = 0; | |
75 | cls_struct_type1.alignment = 0; | |
76 | cls_struct_type1.type = FFI_TYPE_STRUCT; | |
77 | cls_struct_type1.elements = cls_struct_fields1; | |
78 | ||
79 | struct A e_dbl = { 1.0, 7}; | |
80 | struct B f_dbl = {{12.0 , 127}, 99}; | |
81 | ||
82 | struct B res_dbl; | |
83 | ||
84 | cls_struct_fields[0] = &ffi_type_longdouble; | |
85 | cls_struct_fields[1] = &ffi_type_uchar; | |
86 | cls_struct_fields[2] = NULL; | |
87 | ||
88 | cls_struct_fields1[0] = &cls_struct_type; | |
89 | cls_struct_fields1[1] = &ffi_type_uchar; | |
90 | cls_struct_fields1[2] = NULL; | |
91 | ||
92 | ||
93 | dbl_arg_types[0] = &cls_struct_type; | |
94 | dbl_arg_types[1] = &cls_struct_type1; | |
95 | dbl_arg_types[2] = NULL; | |
96 | ||
97 | CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &cls_struct_type1, | |
98 | dbl_arg_types) == FFI_OK); | |
99 | ||
100 | args_dbl[0] = &e_dbl; | |
101 | args_dbl[1] = &f_dbl; | |
102 | args_dbl[2] = NULL; | |
103 | ||
104 | ffi_call(&cif, FFI_FN(B_fn), &res_dbl, args_dbl); | |
105 | /* { dg-output "1 7 12 127 99: 13 233 134" } */ | |
106 | CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); | |
107 | CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); | |
108 | CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); | |
109 | ||
110 | ||
111 | CHECK(ffi_prep_closure(pcl, &cif, B_gn, NULL) == FFI_OK); | |
112 | ||
113 | res_dbl = ((B(*)(A, B))(pcl))(e_dbl, f_dbl); | |
114 | /* { dg-output "\n1 7 12 127 99: 13 233 134" } */ | |
115 | CHECK( res_dbl.x.a == (e_dbl.a + f_dbl.x.a)); | |
116 | CHECK( res_dbl.x.b == (e_dbl.b + f_dbl.x.b + f_dbl.y)); | |
117 | CHECK( res_dbl.y == (e_dbl.b + f_dbl.x.b)); | |
118 | ||
119 | exit(0); | |
120 | } |