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 ----------------------------------------------------------------------- */
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
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
);
47 static size_t my_strlen(char *s
)
53 static size_t __attribute__((stdcall)) my_stdcall_strlen(char *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
;
67 static signed char return_sc(signed char sc
)
72 static unsigned char return_uc(unsigned char uc
)
77 static long long return_ll(long long ll
)
82 static int floating(int a
, float b
, double c
, long double d
, int e
)
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
);
93 i
= (int) ((float)a
/b
+ ((float)c
/(float)d
));
98 static float many(float f1
,
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
);
119 return ((f1
/f2
+f3
/f4
+f5
/f6
+f7
/f8
+f9
/f10
+f11
/f12
) * f13
);
123 static float __attribute__((stdcall)) stdcall_many(float f1
,
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
)
146 static long double ldblit(float f
)
148 return (long double) (((long double) f
)/ (long double) 3.0);
209 static test_structure_1
struct1(test_structure_1 ts
)
220 static test_structure_2
struct2(test_structure_2 ts
)
228 static test_structure_3
struct3(test_structure_3 ts
)
235 static test_structure_4
struct4(test_structure_4 ts
)
237 ts
.ui3
= ts
.ui1
* ts
.ui2
* ts
.ui3
;
242 static test_structure_5
struct5(test_structure_5 ts1
, test_structure_5 ts2
)
250 static test_structure_6
struct6 (test_structure_6 ts
)
258 static test_structure_7
struct7 (test_structure_7 ts
)
267 static test_structure_8
struct8 (test_structure_8 ts
)
277 static test_structure_9
struct9 (test_structure_9 ts
)
285 /* Take an int and a float argument, together with int userdata, and */
286 /* return the sum. */
289 closure_test_fn(ffi_cif
* cif
,void* resp
,void** args
, void* userdata
)
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,
320 static void closure_test_fn1(ffi_cif
* cif
,void* resp
,void** args
,
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,
349 static void closure_test_fn2(ffi_cif
* cif
,void* resp
,void** args
,
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
,
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,
408 int main(/*@unused@*/ int argc
, /*@unused@*/ char *argv
[])
411 ffi_type
*args
[MAX_ARGS
];
412 void *values
[MAX_ARGS
];
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
;
436 ffi_type
* cl_arg_types
[17];
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];
458 ts1_type
.alignment
= 0;
459 ts1_type
.type
= FFI_TYPE_STRUCT
;
462 ts2_type
.alignment
= 0;
463 ts2_type
.type
= FFI_TYPE_STRUCT
;
466 ts3_type
.alignment
= 0;
467 ts3_type
.type
= FFI_TYPE_STRUCT
;
470 ts4_type
.alignment
= 0;
471 ts4_type
.type
= FFI_TYPE_STRUCT
;
474 ts5_type
.alignment
= 0;
475 ts5_type
.type
= FFI_TYPE_STRUCT
;
478 ts6_type
.alignment
= 0;
479 ts6_type
.type
= FFI_TYPE_STRUCT
;
482 ts7_type
.alignment
= 0;
483 ts7_type
.type
= FFI_TYPE_STRUCT
;
486 ts8_type
.alignment
= 0;
487 ts8_type
.type
= FFI_TYPE_STRUCT
;
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
;
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.");
552 args
[0] = &ffi_type_sint64
;
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
++)
562 ffi_call(&cif
, FFI_FN(return_ll
), &rlonglong
, values
);
563 CHECK(rlonglong
== ll
);
566 for (ll
= 55555555555000LL; ll
< 55555555555100LL; ll
++)
569 ffi_call(&cif
, FFI_FN(return_ll
), &rlonglong
, values
);
570 CHECK(rlonglong
== ll
);
574 args
[0] = &ffi_type_schar
;
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@*/)
585 ffi_call(&cif
, FFI_FN(return_sc
), &rint
, values
);
586 CHECK(rint
== (ffi_arg
) sc
);
589 args
[0] = &ffi_type_uchar
;
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@*/)
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");
610 /* float arg tests */
612 args
[0] = &ffi_type_float
;
615 /* Initialize the cif */
616 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
617 &ffi_type_longdouble
, args
) == FFI_OK
);
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
));
628 ffi_call(&cif
, FFI_FN(ldblit
), &ld
, values
);
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
);
637 /* These are not always the same!! Check for a reasonable delta */
639 if (ld
- ldblit(f
) < LDBL_EPSILON
)
641 puts("long double return value tests ok!");
646 /* float arg tests */
648 args
[0] = &ffi_type_sint
;
650 args
[1] = &ffi_type_float
;
652 args
[2] = &ffi_type_double
;
654 args
[3] = &ffi_type_longdouble
;
656 args
[4] = &ffi_type_sint
;
659 /* Initialize the cif */
660 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 5,
661 &ffi_type_sint
, args
) == FFI_OK
);
665 d
= (double)1.0/(double)3.0;
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");
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
);
691 ffi_call(&cif
, FFI_FN(my_strlen
), &rint
, values
);
695 ffi_call(&cif
, FFI_FN(my_strlen
), &rint
, values
);
698 s
= "1234567890123456789012345";
699 ffi_call(&cif
, FFI_FN(my_strlen
), &rint
, values
);
702 printf("strlen tests passed\n");
705 /* float arg tests */
707 args
[0] = &ffi_type_float
;
710 /* Initialize the cif */
711 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1,
712 &ffi_type_double
, args
) == FFI_OK
);
716 ffi_call(&cif
, FFI_FN(dblit
), &d
, values
);
718 /* These are not always the same!! Check for a reasonable delta */
720 CHECK(d
- dblit(f
) < DBL_EPSILON
);
723 printf("double return value tests ok!\n");
731 for (ul
= 0; ul
< 13; ul
++)
733 args
[ul
] = &ffi_type_float
;
734 values
[ul
] = &fa
[ul
];
738 /* Initialize the cif */
739 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 13,
740 &ffi_type_float
, args
) == FFI_OK
);
743 ff
= many (fa
[0], fa
[1],
748 fa
[10],fa
[11],fa
[12]);
751 ffi_call(&cif
, FFI_FN(many
), &f
, values
);
754 if (f
- ff
< FLT_EPSILON
)
756 printf("many arg tests ok!\n");
759 printf("many arg tests failed! This is a gcc bug.\n");
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
;
776 /* Initialize the cif */
777 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 4,
778 &ffi_type_sint
, args
) == FFI_OK
);
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)
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 */
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
));
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
);
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");
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
));
837 values
[0] = &ts2_arg
;
839 /* Initialize the cif */
840 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts2_type
, args
) == FFI_OK
);
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");
864 test_structure_3 ts3_arg
;
865 test_structure_3
*ts3_result
=
866 (test_structure_3
*) malloc (sizeof(test_structure_3
));
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
);
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!");
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.");
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
));
904 values
[0] = &ts4_arg
;
906 /* Initialize the cif */
907 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts4_type
, args
) == FFI_OK
);
913 ffi_call (&cif
, FFI_FN(struct4
), ts4_result
, values
);
915 if (ts4_result
->ui3
== 2U * 3U * 4U)
916 puts ("structure test 4 ok!");
918 puts ("Structure test 4 found GCC's structure passing bug.");
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
));
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
);
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!");
950 puts ("Structure test 5 found GCC's structure passing bug.");
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
));
964 values
[0] = &ts6_arg
;
966 /* Initialize the cif */
967 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts6_type
, args
) == FFI_OK
);
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");
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
));
997 values
[0] = &ts7_arg
;
999 /* Initialize the cif */
1000 CHECK(ffi_prep_cif(&cif
, FFI_DEFAULT_ABI
, 1, &ts7_type
, args
) == FFI_OK
);
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");
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
);
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");
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
);
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");
1100 printf("Structure passing doesn't work on Win32.\n");
1101 #endif /* 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
);
1114 ffi_call(&cif
, FFI_FN(my_stdcall_strlen
), &rint
, values
);
1118 ffi_call(&cif
, FFI_FN(my_stdcall_strlen
), &rint
, values
);
1121 s
= "1234567890123456789012345";
1122 ffi_call(&cif
, FFI_FN(my_stdcall_strlen
), &rint
, values
);
1125 printf("stdcall strlen tests passed\n");
1128 /* stdcall many arg tests */
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
);
1145 ff
= stdcall_many(fa
[0], fa
[1],
1150 fa
[10],fa
[11],fa
[12]);
1153 ffi_call(&cif
, FFI_FN(stdcall_many
), &f
, values
);
1156 if (f
- ff
< FLT_EPSILON
)
1158 printf("stdcall many arg tests ok!\n");
1162 #endif /* X86_WIN32 */
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
));
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,
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,
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");
1307 /* If we arrived here, all is good */
1308 (void) puts("\nLooks good. No surprises.\n");