1 /* Area: ffi_call, closure_call 2 Purpose: Check parameter passing with nested structs 3 of a single type. This tests the special cases 4 for homogeneous floating-point aggregates in the 5 AArch64 PCS. 6 Limitations: none. 7 PR: none. 8 Originator: ARM Ltd. */ 9 10 /* { dg-do run } */ 11 #include "ffitest.h" 12 13 typedef struct A { 14 float a_x; 15 float a_y; 16 } A; 17 18 typedef struct B { 19 float b_x; 20 float b_y; 21 } B; 22 23 typedef struct C { 24 A a; 25 B b; 26 } C; 27 28 static C C_fn (int x, int y, int z, C source, int i, int j, int k) 29 { 30 C result; 31 result.a.a_x = source.a.a_x; 32 result.a.a_y = source.a.a_y; 33 result.b.b_x = source.b.b_x; 34 result.b.b_y = source.b.b_y; 35 36 printf ("%d, %d, %d, %d, %d, %d\n", x, y, z, i, j, k); 37 38 printf ("%.1f, %.1f, %.1f, %.1f, " 39 "%.1f, %.1f, %.1f, %.1f\n", 40 source.a.a_x, source.a.a_y, 41 source.b.b_x, source.b.b_y, 42 result.a.a_x, result.a.a_y, 43 result.b.b_x, result.b.b_y); 44 45 return result; 46 } 47 48 int main (void) 49 { 50 ffi_cif cif; 51 52 ffi_type* struct_fields_source_a[3]; 53 ffi_type* struct_fields_source_b[3]; 54 ffi_type* struct_fields_source_c[3]; 55 ffi_type* arg_types[8]; 56 57 ffi_type struct_type_a, struct_type_b, struct_type_c; 58 59 struct A source_fld_a = {1.0, 2.0}; 60 struct B source_fld_b = {4.0, 8.0}; 61 int k = 1; 62 63 struct C result; 64 struct C source = {source_fld_a, source_fld_b}; 65 66 struct_type_a.size = 0; 67 struct_type_a.alignment = 0; 68 struct_type_a.type = FFI_TYPE_STRUCT; 69 struct_type_a.elements = struct_fields_source_a; 70 71 struct_type_b.size = 0; 72 struct_type_b.alignment = 0; 73 struct_type_b.type = FFI_TYPE_STRUCT; 74 struct_type_b.elements = struct_fields_source_b; 75 76 struct_type_c.size = 0; 77 struct_type_c.alignment = 0; 78 struct_type_c.type = FFI_TYPE_STRUCT; 79 struct_type_c.elements = struct_fields_source_c; 80 81 struct_fields_source_a[0] = &ffi_type_float; 82 struct_fields_source_a[1] = &ffi_type_float; 83 struct_fields_source_a[2] = NULL; 84 85 struct_fields_source_b[0] = &ffi_type_float; 86 struct_fields_source_b[1] = &ffi_type_float; 87 struct_fields_source_b[2] = NULL; 88 89 struct_fields_source_c[0] = &struct_type_a; 90 struct_fields_source_c[1] = &struct_type_b; 91 struct_fields_source_c[2] = NULL; 92 93 arg_types[0] = &ffi_type_sint32; 94 arg_types[1] = &ffi_type_sint32; 95 arg_types[2] = &ffi_type_sint32; 96 arg_types[3] = &struct_type_c; 97 arg_types[4] = &ffi_type_sint32; 98 arg_types[5] = &ffi_type_sint32; 99 arg_types[6] = &ffi_type_sint32; 100 arg_types[7] = NULL; 101 102 void *args[7]; 103 args[0] = &k; 104 args[1] = &k; 105 args[2] = &k; 106 args[3] = &source; 107 args[4] = &k; 108 args[5] = &k; 109 args[6] = &k; 110 CHECK (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 7, &struct_type_c, 111 arg_types) == FFI_OK); 112 113 ffi_call (&cif, FFI_FN (C_fn), &result, args); 114 /* { dg-output "1, 1, 1, 1, 1, 1\n" } */ 115 /* { dg-output "1.0, 2.0, 4.0, 8.0, 1.0, 2.0, 4.0, 8.0" } */ 116 CHECK (result.a.a_x == source.a.a_x); 117 CHECK (result.a.a_y == source.a.a_y); 118 CHECK (result.b.b_x == source.b.b_x); 119 CHECK (result.b.b_y == source.b.b_y); 120 exit (0); 121 } 122