re PR rtl-optimization/8492 (GCC spins forever compiling loop)
[official-gcc.git] / libffi / src / ffitest.c
bloba05b746865d1c7cbc5f0009081508ca448e51153
1 /* -----------------------------------------------------------------------
2 ffitest.c - Copyright (c) 1996, 1997, 1998, 2002, 2003 Red Hat, Inc.
4 Permission is hereby granted, free of charge, to any person obtaining
5 a copy of this software and associated documentation files (the
6 ``Software''), to deal in the Software without restriction, including
7 without limitation the rights to use, copy, modify, merge, publish,
8 distribute, sublicense, and/or sell copies of the Software, and to
9 permit persons to whom the Software is furnished to do so, subject to
10 the following conditions:
12 The above copyright notice and this permission notice shall be included
13 in all copies or substantial portions of the Software.
15 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 OTHER DEALINGS IN THE SOFTWARE.
22 ----------------------------------------------------------------------- */
24 #include <ffi.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <float.h>
30 /* This is lame. Long double support is barely there under SunOS 4.x */
31 #if defined(SPARC) && (SIZEOF_LONG_DOUBLE != 16)
32 #define BROKEN_LONG_DOUBLE
33 #endif
35 #define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0
37 static int fail(char *file, int line)
39 fprintf(stderr, "Test failure: %s line %d\n", file, line);
40 exit(EXIT_FAILURE);
41 /*@notreached@*/
42 return 0;
45 #define MAX_ARGS 256
47 static size_t my_strlen(char *s)
49 return (strlen(s));
52 #ifdef X86_WIN32
53 static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s)
55 return (strlen(s));
57 #endif /* X86_WIN32 */
59 static int promotion(signed char sc, signed short ss,
60 unsigned char uc, unsigned short us)
62 int r = (int) sc + (int) ss + (int) uc + (int) us;
64 return r;
67 static signed char return_sc(signed char sc)
69 return sc;
72 static unsigned char return_uc(unsigned char uc)
74 return uc;
77 static long long return_ll(long long ll)
79 return ll;
82 static int floating(int a, float b, double c, long double d, int e)
84 int i;
86 #if 0
87 /* This is ifdef'd out for now. long double support under SunOS/gcc
88 is pretty much non-existent. You'll get the odd bus error in library
89 routines like printf(). */
90 printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e);
91 #endif
93 i = (int) ((float)a/b + ((float)c/(float)d));
95 return i;
98 static float many(float f1,
99 float f2,
100 float f3,
101 float f4,
102 float f5,
103 float f6,
104 float f7,
105 float f8,
106 float f9,
107 float f10,
108 float f11,
109 float f12,
110 float f13)
112 #if 0
113 printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
114 (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
115 (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
116 (double) f11, (double) f12, (double) f13);
117 #endif
119 return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
122 #ifdef X86_WIN32
123 static float __attribute__((stdcall)) stdcall_many(float f1,
124 float f2,
125 float f3,
126 float f4,
127 float f5,
128 float f6,
129 float f7,
130 float f8,
131 float f9,
132 float f10,
133 float f11,
134 float f12,
135 float f13)
137 return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
139 #endif /* X86_WIN32 */
141 static double dblit(float f)
143 return f/3.0;
146 static long double ldblit(float f)
148 return (long double) (((long double) f)/ (long double) 3.0);
151 typedef struct
153 unsigned char uc;
154 double d;
155 unsigned int ui;
156 } test_structure_1;
158 typedef struct
160 double d1;
161 double d2;
162 } test_structure_2;
164 typedef struct
166 int si;
167 } test_structure_3;
169 typedef struct
171 unsigned ui1;
172 unsigned ui2;
173 unsigned ui3;
174 } test_structure_4;
176 typedef struct
178 char c1;
179 char c2;
180 } test_structure_5;
182 typedef struct
184 float f;
185 double d;
186 } test_structure_6;
188 typedef struct
190 float f1;
191 float f2;
192 double d;
193 } test_structure_7;
195 typedef struct
197 float f1;
198 float f2;
199 float f3;
200 float f4;
201 } test_structure_8;
203 typedef struct
205 float f;
206 int i;
207 } test_structure_9;
209 static test_structure_1 struct1(test_structure_1 ts)
211 /*@-type@*/
212 ts.uc++;
213 /*@=type@*/
214 ts.d--;
215 ts.ui++;
217 return ts;
220 static test_structure_2 struct2(test_structure_2 ts)
222 ts.d1--;
223 ts.d2--;
225 return ts;
228 static test_structure_3 struct3(test_structure_3 ts)
230 ts.si = -(ts.si*2);
232 return ts;
235 static test_structure_4 struct4(test_structure_4 ts)
237 ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
239 return ts;
242 static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
244 ts1.c1 += ts2.c1;
245 ts1.c2 -= ts2.c2;
247 return ts1;
250 static test_structure_6 struct6 (test_structure_6 ts)
252 ts.f += 1;
253 ts.d += 1;
255 return ts;
258 static test_structure_7 struct7 (test_structure_7 ts)
260 ts.f1 += 1;
261 ts.f2 += 1;
262 ts.d += 1;
264 return ts;
267 static test_structure_8 struct8 (test_structure_8 ts)
269 ts.f1 += 1;
270 ts.f2 += 1;
271 ts.f3 += 1;
272 ts.f4 += 1;
274 return ts;
277 static test_structure_9 struct9 (test_structure_9 ts)
279 ts.f += 1;
280 ts.i += 1;
282 return ts;
285 /* Take an int and a float argument, together with int userdata, and */
286 /* return the sum. */
287 #if FFI_CLOSURES
288 static void
289 closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
291 *(ffi_arg*)resp =
292 (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
293 (int)(*(unsigned long long *)args[2]) + (int)*(int *)args[3] +
294 (int)(*(signed short *)args[4]) +
295 (int)(*(unsigned long long *)args[5]) +
296 (int)*(int *)args[6] + (int)(*(int *)args[7]) +
297 (int)(*(double *)args[8]) + (int)*(int *)args[9] +
298 (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
299 (int)*(int *)args[12] + (int)(*(int *)args[13]) +
300 (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
302 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
303 (int)*(unsigned long long *)args[0], (int)(*(int *)args[1]),
304 (int)(*(unsigned long long *)args[2]),
305 (int)*(int *)args[3], (int)(*(signed short *)args[4]),
306 (int)(*(unsigned long long *)args[5]),
307 (int)*(int *)args[6], (int)(*(int *)args[7]),
308 (int)(*(double *)args[8]), (int)*(int *)args[9],
309 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
310 (int)*(int *)args[12], (int)(*(int *)args[13]),
311 (int)(*(int *)args[14]),*(int *)args[15],
312 (int)(long)userdata, *(int*)resp);
315 typedef int (*closure_test_type)(unsigned long long, int, unsigned long long,
316 int, signed short, unsigned long long, int,
317 int, double, int, int, float, int, int,
318 int, int);
320 static void closure_test_fn1(ffi_cif* cif,void* resp,void** args,
321 void* userdata)
323 *(ffi_arg*)resp =
324 (int)*(float *)args[0] +(int)(*(float *)args[1]) +
325 (int)(*(float *)args[2]) + (int)*(float *)args[3] +
326 (int)(*(signed short *)args[4]) + (int)(*(float *)args[5]) +
327 (int)*(float *)args[6] + (int)(*(int *)args[7]) +
328 (int)(*(double*)args[8]) + (int)*(int *)args[9] +
329 (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
330 (int)*(int *)args[12] + (int)(*(int *)args[13]) +
331 (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
333 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
334 (int)*(float *)args[0], (int)(*(float *)args[1]),
335 (int)(*(float *)args[2]), (int)*(float *)args[3],
336 (int)(*(signed short *)args[4]), (int)(*(float *)args[5]),
337 (int)*(float *)args[6], (int)(*(int *)args[7]),
338 (int)(*(double *)args[8]), (int)*(int *)args[9],
339 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
340 (int)*(int *)args[12], (int)(*(int *)args[13]),
341 (int)(*(int *)args[14]), *(int *)args[15],
342 (int)(long)userdata, *(int*)resp);
345 typedef int (*closure_test_type1)(float, float, float, float, signed short,
346 float, float, int, double, int, int, float,
347 int, int, int, int);
349 static void closure_test_fn2(ffi_cif* cif,void* resp,void** args,
350 void* userdata)
352 *(ffi_arg*)resp =
353 (int)*(double *)args[0] +(int)(*(double *)args[1]) +
354 (int)(*(double *)args[2]) + (int)*(double *)args[3] +
355 (int)(*(signed short *)args[4]) + (int)(*(double *)args[5]) +
356 (int)*(double *)args[6] + (int)(*(int *)args[7]) +
357 (int)(*(double *)args[8]) + (int)*(int *)args[9] +
358 (int)(*(int *)args[10]) + (int)(*(float *)args[11]) +
359 (int)*(int *)args[12] + (int)(*(float *)args[13]) +
360 (int)(*(int *)args[14]) + *(int *)args[15] + (int)(long)userdata;
362 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
363 (int)*(double *)args[0], (int)(*(double *)args[1]),
364 (int)(*(double *)args[2]), (int)*(double *)args[3],
365 (int)(*(signed short *)args[4]), (int)(*(double *)args[5]),
366 (int)*(double *)args[6], (int)(*(int *)args[7]),
367 (int)(*(double*)args[8]), (int)*(int *)args[9],
368 (int)(*(int *)args[10]), (int)(*(float *)args[11]),
369 (int)*(int *)args[12], (int)(*(float *)args[13]),
370 (int)(*(int *)args[14]), *(int *)args[15], (int)(long)userdata,
371 *(int*)resp);
374 typedef int (*closure_test_type2)(double, double, double, double, signed short,
375 double, double, int, double, int, int, float,
376 int, float, int, int);
378 static void closure_test_fn3(ffi_cif* cif,void* resp,void** args,
379 void* userdata)
381 *(ffi_arg*)resp =
382 (int)*(float *)args[0] +(int)(*(float *)args[1]) +
383 (int)(*(float *)args[2]) + (int)*(float *)args[3] +
384 (int)(*(float *)args[4]) + (int)(*(float *)args[5]) +
385 (int)*(float *)args[6] + (int)(*(float *)args[7]) +
386 (int)(*(double *)args[8]) + (int)*(int *)args[9] +
387 (int)(*(float *)args[10]) + (int)(*(float *)args[11]) +
388 (int)*(int *)args[12] + (int)(*(float *)args[13]) +
389 (int)(*(float *)args[14]) + *(int *)args[15] + (int)(long)userdata;
391 printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d: %d\n",
392 (int)*(float *)args[0], (int)(*(float *)args[1]),
393 (int)(*(float *)args[2]), (int)*(float *)args[3],
394 (int)(*(float *)args[4]), (int)(*(float *)args[5]),
395 (int)*(float *)args[6], (int)(*(float *)args[7]),
396 (int)(*(double *)args[8]), (int)*(int *)args[9],
397 (int)(*(float *)args[10]), (int)(*(float *)args[11]),
398 (int)*(int *)args[12], (int)(*(float *)args[13]),
399 (int)(*(float *)args[14]), *(int *)args[15], (int)(long)userdata,
400 *(int*)resp);
403 typedef int (*closure_test_type3)(float, float, float, float, float, float,
404 float, float, double, int, float, float, int,
405 float, float, int);
406 #endif
408 int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
410 ffi_cif cif;
411 ffi_type *args[MAX_ARGS];
412 void *values[MAX_ARGS];
413 char *s;
414 signed char sc;
415 unsigned char uc;
416 signed short ss;
417 unsigned short us;
418 unsigned long ul;
419 long long ll;
420 float f;
421 double d;
422 long double ld;
423 signed int si1;
424 signed int si2;
426 ffi_arg rint;
427 long long rlonglong;
429 # if FFI_CLOSURES
430 /* The closure must not be an automatic variable on
431 platforms (Solaris) that forbid stack execution by default. */
432 static ffi_closure cl;
433 #endif
435 ffi_type * cl_arg_types[17];
437 ffi_type ts1_type;
438 ffi_type ts2_type;
439 ffi_type ts3_type;
440 ffi_type ts4_type;
441 ffi_type ts5_type;
442 ffi_type ts6_type;
443 ffi_type ts7_type;
444 ffi_type ts8_type;
445 ffi_type ts9_type;
446 ffi_type *ts1_type_elements[4];
447 ffi_type *ts2_type_elements[3];
448 ffi_type *ts3_type_elements[2];
449 ffi_type *ts4_type_elements[4];
450 ffi_type *ts5_type_elements[3];
451 ffi_type *ts6_type_elements[3];
452 ffi_type *ts7_type_elements[4];
453 ffi_type *ts8_type_elements[5];
454 ffi_type *ts9_type_elements[3];
456 ts1_type.size = 0;
457 ts1_type.alignment = 0;
458 ts1_type.type = FFI_TYPE_STRUCT;
460 ts2_type.size = 0;
461 ts2_type.alignment = 0;
462 ts2_type.type = FFI_TYPE_STRUCT;
464 ts3_type.size = 0;
465 ts3_type.alignment = 0;
466 ts3_type.type = FFI_TYPE_STRUCT;
468 ts4_type.size = 0;
469 ts4_type.alignment = 0;
470 ts4_type.type = FFI_TYPE_STRUCT;
472 ts5_type.size = 0;
473 ts5_type.alignment = 0;
474 ts5_type.type = FFI_TYPE_STRUCT;
476 ts6_type.size = 0;
477 ts6_type.alignment = 0;
478 ts6_type.type = FFI_TYPE_STRUCT;
480 ts7_type.size = 0;
481 ts7_type.alignment = 0;
482 ts7_type.type = FFI_TYPE_STRUCT;
484 ts8_type.size = 0;
485 ts8_type.alignment = 0;
486 ts8_type.type = FFI_TYPE_STRUCT;
488 ts9_type.size = 0;
489 ts9_type.alignment = 0;
490 ts9_type.type = FFI_TYPE_STRUCT;
492 /*@-immediatetrans@*/
493 ts1_type.elements = ts1_type_elements;
494 ts2_type.elements = ts2_type_elements;
495 ts3_type.elements = ts3_type_elements;
496 ts4_type.elements = ts4_type_elements;
497 ts5_type.elements = ts5_type_elements;
498 ts6_type.elements = ts6_type_elements;
499 ts7_type.elements = ts7_type_elements;
500 ts8_type.elements = ts8_type_elements;
501 ts9_type.elements = ts9_type_elements;
502 /*@=immediatetrans@*/
504 ts1_type_elements[0] = &ffi_type_uchar;
505 ts1_type_elements[1] = &ffi_type_double;
506 ts1_type_elements[2] = &ffi_type_uint;
507 ts1_type_elements[3] = NULL;
509 ts2_type_elements[0] = &ffi_type_double;
510 ts2_type_elements[1] = &ffi_type_double;
511 ts2_type_elements[2] = NULL;
513 ts3_type_elements[0] = &ffi_type_sint;
514 ts3_type_elements[1] = NULL;
516 ts4_type_elements[0] = &ffi_type_uint;
517 ts4_type_elements[1] = &ffi_type_uint;
518 ts4_type_elements[2] = &ffi_type_uint;
519 ts4_type_elements[3] = NULL;
521 ts5_type_elements[0] = &ffi_type_schar;
522 ts5_type_elements[1] = &ffi_type_schar;
523 ts5_type_elements[2] = NULL;
525 ts6_type_elements[0] = &ffi_type_float;
526 ts6_type_elements[1] = &ffi_type_double;
527 ts6_type_elements[2] = NULL;
529 ts7_type_elements[0] = &ffi_type_float;
530 ts7_type_elements[1] = &ffi_type_float;
531 ts7_type_elements[2] = &ffi_type_double;
532 ts7_type_elements[3] = NULL;
534 ts8_type_elements[0] = &ffi_type_float;
535 ts8_type_elements[1] = &ffi_type_float;
536 ts8_type_elements[2] = &ffi_type_float;
537 ts8_type_elements[3] = &ffi_type_float;
538 ts8_type_elements[4] = NULL;
540 ts9_type_elements[0] = &ffi_type_float;
541 ts9_type_elements[1] = &ffi_type_sint;
542 ts9_type_elements[2] = NULL;
544 ul = 0;
546 /* return value tests */
548 #if defined(MIPS) /* || defined(ARM) */
549 puts ("long long tests not run. This is a known bug on this architecture.");
550 #else
551 args[0] = &ffi_type_sint64;
552 values[0] = &ll;
554 /* Initialize the cif */
555 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
556 &ffi_type_sint64, args) == FFI_OK);
558 for (ll = 0LL; ll < 100LL; ll++)
560 ul++;
561 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
562 CHECK(rlonglong == ll);
565 for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
567 ul++;
568 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
569 CHECK(rlonglong == ll);
571 #endif
573 args[0] = &ffi_type_schar;
574 values[0] = &sc;
576 /* Initialize the cif */
577 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
578 &ffi_type_schar, args) == FFI_OK);
580 for (sc = (signed char) -127;
581 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
583 ul++;
584 ffi_call(&cif, FFI_FN(return_sc), &rint, values);
585 CHECK(rint == (ffi_arg) sc);
588 args[0] = &ffi_type_uchar;
589 values[0] = &uc;
591 /* Initialize the cif */
592 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
593 &ffi_type_uchar, args) == FFI_OK);
595 for (uc = (unsigned char) '\x00';
596 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
598 ul++;
599 ffi_call(&cif, FFI_FN(return_uc), &rint, values);
600 CHECK(rint == (signed int) uc);
603 printf("%lu return value tests run\n", ul);
606 #ifdef BROKEN_LONG_DOUBLE
607 printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
608 #else
609 /* float arg tests */
611 args[0] = &ffi_type_float;
612 values[0] = &f;
614 /* Initialize the cif */
615 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
616 &ffi_type_longdouble, args) == FFI_OK);
618 f = 3.14159;
620 #if 0
621 /* This is ifdef'd out for now. long double support under SunOS/gcc
622 is pretty much non-existent. You'll get the odd bus error in library
623 routines like printf(). */
624 printf ("%Lf\n", ldblit(f));
625 #endif
626 ld = 666;
627 ffi_call(&cif, FFI_FN(ldblit), &ld, values);
629 #if 0
630 /* This is ifdef'd out for now. long double support under SunOS/gcc
631 is pretty much non-existent. You'll get the odd bus error in library
632 routines like printf(). */
633 printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
634 #endif
636 /* These are not always the same!! Check for a reasonable delta */
637 /*@-realcompare@*/
638 if (ld - ldblit(f) < LDBL_EPSILON)
639 /*@=realcompare@*/
640 puts("long double return value tests ok!");
641 else
642 CHECK(0);
645 /* float arg tests */
647 args[0] = &ffi_type_sint;
648 values[0] = &si1;
649 args[1] = &ffi_type_float;
650 values[1] = &f;
651 args[2] = &ffi_type_double;
652 values[2] = &d;
653 args[3] = &ffi_type_longdouble;
654 values[3] = &ld;
655 args[4] = &ffi_type_sint;
656 values[4] = &si2;
658 /* Initialize the cif */
659 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
660 &ffi_type_sint, args) == FFI_OK);
662 si1 = 6;
663 f = 3.14159;
664 d = (double)1.0/(double)3.0;
665 ld = 2.71828182846L;
666 si2 = 10;
668 floating (si1, f, d, ld, si2);
670 ffi_call(&cif, FFI_FN(floating), &rint, values);
672 printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
674 CHECK(rint == floating(si1, f, d, ld, si2));
676 printf("float arg tests ok!\n");
678 #endif
680 /* strlen tests */
682 args[0] = &ffi_type_pointer;
683 values[0] = (void*) &s;
685 /* Initialize the cif */
686 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
687 &ffi_type_sint, args) == FFI_OK);
689 s = "a";
690 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
691 CHECK(rint == 1);
693 s = "1234567";
694 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
695 CHECK(rint == 7);
697 s = "1234567890123456789012345";
698 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
699 CHECK(rint == 25);
701 printf("strlen tests passed\n");
704 /* float arg tests */
706 args[0] = &ffi_type_float;
707 values[0] = &f;
709 /* Initialize the cif */
710 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
711 &ffi_type_double, args) == FFI_OK);
713 f = 3.14159;
715 ffi_call(&cif, FFI_FN(dblit), &d, values);
717 /* These are not always the same!! Check for a reasonable delta */
718 /*@-realcompare@*/
719 CHECK(d - dblit(f) < DBL_EPSILON);
720 /*@=realcompare@*/
722 printf("double return value tests ok!\n");
725 /* many arg tests */
727 float ff;
728 float fa[13];
730 for (ul = 0; ul < 13; ul++)
732 args[ul] = &ffi_type_float;
733 values[ul] = &fa[ul];
734 fa[ul] = (float) ul;
737 /* Initialize the cif */
738 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
739 &ffi_type_float, args) == FFI_OK);
741 /*@-usedef@*/
742 ff = many (fa[0], fa[1],
743 fa[2], fa[3],
744 fa[4], fa[5],
745 fa[6], fa[7],
746 fa[8], fa[9],
747 fa[10],fa[11],fa[12]);
748 /*@=usedef@*/
750 ffi_call(&cif, FFI_FN(many), &f, values);
752 /*@-realcompare@*/
753 if (f - ff < FLT_EPSILON)
754 /*@=realcompare@*/
755 printf("many arg tests ok!\n");
756 else
757 #ifdef POWERPC
758 printf("many arg tests failed! This is a gcc bug.\n");
759 #else
760 CHECK(0);
761 #endif
764 /* promotion tests */
766 args[0] = &ffi_type_schar;
767 args[1] = &ffi_type_sshort;
768 args[2] = &ffi_type_uchar;
769 args[3] = &ffi_type_ushort;
770 values[0] = &sc;
771 values[1] = &ss;
772 values[2] = &uc;
773 values[3] = &us;
775 /* Initialize the cif */
776 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
777 &ffi_type_sint, args) == FFI_OK);
779 us = 0;
780 ul = 0;
782 for (sc = (signed char) -127;
783 sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
784 for (ss = -30000; ss <= 30000; ss += 10000)
785 for (uc = (unsigned char) 0;
786 uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
787 for (us = 0; us <= 60000; us += 10000)
789 ul++;
790 ffi_call(&cif, FFI_FN(promotion), &rint, values);
791 CHECK((int)rint == (signed char) sc + (signed short) ss +
792 (unsigned char) uc + (unsigned short) us);
794 printf("%lu promotion tests run\n", ul);
797 #ifndef X86_WIN32 /* Structures dont work on Win32 */
799 /* struct tests */
801 test_structure_1 ts1_arg;
802 /* This is a hack to get a properly aligned result buffer */
803 test_structure_1 *ts1_result =
804 (test_structure_1 *) malloc (sizeof(test_structure_1));
806 args[0] = &ts1_type;
807 values[0] = &ts1_arg;
809 /* Initialize the cif */
810 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
811 &ts1_type, args) == FFI_OK);
813 ts1_arg.uc = '\x01';
814 ts1_arg.d = 3.14159;
815 ts1_arg.ui = 555;
817 ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
819 CHECK(ts1_result->ui == 556);
820 CHECK(ts1_result->d == 3.14159 - 1);
822 puts ("structure test 1 ok!\n");
824 free (ts1_result);
827 /* struct tests */
829 test_structure_2 ts2_arg;
831 /* This is a hack to get a properly aligned result buffer */
832 test_structure_2 *ts2_result =
833 (test_structure_2 *) malloc (sizeof(test_structure_2));
835 args[0] = &ts2_type;
836 values[0] = &ts2_arg;
838 /* Initialize the cif */
839 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
841 ts2_arg.d1 = 5.55;
842 ts2_arg.d2 = 6.66;
844 printf ("%g\n", ts2_result->d1);
845 printf ("%g\n", ts2_result->d2);
847 ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
849 printf ("%g\n", ts2_result->d1);
850 printf ("%g\n", ts2_result->d2);
852 CHECK(ts2_result->d1 == 5.55 - 1);
853 CHECK(ts2_result->d2 == 6.66 - 1);
855 printf("structure test 2 ok!\n");
857 free (ts2_result);
860 /* struct tests */
862 int compare_value;
863 test_structure_3 ts3_arg;
864 test_structure_3 *ts3_result =
865 (test_structure_3 *) malloc (sizeof(test_structure_3));
867 args[0] = &ts3_type;
868 values[0] = &ts3_arg;
870 /* Initialize the cif */
871 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
872 &ts3_type, args) == FFI_OK);
874 ts3_arg.si = -123;
875 compare_value = ts3_arg.si;
877 ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
879 printf ("%d %d\n", ts3_result->si, -(compare_value*2));
881 if (ts3_result->si == -(ts3_arg.si*2))
882 puts ("structure test 3 ok!");
883 else
885 puts ("Structure test 3 found structure passing bug.");
886 puts (" Current versions of GCC are not 100% compliant with the");
887 puts (" n32 ABI. There is a known problem related to passing");
888 puts (" small structures. Send a bug report to the gcc maintainers.");
891 free (ts3_result);
894 /* struct tests */
896 test_structure_4 ts4_arg;
898 /* This is a hack to get a properly aligned result buffer */
899 test_structure_4 *ts4_result =
900 (test_structure_4 *) malloc (sizeof(test_structure_4));
902 args[0] = &ts4_type;
903 values[0] = &ts4_arg;
905 /* Initialize the cif */
906 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
908 ts4_arg.ui1 = 2;
909 ts4_arg.ui2 = 3;
910 ts4_arg.ui3 = 4;
912 ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
914 if (ts4_result->ui3 == 2U * 3U * 4U)
915 puts ("structure test 4 ok!");
916 else
917 puts ("Structure test 4 found GCC's structure passing bug.");
919 free (ts4_result);
922 /* struct tests */
924 test_structure_5 ts5_arg1, ts5_arg2;
926 /* This is a hack to get a properly aligned result buffer */
927 test_structure_5 *ts5_result =
928 (test_structure_5 *) malloc (sizeof(test_structure_5));
930 args[0] = &ts5_type;
931 args[1] = &ts5_type;
932 values[0] = &ts5_arg1;
933 values[1] = &ts5_arg2;
935 /* Initialize the cif */
936 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
938 ts5_arg1.c1 = 2;
939 ts5_arg1.c2 = 6;
940 ts5_arg2.c1 = 5;
941 ts5_arg2.c2 = 3;
943 ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
945 if (ts5_result->c1 == 7
946 && ts5_result->c2 == 3)
947 puts ("structure test 5 ok!");
948 else
949 puts ("Structure test 5 found GCC's structure passing bug.");
951 free (ts5_result);
954 /* struct tests */
956 test_structure_6 ts6_arg;
958 /* This is a hack to get a properly aligned result buffer */
959 test_structure_6 *ts6_result =
960 (test_structure_6 *) malloc (sizeof(test_structure_6));
962 args[0] = &ts6_type;
963 values[0] = &ts6_arg;
965 /* Initialize the cif */
966 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
968 ts6_arg.f = 5.55f;
969 ts6_arg.d = 6.66;
971 printf ("%g\n", ts6_arg.f);
972 printf ("%g\n", ts6_arg.d);
974 ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
976 printf ("%g\n", ts6_result->f);
977 printf ("%g\n", ts6_result->d);
979 CHECK(ts6_result->f == 5.55f + 1);
980 CHECK(ts6_result->d == 6.66 + 1);
982 printf("structure test 6 ok!\n");
984 free (ts6_result);
987 /* struct tests */
989 test_structure_7 ts7_arg;
991 /* This is a hack to get a properly aligned result buffer */
992 test_structure_7 *ts7_result =
993 (test_structure_7 *) malloc (sizeof(test_structure_7));
995 args[0] = &ts7_type;
996 values[0] = &ts7_arg;
998 /* Initialize the cif */
999 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
1001 ts7_arg.f1 = 5.55f;
1002 ts7_arg.f2 = 55.5f;
1003 ts7_arg.d = 6.66;
1005 printf ("%g\n", ts7_arg.f1);
1006 printf ("%g\n", ts7_arg.f2);
1007 printf ("%g\n", ts7_arg.d);
1009 ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
1011 printf ("%g\n", ts7_result->f1);
1012 printf ("%g\n", ts7_result->f2);
1013 printf ("%g\n", ts7_result->d);
1015 CHECK(ts7_result->f1 == 5.55f + 1);
1016 CHECK(ts7_result->f2 == 55.5f + 1);
1017 CHECK(ts7_result->d == 6.66 + 1);
1019 printf("structure test 7 ok!\n");
1021 free (ts7_result);
1024 /* struct tests */
1026 test_structure_8 ts8_arg;
1028 /* This is a hack to get a properly aligned result buffer */
1029 test_structure_8 *ts8_result =
1030 (test_structure_8 *) malloc (sizeof(test_structure_8));
1032 args[0] = &ts8_type;
1033 values[0] = &ts8_arg;
1035 /* Initialize the cif */
1036 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
1038 ts8_arg.f1 = 5.55f;
1039 ts8_arg.f2 = 55.5f;
1040 ts8_arg.f3 = -5.55f;
1041 ts8_arg.f4 = -55.5f;
1043 printf ("%g\n", ts8_arg.f1);
1044 printf ("%g\n", ts8_arg.f2);
1045 printf ("%g\n", ts8_arg.f3);
1046 printf ("%g\n", ts8_arg.f4);
1048 ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
1050 printf ("%g\n", ts8_result->f1);
1051 printf ("%g\n", ts8_result->f2);
1052 printf ("%g\n", ts8_result->f3);
1053 printf ("%g\n", ts8_result->f4);
1055 CHECK(ts8_result->f1 == 5.55f + 1);
1056 CHECK(ts8_result->f2 == 55.5f + 1);
1057 CHECK(ts8_result->f3 == -5.55f + 1);
1058 CHECK(ts8_result->f4 == -55.5f + 1);
1060 printf("structure test 8 ok!\n");
1062 free (ts8_result);
1065 /* struct tests */
1067 test_structure_9 ts9_arg;
1069 /* This is a hack to get a properly aligned result buffer */
1070 test_structure_9 *ts9_result =
1071 (test_structure_9 *) malloc (sizeof(test_structure_9));
1073 args[0] = &ts9_type;
1074 values[0] = &ts9_arg;
1076 /* Initialize the cif */
1077 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
1079 ts9_arg.f = 5.55f;
1080 ts9_arg.i = 5;
1082 printf ("%g\n", ts9_arg.f);
1083 printf ("%d\n", ts9_arg.i);
1085 ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
1087 printf ("%g\n", ts9_result->f);
1088 printf ("%d\n", ts9_result->i);
1090 CHECK(ts9_result->f == 5.55f + 1);
1091 CHECK(ts9_result->i == 5 + 1);
1093 printf("structure test 9 ok!\n");
1095 free (ts9_result);
1098 #else
1099 printf("Structure passing doesn't work on Win32.\n");
1100 #endif /* X86_WIN32 */
1102 #ifdef X86_WIN32
1103 /* stdcall strlen tests */
1105 args[0] = &ffi_type_pointer;
1106 values[0] = (void*) &s;
1108 /* Initialize the cif */
1109 CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
1110 &ffi_type_sint, args) == FFI_OK);
1112 s = "a";
1113 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1114 CHECK(rint == 1);
1116 s = "1234567";
1117 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1118 CHECK(rint == 7);
1120 s = "1234567890123456789012345";
1121 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1122 CHECK(rint == 25);
1124 printf("stdcall strlen tests passed\n");
1127 /* stdcall many arg tests */
1129 float ff;
1130 float fa[13];
1132 for (ul = 0; ul < 13; ul++)
1134 args[ul] = &ffi_type_float;
1135 values[ul] = &fa[ul];
1136 fa[ul] = (float) ul;
1139 /* Initialize the cif */
1140 CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
1141 &ffi_type_float, args) == FFI_OK);
1143 /*@-usedef@*/
1144 ff = stdcall_many(fa[0], fa[1],
1145 fa[2], fa[3],
1146 fa[4], fa[5],
1147 fa[6], fa[7],
1148 fa[8], fa[9],
1149 fa[10],fa[11],fa[12]);
1150 /*@=usedef@*/
1152 ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
1154 /*@-realcompare@*/
1155 if (f - ff < FLT_EPSILON)
1156 /*@=realcompare@*/
1157 printf("stdcall many arg tests ok!\n");
1158 else
1159 CHECK(0);
1161 #endif /* X86_WIN32 */
1163 # if FFI_CLOSURES
1164 /* A simple closure test */
1166 (void) puts("\nEnter FFI_CLOSURES\n");
1168 cl_arg_types[0] = &ffi_type_uint64;
1169 cl_arg_types[1] = &ffi_type_uint;
1170 cl_arg_types[2] = &ffi_type_uint64;
1171 cl_arg_types[3] = &ffi_type_uint;
1172 cl_arg_types[4] = &ffi_type_sshort;
1173 cl_arg_types[5] = &ffi_type_uint64;
1174 cl_arg_types[6] = &ffi_type_uint;
1175 cl_arg_types[7] = &ffi_type_uint;
1176 cl_arg_types[8] = &ffi_type_double;
1177 cl_arg_types[9] = &ffi_type_uint;
1178 cl_arg_types[10] = &ffi_type_uint;
1179 cl_arg_types[11] = &ffi_type_float;
1180 cl_arg_types[12] = &ffi_type_uint;
1181 cl_arg_types[13] = &ffi_type_uint;
1182 cl_arg_types[14] = &ffi_type_uint;
1183 cl_arg_types[15] = &ffi_type_uint;
1184 cl_arg_types[16] = NULL;
1186 /* Initialize the cif */
1187 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1188 &ffi_type_sint, cl_arg_types) == FFI_OK);
1190 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
1191 (void *) 3 /* userdata */) == FFI_OK);
1193 CHECK((*((closure_test_type)(&cl)))
1194 (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
1195 19, 21, 1) == 680);
1200 cl_arg_types[0] = &ffi_type_float;
1201 cl_arg_types[1] = &ffi_type_float;
1202 cl_arg_types[2] = &ffi_type_float;
1203 cl_arg_types[3] = &ffi_type_float;
1204 cl_arg_types[4] = &ffi_type_sshort;
1205 cl_arg_types[5] = &ffi_type_float;
1206 cl_arg_types[6] = &ffi_type_float;
1207 cl_arg_types[7] = &ffi_type_uint;
1208 cl_arg_types[8] = &ffi_type_double;
1209 cl_arg_types[9] = &ffi_type_uint;
1210 cl_arg_types[10] = &ffi_type_uint;
1211 cl_arg_types[11] = &ffi_type_float;
1212 cl_arg_types[12] = &ffi_type_uint;
1213 cl_arg_types[13] = &ffi_type_uint;
1214 cl_arg_types[14] = &ffi_type_uint;
1215 cl_arg_types[15] = &ffi_type_uint;
1216 cl_arg_types[16] = NULL;
1218 /* Initialize the cif */
1219 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1220 &ffi_type_sint, cl_arg_types) == FFI_OK);
1222 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn1,
1223 (void *) 3 /* userdata */) == FFI_OK);
1225 CHECK((*((closure_test_type1)(&cl)))
1226 (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
1227 19, 21, 1) == 255);
1232 cl_arg_types[0] = &ffi_type_double;
1233 cl_arg_types[1] = &ffi_type_double;
1234 cl_arg_types[2] = &ffi_type_double;
1235 cl_arg_types[3] = &ffi_type_double;
1236 cl_arg_types[4] = &ffi_type_sshort;
1237 cl_arg_types[5] = &ffi_type_double;
1238 cl_arg_types[6] = &ffi_type_double;
1239 cl_arg_types[7] = &ffi_type_uint;
1240 cl_arg_types[8] = &ffi_type_double;
1241 cl_arg_types[9] = &ffi_type_uint;
1242 cl_arg_types[10] = &ffi_type_uint;
1243 cl_arg_types[11] = &ffi_type_float;
1244 cl_arg_types[12] = &ffi_type_uint;
1245 cl_arg_types[13] = &ffi_type_float;
1246 cl_arg_types[14] = &ffi_type_uint;
1247 cl_arg_types[15] = &ffi_type_uint;
1248 cl_arg_types[16] = NULL;
1250 /* Initialize the cif */
1251 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1252 &ffi_type_sint, cl_arg_types) == FFI_OK);
1254 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn2,
1255 (void *) 3 /* userdata */) == FFI_OK);
1257 CHECK((*((closure_test_type2)(&cl)))
1258 (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
1259 19.0, 21, 1) == 255);
1265 cl_arg_types[0] = &ffi_type_float;
1266 cl_arg_types[1] = &ffi_type_float;
1267 cl_arg_types[2] = &ffi_type_float;
1268 cl_arg_types[3] = &ffi_type_float;
1269 cl_arg_types[4] = &ffi_type_float;
1270 cl_arg_types[5] = &ffi_type_float;
1271 cl_arg_types[6] = &ffi_type_float;
1272 cl_arg_types[7] = &ffi_type_float;
1273 cl_arg_types[8] = &ffi_type_double;
1274 cl_arg_types[9] = &ffi_type_uint;
1275 cl_arg_types[10] = &ffi_type_float;
1276 cl_arg_types[11] = &ffi_type_float;
1277 cl_arg_types[12] = &ffi_type_uint;
1278 cl_arg_types[13] = &ffi_type_float;
1279 cl_arg_types[14] = &ffi_type_float;
1280 cl_arg_types[15] = &ffi_type_uint;
1281 cl_arg_types[16] = NULL;
1283 /* Initialize the cif */
1284 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1285 &ffi_type_sint, cl_arg_types) == FFI_OK);
1287 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn3,
1288 (void *) 3 /* userdata */) == FFI_OK);
1290 CHECK((*((closure_test_type3)(&cl)))
1291 (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
1292 19.19, 21.21, 1) == 135);
1295 (void) puts("\nFinished FFI_CLOSURES\n");
1297 # endif
1299 /* If we arrived here, all is good */
1300 (void) puts("\nLooks good. No surprises.\n");
1302 /*@-compdestroy@*/
1304 return 0;