1 /* Area: ffi_call, closure_call
2 Purpose: Check pointer arguments across multiple hideous stack frames.
5 Originator: Blake Chaffin 6/7/2007 */
7 /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
13 long double a1
, char b1
,
14 long double a2
, char b2
,
15 long double a3
, char b3
,
16 long double a4
, char b4
)
18 return a1
+ b1
+ a2
+ b2
+ a3
+ b3
+ a4
+ b4
;
21 void* cls_pointer_fn2(void* a1
, void* a2
)
23 long double trample1
= (intptr_t)a1
+ (intptr_t)a2
;
24 char trample2
= ((char*)&a1
)[0] + ((char*)&a2
)[0];
25 long double trample3
= (intptr_t)trample1
+ (intptr_t)a1
;
26 char trample4
= trample2
+ ((char*)&a1
)[1];
27 long double trample5
= (intptr_t)trample3
+ (intptr_t)a2
;
28 char trample6
= trample4
+ ((char*)&a2
)[1];
29 long double trample7
= (intptr_t)trample5
+ (intptr_t)trample1
;
30 char trample8
= trample6
+ trample2
;
33 dummyVar
= dummy_func(trample1
, trample2
, trample3
, trample4
,
34 trample5
, trample6
, trample7
, trample8
);
36 result
= (void*)((intptr_t)a1
+ (intptr_t)a2
);
38 printf("0x%08x 0x%08x: 0x%08x\n",
39 (unsigned int)(uintptr_t) a1
,
40 (unsigned int)(uintptr_t) a2
,
41 (unsigned int)(uintptr_t) result
);
46 void* cls_pointer_fn1(void* a1
, void* a2
)
48 long double trample1
= (intptr_t)a1
+ (intptr_t)a2
;
49 char trample2
= ((char*)&a1
)[0] + ((char*)&a2
)[0];
50 long double trample3
= (intptr_t)trample1
+ (intptr_t)a1
;
51 char trample4
= trample2
+ ((char*)&a1
)[1];
52 long double trample5
= (intptr_t)trample3
+ (intptr_t)a2
;
53 char trample6
= trample4
+ ((char*)&a2
)[1];
54 long double trample7
= (intptr_t)trample5
+ (intptr_t)trample1
;
55 char trample8
= trample6
+ trample2
;
58 dummyVar
= dummy_func(trample1
, trample2
, trample3
, trample4
,
59 trample5
, trample6
, trample7
, trample8
);
61 result
= (void*)((intptr_t)a1
+ (intptr_t)a2
);
63 printf("0x%08x 0x%08x: 0x%08x\n",
64 (unsigned int)(intptr_t) a1
,
65 (unsigned int)(intptr_t) a2
,
66 (unsigned int)(intptr_t) result
);
68 result
= cls_pointer_fn2(result
, a1
);
74 cls_pointer_gn(ffi_cif
* cif __UNUSED__
, void* resp
,
75 void** args
, void* userdata __UNUSED__
)
77 void* a1
= *(void**)(args
[0]);
78 void* a2
= *(void**)(args
[1]);
80 long double trample1
= (intptr_t)a1
+ (intptr_t)a2
;
81 char trample2
= ((char*)&a1
)[0] + ((char*)&a2
)[0];
82 long double trample3
= (intptr_t)trample1
+ (intptr_t)a1
;
83 char trample4
= trample2
+ ((char*)&a1
)[1];
84 long double trample5
= (intptr_t)trample3
+ (intptr_t)a2
;
85 char trample6
= trample4
+ ((char*)&a2
)[1];
86 long double trample7
= (intptr_t)trample5
+ (intptr_t)trample1
;
87 char trample8
= trample6
+ trample2
;
89 dummyVar
= dummy_func(trample1
, trample2
, trample3
, trample4
,
90 trample5
, trample6
, trample7
, trample8
);
92 *(void**)resp
= cls_pointer_fn1(a1
, a2
);
99 ffi_closure
* pcl
= ffi_closure_alloc(sizeof(ffi_closure
), &code
);
101 /* ffi_type cls_pointer_type; */
102 ffi_type
* arg_types
[3];
104 /* cls_pointer_type.size = sizeof(void*);
105 cls_pointer_type.alignment = 0;
106 cls_pointer_type.type = FFI_TYPE_POINTER;
107 cls_pointer_type.elements = NULL;*/
109 void* arg1
= (void*)0x01234567;
110 void* arg2
= (void*)0x89abcdef;
113 arg_types
[0] = &ffi_type_pointer
;
114 arg_types
[1] = &ffi_type_pointer
;
117 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 2, &ffi_type_pointer
,
118 arg_types
) == FFI_OK
);
125 ffi_call(&cif
, FFI_FN(cls_pointer_fn1
), &res
, args
);
127 printf("res: 0x%08x\n", (unsigned int) res
);
128 /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
129 /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
130 /* { dg-output "\nres: 0x8bf258bd" } */
132 CHECK(ffi_prep_closure_loc(pcl
, &cif
, cls_pointer_gn
, NULL
, code
) == FFI_OK
);
134 res
= (ffi_arg
)(uintptr_t)((void*(*)(void*, void*))(code
))(arg1
, arg2
);
136 printf("res: 0x%08x\n", (unsigned int) res
);
137 /* { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" } */
138 /* { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" } */
139 /* { dg-output "\nres: 0x8bf258bd" } */