1/* Area: ffi_call, closure_call 2 Purpose: Check large structure returns. 3 Limitations: none. 4 PR: none. 5 Originator: Blake Chaffin 6/18/2007 6*/ 7 8/* { dg-do run { xfail mips*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ 9/* { dg-options -mlong-double-128 { target powerpc64*-*-* } } */ 10 11#include <stdint.h> 12 13#include "ffitest.h" 14 15typedef struct BigStruct{ 16 uint8_t a; 17 int8_t b; 18 uint16_t c; 19 int16_t d; 20 uint32_t e; 21 int32_t f; 22 uint64_t g; 23 int64_t h; 24 float i; 25 double j; 26 long double k; 27 char* l; 28 uint8_t m; 29 int8_t n; 30 uint16_t o; 31 int16_t p; 32 uint32_t q; 33 int32_t r; 34 uint64_t s; 35 int64_t t; 36 float u; 37 double v; 38 long double w; 39 char* x; 40 uint8_t y; 41 int8_t z; 42 uint16_t aa; 43 int16_t bb; 44 uint32_t cc; 45 int32_t dd; 46 uint64_t ee; 47 int64_t ff; 48 float gg; 49 double hh; 50 long double ii; 51 char* jj; 52 uint8_t kk; 53 int8_t ll; 54 uint16_t mm; 55 int16_t nn; 56 uint32_t oo; 57 int32_t pp; 58 uint64_t qq; 59 int64_t rr; 60 float ss; 61 double tt; 62 long double uu; 63 char* vv; 64 uint8_t ww; 65 int8_t xx; 66} BigStruct; 67 68BigStruct 69test_large_fn( 70 uint8_t ui8_1, 71 int8_t si8_1, 72 uint16_t ui16_1, 73 int16_t si16_1, 74 uint32_t ui32_1, 75 int32_t si32_1, 76 uint64_t ui64_1, 77 int64_t si64_1, 78 float f_1, 79 double d_1, 80 long double ld_1, 81 char* p_1, 82 uint8_t ui8_2, 83 int8_t si8_2, 84 uint16_t ui16_2, 85 int16_t si16_2, 86 uint32_t ui32_2, 87 int32_t si32_2, 88 uint64_t ui64_2, 89 int64_t si64_2, 90 float f_2, 91 double d_2, 92 long double ld_2, 93 char* p_2, 94 uint8_t ui8_3, 95 int8_t si8_3, 96 uint16_t ui16_3, 97 int16_t si16_3, 98 uint32_t ui32_3, 99 int32_t si32_3, 100 uint64_t ui64_3, 101 int64_t si64_3, 102 float f_3, 103 double d_3, 104 long double ld_3, 105 char* p_3, 106 uint8_t ui8_4, 107 int8_t si8_4, 108 uint16_t ui16_4, 109 int16_t si16_4, 110 uint32_t ui32_4, 111 int32_t si32_4, 112 uint64_t ui64_4, 113 int64_t si64_4, 114 float f_4, 115 double d_4, 116 long double ld_4, 117 char* p_4, 118 uint8_t ui8_5, 119 int8_t si8_5) 120{ 121 BigStruct retVal = { 122 ui8_1 + 1, si8_1 + 1, ui16_1 + 1, si16_1 + 1, ui32_1 + 1, si32_1 + 1, 123 ui64_1 + 1, si64_1 + 1, f_1 + 1, d_1 + 1, ld_1 + 1, (char*)((long)p_1 + 1), 124 ui8_2 + 2, si8_2 + 2, ui16_2 + 2, si16_2 + 2, ui32_2 + 2, si32_2 + 2, 125 ui64_2 + 2, si64_2 + 2, f_2 + 2, d_2 + 2, ld_2 + 2, (char*)((long)p_2 + 2), 126 ui8_3 + 3, si8_3 + 3, ui16_3 + 3, si16_3 + 3, ui32_3 + 3, si32_3 + 3, 127 ui64_3 + 3, si64_3 + 3, f_3 + 3, d_3 + 3, ld_3 + 3, (char*)((long)p_3 + 3), 128 ui8_4 + 4, si8_4 + 4, ui16_4 + 4, si16_4 + 4, ui32_4 + 4, si32_4 + 4, 129 ui64_4 + 4, si64_4 + 4, f_4 + 4, d_4 + 4, ld_4 + 4, (char*)((long)p_4 + 4), 130 ui8_5 + 5, si8_5 + 5}; 131 132 printf("%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 133 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 134 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 135 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p %hhu %hhd: " 136 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 137 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 138 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 139 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p %hhu %hhd\n", 140 ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1, 141 ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2, 142 ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3, 143 ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4, ui8_5, si8_5, 144 retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, 145 retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, retVal.l, 146 retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, 147 retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, retVal.x, 148 retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, 149 retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, retVal.jj, 150 retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, 151 retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, retVal.vv, retVal.ww, retVal.xx); 152 153 return retVal; 154} 155 156static void 157cls_large_fn(ffi_cif* cif, void* resp, void** args, void* userdata) 158{ 159 uint8_t ui8_1 = *(uint8_t*)args[0]; 160 int8_t si8_1 = *(int8_t*)args[1]; 161 uint16_t ui16_1 = *(uint16_t*)args[2]; 162 int16_t si16_1 = *(int16_t*)args[3]; 163 uint32_t ui32_1 = *(uint32_t*)args[4]; 164 int32_t si32_1 = *(int32_t*)args[5]; 165 uint64_t ui64_1 = *(uint64_t*)args[6]; 166 int64_t si64_1 = *(int64_t*)args[7]; 167 float f_1 = *(float*)args[8]; 168 double d_1 = *(double*)args[9]; 169 long double ld_1 = *(long double*)args[10]; 170 char* p_1 = *(char**)args[11]; 171 uint8_t ui8_2 = *(uint8_t*)args[12]; 172 int8_t si8_2 = *(int8_t*)args[13]; 173 uint16_t ui16_2 = *(uint16_t*)args[14]; 174 int16_t si16_2 = *(int16_t*)args[15]; 175 uint32_t ui32_2 = *(uint32_t*)args[16]; 176 int32_t si32_2 = *(int32_t*)args[17]; 177 uint64_t ui64_2 = *(uint64_t*)args[18]; 178 int64_t si64_2 = *(int64_t*)args[19]; 179 float f_2 = *(float*)args[20]; 180 double d_2 = *(double*)args[21]; 181 long double ld_2 = *(long double*)args[22]; 182 char* p_2 = *(char**)args[23]; 183 uint8_t ui8_3 = *(uint8_t*)args[24]; 184 int8_t si8_3 = *(int8_t*)args[25]; 185 uint16_t ui16_3 = *(uint16_t*)args[26]; 186 int16_t si16_3 = *(int16_t*)args[27]; 187 uint32_t ui32_3 = *(uint32_t*)args[28]; 188 int32_t si32_3 = *(int32_t*)args[29]; 189 uint64_t ui64_3 = *(uint64_t*)args[30]; 190 int64_t si64_3 = *(int64_t*)args[31]; 191 float f_3 = *(float*)args[32]; 192 double d_3 = *(double*)args[33]; 193 long double ld_3 = *(long double*)args[34]; 194 char* p_3 = *(char**)args[35]; 195 uint8_t ui8_4 = *(uint8_t*)args[36]; 196 int8_t si8_4 = *(int8_t*)args[37]; 197 uint16_t ui16_4 = *(uint16_t*)args[38]; 198 int16_t si16_4 = *(int16_t*)args[39]; 199 uint32_t ui32_4 = *(uint32_t*)args[40]; 200 int32_t si32_4 = *(int32_t*)args[41]; 201 uint64_t ui64_4 = *(uint64_t*)args[42]; 202 int64_t si64_4 = *(int64_t*)args[43]; 203 float f_4 = *(float*)args[44]; 204 double d_4 = *(double*)args[45]; 205 long double ld_4 = *(long double*)args[46]; 206 char* p_4 = *(char**)args[47]; 207 uint8_t ui8_5 = *(uint8_t*)args[48]; 208 int8_t si8_5 = *(int8_t*)args[49]; 209 210 *(BigStruct*)resp = test_large_fn( 211 ui8_1, si8_1, ui16_1, si16_1, ui32_1, si32_1, ui64_1, si64_1, f_1, d_1, ld_1, p_1, 212 ui8_2, si8_2, ui16_2, si16_2, ui32_2, si32_2, ui64_2, si64_2, f_2, d_2, ld_2, p_2, 213 ui8_3, si8_3, ui16_3, si16_3, ui32_3, si32_3, ui64_3, si64_3, f_3, d_3, ld_3, p_3, 214 ui8_4, si8_4, ui16_4, si16_4, ui32_4, si32_4, ui64_4, si64_4, f_4, d_4, ld_4, p_4, 215 ui8_5, si8_5); 216} 217 218int 219main(int argc, const char** argv) 220{ 221#ifndef USING_MMAP 222 static ffi_closure cl; 223#endif 224 ffi_closure *pcl; 225 226#ifdef USING_MMAP 227 pcl = allocate_mmap(sizeof(ffi_closure)); 228#else 229 pcl = &cl; 230#endif 231 232 ffi_cif cif; 233 ffi_type* argTypes[51]; 234 void* argValues[51]; 235 236 ffi_type ret_struct_type; 237 ffi_type* st_fields[51]; 238 BigStruct retVal = {0}; 239 240 ret_struct_type.size = 0; 241 ret_struct_type.alignment = 0; 242 ret_struct_type.type = FFI_TYPE_STRUCT; 243 ret_struct_type.elements = st_fields; 244 245 st_fields[0] = st_fields[12] = st_fields[24] = st_fields[36] = st_fields[48] = &ffi_type_uint8; 246 st_fields[1] = st_fields[13] = st_fields[25] = st_fields[37] = st_fields[49] = &ffi_type_sint8; 247 st_fields[2] = st_fields[14] = st_fields[26] = st_fields[38] = &ffi_type_uint16; 248 st_fields[3] = st_fields[15] = st_fields[27] = st_fields[39] = &ffi_type_sint16; 249 st_fields[4] = st_fields[16] = st_fields[28] = st_fields[40] = &ffi_type_uint32; 250 st_fields[5] = st_fields[17] = st_fields[29] = st_fields[41] = &ffi_type_sint32; 251 st_fields[6] = st_fields[18] = st_fields[30] = st_fields[42] = &ffi_type_uint64; 252 st_fields[7] = st_fields[19] = st_fields[31] = st_fields[43] = &ffi_type_sint64; 253 st_fields[8] = st_fields[20] = st_fields[32] = st_fields[44] = &ffi_type_float; 254 st_fields[9] = st_fields[21] = st_fields[33] = st_fields[45] = &ffi_type_double; 255 st_fields[10] = st_fields[22] = st_fields[34] = st_fields[46] = &ffi_type_longdouble; 256 st_fields[11] = st_fields[23] = st_fields[35] = st_fields[47] = &ffi_type_pointer; 257 258 st_fields[50] = NULL; 259 260 uint8_t ui8 = 1; 261 int8_t si8 = 2; 262 uint16_t ui16 = 3; 263 int16_t si16 = 4; 264 uint32_t ui32 = 5; 265 int32_t si32 = 6; 266 uint64_t ui64 = 7; 267 int64_t si64 = 8; 268 float f = 9; 269 double d = 10; 270 long double ld = 11; 271 char* p = (char*)0x12345678; 272 273 argTypes[0] = argTypes[12] = argTypes[24] = argTypes[36] = argTypes[48] = &ffi_type_uint8; 274 argValues[0] = argValues[12] = argValues[24] = argValues[36] = argValues[48] = &ui8; 275 argTypes[1] = argTypes[13] = argTypes[25] = argTypes[37] = argTypes[49] = &ffi_type_sint8; 276 argValues[1] = argValues[13] = argValues[25] = argValues[37] = argValues[49] = &si8; 277 argTypes[2] = argTypes[14] = argTypes[26] = argTypes[38] = &ffi_type_uint16; 278 argValues[2] = argValues[14] = argValues[26] = argValues[38] = &ui16; 279 argTypes[3] = argTypes[15] = argTypes[27] = argTypes[39] = &ffi_type_sint16; 280 argValues[3] = argValues[15] = argValues[27] = argValues[39] = &si16; 281 argTypes[4] = argTypes[16] = argTypes[28] = argTypes[40] = &ffi_type_uint32; 282 argValues[4] = argValues[16] = argValues[28] = argValues[40] = &ui32; 283 argTypes[5] = argTypes[17] = argTypes[29] = argTypes[41] = &ffi_type_sint32; 284 argValues[5] = argValues[17] = argValues[29] = argValues[41] = &si32; 285 argTypes[6] = argTypes[18] = argTypes[30] = argTypes[42] = &ffi_type_uint64; 286 argValues[6] = argValues[18] = argValues[30] = argValues[42] = &ui64; 287 argTypes[7] = argTypes[19] = argTypes[31] = argTypes[43] = &ffi_type_sint64; 288 argValues[7] = argValues[19] = argValues[31] = argValues[43] = &si64; 289 argTypes[8] = argTypes[20] = argTypes[32] = argTypes[44] = &ffi_type_float; 290 argValues[8] = argValues[20] = argValues[32] = argValues[44] = &f; 291 argTypes[9] = argTypes[21] = argTypes[33] = argTypes[45] = &ffi_type_double; 292 argValues[9] = argValues[21] = argValues[33] = argValues[45] = &d; 293 argTypes[10] = argTypes[22] = argTypes[34] = argTypes[46] = &ffi_type_longdouble; 294 argValues[10] = argValues[22] = argValues[34] = argValues[46] = &ld; 295 argTypes[11] = argTypes[23] = argTypes[35] = argTypes[47] = &ffi_type_pointer; 296 argValues[11] = argValues[23] = argValues[35] = argValues[47] = &p; 297 298 argTypes[50] = NULL; 299 argValues[50] = NULL; 300 301 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 50, &ret_struct_type, argTypes) == FFI_OK); 302 303 ffi_call(&cif, FFI_FN(test_large_fn), &retVal, argValues); 304 // { dg-output "1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } 305 printf("res: %hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 306 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 307 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 308 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p %hhu %hhd\n", 309 retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, 310 retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, retVal.l, 311 retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, 312 retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, retVal.x, 313 retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, 314 retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, retVal.jj, 315 retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, 316 retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, retVal.vv, retVal.ww, retVal.xx); 317 // { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } 318 319 CHECK(ffi_prep_closure(pcl, &cif, cls_large_fn, NULL) == FFI_OK); 320 321 retVal = ((BigStruct(*)( 322 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, 323 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, 324 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, 325 uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, int64_t, float, double, long double, char*, 326 uint8_t, int8_t))(pcl))( 327 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, 328 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, 329 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, 330 ui8, si8, ui16, si16, ui32, si32, ui64, si64, f, d, ld, p, 331 ui8, si8); 332 // { dg-output "\n1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2 3 4 5 6 7 8 9 10 11 0x12345678 1 2: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } 333 printf("res: %hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 334 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 335 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p " 336 "%hhu %hhd %hu %hd %u %d %llu %lld %.0f %.0f %L.0f %p %hhu %hhd\n", 337 retVal.a, retVal.b, retVal.c, retVal.d, retVal.e, retVal.f, 338 retVal.g, retVal.h, retVal.i, retVal.j, retVal.k, retVal.l, 339 retVal.m, retVal.n, retVal.o, retVal.p, retVal.q, retVal.r, 340 retVal.s, retVal.t, retVal.u, retVal.v, retVal.w, retVal.x, 341 retVal.y, retVal.z, retVal.aa, retVal.bb, retVal.cc, retVal.dd, 342 retVal.ee, retVal.ff, retVal.gg, retVal.hh, retVal.ii, retVal.jj, 343 retVal.kk, retVal.ll, retVal.mm, retVal.nn, retVal.oo, retVal.pp, 344 retVal.qq, retVal.rr, retVal.ss, retVal.tt, retVal.uu, retVal.vv, retVal.ww, retVal.xx); 345 // { dg-output "\nres: 2 3 4 5 6 7 8 9 10 11 12 0x12345679 3 4 5 6 7 8 9 10 11 12 13 0x1234567a 4 5 6 7 8 9 10 11 12 13 14 0x1234567b 5 6 7 8 9 10 11 12 13 14 15 0x1234567c 6 7" } 346 347 return 0; 348} 349