Add x prefix to v850e case for handling --with-cpu=v850e.
[official-gcc.git] / libffi / src / ffitest.c
blob8d72df1cc031c2e95740733392e629bc9d5a75fe
1 /* -----------------------------------------------------------------------
2 ffitest.c - Copyright (c) 1996, 1997, 1998 Cygnus Solutions
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 static int promotion(signed char sc, signed short ss,
53 unsigned char uc, unsigned short us)
55 int r = (int) sc + (int) ss + (int) uc + (int) us;
57 return r;
60 static signed char return_sc(signed char sc)
62 return sc;
65 static unsigned char return_uc(unsigned char uc)
67 return uc;
70 static long long return_ll(long long ll)
72 return ll;
75 static int floating(int a, float b, double c, long double d, int e)
77 int i;
79 #if 0
80 /* This is ifdef'd out for now. long double support under SunOS/gcc
81 is pretty much non-existent. You'll get the odd bus error in library
82 routines like printf(). */
83 printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e);
84 #endif
86 i = (int) ((float)a/b + ((float)c/(float)d));
88 return i;
91 static float many(float f1,
92 float f2,
93 float f3,
94 float f4,
95 float f5,
96 float f6,
97 float f7,
98 float f8,
99 float f9,
100 float f10,
101 float f11,
102 float f12,
103 float f13)
105 #if 0
106 printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n",
107 (double) f1, (double) f2, (double) f3, (double) f4, (double) f5,
108 (double) f6, (double) f7, (double) f8, (double) f9, (double) f10,
109 (double) f11, (double) f12, (double) f13);
110 #endif
112 return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
115 static double dblit(float f)
117 return f/3.0;
120 static long double ldblit(float f)
122 return (long double) (((long double) f)/ (long double) 3.0);
125 typedef struct
127 unsigned char uc;
128 double d;
129 unsigned int ui;
130 } test_structure_1;
132 typedef struct
134 double d1;
135 double d2;
136 } test_structure_2;
138 typedef struct
140 int si;
141 } test_structure_3;
143 typedef struct
145 unsigned ui1;
146 unsigned ui2;
147 unsigned ui3;
148 } test_structure_4;
150 typedef struct
152 char c1;
153 char c2;
154 } test_structure_5;
156 typedef struct
158 float f;
159 double d;
160 } test_structure_6;
162 typedef struct
164 float f1;
165 float f2;
166 double d;
167 } test_structure_7;
169 typedef struct
171 float f1;
172 float f2;
173 float f3;
174 float f4;
175 } test_structure_8;
177 typedef struct
179 float f;
180 int i;
181 } test_structure_9;
183 static test_structure_1 struct1(test_structure_1 ts)
185 /*@-type@*/
186 ts.uc++;
187 /*@=type@*/
188 ts.d--;
189 ts.ui++;
191 return ts;
194 static test_structure_2 struct2(test_structure_2 ts)
196 ts.d1--;
197 ts.d2--;
199 return ts;
202 static test_structure_3 struct3(test_structure_3 ts)
204 ts.si = -(ts.si*2);
206 return ts;
209 static test_structure_4 struct4(test_structure_4 ts)
211 ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
213 return ts;
216 static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
218 ts1.c1 += ts2.c1;
219 ts1.c2 -= ts2.c2;
221 return ts1;
224 static test_structure_6 struct6 (test_structure_6 ts)
226 ts.f += 1;
227 ts.d += 1;
229 return ts;
232 static test_structure_7 struct7 (test_structure_7 ts)
234 ts.f1 += 1;
235 ts.f2 += 1;
236 ts.d += 1;
238 return ts;
241 static test_structure_8 struct8 (test_structure_8 ts)
243 ts.f1 += 1;
244 ts.f2 += 1;
245 ts.f3 += 1;
246 ts.f4 += 1;
248 return ts;
251 static test_structure_9 struct9 (test_structure_9 ts)
253 ts.f += 1;
254 ts.i += 1;
256 return ts;
259 /* Take an int and a float argument, together with int userdata, and */
260 /* return the sum. */
261 #if FFI_CLOSURES
262 static void
263 closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
265 *(int*)resp = *(int*)args[0] + (int)(*(float*)args[1]) + (int)(long)userdata;
268 typedef int (*closure_test_type)(int, float);
269 #endif
271 int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
273 ffi_cif cif;
274 ffi_type *args[MAX_ARGS];
275 void *values[MAX_ARGS];
276 char *s;
277 signed char sc;
278 unsigned char uc;
279 signed short ss;
280 unsigned short us;
281 unsigned long ul;
282 long long ll;
283 float f;
284 double d;
285 long double ld;
286 signed int si1;
287 signed int si2;
289 ffi_arg rint;
290 long long rlonglong;
292 ffi_type ts1_type;
293 ffi_type ts2_type;
294 ffi_type ts3_type;
295 ffi_type ts4_type;
296 ffi_type ts5_type;
297 ffi_type ts6_type;
298 ffi_type ts7_type;
299 ffi_type ts8_type;
300 ffi_type ts9_type;
301 ffi_type *ts1_type_elements[4];
302 ffi_type *ts2_type_elements[3];
303 ffi_type *ts3_type_elements[2];
304 ffi_type *ts4_type_elements[4];
305 ffi_type *ts5_type_elements[3];
306 ffi_type *ts6_type_elements[3];
307 ffi_type *ts7_type_elements[4];
308 ffi_type *ts8_type_elements[5];
309 ffi_type *ts9_type_elements[3];
311 ts1_type.size = 0;
312 ts1_type.alignment = 0;
313 ts1_type.type = FFI_TYPE_STRUCT;
315 ts2_type.size = 0;
316 ts2_type.alignment = 0;
317 ts2_type.type = FFI_TYPE_STRUCT;
319 ts3_type.size = 0;
320 ts3_type.alignment = 0;
321 ts3_type.type = FFI_TYPE_STRUCT;
323 ts4_type.size = 0;
324 ts4_type.alignment = 0;
325 ts4_type.type = FFI_TYPE_STRUCT;
327 ts5_type.size = 0;
328 ts5_type.alignment = 0;
329 ts5_type.type = FFI_TYPE_STRUCT;
331 ts6_type.size = 0;
332 ts6_type.alignment = 0;
333 ts6_type.type = FFI_TYPE_STRUCT;
335 ts7_type.size = 0;
336 ts7_type.alignment = 0;
337 ts7_type.type = FFI_TYPE_STRUCT;
339 ts8_type.size = 0;
340 ts8_type.alignment = 0;
341 ts8_type.type = FFI_TYPE_STRUCT;
343 ts9_type.size = 0;
344 ts9_type.alignment = 0;
345 ts9_type.type = FFI_TYPE_STRUCT;
347 /*@-immediatetrans@*/
348 ts1_type.elements = ts1_type_elements;
349 ts2_type.elements = ts2_type_elements;
350 ts3_type.elements = ts3_type_elements;
351 ts4_type.elements = ts4_type_elements;
352 ts5_type.elements = ts5_type_elements;
353 ts6_type.elements = ts6_type_elements;
354 ts7_type.elements = ts7_type_elements;
355 ts8_type.elements = ts8_type_elements;
356 ts9_type.elements = ts9_type_elements;
357 /*@=immediatetrans@*/
359 ts1_type_elements[0] = &ffi_type_uchar;
360 ts1_type_elements[1] = &ffi_type_double;
361 ts1_type_elements[2] = &ffi_type_uint;
362 ts1_type_elements[3] = NULL;
364 ts2_type_elements[0] = &ffi_type_double;
365 ts2_type_elements[1] = &ffi_type_double;
366 ts2_type_elements[2] = NULL;
368 ts3_type_elements[0] = &ffi_type_sint;
369 ts3_type_elements[1] = NULL;
371 ts4_type_elements[0] = &ffi_type_uint;
372 ts4_type_elements[1] = &ffi_type_uint;
373 ts4_type_elements[2] = &ffi_type_uint;
374 ts4_type_elements[3] = NULL;
376 ts5_type_elements[0] = &ffi_type_schar;
377 ts5_type_elements[1] = &ffi_type_schar;
378 ts5_type_elements[2] = NULL;
380 ts6_type_elements[0] = &ffi_type_float;
381 ts6_type_elements[1] = &ffi_type_double;
382 ts6_type_elements[2] = NULL;
384 ts7_type_elements[0] = &ffi_type_float;
385 ts7_type_elements[1] = &ffi_type_float;
386 ts7_type_elements[2] = &ffi_type_double;
387 ts7_type_elements[3] = NULL;
389 ts8_type_elements[0] = &ffi_type_float;
390 ts8_type_elements[1] = &ffi_type_float;
391 ts8_type_elements[2] = &ffi_type_float;
392 ts8_type_elements[3] = &ffi_type_float;
393 ts8_type_elements[4] = NULL;
395 ts9_type_elements[0] = &ffi_type_float;
396 ts9_type_elements[1] = &ffi_type_sint;
397 ts9_type_elements[2] = NULL;
399 ul = 0;
401 /* return value tests */
403 #if defined(MIPS) /* || defined(ARM) */
404 puts ("long long tests not run. This is a known bug on this architecture.");
405 #else
406 args[0] = &ffi_type_sint64;
407 values[0] = &ll;
409 /* Initialize the cif */
410 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
411 &ffi_type_sint64, args) == FFI_OK);
413 for (ll = 0LL; ll < 100LL; ll++)
415 ul++;
416 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
417 CHECK(rlonglong == ll);
420 for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
422 ul++;
423 ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
424 CHECK(rlonglong == ll);
426 #endif
428 args[0] = &ffi_type_schar;
429 values[0] = &sc;
431 /* Initialize the cif */
432 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
433 &ffi_type_schar, args) == FFI_OK);
435 for (sc = (signed char) -127;
436 sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
438 ul++;
439 ffi_call(&cif, FFI_FN(return_sc), &rint, values);
440 CHECK(rint == (ffi_arg) sc);
443 args[0] = &ffi_type_uchar;
444 values[0] = &uc;
446 /* Initialize the cif */
447 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
448 &ffi_type_uchar, args) == FFI_OK);
450 for (uc = (unsigned char) '\x00';
451 uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
453 ul++;
454 ffi_call(&cif, FFI_FN(return_uc), &rint, values);
455 CHECK(rint == (signed int) uc);
458 printf("%lu return value tests run\n", ul);
461 #ifdef BROKEN_LONG_DOUBLE
462 printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n");
463 #else
464 /* float arg tests */
466 args[0] = &ffi_type_float;
467 values[0] = &f;
469 /* Initialize the cif */
470 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
471 &ffi_type_longdouble, args) == FFI_OK);
473 f = 3.14159;
475 #if 0
476 /* This is ifdef'd out for now. long double support under SunOS/gcc
477 is pretty much non-existent. You'll get the odd bus error in library
478 routines like printf(). */
479 printf ("%Lf\n", ldblit(f));
480 #endif
481 ld = 666;
482 ffi_call(&cif, FFI_FN(ldblit), &ld, values);
484 #if 0
485 /* This is ifdef'd out for now. long double support under SunOS/gcc
486 is pretty much non-existent. You'll get the odd bus error in library
487 routines like printf(). */
488 printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
489 #endif
491 /* These are not always the same!! Check for a reasonable delta */
492 /*@-realcompare@*/
493 if (ld - ldblit(f) < LDBL_EPSILON)
494 /*@=realcompare@*/
495 puts("long double return value tests ok!");
496 else
497 CHECK(0);
500 /* float arg tests */
502 args[0] = &ffi_type_sint;
503 values[0] = &si1;
504 args[1] = &ffi_type_float;
505 values[1] = &f;
506 args[2] = &ffi_type_double;
507 values[2] = &d;
508 args[3] = &ffi_type_longdouble;
509 values[3] = &ld;
510 args[4] = &ffi_type_sint;
511 values[4] = &si2;
513 /* Initialize the cif */
514 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
515 &ffi_type_sint, args) == FFI_OK);
517 si1 = 6;
518 f = 3.14159;
519 d = (double)1.0/(double)3.0;
520 ld = 2.71828182846L;
521 si2 = 10;
523 floating (si1, f, d, ld, si2);
525 ffi_call(&cif, FFI_FN(floating), &rint, values);
527 printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
529 CHECK(rint == floating(si1, f, d, ld, si2));
531 printf("float arg tests ok!\n");
533 #endif
535 /* strlen tests */
537 args[0] = &ffi_type_pointer;
538 values[0] = (void*) &s;
540 /* Initialize the cif */
541 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
542 &ffi_type_sint, args) == FFI_OK);
544 s = "a";
545 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
546 CHECK(rint == 1);
548 s = "1234567";
549 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
550 CHECK(rint == 7);
552 s = "1234567890123456789012345";
553 ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
554 CHECK(rint == 25);
556 printf("strlen tests passed\n");
559 /* float arg tests */
561 args[0] = &ffi_type_float;
562 values[0] = &f;
564 /* Initialize the cif */
565 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
566 &ffi_type_double, args) == FFI_OK);
568 f = 3.14159;
570 ffi_call(&cif, FFI_FN(dblit), &d, values);
572 /* These are not always the same!! Check for a reasonable delta */
573 /*@-realcompare@*/
574 CHECK(d - dblit(f) < DBL_EPSILON);
575 /*@=realcompare@*/
577 printf("double return value tests ok!\n");
580 /* many arg tests */
582 float ff;
583 float fa[13];
585 for (ul = 0; ul < 13; ul++)
587 args[ul] = &ffi_type_float;
588 values[ul] = &fa[ul];
589 fa[ul] = (float) ul;
592 /* Initialize the cif */
593 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13,
594 &ffi_type_float, args) == FFI_OK);
596 /*@-usedef@*/
597 ff = many (fa[0], fa[1],
598 fa[2], fa[3],
599 fa[4], fa[5],
600 fa[6], fa[7],
601 fa[8], fa[9],
602 fa[10],fa[11],fa[12]);
603 /*@=usedef@*/
605 ffi_call(&cif, FFI_FN(many), &f, values);
607 /*@-realcompare@*/
608 if (f - ff < FLT_EPSILON)
609 /*@=realcompare@*/
610 printf("many arg tests ok!\n");
611 else
612 #ifdef POWERPC
613 printf("many arg tests failed! This is a gcc bug.\n");
614 #else
615 CHECK(0);
616 #endif
619 /* promotion tests */
621 args[0] = &ffi_type_schar;
622 args[1] = &ffi_type_sshort;
623 args[2] = &ffi_type_uchar;
624 args[3] = &ffi_type_ushort;
625 values[0] = &sc;
626 values[1] = &ss;
627 values[2] = &uc;
628 values[3] = &us;
630 /* Initialize the cif */
631 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4,
632 &ffi_type_sint, args) == FFI_OK);
634 us = 0;
635 ul = 0;
637 for (sc = (signed char) -127;
638 sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/)
639 for (ss = -30000; ss <= 30000; ss += 10000)
640 for (uc = (unsigned char) 0;
641 uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/)
642 for (us = 0; us <= 60000; us += 10000)
644 ul++;
645 ffi_call(&cif, FFI_FN(promotion), &rint, values);
646 CHECK((int)rint == (signed char) sc + (signed short) ss +
647 (unsigned char) uc + (unsigned short) us);
649 printf("%lu promotion tests run\n", ul);
652 #ifndef X86_WIN32 /* Structures dont work on Win32 */
654 /* struct tests */
656 test_structure_1 ts1_arg;
657 /* This is a hack to get a properly aligned result buffer */
658 test_structure_1 *ts1_result =
659 (test_structure_1 *) malloc (sizeof(test_structure_1));
661 args[0] = &ts1_type;
662 values[0] = &ts1_arg;
664 /* Initialize the cif */
665 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
666 &ts1_type, args) == FFI_OK);
668 ts1_arg.uc = '\x01';
669 ts1_arg.d = 3.14159;
670 ts1_arg.ui = 555;
672 ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
674 CHECK(ts1_result->ui == 556);
675 CHECK(ts1_result->d == 3.14159 - 1);
677 puts ("structure test 1 ok!\n");
679 free (ts1_result);
682 /* struct tests */
684 test_structure_2 ts2_arg;
686 /* This is a hack to get a properly aligned result buffer */
687 test_structure_2 *ts2_result =
688 (test_structure_2 *) malloc (sizeof(test_structure_2));
690 args[0] = &ts2_type;
691 values[0] = &ts2_arg;
693 /* Initialize the cif */
694 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
696 ts2_arg.d1 = 5.55;
697 ts2_arg.d2 = 6.66;
699 printf ("%g\n", ts2_result->d1);
700 printf ("%g\n", ts2_result->d2);
702 ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
704 printf ("%g\n", ts2_result->d1);
705 printf ("%g\n", ts2_result->d2);
707 CHECK(ts2_result->d1 == 5.55 - 1);
708 CHECK(ts2_result->d2 == 6.66 - 1);
710 printf("structure test 2 ok!\n");
712 free (ts2_result);
715 /* struct tests */
717 int compare_value;
718 test_structure_3 ts3_arg;
719 test_structure_3 *ts3_result =
720 (test_structure_3 *) malloc (sizeof(test_structure_3));
722 args[0] = &ts3_type;
723 values[0] = &ts3_arg;
725 /* Initialize the cif */
726 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
727 &ts3_type, args) == FFI_OK);
729 ts3_arg.si = -123;
730 compare_value = ts3_arg.si;
732 ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
734 printf ("%d %d\n", ts3_result->si, -(compare_value*2));
736 if (ts3_result->si == -(ts3_arg.si*2))
737 puts ("structure test 3 ok!");
738 else
740 puts ("Structure test 3 found structure passing bug.");
741 puts (" Current versions of GCC are not 100% compliant with the");
742 puts (" n32 ABI. There is a known problem related to passing");
743 puts (" small structures. Send a bug report to the gcc maintainers.");
746 free (ts3_result);
749 /* struct tests */
751 test_structure_4 ts4_arg;
753 /* This is a hack to get a properly aligned result buffer */
754 test_structure_4 *ts4_result =
755 (test_structure_4 *) malloc (sizeof(test_structure_4));
757 args[0] = &ts4_type;
758 values[0] = &ts4_arg;
760 /* Initialize the cif */
761 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
763 ts4_arg.ui1 = 2;
764 ts4_arg.ui2 = 3;
765 ts4_arg.ui3 = 4;
767 ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
769 if (ts4_result->ui3 == 2U * 3U * 4U)
770 puts ("structure test 4 ok!");
771 else
772 puts ("Structure test 4 found GCC's structure passing bug.");
774 free (ts4_result);
777 /* struct tests */
779 test_structure_5 ts5_arg1, ts5_arg2;
781 /* This is a hack to get a properly aligned result buffer */
782 test_structure_5 *ts5_result =
783 (test_structure_5 *) malloc (sizeof(test_structure_5));
785 args[0] = &ts5_type;
786 args[1] = &ts5_type;
787 values[0] = &ts5_arg1;
788 values[1] = &ts5_arg2;
790 /* Initialize the cif */
791 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
793 ts5_arg1.c1 = 2;
794 ts5_arg1.c2 = 6;
795 ts5_arg2.c1 = 5;
796 ts5_arg2.c2 = 3;
798 ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
800 if (ts5_result->c1 == 7
801 && ts5_result->c2 == 3)
802 puts ("structure test 5 ok!");
803 else
804 puts ("Structure test 5 found GCC's structure passing bug.");
806 free (ts5_result);
809 /* struct tests */
811 test_structure_6 ts6_arg;
813 /* This is a hack to get a properly aligned result buffer */
814 test_structure_6 *ts6_result =
815 (test_structure_6 *) malloc (sizeof(test_structure_6));
817 args[0] = &ts6_type;
818 values[0] = &ts6_arg;
820 /* Initialize the cif */
821 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
823 ts6_arg.f = 5.55f;
824 ts6_arg.d = 6.66;
826 printf ("%g\n", ts6_arg.f);
827 printf ("%g\n", ts6_arg.d);
829 ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
831 printf ("%g\n", ts6_result->f);
832 printf ("%g\n", ts6_result->d);
834 CHECK(ts6_result->f == 5.55f + 1);
835 CHECK(ts6_result->d == 6.66 + 1);
837 printf("structure test 6 ok!\n");
839 free (ts6_result);
842 /* struct tests */
844 test_structure_7 ts7_arg;
846 /* This is a hack to get a properly aligned result buffer */
847 test_structure_7 *ts7_result =
848 (test_structure_7 *) malloc (sizeof(test_structure_7));
850 args[0] = &ts7_type;
851 values[0] = &ts7_arg;
853 /* Initialize the cif */
854 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
856 ts7_arg.f1 = 5.55f;
857 ts7_arg.f2 = 55.5f;
858 ts7_arg.d = 6.66;
860 printf ("%g\n", ts7_arg.f1);
861 printf ("%g\n", ts7_arg.f2);
862 printf ("%g\n", ts7_arg.d);
864 ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
866 printf ("%g\n", ts7_result->f1);
867 printf ("%g\n", ts7_result->f2);
868 printf ("%g\n", ts7_result->d);
870 CHECK(ts7_result->f1 == 5.55f + 1);
871 CHECK(ts7_result->f2 == 55.5f + 1);
872 CHECK(ts7_result->d == 6.66 + 1);
874 printf("structure test 7 ok!\n");
876 free (ts7_result);
879 /* struct tests */
881 test_structure_8 ts8_arg;
883 /* This is a hack to get a properly aligned result buffer */
884 test_structure_8 *ts8_result =
885 (test_structure_8 *) malloc (sizeof(test_structure_8));
887 args[0] = &ts8_type;
888 values[0] = &ts8_arg;
890 /* Initialize the cif */
891 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
893 ts8_arg.f1 = 5.55f;
894 ts8_arg.f2 = 55.5f;
895 ts8_arg.f3 = -5.55f;
896 ts8_arg.f4 = -55.5f;
898 printf ("%g\n", ts8_arg.f1);
899 printf ("%g\n", ts8_arg.f2);
900 printf ("%g\n", ts8_arg.f3);
901 printf ("%g\n", ts8_arg.f4);
903 ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
905 printf ("%g\n", ts8_result->f1);
906 printf ("%g\n", ts8_result->f2);
907 printf ("%g\n", ts8_result->f3);
908 printf ("%g\n", ts8_result->f4);
910 CHECK(ts8_result->f1 == 5.55f + 1);
911 CHECK(ts8_result->f2 == 55.5f + 1);
912 CHECK(ts8_result->f3 == -5.55f + 1);
913 CHECK(ts8_result->f4 == -55.5f + 1);
915 printf("structure test 8 ok!\n");
917 free (ts8_result);
920 /* struct tests */
922 test_structure_9 ts9_arg;
924 /* This is a hack to get a properly aligned result buffer */
925 test_structure_9 *ts9_result =
926 (test_structure_9 *) malloc (sizeof(test_structure_9));
928 args[0] = &ts9_type;
929 values[0] = &ts9_arg;
931 /* Initialize the cif */
932 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
934 ts9_arg.f = 5.55f;
935 ts9_arg.i = 5;
937 printf ("%g\n", ts9_arg.f);
938 printf ("%d\n", ts9_arg.i);
940 ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
942 printf ("%g\n", ts9_result->f);
943 printf ("%d\n", ts9_result->i);
945 CHECK(ts9_result->f == 5.55f + 1);
946 CHECK(ts9_result->i == 5 + 1);
948 printf("structure test 9 ok!\n");
950 free (ts9_result);
953 #else
954 printf("Structure passing doesn't work on Win32.\n");
955 #endif /* X86_WIN32 */
957 # if FFI_CLOSURES
958 /* A simple closure test */
960 ffi_closure cl;
961 ffi_type * cl_arg_types[3];
963 cl_arg_types[0] = &ffi_type_sint;
964 cl_arg_types[1] = &ffi_type_float;
965 cl_arg_types[2] = NULL;
967 /* Initialize the cif */
968 CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
969 &ffi_type_sint, cl_arg_types) == FFI_OK);
971 CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
972 (void *) 3 /* userdata */)
973 == FFI_OK);
974 CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6);
976 # endif
978 /* If we arrived here, all is good */
979 (void) puts("\nLooks good. No surprises.\n");
981 /*@-compdestroy@*/
983 return 0;