2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / libffi / src / ffitest.c
blob223b49c6dd81b25d1d782648fe4c4e2b9b1aac8b
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)*(ffi_arg *)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)*(ffi_arg *)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)*(ffi_arg *)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)*(ffi_arg *)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 ffi_closure *pcl = &cl;
434 #endif
436 ffi_type * cl_arg_types[17];
438 ffi_type ts1_type;
439 ffi_type ts2_type;
440 ffi_type ts3_type;
441 ffi_type ts4_type;
442 ffi_type ts5_type;
443 ffi_type ts6_type;
444 ffi_type ts7_type;
445 ffi_type ts8_type;
446 ffi_type ts9_type;
447 ffi_type *ts1_type_elements[4];
448 ffi_type *ts2_type_elements[3];
449 ffi_type *ts3_type_elements[2];
450 ffi_type *ts4_type_elements[4];
451 ffi_type *ts5_type_elements[3];
452 ffi_type *ts6_type_elements[3];
453 ffi_type *ts7_type_elements[4];
454 ffi_type *ts8_type_elements[5];
455 ffi_type *ts9_type_elements[3];
457 ts1_type.size = 0;
458 ts1_type.alignment = 0;
459 ts1_type.type = FFI_TYPE_STRUCT;
461 ts2_type.size = 0;
462 ts2_type.alignment = 0;
463 ts2_type.type = FFI_TYPE_STRUCT;
465 ts3_type.size = 0;
466 ts3_type.alignment = 0;
467 ts3_type.type = FFI_TYPE_STRUCT;
469 ts4_type.size = 0;
470 ts4_type.alignment = 0;
471 ts4_type.type = FFI_TYPE_STRUCT;
473 ts5_type.size = 0;
474 ts5_type.alignment = 0;
475 ts5_type.type = FFI_TYPE_STRUCT;
477 ts6_type.size = 0;
478 ts6_type.alignment = 0;
479 ts6_type.type = FFI_TYPE_STRUCT;
481 ts7_type.size = 0;
482 ts7_type.alignment = 0;
483 ts7_type.type = FFI_TYPE_STRUCT;
485 ts8_type.size = 0;
486 ts8_type.alignment = 0;
487 ts8_type.type = FFI_TYPE_STRUCT;
489 ts9_type.size = 0;
490 ts9_type.alignment = 0;
491 ts9_type.type = FFI_TYPE_STRUCT;
493 /*@-immediatetrans@*/
494 ts1_type.elements = ts1_type_elements;
495 ts2_type.elements = ts2_type_elements;
496 ts3_type.elements = ts3_type_elements;
497 ts4_type.elements = ts4_type_elements;
498 ts5_type.elements = ts5_type_elements;
499 ts6_type.elements = ts6_type_elements;
500 ts7_type.elements = ts7_type_elements;
501 ts8_type.elements = ts8_type_elements;
502 ts9_type.elements = ts9_type_elements;
503 /*@=immediatetrans@*/
505 ts1_type_elements[0] = &ffi_type_uchar;
506 ts1_type_elements[1] = &ffi_type_double;
507 ts1_type_elements[2] = &ffi_type_uint;
508 ts1_type_elements[3] = NULL;
510 ts2_type_elements[0] = &ffi_type_double;
511 ts2_type_elements[1] = &ffi_type_double;
512 ts2_type_elements[2] = NULL;
514 ts3_type_elements[0] = &ffi_type_sint;
515 ts3_type_elements[1] = NULL;
517 ts4_type_elements[0] = &ffi_type_uint;
518 ts4_type_elements[1] = &ffi_type_uint;
519 ts4_type_elements[2] = &ffi_type_uint;
520 ts4_type_elements[3] = NULL;
522 ts5_type_elements[0] = &ffi_type_schar;
523 ts5_type_elements[1] = &ffi_type_schar;
524 ts5_type_elements[2] = NULL;
526 ts6_type_elements[0] = &ffi_type_float;
527 ts6_type_elements[1] = &ffi_type_double;
528 ts6_type_elements[2] = NULL;
530 ts7_type_elements[0] = &ffi_type_float;
531 ts7_type_elements[1] = &ffi_type_float;
532 ts7_type_elements[2] = &ffi_type_double;
533 ts7_type_elements[3] = NULL;
535 ts8_type_elements[0] = &ffi_type_float;
536 ts8_type_elements[1] = &ffi_type_float;
537 ts8_type_elements[2] = &ffi_type_float;
538 ts8_type_elements[3] = &ffi_type_float;
539 ts8_type_elements[4] = NULL;
541 ts9_type_elements[0] = &ffi_type_float;
542 ts9_type_elements[1] = &ffi_type_sint;
543 ts9_type_elements[2] = NULL;
545 ul = 0;
547 /* return value tests */
549 #if defined(MIPS) /* || defined(ARM) */
550 puts ("long long tests not run. This is a known bug on this architecture.");
551 #else
552 args[0] = &ffi_type_sint64;
553 values[0] = &ll;
555 /* Initialize the cif */
556 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
557 &ffi_type_sint64, args) == FFI_OK);
559 for (ll = 0LL; ll < 100LL; ll++)
561 ul++;
562 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
563 CHECK(rlonglong == ll);
566 for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
568 ul++;
569 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
570 CHECK(rlonglong == ll);
572 #endif
574 args[0] = &ffi_type_schar;
575 values[0] = &sc;
577 /* Initialize the cif */
578 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
579 &ffi_type_schar, args) == FFI_OK);
581 for (sc = (signed char) -127;
582 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
584 ul++;
585 ffi_call(&cif, FFI_FN(return_sc), &rint, values);
586 CHECK(rint == (ffi_arg) sc);
589 args[0] = &ffi_type_uchar;
590 values[0] = &uc;
592 /* Initialize the cif */
593 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
594 &ffi_type_uchar, args) == FFI_OK);
596 for (uc = (unsigned char) '\x00';
597 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
599 ul++;
600 ffi_call(&cif, FFI_FN(return_uc), &rint, values);
601 CHECK(rint == (signed int) uc);
604 printf("%lu return value tests run\n", ul);
607 #ifdef BROKEN_LONG_DOUBLE
608 printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
609 #else
610 /* float arg tests */
612 args[0] = &ffi_type_float;
613 values[0] = &f;
615 /* Initialize the cif */
616 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
617 &ffi_type_longdouble, args) == FFI_OK);
619 f = 3.14159;
621 #if 0
622 /* This is ifdef'd out for now. long double support under SunOS/gcc
623 is pretty much non-existent. You'll get the odd bus error in library
624 routines like printf(). */
625 printf ("%Lf\n", ldblit(f));
626 #endif
627 ld = 666;
628 ffi_call(&cif, FFI_FN(ldblit), &ld, values);
630 #if 0
631 /* This is ifdef'd out for now. long double support under SunOS/gcc
632 is pretty much non-existent. You'll get the odd bus error in library
633 routines like printf(). */
634 printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
635 #endif
637 /* These are not always the same!! Check for a reasonable delta */
638 /*@-realcompare@*/
639 if (ld - ldblit(f) < LDBL_EPSILON)
640 /*@=realcompare@*/
641 puts("long double return value tests ok!");
642 else
643 CHECK(0);
646 /* float arg tests */
648 args[0] = &ffi_type_sint;
649 values[0] = &si1;
650 args[1] = &ffi_type_float;
651 values[1] = &f;
652 args[2] = &ffi_type_double;
653 values[2] = &d;
654 args[3] = &ffi_type_longdouble;
655 values[3] = &ld;
656 args[4] = &ffi_type_sint;
657 values[4] = &si2;
659 /* Initialize the cif */
660 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
661 &ffi_type_sint, args) == FFI_OK);
663 si1 = 6;
664 f = 3.14159;
665 d = (double)1.0/(double)3.0;
666 ld = 2.71828182846L;
667 si2 = 10;
669 floating (si1, f, d, ld, si2);
671 ffi_call(&cif, FFI_FN(floating), &rint, values);
673 printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
675 CHECK(rint == floating(si1, f, d, ld, si2));
677 printf("float arg tests ok!\n");
679 #endif
681 /* strlen tests */
683 args[0] = &ffi_type_pointer;
684 values[0] = (void*) &s;
686 /* Initialize the cif */
687 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
688 &ffi_type_sint, args) == FFI_OK);
690 s = "a";
691 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
692 CHECK(rint == 1);
694 s = "1234567";
695 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
696 CHECK(rint == 7);
698 s = "1234567890123456789012345";
699 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
700 CHECK(rint == 25);
702 printf("strlen tests passed\n");
705 /* float arg tests */
707 args[0] = &ffi_type_float;
708 values[0] = &f;
710 /* Initialize the cif */
711 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
712 &ffi_type_double, args) == FFI_OK);
714 f = 3.14159;
716 ffi_call(&cif, FFI_FN(dblit), &d, values);
718 /* These are not always the same!! Check for a reasonable delta */
719 /*@-realcompare@*/
720 CHECK(d - dblit(f) < DBL_EPSILON);
721 /*@=realcompare@*/
723 printf("double return value tests ok!\n");
726 /* many arg tests */
728 float ff;
729 float fa[13];
731 for (ul = 0; ul < 13; ul++)
733 args[ul] = &ffi_type_float;
734 values[ul] = &fa[ul];
735 fa[ul] = (float) ul;
738 /* Initialize the cif */
739 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
740 &ffi_type_float, args) == FFI_OK);
742 /*@-usedef@*/
743 ff = many (fa[0], fa[1],
744 fa[2], fa[3],
745 fa[4], fa[5],
746 fa[6], fa[7],
747 fa[8], fa[9],
748 fa[10],fa[11],fa[12]);
749 /*@=usedef@*/
751 ffi_call(&cif, FFI_FN(many), &f, values);
753 /*@-realcompare@*/
754 if (f - ff < FLT_EPSILON)
755 /*@=realcompare@*/
756 printf("many arg tests ok!\n");
757 else
758 #ifdef POWERPC
759 printf("many arg tests failed! This is a gcc bug.\n");
760 #else
761 CHECK(0);
762 #endif
765 /* promotion tests */
767 args[0] = &ffi_type_schar;
768 args[1] = &ffi_type_sshort;
769 args[2] = &ffi_type_uchar;
770 args[3] = &ffi_type_ushort;
771 values[0] = &sc;
772 values[1] = &ss;
773 values[2] = &uc;
774 values[3] = &us;
776 /* Initialize the cif */
777 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
778 &ffi_type_sint, args) == FFI_OK);
780 us = 0;
781 ul = 0;
783 for (sc = (signed char) -127;
784 sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
785 for (ss = -30000; ss <= 30000; ss += 10000)
786 for (uc = (unsigned char) 0;
787 uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
788 for (us = 0; us <= 60000; us += 10000)
790 ul++;
791 ffi_call(&cif, FFI_FN(promotion), &rint, values);
792 CHECK((int)rint == (signed char) sc + (signed short) ss +
793 (unsigned char) uc + (unsigned short) us);
795 printf("%lu promotion tests run\n", ul);
798 #ifndef X86_WIN32 /* Structures dont work on Win32 */
800 /* struct tests */
802 test_structure_1 ts1_arg;
803 /* This is a hack to get a properly aligned result buffer */
804 test_structure_1 *ts1_result =
805 (test_structure_1 *) malloc (sizeof(test_structure_1));
807 args[0] = &ts1_type;
808 values[0] = &ts1_arg;
810 /* Initialize the cif */
811 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
812 &ts1_type, args) == FFI_OK);
814 ts1_arg.uc = '\x01';
815 ts1_arg.d = 3.14159;
816 ts1_arg.ui = 555;
818 ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
820 CHECK(ts1_result->ui == 556);
821 CHECK(ts1_result->d == 3.14159 - 1);
823 puts ("structure test 1 ok!\n");
825 free (ts1_result);
828 /* struct tests */
830 test_structure_2 ts2_arg;
832 /* This is a hack to get a properly aligned result buffer */
833 test_structure_2 *ts2_result =
834 (test_structure_2 *) malloc (sizeof(test_structure_2));
836 args[0] = &ts2_type;
837 values[0] = &ts2_arg;
839 /* Initialize the cif */
840 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
842 ts2_arg.d1 = 5.55;
843 ts2_arg.d2 = 6.66;
845 printf ("%g\n", ts2_arg.d1);
846 printf ("%g\n", ts2_arg.d2);
848 ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
850 printf ("%g\n", ts2_result->d1);
851 printf ("%g\n", ts2_result->d2);
853 CHECK(ts2_result->d1 == 5.55 - 1);
854 CHECK(ts2_result->d2 == 6.66 - 1);
856 printf("structure test 2 ok!\n");
858 free (ts2_result);
861 /* struct tests */
863 int compare_value;
864 test_structure_3 ts3_arg;
865 test_structure_3 *ts3_result =
866 (test_structure_3 *) malloc (sizeof(test_structure_3));
868 args[0] = &ts3_type;
869 values[0] = &ts3_arg;
871 /* Initialize the cif */
872 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
873 &ts3_type, args) == FFI_OK);
875 ts3_arg.si = -123;
876 compare_value = ts3_arg.si;
878 ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
880 printf ("%d %d\n", ts3_result->si, -(compare_value*2));
882 if (ts3_result->si == -(ts3_arg.si*2))
883 puts ("structure test 3 ok!");
884 else
886 puts ("Structure test 3 found structure passing bug.");
887 puts (" Current versions of GCC are not 100% compliant with the");
888 puts (" n32 ABI. There is a known problem related to passing");
889 puts (" small structures. Send a bug report to the gcc maintainers.");
892 free (ts3_result);
895 /* struct tests */
897 test_structure_4 ts4_arg;
899 /* This is a hack to get a properly aligned result buffer */
900 test_structure_4 *ts4_result =
901 (test_structure_4 *) malloc (sizeof(test_structure_4));
903 args[0] = &ts4_type;
904 values[0] = &ts4_arg;
906 /* Initialize the cif */
907 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
909 ts4_arg.ui1 = 2;
910 ts4_arg.ui2 = 3;
911 ts4_arg.ui3 = 4;
913 ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
915 if (ts4_result->ui3 == 2U * 3U * 4U)
916 puts ("structure test 4 ok!");
917 else
918 puts ("Structure test 4 found GCC's structure passing bug.");
920 free (ts4_result);
923 /* struct tests */
925 test_structure_5 ts5_arg1, ts5_arg2;
927 /* This is a hack to get a properly aligned result buffer */
928 test_structure_5 *ts5_result =
929 (test_structure_5 *) malloc (sizeof(test_structure_5));
931 args[0] = &ts5_type;
932 args[1] = &ts5_type;
933 values[0] = &ts5_arg1;
934 values[1] = &ts5_arg2;
936 /* Initialize the cif */
937 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
939 ts5_arg1.c1 = 2;
940 ts5_arg1.c2 = 6;
941 ts5_arg2.c1 = 5;
942 ts5_arg2.c2 = 3;
944 ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
946 if (ts5_result->c1 == 7
947 && ts5_result->c2 == 3)
948 puts ("structure test 5 ok!");
949 else
950 puts ("Structure test 5 found GCC's structure passing bug.");
952 free (ts5_result);
955 /* struct tests */
957 test_structure_6 ts6_arg;
959 /* This is a hack to get a properly aligned result buffer */
960 test_structure_6 *ts6_result =
961 (test_structure_6 *) malloc (sizeof(test_structure_6));
963 args[0] = &ts6_type;
964 values[0] = &ts6_arg;
966 /* Initialize the cif */
967 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
969 ts6_arg.f = 5.55f;
970 ts6_arg.d = 6.66;
972 printf ("%g\n", ts6_arg.f);
973 printf ("%g\n", ts6_arg.d);
975 ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
977 printf ("%g\n", ts6_result->f);
978 printf ("%g\n", ts6_result->d);
980 CHECK(ts6_result->f == 5.55f + 1);
981 CHECK(ts6_result->d == 6.66 + 1);
983 printf("structure test 6 ok!\n");
985 free (ts6_result);
988 /* struct tests */
990 test_structure_7 ts7_arg;
992 /* This is a hack to get a properly aligned result buffer */
993 test_structure_7 *ts7_result =
994 (test_structure_7 *) malloc (sizeof(test_structure_7));
996 args[0] = &ts7_type;
997 values[0] = &ts7_arg;
999 /* Initialize the cif */
1000 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
1002 ts7_arg.f1 = 5.55f;
1003 ts7_arg.f2 = 55.5f;
1004 ts7_arg.d = 6.66;
1006 printf ("%g\n", ts7_arg.f1);
1007 printf ("%g\n", ts7_arg.f2);
1008 printf ("%g\n", ts7_arg.d);
1010 ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
1012 printf ("%g\n", ts7_result->f1);
1013 printf ("%g\n", ts7_result->f2);
1014 printf ("%g\n", ts7_result->d);
1016 CHECK(ts7_result->f1 == 5.55f + 1);
1017 CHECK(ts7_result->f2 == 55.5f + 1);
1018 CHECK(ts7_result->d == 6.66 + 1);
1020 printf("structure test 7 ok!\n");
1022 free (ts7_result);
1025 /* struct tests */
1027 test_structure_8 ts8_arg;
1029 /* This is a hack to get a properly aligned result buffer */
1030 test_structure_8 *ts8_result =
1031 (test_structure_8 *) malloc (sizeof(test_structure_8));
1033 args[0] = &ts8_type;
1034 values[0] = &ts8_arg;
1036 /* Initialize the cif */
1037 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
1039 ts8_arg.f1 = 5.55f;
1040 ts8_arg.f2 = 55.5f;
1041 ts8_arg.f3 = -5.55f;
1042 ts8_arg.f4 = -55.5f;
1044 printf ("%g\n", ts8_arg.f1);
1045 printf ("%g\n", ts8_arg.f2);
1046 printf ("%g\n", ts8_arg.f3);
1047 printf ("%g\n", ts8_arg.f4);
1049 ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
1051 printf ("%g\n", ts8_result->f1);
1052 printf ("%g\n", ts8_result->f2);
1053 printf ("%g\n", ts8_result->f3);
1054 printf ("%g\n", ts8_result->f4);
1056 CHECK(ts8_result->f1 == 5.55f + 1);
1057 CHECK(ts8_result->f2 == 55.5f + 1);
1058 CHECK(ts8_result->f3 == -5.55f + 1);
1059 CHECK(ts8_result->f4 == -55.5f + 1);
1061 printf("structure test 8 ok!\n");
1063 free (ts8_result);
1066 /* struct tests */
1068 test_structure_9 ts9_arg;
1070 /* This is a hack to get a properly aligned result buffer */
1071 test_structure_9 *ts9_result =
1072 (test_structure_9 *) malloc (sizeof(test_structure_9));
1074 args[0] = &ts9_type;
1075 values[0] = &ts9_arg;
1077 /* Initialize the cif */
1078 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
1080 ts9_arg.f = 5.55f;
1081 ts9_arg.i = 5;
1083 printf ("%g\n", ts9_arg.f);
1084 printf ("%d\n", ts9_arg.i);
1086 ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
1088 printf ("%g\n", ts9_result->f);
1089 printf ("%d\n", ts9_result->i);
1091 CHECK(ts9_result->f == 5.55f + 1);
1092 CHECK(ts9_result->i == 5 + 1);
1094 printf("structure test 9 ok!\n");
1096 free (ts9_result);
1099 #else
1100 printf("Structure passing doesn't work on Win32.\n");
1101 #endif /* X86_WIN32 */
1103 #ifdef X86_WIN32
1104 /* stdcall strlen tests */
1106 args[0] = &ffi_type_pointer;
1107 values[0] = (void*) &s;
1109 /* Initialize the cif */
1110 CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
1111 &ffi_type_sint, args) == FFI_OK);
1113 s = "a";
1114 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1115 CHECK(rint == 1);
1117 s = "1234567";
1118 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1119 CHECK(rint == 7);
1121 s = "1234567890123456789012345";
1122 ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1123 CHECK(rint == 25);
1125 printf("stdcall strlen tests passed\n");
1128 /* stdcall many arg tests */
1130 float ff;
1131 float fa[13];
1133 for (ul = 0; ul < 13; ul++)
1135 args[ul] = &ffi_type_float;
1136 values[ul] = &fa[ul];
1137 fa[ul] = (float) ul;
1140 /* Initialize the cif */
1141 CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
1142 &ffi_type_float, args) == FFI_OK);
1144 /*@-usedef@*/
1145 ff = stdcall_many(fa[0], fa[1],
1146 fa[2], fa[3],
1147 fa[4], fa[5],
1148 fa[6], fa[7],
1149 fa[8], fa[9],
1150 fa[10],fa[11],fa[12]);
1151 /*@=usedef@*/
1153 ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
1155 /*@-realcompare@*/
1156 if (f - ff < FLT_EPSILON)
1157 /*@=realcompare@*/
1158 printf("stdcall many arg tests ok!\n");
1159 else
1160 CHECK(0);
1162 #endif /* X86_WIN32 */
1164 # if FFI_CLOSURES
1165 # if __GNUC__ >= 2
1166 /* Hide before the compiler that pcl is &cl, since on
1167 some architectures it is not possible to call a data
1168 object using direct function call. */
1169 asm ("" : "=g" (pcl) : "0" (pcl));
1170 # endif
1172 /* A simple closure test */
1174 (void) puts("\nEnter FFI_CLOSURES\n");
1176 cl_arg_types[0] = &ffi_type_uint64;
1177 cl_arg_types[1] = &ffi_type_uint;
1178 cl_arg_types[2] = &ffi_type_uint64;
1179 cl_arg_types[3] = &ffi_type_uint;
1180 cl_arg_types[4] = &ffi_type_sshort;
1181 cl_arg_types[5] = &ffi_type_uint64;
1182 cl_arg_types[6] = &ffi_type_uint;
1183 cl_arg_types[7] = &ffi_type_uint;
1184 cl_arg_types[8] = &ffi_type_double;
1185 cl_arg_types[9] = &ffi_type_uint;
1186 cl_arg_types[10] = &ffi_type_uint;
1187 cl_arg_types[11] = &ffi_type_float;
1188 cl_arg_types[12] = &ffi_type_uint;
1189 cl_arg_types[13] = &ffi_type_uint;
1190 cl_arg_types[14] = &ffi_type_uint;
1191 cl_arg_types[15] = &ffi_type_uint;
1192 cl_arg_types[16] = NULL;
1194 /* Initialize the cif */
1195 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1196 &ffi_type_sint, cl_arg_types) == FFI_OK);
1198 CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn,
1199 (void *) 3 /* userdata */) == FFI_OK);
1201 CHECK((*((closure_test_type)pcl))
1202 (1LL, 2, 3LL, 4, 127, 429LL, 7, 8, 9.5, 10, 11, 12, 13,
1203 19, 21, 1) == 680);
1208 cl_arg_types[0] = &ffi_type_float;
1209 cl_arg_types[1] = &ffi_type_float;
1210 cl_arg_types[2] = &ffi_type_float;
1211 cl_arg_types[3] = &ffi_type_float;
1212 cl_arg_types[4] = &ffi_type_sshort;
1213 cl_arg_types[5] = &ffi_type_float;
1214 cl_arg_types[6] = &ffi_type_float;
1215 cl_arg_types[7] = &ffi_type_uint;
1216 cl_arg_types[8] = &ffi_type_double;
1217 cl_arg_types[9] = &ffi_type_uint;
1218 cl_arg_types[10] = &ffi_type_uint;
1219 cl_arg_types[11] = &ffi_type_float;
1220 cl_arg_types[12] = &ffi_type_uint;
1221 cl_arg_types[13] = &ffi_type_uint;
1222 cl_arg_types[14] = &ffi_type_uint;
1223 cl_arg_types[15] = &ffi_type_uint;
1224 cl_arg_types[16] = NULL;
1226 /* Initialize the cif */
1227 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1228 &ffi_type_sint, cl_arg_types) == FFI_OK);
1230 CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn1,
1231 (void *) 3 /* userdata */) == FFI_OK);
1233 CHECK((*((closure_test_type1)pcl))
1234 (1.1, 2.2, 3.3, 4.4, 127, 5.5, 6.6, 8, 9, 10, 11, 12.0, 13,
1235 19, 21, 1) == 255);
1240 cl_arg_types[0] = &ffi_type_double;
1241 cl_arg_types[1] = &ffi_type_double;
1242 cl_arg_types[2] = &ffi_type_double;
1243 cl_arg_types[3] = &ffi_type_double;
1244 cl_arg_types[4] = &ffi_type_sshort;
1245 cl_arg_types[5] = &ffi_type_double;
1246 cl_arg_types[6] = &ffi_type_double;
1247 cl_arg_types[7] = &ffi_type_uint;
1248 cl_arg_types[8] = &ffi_type_double;
1249 cl_arg_types[9] = &ffi_type_uint;
1250 cl_arg_types[10] = &ffi_type_uint;
1251 cl_arg_types[11] = &ffi_type_float;
1252 cl_arg_types[12] = &ffi_type_uint;
1253 cl_arg_types[13] = &ffi_type_float;
1254 cl_arg_types[14] = &ffi_type_uint;
1255 cl_arg_types[15] = &ffi_type_uint;
1256 cl_arg_types[16] = NULL;
1258 /* Initialize the cif */
1259 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1260 &ffi_type_sint, cl_arg_types) == FFI_OK);
1262 CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn2,
1263 (void *) 3 /* userdata */) == FFI_OK);
1265 CHECK((*((closure_test_type2)pcl))
1266 (1, 2, 3, 4, 127, 5, 6, 8, 9, 10, 11, 12.0, 13,
1267 19.0, 21, 1) == 255);
1273 cl_arg_types[0] = &ffi_type_float;
1274 cl_arg_types[1] = &ffi_type_float;
1275 cl_arg_types[2] = &ffi_type_float;
1276 cl_arg_types[3] = &ffi_type_float;
1277 cl_arg_types[4] = &ffi_type_float;
1278 cl_arg_types[5] = &ffi_type_float;
1279 cl_arg_types[6] = &ffi_type_float;
1280 cl_arg_types[7] = &ffi_type_float;
1281 cl_arg_types[8] = &ffi_type_double;
1282 cl_arg_types[9] = &ffi_type_uint;
1283 cl_arg_types[10] = &ffi_type_float;
1284 cl_arg_types[11] = &ffi_type_float;
1285 cl_arg_types[12] = &ffi_type_uint;
1286 cl_arg_types[13] = &ffi_type_float;
1287 cl_arg_types[14] = &ffi_type_float;
1288 cl_arg_types[15] = &ffi_type_uint;
1289 cl_arg_types[16] = NULL;
1291 /* Initialize the cif */
1292 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1293 &ffi_type_sint, cl_arg_types) == FFI_OK);
1295 CHECK(ffi_prep_closure(pcl, &cif, closure_test_fn3,
1296 (void *) 3 /* userdata */) == FFI_OK);
1298 CHECK((*((closure_test_type3)pcl))
1299 (1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9, 10, 11.11, 12.0, 13,
1300 19.19, 21.21, 1) == 135);
1303 (void) puts("\nFinished FFI_CLOSURES\n");
1305 # endif
1307 /* If we arrived here, all is good */
1308 (void) puts("\nLooks good. No surprises.\n");
1310 /*@-compdestroy@*/
1312 return 0;