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
;
32 dummyVar
= dummy_func(trample1
, trample2
, trample3
, trample4
,
33 trample5
, trample6
, trample7
, trample8
);
35 void* result
= (void*)((intptr_t)a1
+ (intptr_t)a2
);
37 printf("0x%08x 0x%08x: 0x%08x\n",
38 (unsigned int)(uintptr_t) a1
,
39 (unsigned int)(uintptr_t) a2
,
40 (unsigned int)(uintptr_t) result
);
45 void* cls_pointer_fn1(void* a1
, void* a2
)
47 long double trample1
= (intptr_t)a1
+ (intptr_t)a2
;
48 char trample2
= ((char*)&a1
)[0] + ((char*)&a2
)[0];
49 long double trample3
= (intptr_t)trample1
+ (intptr_t)a1
;
50 char trample4
= trample2
+ ((char*)&a1
)[1];
51 long double trample5
= (intptr_t)trample3
+ (intptr_t)a2
;
52 char trample6
= trample4
+ ((char*)&a2
)[1];
53 long double trample7
= (intptr_t)trample5
+ (intptr_t)trample1
;
54 char trample8
= trample6
+ trample2
;
56 dummyVar
= dummy_func(trample1
, trample2
, trample3
, trample4
,
57 trample5
, trample6
, trample7
, trample8
);
59 void* result
= (void*)((intptr_t)a1
+ (intptr_t)a2
);
61 printf("0x%08x 0x%08x: 0x%08x\n",
62 (unsigned int)(intptr_t) a1
,
63 (unsigned int)(intptr_t) a2
,
64 (unsigned int)(intptr_t) result
);
66 result
= cls_pointer_fn2(result
, a1
);
72 cls_pointer_gn(ffi_cif
* cif __UNUSED__
, void* resp
,
73 void** args
, void* userdata __UNUSED__
)
75 void* a1
= *(void**)(args
[0]);
76 void* a2
= *(void**)(args
[1]);
78 long double trample1
= (intptr_t)a1
+ (intptr_t)a2
;
79 char trample2
= ((char*)&a1
)[0] + ((char*)&a2
)[0];
80 long double trample3
= (intptr_t)trample1
+ (intptr_t)a1
;
81 char trample4
= trample2
+ ((char*)&a1
)[1];
82 long double trample5
= (intptr_t)trample3
+ (intptr_t)a2
;
83 char trample6
= trample4
+ ((char*)&a2
)[1];
84 long double trample7
= (intptr_t)trample5
+ (intptr_t)trample1
;
85 char trample8
= trample6
+ trample2
;
87 dummyVar
= dummy_func(trample1
, trample2
, trample3
, trample4
,
88 trample5
, trample6
, trample7
, trample8
);
90 *(void**)resp
= cls_pointer_fn1(a1
, a2
);
97 ffi_closure
* pcl
= ffi_closure_alloc(sizeof(ffi_closure
), &code
);
99 // ffi_type cls_pointer_type;
100 ffi_type
* arg_types
[3];
102 /* cls_pointer_type.size = sizeof(void*);
103 cls_pointer_type.alignment = 0;
104 cls_pointer_type.type = FFI_TYPE_POINTER;
105 cls_pointer_type.elements = NULL;*/
107 void* arg1
= (void*)0x01234567;
108 void* arg2
= (void*)0x89abcdef;
111 arg_types
[0] = &ffi_type_pointer
;
112 arg_types
[1] = &ffi_type_pointer
;
115 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 2, &ffi_type_pointer
,
116 arg_types
) == FFI_OK
);
123 ffi_call(&cif
, FFI_FN(cls_pointer_fn1
), &res
, args
);
125 printf("res: 0x%08x\n", (unsigned int) res
);
126 // { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
127 // { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
128 // { dg-output "\nres: 0x8bf258bd" }
130 CHECK(ffi_prep_closure_loc(pcl
, &cif
, cls_pointer_gn
, NULL
, code
) == FFI_OK
);
132 res
= (ffi_arg
)(uintptr_t)((void*(*)(void*, void*))(code
))(arg1
, arg2
);
134 printf("res: 0x%08x\n", (unsigned int) res
);
135 // { dg-output "\n0x01234567 0x89abcdef: 0x8acf1356" }
136 // { dg-output "\n0x8acf1356 0x01234567: 0x8bf258bd" }
137 // { dg-output "\nres: 0x8bf258bd" }