1/* Area:		ffi_call, closure_call
2   Purpose:		Test long doubles passed in variable argument lists.
3   Limitations:	none.
4   PR:			none.
5   Originator:	Blake Chaffin 6/6/2007	 */
6
7/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
8#include "ffitest.h"
9
10static void
11cls_longdouble_va_fn(ffi_cif* cif, void* resp, void** args, void* userdata)
12{
13	char*		format	= *(char**)args[0];
14	long double	ldValue	= *(long double*)args[1];
15
16	*(ffi_arg*)resp = printf(format, ldValue);
17}
18
19int main (void)
20{
21	ffi_cif cif;
22#ifndef USING_MMAP
23	static ffi_closure cl;
24#endif
25	ffi_closure *pcl;
26	void* args[3];
27	ffi_type* arg_types[3];
28
29#ifdef USING_MMAP
30	pcl = allocate_mmap (sizeof(ffi_closure));
31#else
32	pcl = &cl;
33#endif
34
35	char*		format	= "%L.1f\n";
36	long double	ldArg	= 7;
37	ffi_arg		res		= 0;
38
39	arg_types[0] = &ffi_type_pointer;
40	arg_types[1] = &ffi_type_longdouble;
41	arg_types[2] = NULL;
42
43	CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ffi_type_sint,
44		arg_types) == FFI_OK);
45
46	args[0] = &format;
47	args[1] = &ldArg;
48	args[2] = NULL;
49
50	ffi_call(&cif, FFI_FN(printf), &res, args);
51	// { dg-output "7.0" }
52	printf("res: %d\n", res);
53	// { dg-output "\nres: 4" }
54
55	CHECK(ffi_prep_closure(pcl, &cif, cls_longdouble_va_fn, NULL) == FFI_OK);
56
57	res	= ((int(*)(char*, long double))(pcl))(format, ldArg);
58	// { dg-output "\n7.0" }
59	printf("res: %d\n", res);
60	// { dg-output "\nres: 4" }
61
62	exit(0);
63}
64