OSDN Git Service

* configure.in (powerpc64*-*-linux*): Remove.
[pf3gnuchains/gcc-fork.git] / libffi / include / ffi.h.in
1 /* -----------------------------------------------------------------*-C-*-
2    libffi @VERSION@ - Copyright (c) 1996-2003  Cygnus Solutions
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
25 /* -------------------------------------------------------------------
26    The basic API is described in the README file.
27
28    The raw API is designed to bypass some of the argument packing
29    and unpacking on architectures for which it can be avoided.
30
31    The closure API allows interpreted functions to be packaged up
32    inside a C function pointer, so that they can be called as C functions,
33    with no understanding on the client side that they are interpreted.
34    It can also be used in other cases in which it is necessary to package
35    up a user specified parameter and a function pointer as a single
36    function pointer.
37
38    The closure API must be implemented in order to get its functionality,
39    e.g. for use by gij.  Routines are provided to emulate the raw API
40    if the underlying platform doesn't allow faster implementation.
41
42    More details on the raw and cloure API can be found in:
43
44    http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
45
46    and
47
48    http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
49    -------------------------------------------------------------------- */
50
51 #ifndef LIBFFI_H
52 #define LIBFFI_H
53
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
57
58 /* Specify which architecture libffi is configured for. */
59 #define @TARGET@
60
61 /* ---- System configuration information --------------------------------- */
62
63 #include <fficonfig.h>
64
65 #if !defined(LIBFFI_ASM)
66 #include <stddef.h>
67 #if defined(FFI_DEBUG) 
68 #include <stdio.h>
69 #endif
70 #endif
71
72 /* ---- Generic type definitions ----------------------------------------- */
73
74 #define FLOAT32 float
75 #define FLOAT64 double
76 #define FLOAT80 long double
77
78 #define UINT8   unsigned char
79 #define SINT8   signed char
80
81 #if SIZEOF_INT == 2
82
83 #define UINT16  unsigned int
84 #define SINT16  int
85 #define ffi_type_uint ffi_type_uint16
86 #define ffi_type_sint ffi_type_sint16
87
88 #else 
89 #if SIZEOF_SHORT == 2
90
91 #define UINT16  unsigned short
92 #define SINT16  short
93 #define ffi_type_ushort ffi_type_uint16
94 #define ffi_type_sshort ffi_type_sint16
95
96 #endif
97 #endif
98
99 #if SIZEOF_INT == 4
100
101 #define UINT32  unsigned int
102 #define SINT32  int
103 #define ffi_type_uint ffi_type_uint32
104 #define ffi_type_sint ffi_type_sint32
105
106 #else 
107 #if SIZEOF_SHORT == 4
108
109 #define UINT32  unsigned short
110 #define SINT32  short
111 #define ffi_type_ushort ffi_type_uint32
112 #define ffi_type_sshort ffi_type_sint32
113
114 #else
115 #if SIZEOF_LONG == 4
116
117 #define UINT32  unsigned long
118 #define SINT32  long
119 #define ffi_type_ulong ffi_type_uint32
120 #define ffi_type_slong ffi_type_sint32
121
122 #endif
123 #endif
124 #endif
125
126 #if SIZEOF_INT == 8
127
128 #define UINT64  unsigned int
129 #define SINT64  int
130 #define ffi_type_uint ffi_type_uint64
131 #define ffi_type_sint ffi_type_sint64
132
133 #else
134 #if SIZEOF_LONG == 8
135
136 #define UINT64  unsigned long
137 #define SINT64  long
138 #define ffi_type_ulong ffi_type_uint64
139 #define ffi_type_slong ffi_type_sint64
140
141 #else
142 #if SIZEOF_LONG_LONG == 8
143
144 #define UINT64  unsigned long long
145 #define SINT64  long long
146 #define ffi_type_ulong ffi_type_uint64
147 #define ffi_type_slong ffi_type_sint64
148
149 #endif
150 #endif
151 #endif
152
153 /* ---- System specific configurations ----------------------------------- */
154
155 #ifdef MIPS
156 #include <ffi_mips.h>
157 #else
158 #define SIZEOF_ARG SIZEOF_VOID_P
159 #endif
160
161 #ifdef POWERPC
162 #if defined (__powerpc64__)
163 #define POWERPC64
164 #endif
165 #endif
166
167 #ifdef SPARC
168 #if defined(__arch64__) || defined(__sparcv9)
169 #define SPARC64
170 #endif
171 #endif
172
173 #ifdef S390
174 #if defined (__s390x__)
175 #define S390X
176 #endif
177 #endif
178
179 #ifdef X86_64
180 #if defined (__i386__)
181 #undef X86_64
182 #define X86
183 #endif
184 #endif
185
186 #ifndef LIBFFI_ASM
187
188 /* ---- Generic type definitions ----------------------------------------- */
189
190 #define ALIGN(v, a)  (((((size_t) (v))-1) | ((a)-1))+1)
191 /* The closure code assumes that this works on pointers, i.e. a size_t  */
192 /* can hold a pointer.                                                  */
193
194 typedef enum ffi_abi {
195
196   /* Leave this for debugging purposes */
197   FFI_FIRST_ABI = 0,
198
199   /* ---- Sparc -------------------- */
200 #ifdef SPARC
201   FFI_V8,
202   FFI_V8PLUS,
203   FFI_V9,
204 #ifdef SPARC64
205   FFI_DEFAULT_ABI = FFI_V9,
206 #else
207   FFI_DEFAULT_ABI = FFI_V8,
208 #endif
209 #endif
210
211   /* ---- Intel x86 Win32 ---------- */
212 #ifdef X86_WIN32
213   FFI_SYSV,
214   FFI_STDCALL,
215   /* TODO: Add fastcall support for the sake of completeness */
216   FFI_DEFAULT_ABI = FFI_SYSV,
217 #endif
218
219   /* ---- Intel x86 and AMD x86-64 - */
220 #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
221   FFI_SYSV,
222   FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
223 #ifdef __i386__
224   FFI_DEFAULT_ABI = FFI_SYSV,
225 #else
226   FFI_DEFAULT_ABI = FFI_UNIX64,
227 #endif
228 #endif
229
230   /* ---- Intel ia64 ---------------- */
231 #ifdef IA64
232   FFI_UNIX,     /* Linux and all Unix variants use the same conventions */
233   FFI_DEFAULT_ABI = FFI_UNIX,
234 #endif
235
236   /* ---- Mips --------------------- */
237 #ifdef MIPS
238   FFI_O32,
239   FFI_N32,
240   FFI_N64,
241 #endif
242
243   /* ---- Alpha -------------------- */
244 #ifdef ALPHA
245   FFI_OSF,
246   FFI_DEFAULT_ABI = FFI_OSF,
247 #endif
248
249   /* ---- Motorola m68k ------------ */
250 #ifdef M68K
251   FFI_SYSV,
252   FFI_DEFAULT_ABI = FFI_SYSV,
253 #endif
254
255   /* ---- PowerPC ------------------ */
256 #ifdef POWERPC
257   FFI_SYSV,
258   FFI_GCC_SYSV,
259   FFI_LINUX64,
260 # ifdef POWERPC64
261   FFI_DEFAULT_ABI = FFI_LINUX64,
262 # else
263   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
264 # endif
265 #endif
266
267 #ifdef POWERPC_AIX
268   FFI_AIX,
269   FFI_DARWIN,
270   FFI_DEFAULT_ABI = FFI_AIX,
271 #endif
272
273 #ifdef POWERPC_DARWIN
274   FFI_AIX,
275   FFI_DARWIN,
276   FFI_DEFAULT_ABI = FFI_DARWIN,
277 #endif
278
279   /* ---- ARM  --------------------- */
280 #ifdef ARM
281   FFI_SYSV,
282   FFI_DEFAULT_ABI = FFI_SYSV,
283 #endif
284
285   /* ---- S390 --------------------- */
286 #ifdef S390
287   FFI_SYSV,
288   FFI_DEFAULT_ABI = FFI_SYSV,
289 #endif
290
291   /* ---- SuperH ------------------- */
292 #ifdef SH
293   FFI_SYSV,
294   FFI_DEFAULT_ABI = FFI_SYSV,
295 #endif
296
297   /* Leave this for debugging purposes */
298   FFI_LAST_ABI
299
300 } ffi_abi;
301
302 typedef struct _ffi_type
303 {
304   size_t size;
305   unsigned short alignment;
306   unsigned short type;
307   /*@null@*/ struct _ffi_type **elements;
308 } ffi_type;
309
310 /* These are defined in types.c */
311 extern ffi_type ffi_type_void;
312 extern ffi_type ffi_type_uint8;
313 extern ffi_type ffi_type_sint8;
314 extern ffi_type ffi_type_uint16;
315 extern ffi_type ffi_type_sint16;
316 extern ffi_type ffi_type_uint32;
317 extern ffi_type ffi_type_sint32;
318 extern ffi_type ffi_type_uint64;
319 extern ffi_type ffi_type_sint64;
320 extern ffi_type ffi_type_float;
321 extern ffi_type ffi_type_double;
322 extern ffi_type ffi_type_longdouble;
323 extern ffi_type ffi_type_pointer;
324
325 /* Characters are 8 bit integral types */
326 #define ffi_type_schar ffi_type_sint8
327 #define ffi_type_uchar ffi_type_uint8
328
329 typedef enum {
330   FFI_OK = 0,
331   FFI_BAD_TYPEDEF,
332   FFI_BAD_ABI 
333 } ffi_status;
334
335 typedef unsigned FFI_TYPE;
336
337 typedef struct {
338   ffi_abi abi;
339   unsigned nargs;
340   /*@dependent@*/ ffi_type **arg_types;
341   /*@dependent@*/ ffi_type *rtype;
342   unsigned bytes;
343   unsigned flags;
344
345 #ifdef MIPS
346 #if _MIPS_SIM == _ABIN32
347   unsigned rstruct_flag;
348 #endif
349 #endif
350
351 } ffi_cif;
352
353 #if SIZEOF_ARG == 4
354 typedef UINT32 ffi_arg;
355 #else
356 #if SIZEOF_ARG == 8
357 typedef UINT64 ffi_arg;
358 #else
359 -- unsupported configuration
360 #endif
361 #endif
362
363 /* ---- Definitions for the raw API -------------------------------------- */
364
365 #if !FFI_NO_RAW_API
366
367 #if SIZEOF_ARG == 4
368
369 #define UINT_ARG UINT32
370 #define SINT_ARG SINT32
371
372 #endif
373
374 #if SIZEOF_ARG == 8
375
376 #define UINT_ARG UINT64
377 #define SINT_ARG SINT64
378
379 #endif
380
381 typedef union {
382   SINT_ARG sint;
383   UINT_ARG uint;
384   float    flt;
385   char     data[SIZEOF_ARG];
386   void*    ptr;
387 } ffi_raw;
388
389 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
390                    void (*fn)(), 
391                    /*@out@*/ void *rvalue, 
392                    /*@dependent@*/ ffi_raw *avalue);
393
394 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
395 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
396 size_t ffi_raw_size (ffi_cif *cif);
397
398 #if !NO_JAVA_RAW_API
399
400 /* This is analogous to the raw API, except it uses Java parameter      */
401 /* packing, even on 64-bit machines.  I.e. on 64-bit machines           */
402 /* longs and doubles are followed by an empty 64-bit word.              */
403
404 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
405                         void (*fn)(), 
406                         /*@out@*/ void *rvalue, 
407                         /*@dependent@*/ ffi_raw *avalue);
408
409 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
410 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
411 size_t ffi_java_raw_size (ffi_cif *cif);
412
413 #endif /* !NO_JAVA_RAW_API */
414
415 #endif /* !FFI_NO_RAW_API */
416
417 /* ---- Definitions for closures ----------------------------------------- */
418
419 #ifdef __i386__
420
421 #define FFI_CLOSURES 1          /* x86 supports closures */
422 #define FFI_TRAMPOLINE_SIZE 10
423 #define FFI_NATIVE_RAW_API 1    /* and has native raw api support */
424
425 #elif defined(IA64)
426
427 #define FFI_CLOSURES 1
428 #define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which   */
429                                 /* can be interpreted as a C function   */
430                                 /* decriptor:                           */
431
432 struct ffi_ia64_trampoline_struct {
433     void * code_pointer;        /* Pointer to ffi_closure_UNIX  */
434     void * fake_gp;             /* Pointer to closure, installed as gp  */
435     void * real_gp;             /* Real gp value, reinstalled by        */
436                                 /* ffi_closure_UNIX.                    */
437 };
438 #define FFI_NATIVE_RAW_API 0
439
440 #elif defined(ALPHA)
441
442 #define FFI_CLOSURES 1
443 #define FFI_TRAMPOLINE_SIZE 24
444 #define FFI_NATIVE_RAW_API 0
445
446 #elif defined(POWERPC)
447
448 #define FFI_CLOSURES 1
449 #ifdef POWERPC64
450 #define FFI_TRAMPOLINE_SIZE 24
451 #else
452 #define FFI_TRAMPOLINE_SIZE 40
453 #endif
454 #define FFI_NATIVE_RAW_API 0
455
456 #elif defined(POWERPC_DARWIN)
457
458 #define FFI_CLOSURES 1
459 #define FFI_TRAMPOLINE_SIZE 40
460 #define FFI_NATIVE_RAW_API 0
461
462 #elif defined(POWERPC_AIX)
463
464 #define FFI_CLOSURES 1
465 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */ 
466 #define FFI_NATIVE_RAW_API 0
467
468 #elif defined(SPARC64)
469
470 #define FFI_CLOSURES 1
471 #define FFI_TRAMPOLINE_SIZE 24
472 #define FFI_NATIVE_RAW_API 0
473
474 #elif defined(SPARC)
475
476 #define FFI_CLOSURES 1
477 #define FFI_TRAMPOLINE_SIZE 16
478 #define FFI_NATIVE_RAW_API 0
479
480 #elif defined(S390)
481
482 #define FFI_CLOSURES 1
483 #ifdef S390X
484 #define FFI_TRAMPOLINE_SIZE 32
485 #else
486 #define FFI_TRAMPOLINE_SIZE 16
487 #endif
488 #define FFI_NATIVE_RAW_API 0
489
490 #elif defined(SH)
491
492 #define FFI_CLOSURES 1
493 #define FFI_TRAMPOLINE_SIZE 16
494 #define FFI_NATIVE_RAW_API 0
495
496 #elif defined(__x86_64__)
497
498 #define FFI_CLOSURES 1
499 #define FFI_TRAMPOLINE_SIZE 24
500 #define FFI_NATIVE_RAW_API 0
501
502 #else 
503
504 #define FFI_CLOSURES 0
505 #define FFI_NATIVE_RAW_API 0
506
507 #endif
508
509 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
510
511 struct ffi_aix_trampoline_struct {
512     void * code_pointer;        /* Pointer to ffi_closure_ASM */
513     void * toc;                 /* TOC */
514     void * static_chain;        /* Pointer to closure */
515 };
516
517 #endif
518
519
520
521 #if FFI_CLOSURES
522
523 typedef struct {
524   char tramp[FFI_TRAMPOLINE_SIZE];
525   ffi_cif   *cif;
526   void     (*fun)(ffi_cif*,void*,void**,void*);
527   void      *user_data;
528 } ffi_closure;
529
530 ffi_status
531 ffi_prep_closure (ffi_closure*,
532                   ffi_cif *,
533                   void (*fun)(ffi_cif*,void*,void**,void*),
534                   void *user_data);
535
536 #if !FFI_NO_RAW_API
537
538 typedef struct {
539   char tramp[FFI_TRAMPOLINE_SIZE];
540
541   ffi_cif   *cif;
542
543 #if !FFI_NATIVE_RAW_API
544
545   /* if this is enabled, then a raw closure has the same layout 
546      as a regular closure.  We use this to install an intermediate 
547      handler to do the transaltion, void** -> ffi_raw*. */
548
549   void     (*translate_args)(ffi_cif*,void*,void**,void*);
550   void      *this_closure;
551
552 #endif
553
554   void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
555   void      *user_data;
556
557 } ffi_raw_closure;
558
559 ffi_status
560 ffi_prep_raw_closure (ffi_raw_closure*,
561                       ffi_cif *cif,
562                       void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
563                       void *user_data);
564
565 #ifndef NO_JAVA_RAW_API
566 ffi_status
567 ffi_prep_java_raw_closure (ffi_raw_closure*,
568                            ffi_cif *cif,
569                            void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
570                            void *user_data);
571 #endif
572
573 #endif /* !FFI_NO_RAW_API */
574 #endif /* FFI_CLOSURES */
575
576 /* ---- Public interface definition -------------------------------------- */
577
578 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
579                         ffi_abi abi,
580                         unsigned int nargs, 
581                         /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
582                         /*@dependent@*/ ffi_type **atypes);
583
584 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
585               void (*fn)(), 
586               /*@out@*/ void *rvalue, 
587               /*@dependent@*/ void **avalue);
588
589 /* Useful for eliminating compiler warnings */
590 #define FFI_FN(f) ((void (*)())f)
591
592 /* ---- Definitions shared with assembly code ---------------------------- */
593
594 #endif
595
596 #define FFI_TYPE_VOID       0    
597 #define FFI_TYPE_INT        1
598 #define FFI_TYPE_FLOAT      2    
599 #define FFI_TYPE_DOUBLE     3
600 #if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
601 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
602 #else
603 #define FFI_TYPE_LONGDOUBLE 4
604 #endif
605
606 #define FFI_TYPE_UINT8      5   /* If this changes, update ffi_mips.h. */
607 #define FFI_TYPE_SINT8      6   /* If this changes, update ffi_mips.h. */
608 #define FFI_TYPE_UINT16     7 
609 #define FFI_TYPE_SINT16     8
610 #define FFI_TYPE_UINT32     9
611 #define FFI_TYPE_SINT32     10
612 #define FFI_TYPE_UINT64     11
613 #define FFI_TYPE_SINT64     12
614 #define FFI_TYPE_STRUCT     13  /* If this changes, update ffi_mips.h. */
615 #define FFI_TYPE_POINTER    14
616
617 /* This should always refer to the last type code (for sanity checks) */
618 #define FFI_TYPE_LAST       FFI_TYPE_POINTER
619
620 #ifdef __cplusplus
621 }
622 #endif
623
624 #endif
625