/* Area:	ffi_call, closure_call
   Purpose:	Check structure passing with different structure size.
		Contains structs as parameter of the struct itself.
   Limitations:	none.
   PR:		none.
   Originator:	<andreast@gcc.gnu.org> 20030828	 */

/* { dg-do run } */
#include "ffitest.h"

typedef struct cls_struct_16byte1 {
  double a;
  float b;
  int c;
} cls_struct_16byte1;

typedef struct cls_struct_16byte2 {
  int ii;
  double dd;
  float ff;
} cls_struct_16byte2;

typedef struct cls_struct_combined {
  cls_struct_16byte1 d;
  cls_struct_16byte2 e;
} cls_struct_combined;

cls_struct_combined cls_struct_combined_fn(struct cls_struct_16byte1 b0,
			    struct cls_struct_16byte2 b1,
			    struct cls_struct_combined b2)
{
  struct cls_struct_combined result;

  result.d.a = b0.a + b1.dd + b2.d.a;
  result.d.b = b0.b + b1.ff + b2.d.b;
  result.d.c = b0.c + b1.ii + b2.d.c;
  result.e.ii = b0.c + b1.ii + b2.e.ii;
  result.e.dd = b0.a + b1.dd + b2.e.dd;
  result.e.ff = b0.b + b1.ff + b2.e.ff;

  printf("%g %g %d %d %g %g %g %g %d %d %g %g: %g %g %d %d %g %g\n",
	 b0.a, b0.b, b0.c,
	 b1.ii, b1.dd, b1.ff,
	 b2.d.a, b2.d.b, b2.d.c,
	 b2.e.ii, b2.e.dd, b2.e.ff,
	 result.d.a, result.d.b, result.d.c,
	 result.e.ii, result.e.dd, result.e.ff);

  return result;
}

static void
cls_struct_combined_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
		       void* userdata __UNUSED__)
{
  struct cls_struct_16byte1 b0;
  struct cls_struct_16byte2 b1;
  struct cls_struct_combined b2;

  b0 = *(struct cls_struct_16byte1*)(args[0]);
  b1 = *(struct cls_struct_16byte2*)(args[1]);
  b2 = *(struct cls_struct_combined*)(args[2]);


  *(cls_struct_combined*)resp = cls_struct_combined_fn(b0, b1, b2);
}

int main (void)
{
  ffi_cif cif;
  void *code;
  ffi_closure *pcl = ffi_closure_alloc(sizeof(ffi_closure), &code);
  void* args_dbl[5];
  ffi_type* cls_struct_fields[5];
  ffi_type* cls_struct_fields1[5];
  ffi_type* cls_struct_fields2[5];
  ffi_type cls_struct_type, cls_struct_type1, cls_struct_type2;
  ffi_type* dbl_arg_types[5];

  struct cls_struct_16byte1 e_dbl = { 9.0, 2.0, 6};
  struct cls_struct_16byte2 f_dbl = { 1, 2.0, 3.0};
  struct cls_struct_combined g_dbl = {{4.0, 5.0, 6},
				      {3, 1.0, 8.0}};
  struct cls_struct_combined res_dbl;

  cls_struct_type.size = 0;
  cls_struct_type.alignment = 0;
  cls_struct_type.type = FFI_TYPE_STRUCT;
  cls_struct_type.elements = cls_struct_fields;

  cls_struct_type1.size = 0;
  cls_struct_type1.alignment = 0;
  cls_struct_type1.type = FFI_TYPE_STRUCT;
  cls_struct_type1.elements = cls_struct_fields1;

  cls_struct_type2.size = 0;
  cls_struct_type2.alignment = 0;
  cls_struct_type2.type = FFI_TYPE_STRUCT;
  cls_struct_type2.elements = cls_struct_fields2;

  cls_struct_fields[0] = &ffi_type_double;
  cls_struct_fields[1] = &ffi_type_float;
  cls_struct_fields[2] = &ffi_type_sint;
  cls_struct_fields[3] = NULL;

  cls_struct_fields1[0] = &ffi_type_sint;
  cls_struct_fields1[1] = &ffi_type_double;
  cls_struct_fields1[2] = &ffi_type_float;
  cls_struct_fields1[3] = NULL;

  cls_struct_fields2[0] = &cls_struct_type;
  cls_struct_fields2[1] = &cls_struct_type1;
  cls_struct_fields2[2] = NULL;


  dbl_arg_types[0] = &cls_struct_type;
  dbl_arg_types[1] = &cls_struct_type1;
  dbl_arg_types[2] = &cls_struct_type2;
  dbl_arg_types[3] = NULL;

  CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 3, &cls_struct_type2,
		     dbl_arg_types) == FFI_OK);

  args_dbl[0] = &e_dbl;
  args_dbl[1] = &f_dbl;
  args_dbl[2] = &g_dbl;
  args_dbl[3] = NULL;

  ffi_call(&cif, FFI_FN(cls_struct_combined_fn), &res_dbl, args_dbl);
  /* { dg-output "9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));

  CHECK(ffi_prep_closure_loc(pcl, &cif, cls_struct_combined_gn, NULL, code) == FFI_OK);

  res_dbl = ((cls_struct_combined(*)(cls_struct_16byte1,
				     cls_struct_16byte2,
				     cls_struct_combined))
	     (code))(e_dbl, f_dbl, g_dbl);
  /* { dg-output "\n9 2 6 1 2 3 4 5 6 3 1 8: 15 10 13 10 12 13" } */
  CHECK( res_dbl.d.a == (e_dbl.a + f_dbl.dd + g_dbl.d.a));
  CHECK( res_dbl.d.b == (e_dbl.b + f_dbl.ff + g_dbl.d.b));
  CHECK( res_dbl.d.c == (e_dbl.c + f_dbl.ii + g_dbl.d.c));
  CHECK( res_dbl.e.ii == (e_dbl.c + f_dbl.ii + g_dbl.e.ii));
  CHECK( res_dbl.e.dd == (e_dbl.a + f_dbl.dd + g_dbl.e.dd));
  CHECK( res_dbl.e.ff == (e_dbl.b + f_dbl.ff + g_dbl.e.ff));
  exit(0);
}
