1 /* Area:		ffi_call, closure_call
2    Purpose:		Check long double arguments.
3    Limitations:	none.
4    PR:			none.
5    Originator:	Blake Chaffin	*/
6 
7 /* This test is known to PASS on armv7l-unknown-linux-gnueabihf, so I have
8    remove the xfail for arm*-*-* below, until we know more.  */
9 /* { dg-do run { xfail strongarm*-*-* xscale*-*-* } } */
10 /* { dg-options -mlong-double-128 { target powerpc64*-*-linux* } } */
11 
12 #include "ffitest.h"
13 
cls_ldouble_fn(long double a1,long double a2,long double a3,long double a4,long double a5,long double a6,long double a7,long double a8)14 long double cls_ldouble_fn(
15 	long double	a1,
16 	long double	a2,
17 	long double	a3,
18 	long double	a4,
19 	long double	a5,
20 	long double	a6,
21 	long double	a7,
22 	long double	a8)
23 {
24 	long double	r = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
25 
26 	printf("%Lg %Lg %Lg %Lg %Lg %Lg %Lg %Lg: %Lg\n",
27 		a1, a2, a3, a4, a5, a6, a7, a8, r);
28 
29 	return r;
30 }
31 
32 static void
cls_ldouble_gn(ffi_cif * cif __UNUSED__,void * resp,void ** args,void * userdata __UNUSED__)33 cls_ldouble_gn(ffi_cif* cif __UNUSED__, void* resp,
34 	       void** args, void* userdata __UNUSED__)
35 {
36 	long double	a1	= *(long double*)args[0];
37 	long double	a2	= *(long double*)args[1];
38 	long double	a3	= *(long double*)args[2];
39 	long double	a4	= *(long double*)args[3];
40 	long double	a5	= *(long double*)args[4];
41 	long double	a6	= *(long double*)args[5];
42 	long double	a7	= *(long double*)args[6];
43 	long double	a8	= *(long double*)args[7];
44 
45 	*(long double*)resp = cls_ldouble_fn(
46 		a1, a2, a3, a4, a5, a6, a7, a8);
47 }
48 
main(void)49 int main(void)
50 {
51 	ffi_cif	cif;
52         void* code;
53 	ffi_closure*	pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
54 	void*			args[9];
55 	ffi_type*		arg_types[9];
56 	long double		res	= 0;
57 
58 	long double	arg1	= 1;
59 	long double	arg2	= 2;
60 	long double	arg3	= 3;
61 	long double	arg4	= 4;
62 	long double	arg5	= 5;
63 	long double	arg6	= 6;
64 	long double	arg7	= 7;
65 	long double	arg8	= 8;
66 
67 	arg_types[0] = &ffi_type_longdouble;
68 	arg_types[1] = &ffi_type_longdouble;
69 	arg_types[2] = &ffi_type_longdouble;
70 	arg_types[3] = &ffi_type_longdouble;
71 	arg_types[4] = &ffi_type_longdouble;
72 	arg_types[5] = &ffi_type_longdouble;
73 	arg_types[6] = &ffi_type_longdouble;
74 	arg_types[7] = &ffi_type_longdouble;
75 	arg_types[8] = NULL;
76 
77 	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 8, &ffi_type_longdouble,
78 		arg_types) == FFI_OK);
79 
80 	args[0] = &arg1;
81 	args[1] = &arg2;
82 	args[2] = &arg3;
83 	args[3] = &arg4;
84 	args[4] = &arg5;
85 	args[5] = &arg6;
86 	args[6] = &arg7;
87 	args[7] = &arg8;
88 	args[8] = NULL;
89 
90 	ffi_call(&cif, FFI_FN(cls_ldouble_fn), &res, args);
91 	/* { dg-output "1 2 3 4 5 6 7 8: 36" } */
92 	printf("res: %Lg\n", res);
93 	/* { dg-output "\nres: 36" } */
94 
95 	CHECK(ffi_prep_closure_loc(pcl, &cif, cls_ldouble_gn, NULL, code) == FFI_OK);
96 
97 	res = ((long double(*)(long double, long double, long double, long double,
98 		long double, long double, long double, long double))(code))(arg1, arg2,
99 		arg3, arg4, arg5, arg6, arg7, arg8);
100 	/* { dg-output "\n1 2 3 4 5 6 7 8: 36" } */
101 	printf("res: %Lg\n", res);
102 	/* { dg-output "\nres: 36" } */
103 
104 	return 0;
105 }
106