1457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* Area:	closure_call
2457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   Purpose:	Check multiple values passing from different type.
3457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique		Also, exceed the limit of gpr and fpr registers on PowerPC.
4457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   Limitations:	none.
5457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   PR:		PR23404
6457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   Originator:	<andreast@gcc.gnu.org> 20050830	 */
7457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
8457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* { dg-do run } */
9457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#include "ffitest.h"
10457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
11457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquestatic void
12457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piqueclosure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
13457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique		 void* userdata)
14457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique{
15457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  *(ffi_arg*)resp =
16457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)*(unsigned long long *)args[0] +
17457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)(*(unsigned long long *)args[1]) +
18457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)(*(unsigned long long *)args[2]) +
19457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)*(unsigned long long *)args[3] +
20457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)(*(int *)args[4]) + (int)(*(double *)args[5]) +
21457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)*(double *)args[6] + (int)(*(float *)args[7]) +
22457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)(*(double *)args[8]) + (int)*(double *)args[9] +
23457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
24457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)*(int *)args[12] + (int)(*(int *)args[13]) +
25457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (int)(*(double *)args[14]) +  (int)*(double *)args[15] +
26457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (intptr_t)userdata;
27457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
28457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
29457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)*(unsigned long long  *)args[0],
30457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(*(unsigned long long  *)args[1]),
31457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(*(unsigned long long  *)args[2]),
32457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)*(unsigned long long  *)args[3],
33457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(*(int *)args[4]), (int)(*(double *)args[5]),
34457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)*(double *)args[6], (int)(*(float *)args[7]),
35457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(*(double *)args[8]), (int)*(double *)args[9],
36457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
37457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)*(int *)args[12], (int)(*(int *)args[13]),
38457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(*(double *)args[14]), (int)(*(double *)args[15]),
39457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	 (int)(intptr_t)userdata, (int)*(ffi_arg *)resp);
40457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
41457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique}
42457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
43457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piquetypedef int (*closure_test_type0)(unsigned long long,
44457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique				  unsigned long long,
45457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique				  unsigned long long,
46457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique				  unsigned long long,
47457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique				  int, double, double, float, double, double,
48457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique				  int, float, int, int, double, double);
49457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
50457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piqueint main (void)
51457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique{
52457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  ffi_cif cif;
53457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  void *code;
54457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
55457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  ffi_type * cl_arg_types[17];
56457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  int res;
57457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
58457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[0] = &ffi_type_uint64;
59457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[1] = &ffi_type_uint64;
60457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[2] = &ffi_type_uint64;
61457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[3] = &ffi_type_uint64;
62457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[4] = &ffi_type_sint;
63457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[5] = &ffi_type_double;
64457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[6] = &ffi_type_double;
65457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[7] = &ffi_type_float;
66457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[8] = &ffi_type_double;
67457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[9] = &ffi_type_double;
68457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[10] = &ffi_type_sint;
69457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[11] = &ffi_type_float;
70457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[12] = &ffi_type_sint;
71457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[13] = &ffi_type_sint;
72457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[14] = &ffi_type_double;
73457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[15] = &ffi_type_double;
74457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  cl_arg_types[16] = NULL;
75457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
76457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  /* Initialize the cif */
77457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
78457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique		     &ffi_type_sint, cl_arg_types) == FFI_OK);
79457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
80457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  CHECK(ffi_prep_closure_loc(pcl, &cif, closure_test_fn0,
81457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique                             (void *) 3 /* userdata */, code) == FFI_OK);
82457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
83457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  res = (*((closure_test_type0)code))
84457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique    (1, 2, 3, 4, 127, 429., 7., 8., 9.5, 10., 11, 12., 13,
85457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique     19, 21., 1.);
86457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  /* { dg-output "1 2 3 4 127 429 7 8 9 10 11 12 13 19 21 1 3: 680" } */
87457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  printf("res: %d\n",res);
88457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  /* { dg-output "\nres: 680" } */
89457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique  exit(0);
90457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique}
91