OSDN Git Service

a05b746865d1c7cbc5f0009081508ca448e51153
[pf3gnuchains/gcc-fork.git] / libffi / src / ffitest.c
1 /* -----------------------------------------------------------------------
2    ffitest.c - Copyright (c) 1996, 1997, 1998, 2002, 2003  Red Hat, Inc.
3
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:
11
12    The above copyright notice and this permission notice shall be included
13    in all copies or substantial portions of the Software.
14
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    ----------------------------------------------------------------------- */
23
24 #include <ffi.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <float.h>
29
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
34
35 #define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0 
36
37 static int fail(char *file, int line)
38 {
39   fprintf(stderr, "Test failure: %s line %d\n", file, line);
40   exit(EXIT_FAILURE);
41   /*@notreached@*/
42   return 0;
43 }
44
45 #define MAX_ARGS 256
46
47 static size_t my_strlen(char *s)
48 {
49   return (strlen(s));
50 }
51
52 #ifdef X86_WIN32
53 static size_t __attribute__((stdcall)) my_stdcall_strlen(char *s)
54 {
55   return (strlen(s));
56 }
57 #endif /* X86_WIN32 */
58
59 static int promotion(signed char sc, signed short ss, 
60                      unsigned char uc, unsigned short us)
61 {
62   int r = (int) sc + (int) ss + (int) uc + (int) us;
63
64   return r;
65 }
66
67 static signed char return_sc(signed char sc)
68 {
69   return sc;
70 }
71
72 static unsigned char return_uc(unsigned char uc)
73 {
74   return uc;
75 }
76
77 static long long return_ll(long long ll)
78 {
79   return ll;
80 }
81
82 static int floating(int a, float b, double c, long double d, int e)
83 {
84   int i;
85
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
92
93   i = (int) ((float)a/b + ((float)c/(float)d));
94
95   return i;
96 }
97
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)
111 {
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
118
119   return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
120 }
121
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)
136 {
137   return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13);
138 }
139 #endif /* X86_WIN32 */
140
141 static double dblit(float f)
142 {
143   return f/3.0;
144 }
145
146 static long double ldblit(float f)
147 {
148   return (long double) (((long double) f)/ (long double) 3.0);
149 }
150
151 typedef struct
152 {
153   unsigned char uc;
154   double d;
155   unsigned int ui;
156 } test_structure_1;
157
158 typedef struct
159 {
160   double d1;
161   double d2;
162 } test_structure_2;
163
164 typedef struct
165 {
166   int si;
167 } test_structure_3;
168
169 typedef struct
170 {
171   unsigned ui1;
172   unsigned ui2;
173   unsigned ui3;
174 } test_structure_4;
175
176 typedef struct
177 {
178   char c1;
179   char c2;
180 } test_structure_5;
181
182 typedef struct
183 {
184   float f;
185   double d;
186 } test_structure_6;
187
188 typedef struct
189 {
190   float f1;
191   float f2;
192   double d;
193 } test_structure_7;
194
195 typedef struct
196 {
197   float f1;
198   float f2;
199   float f3;
200   float f4;
201 } test_structure_8;
202
203 typedef struct
204 {
205   float f;
206   int i;
207 } test_structure_9;
208
209 static test_structure_1 struct1(test_structure_1 ts)
210 {
211   /*@-type@*/
212   ts.uc++;
213   /*@=type@*/
214   ts.d--;
215   ts.ui++;
216
217   return ts;
218 }
219
220 static test_structure_2 struct2(test_structure_2 ts)
221 {
222   ts.d1--;
223   ts.d2--;
224
225   return ts;
226 }
227
228 static test_structure_3 struct3(test_structure_3 ts)
229 {
230   ts.si = -(ts.si*2);
231
232   return ts;
233 }
234
235 static test_structure_4 struct4(test_structure_4 ts)
236 {
237   ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3;
238
239   return ts;
240 }
241
242 static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
243 {
244   ts1.c1 += ts2.c1;
245   ts1.c2 -= ts2.c2;
246
247   return ts1;
248 }
249
250 static test_structure_6 struct6 (test_structure_6 ts)
251 {
252   ts.f += 1;
253   ts.d += 1;
254
255   return ts;
256 }
257
258 static test_structure_7 struct7 (test_structure_7 ts)
259 {
260   ts.f1 += 1;
261   ts.f2 += 1;
262   ts.d += 1;
263
264   return ts;
265 }
266
267 static test_structure_8 struct8 (test_structure_8 ts)
268 {
269   ts.f1 += 1;
270   ts.f2 += 1;
271   ts.f3 += 1;
272   ts.f4 += 1;
273
274   return ts;
275 }
276
277 static test_structure_9 struct9 (test_structure_9 ts)
278 {
279   ts.f += 1;
280   ts.i += 1;
281
282   return ts;
283 }
284
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)
290 {
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;
301
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);
313 }
314
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);
319
320 static void closure_test_fn1(ffi_cif* cif,void* resp,void** args, 
321                              void* userdata)
322  {
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;
332
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);
343 }
344
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);
348
349 static void closure_test_fn2(ffi_cif* cif,void* resp,void** args, 
350                              void* userdata)
351  {
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;
361
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);
372  }
373
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);
377
378 static void closure_test_fn3(ffi_cif* cif,void* resp,void** args,
379                              void* userdata)
380  {
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;
390
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);
401  }
402
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
407
408 int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
409 {
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;
425
426   ffi_arg rint;
427   long long rlonglong;
428
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
434
435   ffi_type * cl_arg_types[17];
436
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];
455
456   ts1_type.size = 0;
457   ts1_type.alignment = 0;
458   ts1_type.type = FFI_TYPE_STRUCT;
459
460   ts2_type.size = 0;
461   ts2_type.alignment = 0;
462   ts2_type.type = FFI_TYPE_STRUCT;
463
464   ts3_type.size = 0;
465   ts3_type.alignment = 0;
466   ts3_type.type = FFI_TYPE_STRUCT;
467
468   ts4_type.size = 0;
469   ts4_type.alignment = 0;
470   ts4_type.type = FFI_TYPE_STRUCT;
471
472   ts5_type.size = 0;
473   ts5_type.alignment = 0;
474   ts5_type.type = FFI_TYPE_STRUCT;
475
476   ts6_type.size = 0;
477   ts6_type.alignment = 0;
478   ts6_type.type = FFI_TYPE_STRUCT;
479
480   ts7_type.size = 0;
481   ts7_type.alignment = 0;
482   ts7_type.type = FFI_TYPE_STRUCT;
483
484   ts8_type.size = 0;
485   ts8_type.alignment = 0;
486   ts8_type.type = FFI_TYPE_STRUCT;
487
488   ts9_type.size = 0;
489   ts9_type.alignment = 0;
490   ts9_type.type = FFI_TYPE_STRUCT;
491
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@*/
503   
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;
508   
509   ts2_type_elements[0] = &ffi_type_double;
510   ts2_type_elements[1] = &ffi_type_double;
511   ts2_type_elements[2] = NULL;
512
513   ts3_type_elements[0] = &ffi_type_sint;
514   ts3_type_elements[1] = NULL;
515
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;
520
521   ts5_type_elements[0] = &ffi_type_schar;
522   ts5_type_elements[1] = &ffi_type_schar;
523   ts5_type_elements[2] = NULL;
524
525   ts6_type_elements[0] = &ffi_type_float;
526   ts6_type_elements[1] = &ffi_type_double;
527   ts6_type_elements[2] = NULL;
528
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;
533
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;
539
540   ts9_type_elements[0] = &ffi_type_float;
541   ts9_type_elements[1] = &ffi_type_sint;
542   ts9_type_elements[2] = NULL;
543
544   ul = 0;
545
546   /* return value tests */
547   {
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;
553     
554     /* Initialize the cif */
555     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
556                        &ffi_type_sint64, args) == FFI_OK);
557
558     for (ll = 0LL; ll < 100LL; ll++)
559       {
560         ul++;
561         ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
562         CHECK(rlonglong == ll);
563       }
564
565     for (ll = 55555555555000LL; ll < 55555555555100LL; ll++)
566       {
567         ul++;
568         ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values);
569         CHECK(rlonglong == ll);
570       }
571 #endif
572
573     args[0] = &ffi_type_schar;
574     values[0] = &sc;
575     
576     /* Initialize the cif */
577     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
578                        &ffi_type_schar, args) == FFI_OK);
579
580     for (sc = (signed char) -127; 
581          sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/)
582       {
583         ul++;
584         ffi_call(&cif, FFI_FN(return_sc), &rint, values);
585         CHECK(rint == (ffi_arg) sc);
586       }
587
588     args[0] = &ffi_type_uchar;
589     values[0] = &uc;
590     
591     /* Initialize the cif */
592     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
593                        &ffi_type_uchar, args) == FFI_OK);
594
595     for (uc = (unsigned char) '\x00'; 
596          uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/)
597       {
598         ul++;
599         ffi_call(&cif, FFI_FN(return_uc), &rint, values);
600         CHECK(rint == (signed int) uc);
601       }
602
603     printf("%lu return value tests run\n", ul);
604   }
605
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 */
610   {
611     args[0] = &ffi_type_float;
612     values[0] = &f;
613
614     /* Initialize the cif */
615     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
616                        &ffi_type_longdouble, args) == FFI_OK);
617
618     f = 3.14159;
619
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);
628
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
635
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);
643   }
644
645   /* float arg tests */
646   {
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;
657     
658     /* Initialize the cif */
659     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5,
660                        &ffi_type_sint, args) == FFI_OK);
661
662     si1 = 6;
663     f = 3.14159;
664     d = (double)1.0/(double)3.0;
665     ld = 2.71828182846L;
666     si2 = 10;
667
668     floating (si1, f, d, ld, si2);
669
670     ffi_call(&cif, FFI_FN(floating), &rint, values);
671
672     printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
673
674     CHECK(rint == floating(si1, f, d, ld, si2));
675
676     printf("float arg tests ok!\n");
677   }
678 #endif
679
680   /* strlen tests */
681   {
682     args[0] = &ffi_type_pointer;
683     values[0] = (void*) &s;
684     
685     /* Initialize the cif */
686     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
687                        &ffi_type_sint, args) == FFI_OK);
688
689     s = "a";
690     ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
691     CHECK(rint == 1);
692
693     s = "1234567";
694     ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
695     CHECK(rint == 7);
696
697     s = "1234567890123456789012345";
698     ffi_call(&cif, FFI_FN(my_strlen), &rint, values);
699     CHECK(rint == 25);
700
701     printf("strlen tests passed\n");
702   }
703
704   /* float arg tests */
705   {
706     args[0] = &ffi_type_float;
707     values[0] = &f;
708     
709     /* Initialize the cif */
710     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
711                        &ffi_type_double, args) == FFI_OK);
712
713     f = 3.14159;
714
715     ffi_call(&cif, FFI_FN(dblit), &d, values);
716
717     /* These are not always the same!! Check for a reasonable delta */
718     /*@-realcompare@*/
719     CHECK(d - dblit(f) < DBL_EPSILON);
720     /*@=realcompare@*/
721
722     printf("double return value tests ok!\n");
723   }
724
725   /* many arg tests */
726   {
727     float ff;
728     float fa[13];
729     
730     for (ul = 0; ul < 13; ul++)
731       {
732         args[ul] = &ffi_type_float;
733         values[ul] = &fa[ul];
734         fa[ul] = (float) ul;
735       }
736
737     /* Initialize the cif */
738     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, 
739                        &ffi_type_float, args) == FFI_OK);
740
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@*/
749
750     ffi_call(&cif, FFI_FN(many), &f, values);
751
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
762   }
763
764   /* promotion tests */
765   {
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;
774     
775     /* Initialize the cif */
776     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, 
777                        &ffi_type_sint, args) == FFI_OK);
778
779     us = 0;
780     ul = 0;
781
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)
788             {
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);
793             }
794     printf("%lu promotion tests run\n", ul);
795   }
796
797 #ifndef X86_WIN32 /* Structures dont work on Win32 */
798
799   /* struct tests */
800   {
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));
805
806     args[0] = &ts1_type;
807     values[0] = &ts1_arg;
808     
809     /* Initialize the cif */
810     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
811                        &ts1_type, args) == FFI_OK);
812
813     ts1_arg.uc = '\x01';
814     ts1_arg.d = 3.14159;
815     ts1_arg.ui = 555;
816
817     ffi_call(&cif, FFI_FN(struct1), ts1_result, values);
818
819     CHECK(ts1_result->ui == 556);
820     CHECK(ts1_result->d == 3.14159 - 1);
821
822     puts ("structure test 1 ok!\n");
823
824     free (ts1_result);
825   }
826
827   /* struct tests */
828   {
829     test_structure_2 ts2_arg;
830
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));
834
835     args[0] = &ts2_type;
836     values[0] = &ts2_arg;
837     
838     /* Initialize the cif */
839     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
840
841     ts2_arg.d1 = 5.55;
842     ts2_arg.d2 = 6.66;
843
844     printf ("%g\n", ts2_result->d1);
845     printf ("%g\n", ts2_result->d2);
846
847     ffi_call(&cif, FFI_FN(struct2), ts2_result, values);
848
849     printf ("%g\n", ts2_result->d1);
850     printf ("%g\n", ts2_result->d2);
851     
852     CHECK(ts2_result->d1 == 5.55 - 1);
853     CHECK(ts2_result->d2 == 6.66 - 1);
854
855     printf("structure test 2 ok!\n");
856
857     free (ts2_result);
858   }
859
860   /* struct tests */
861   {
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));
866
867     args[0] = &ts3_type;
868     values[0] = &ts3_arg;
869     
870     /* Initialize the cif */
871     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
872                        &ts3_type, args) == FFI_OK);
873
874     ts3_arg.si = -123;
875     compare_value = ts3_arg.si;
876
877     ffi_call(&cif, FFI_FN(struct3), ts3_result, values);
878
879     printf ("%d %d\n", ts3_result->si, -(compare_value*2));
880
881     if (ts3_result->si == -(ts3_arg.si*2))
882         puts ("structure test 3 ok!");
883     else
884       {
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.");
889       }
890
891     free (ts3_result);
892   }
893
894   /* struct tests */
895   {
896     test_structure_4 ts4_arg;
897
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));
901
902     args[0] = &ts4_type;
903     values[0] = &ts4_arg;
904     
905     /* Initialize the cif */
906     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
907
908     ts4_arg.ui1 = 2;
909     ts4_arg.ui2 = 3;
910     ts4_arg.ui3 = 4;
911
912     ffi_call (&cif, FFI_FN(struct4), ts4_result, values);
913     
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.");
918
919     free (ts4_result);
920   }
921
922   /* struct tests */
923   {
924     test_structure_5 ts5_arg1, ts5_arg2;
925
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));
929
930     args[0] = &ts5_type;
931     args[1] = &ts5_type;
932     values[0] = &ts5_arg1;
933     values[1] = &ts5_arg2;
934     
935     /* Initialize the cif */
936     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
937
938     ts5_arg1.c1 = 2;
939     ts5_arg1.c2 = 6;
940     ts5_arg2.c1 = 5;
941     ts5_arg2.c2 = 3;
942
943     ffi_call (&cif, FFI_FN(struct5), ts5_result, values);
944     
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.");
950
951     free (ts5_result);
952   }
953
954   /* struct tests */
955   {
956     test_structure_6 ts6_arg;
957
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));
961
962     args[0] = &ts6_type;
963     values[0] = &ts6_arg;
964
965     /* Initialize the cif */
966     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
967
968     ts6_arg.f = 5.55f;
969     ts6_arg.d = 6.66;
970
971     printf ("%g\n", ts6_arg.f);
972     printf ("%g\n", ts6_arg.d);
973
974     ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
975
976     printf ("%g\n", ts6_result->f);
977     printf ("%g\n", ts6_result->d);
978
979     CHECK(ts6_result->f == 5.55f + 1);
980     CHECK(ts6_result->d == 6.66 + 1);
981
982     printf("structure test 6 ok!\n");
983
984     free (ts6_result);
985   }
986
987   /* struct tests */
988   {
989     test_structure_7 ts7_arg;
990
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));
994
995     args[0] = &ts7_type;
996     values[0] = &ts7_arg;
997
998     /* Initialize the cif */
999     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
1000
1001     ts7_arg.f1 = 5.55f;
1002     ts7_arg.f2 = 55.5f;
1003     ts7_arg.d = 6.66;
1004
1005     printf ("%g\n", ts7_arg.f1);
1006     printf ("%g\n", ts7_arg.f2);
1007     printf ("%g\n", ts7_arg.d);
1008
1009     ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
1010
1011     printf ("%g\n", ts7_result->f1);
1012     printf ("%g\n", ts7_result->f2);
1013     printf ("%g\n", ts7_result->d);
1014
1015     CHECK(ts7_result->f1 == 5.55f + 1);
1016     CHECK(ts7_result->f2 == 55.5f + 1);
1017     CHECK(ts7_result->d == 6.66 + 1);
1018
1019     printf("structure test 7 ok!\n");
1020
1021     free (ts7_result);
1022   }
1023
1024   /* struct tests */
1025   {
1026     test_structure_8 ts8_arg;
1027
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));
1031
1032     args[0] = &ts8_type;
1033     values[0] = &ts8_arg;
1034
1035     /* Initialize the cif */
1036     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
1037
1038     ts8_arg.f1 = 5.55f;
1039     ts8_arg.f2 = 55.5f;
1040     ts8_arg.f3 = -5.55f;
1041     ts8_arg.f4 = -55.5f;
1042
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);
1047
1048     ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
1049
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);
1054
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);
1059
1060     printf("structure test 8 ok!\n");
1061
1062     free (ts8_result);
1063   }
1064
1065   /* struct tests */
1066   {
1067     test_structure_9 ts9_arg;
1068
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));
1072
1073     args[0] = &ts9_type;
1074     values[0] = &ts9_arg;
1075
1076     /* Initialize the cif */
1077     CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
1078
1079     ts9_arg.f = 5.55f;
1080     ts9_arg.i = 5;
1081
1082     printf ("%g\n", ts9_arg.f);
1083     printf ("%d\n", ts9_arg.i);
1084
1085     ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
1086
1087     printf ("%g\n", ts9_result->f);
1088     printf ("%d\n", ts9_result->i);
1089
1090     CHECK(ts9_result->f == 5.55f + 1);
1091     CHECK(ts9_result->i == 5 + 1);
1092
1093     printf("structure test 9 ok!\n");
1094
1095     free (ts9_result);
1096   }
1097
1098 #else
1099   printf("Structure passing doesn't work on Win32.\n");
1100 #endif /* X86_WIN32 */
1101
1102 #ifdef X86_WIN32
1103   /* stdcall strlen tests */
1104   {
1105     args[0] = &ffi_type_pointer;
1106     values[0] = (void*) &s;
1107
1108     /* Initialize the cif */
1109     CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 1,
1110                        &ffi_type_sint, args) == FFI_OK);
1111
1112     s = "a";
1113     ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1114     CHECK(rint == 1);
1115
1116     s = "1234567";
1117     ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1118     CHECK(rint == 7);
1119
1120     s = "1234567890123456789012345";
1121     ffi_call(&cif, FFI_FN(my_stdcall_strlen), &rint, values);
1122     CHECK(rint == 25);
1123
1124     printf("stdcall strlen tests passed\n");
1125   }
1126
1127   /* stdcall many arg tests */
1128   {
1129     float ff;
1130     float fa[13];
1131
1132     for (ul = 0; ul < 13; ul++)
1133       {
1134         args[ul] = &ffi_type_float;
1135         values[ul] = &fa[ul];
1136         fa[ul] = (float) ul;
1137       }
1138
1139     /* Initialize the cif */
1140     CHECK(ffi_prep_cif(&cif, FFI_STDCALL, 13,
1141                        &ffi_type_float, args) == FFI_OK);
1142
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@*/
1151
1152     ffi_call(&cif, FFI_FN(stdcall_many), &f, values);
1153
1154     /*@-realcompare@*/
1155     if (f - ff < FLT_EPSILON)
1156     /*@=realcompare@*/
1157         printf("stdcall many arg tests ok!\n");
1158     else
1159         CHECK(0);
1160   }
1161 #endif /* X86_WIN32 */
1162
1163 # if FFI_CLOSURES
1164   /* A simple closure test */
1165     {
1166       (void) puts("\nEnter FFI_CLOSURES\n");
1167
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;   
1185
1186       /* Initialize the cif */
1187       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1188                          &ffi_type_sint, cl_arg_types) == FFI_OK);
1189
1190       CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn,
1191                              (void *) 3 /* userdata */) == FFI_OK);
1192       
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);
1196     }
1197
1198     {
1199
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;
1217       
1218       /* Initialize the cif */
1219       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1220                          &ffi_type_sint, cl_arg_types) == FFI_OK);
1221
1222       CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn1,
1223                              (void *) 3 /* userdata */)  == FFI_OK);
1224       
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);
1228     }
1229
1230     {
1231
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;
1249       
1250       /* Initialize the cif */
1251       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1252                          &ffi_type_sint, cl_arg_types) == FFI_OK);
1253
1254       CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn2,
1255                              (void *) 3 /* userdata */) == FFI_OK);
1256
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);
1260
1261     }
1262
1263     {
1264
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;
1282       
1283       /* Initialize the cif */
1284       CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 16,
1285                          &ffi_type_sint, cl_arg_types) == FFI_OK);
1286
1287       CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn3,
1288                              (void *) 3 /* userdata */)  == FFI_OK);
1289       
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);
1293     }
1294
1295     (void) puts("\nFinished FFI_CLOSURES\n");
1296
1297 # endif
1298
1299   /* If we arrived here, all is good */
1300   (void) puts("\nLooks good. No surprises.\n");
1301
1302   /*@-compdestroy@*/
1303
1304   return 0;
1305 }
1306