* config/xtensa/lib2funcs.S (TRAMPOLINE_SIZE): Change from 49 to 59.
[official-gcc.git] / libffi / include / ffi.h.in
blobc51a809ea3f75c62450fae053f32087ad1394bdd
1 /* -----------------------------------------------------------------*-C-*-
2 libffi @VERSION@ - Copyright (c) 1996-2003 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.
23 ----------------------------------------------------------------------- */
25 /* -------------------------------------------------------------------
26 The basic API is described in the README file.
28 The raw API is designed to bypass some of the argument packing
29 and unpacking on architectures for which it can be avoided.
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.
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.
42 More details on the raw and cloure API can be found in:
44 http://gcc.gnu.org/ml/java/1999-q3/msg00138.html
46 and
48 http://gcc.gnu.org/ml/java/1999-q3/msg00174.html
49 -------------------------------------------------------------------- */
51 #ifndef LIBFFI_H
52 #define LIBFFI_H
54 #ifdef __cplusplus
55 extern "C" {
56 #endif
58 /* Specify which architecture libffi is configured for. */
59 #define @TARGET@
61 /* ---- System configuration information --------------------------------- */
63 #include <fficonfig.h>
65 #if !defined(LIBFFI_ASM)
66 #include <stddef.h>
67 #if defined(FFI_DEBUG)
68 #include <stdio.h>
69 #endif
70 #endif
72 /* ---- Generic type definitions ----------------------------------------- */
74 #define FLOAT32 float
75 #define FLOAT64 double
76 #define FLOAT80 long double
78 #define UINT8 unsigned char
79 #define SINT8 signed char
81 #if SIZEOF_INT == 2
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
88 #else
89 #if SIZEOF_SHORT == 2
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
96 #endif
97 #endif
99 #if SIZEOF_INT == 4
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
106 #else
107 #if SIZEOF_SHORT == 4
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
114 #else
115 #if SIZEOF_LONG == 4
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
122 #endif
123 #endif
124 #endif
126 #if SIZEOF_INT == 8
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
133 #else
134 #if SIZEOF_LONG == 8
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
141 #else
142 #if SIZEOF_LONG_LONG == 8
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
149 #endif
150 #endif
151 #endif
153 /* ---- System specific configurations ----------------------------------- */
155 #ifdef MIPS
156 #include <ffi_mips.h>
157 #else
158 #define SIZEOF_ARG SIZEOF_VOID_P
159 #endif
161 #ifdef POWERPC
162 #if defined (__powerpc64__)
163 #define POWERPC64
164 #endif
165 #endif
167 #ifdef SPARC
168 #if defined(__arch64__) || defined(__sparcv9)
169 #define SPARC64
170 #endif
171 #endif
173 #ifdef S390
174 #if defined (__s390x__)
175 #define S390X
176 #endif
177 #endif
179 #ifdef X86_64
180 #if defined (__i386__)
181 #undef X86_64
182 #define X86
183 #endif
184 #endif
186 #ifndef LIBFFI_ASM
188 /* ---- Generic type definitions ----------------------------------------- */
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. */
194 typedef enum ffi_abi {
196 /* Leave this for debugging purposes */
197 FFI_FIRST_ABI = 0,
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
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
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
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
236 /* ---- Mips --------------------- */
237 #ifdef MIPS
238 FFI_O32,
239 FFI_N32,
240 FFI_N64,
241 #endif
243 /* ---- Alpha -------------------- */
244 #ifdef ALPHA
245 FFI_OSF,
246 FFI_DEFAULT_ABI = FFI_OSF,
247 #endif
249 /* ---- Motorola m68k ------------ */
250 #ifdef M68K
251 FFI_SYSV,
252 FFI_DEFAULT_ABI = FFI_SYSV,
253 #endif
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
267 #ifdef POWERPC_AIX
268 FFI_AIX,
269 FFI_DARWIN,
270 FFI_DEFAULT_ABI = FFI_AIX,
271 #endif
273 #ifdef POWERPC_DARWIN
274 FFI_AIX,
275 FFI_DARWIN,
276 FFI_DEFAULT_ABI = FFI_DARWIN,
277 #endif
279 /* ---- ARM --------------------- */
280 #ifdef ARM
281 FFI_SYSV,
282 FFI_DEFAULT_ABI = FFI_SYSV,
283 #endif
285 /* ---- S390 --------------------- */
286 #ifdef S390
287 FFI_SYSV,
288 FFI_DEFAULT_ABI = FFI_SYSV,
289 #endif
291 /* ---- SuperH ------------------- */
292 #ifdef SH
293 FFI_SYSV,
294 FFI_DEFAULT_ABI = FFI_SYSV,
295 #endif
297 /* Leave this for debugging purposes */
298 FFI_LAST_ABI
300 } ffi_abi;
302 typedef struct _ffi_type
304 size_t size;
305 unsigned short alignment;
306 unsigned short type;
307 /*@null@*/ struct _ffi_type **elements;
308 } ffi_type;
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;
325 /* Characters are 8 bit integral types */
326 #define ffi_type_schar ffi_type_sint8
327 #define ffi_type_uchar ffi_type_uint8
329 typedef enum {
330 FFI_OK = 0,
331 FFI_BAD_TYPEDEF,
332 FFI_BAD_ABI
333 } ffi_status;
335 typedef unsigned FFI_TYPE;
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;
345 #ifdef MIPS
346 #if _MIPS_SIM == _ABIN32
347 unsigned rstruct_flag;
348 #endif
349 #endif
351 } ffi_cif;
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
363 /* ---- Definitions for the raw API -------------------------------------- */
365 #if !FFI_NO_RAW_API
367 #if SIZEOF_ARG == 4
369 #define UINT_ARG UINT32
370 #define SINT_ARG SINT32
372 #endif
374 #if SIZEOF_ARG == 8
376 #define UINT_ARG UINT64
377 #define SINT_ARG SINT64
379 #endif
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;
389 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
390 void (*fn)(),
391 /*@out@*/ void *rvalue,
392 /*@dependent@*/ ffi_raw *avalue);
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);
398 #if !NO_JAVA_RAW_API
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. */
404 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
405 void (*fn)(),
406 /*@out@*/ void *rvalue,
407 /*@dependent@*/ ffi_raw *avalue);
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);
413 #endif /* !NO_JAVA_RAW_API */
415 #endif /* !FFI_NO_RAW_API */
417 /* ---- Definitions for closures ----------------------------------------- */
419 #ifdef __i386__
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 */
425 #elif defined(IA64)
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: */
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. */
438 #define FFI_NATIVE_RAW_API 0
440 #elif defined(ALPHA)
442 #define FFI_CLOSURES 1
443 #define FFI_TRAMPOLINE_SIZE 24
444 #define FFI_NATIVE_RAW_API 0
446 #elif defined(POWERPC)
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
456 #elif defined(POWERPC_DARWIN)
458 #define FFI_CLOSURES 1
459 #define FFI_TRAMPOLINE_SIZE 40
460 #define FFI_NATIVE_RAW_API 0
462 #elif defined(POWERPC_AIX)
464 #define FFI_CLOSURES 1
465 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */
466 #define FFI_NATIVE_RAW_API 0
468 #elif defined(SPARC64)
470 #define FFI_CLOSURES 1
471 #define FFI_TRAMPOLINE_SIZE 24
472 #define FFI_NATIVE_RAW_API 0
474 #elif defined(SPARC)
476 #define FFI_CLOSURES 1
477 #define FFI_TRAMPOLINE_SIZE 16
478 #define FFI_NATIVE_RAW_API 0
480 #elif defined(S390)
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
490 #elif defined(SH)
492 #define FFI_CLOSURES 1
493 #define FFI_TRAMPOLINE_SIZE 16
494 #define FFI_NATIVE_RAW_API 0
496 #elif defined(__x86_64__)
498 #define FFI_CLOSURES 1
499 #define FFI_TRAMPOLINE_SIZE 24
500 #define FFI_NATIVE_RAW_API 0
502 #else
504 #define FFI_CLOSURES 0
505 #define FFI_NATIVE_RAW_API 0
507 #endif
509 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
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 */
517 #endif
521 #if FFI_CLOSURES
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;
530 ffi_status
531 ffi_prep_closure (ffi_closure*,
532 ffi_cif *,
533 void (*fun)(ffi_cif*,void*,void**,void*),
534 void *user_data);
536 #if !FFI_NO_RAW_API
538 typedef struct {
539 char tramp[FFI_TRAMPOLINE_SIZE];
541 ffi_cif *cif;
543 #if !FFI_NATIVE_RAW_API
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*. */
549 void (*translate_args)(ffi_cif*,void*,void**,void*);
550 void *this_closure;
552 #endif
554 void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
555 void *user_data;
557 } ffi_raw_closure;
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);
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
573 #endif /* !FFI_NO_RAW_API */
574 #endif /* FFI_CLOSURES */
576 /* ---- Public interface definition -------------------------------------- */
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);
584 void ffi_call(/*@dependent@*/ ffi_cif *cif,
585 void (*fn)(),
586 /*@out@*/ void *rvalue,
587 /*@dependent@*/ void **avalue);
589 /* Useful for eliminating compiler warnings */
590 #define FFI_FN(f) ((void (*)())f)
592 /* ---- Definitions shared with assembly code ---------------------------- */
594 #endif
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
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
617 /* This should always refer to the last type code (for sanity checks) */
618 #define FFI_TYPE_LAST FFI_TYPE_POINTER
620 #ifdef __cplusplus
622 #endif
624 #endif