* real.c: Avoid parse error if FLOAT_WORDS_BIG_ENDIAN is
[official-gcc.git] / libffi / include / ffi.h.in
blob8fc37f56f4ee3c2178e5157c78cc3effb8f990ba
1 /* -----------------------------------------------------------------*-C-*-
2 libffi @VERSION@ - Copyright (c) 1996-2002 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 SPARC
162 #if defined(__arch64__) || defined(__sparcv9)
163 #define SPARC64
164 #endif
165 #endif
167 #ifndef LIBFFI_ASM
169 /* ---- Generic type definitions ----------------------------------------- */
171 #define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
172 /* The closure code assumes that this works on pointers, i.e. a size_t */
173 /* can hold a pointer. */
175 typedef enum ffi_abi {
177 /* Leave this for debugging purposes */
178 FFI_FIRST_ABI = 0,
180 /* ---- Sparc -------------------- */
181 #ifdef SPARC
182 FFI_V8,
183 FFI_V8PLUS,
184 FFI_V9,
185 #ifdef SPARC64
186 FFI_DEFAULT_ABI = FFI_V9,
187 #else
188 FFI_DEFAULT_ABI = FFI_V8,
189 #endif
190 #endif
192 /* ---- Intel x86 and AMD x86-64 - */
193 #if defined(X86) || defined(X86_64)
194 FFI_SYSV,
195 FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
196 #ifdef X86
197 FFI_DEFAULT_ABI = FFI_SYSV,
198 #else
199 FFI_DEFAULT_ABI = FFI_UNIX64,
200 #endif
201 #endif
203 /* ---- Intel x86 Win32 ---------- */
204 #ifdef X86_WIN32
205 FFI_SYSV,
206 FFI_DEFAULT_ABI = FFI_SYSV,
207 #endif
209 /* ---- Intel ia64 ---------------- */
210 #ifdef IA64
211 FFI_UNIX, /* Linux and all Unix variants use the same conventions */
212 FFI_DEFAULT_ABI = FFI_UNIX,
213 #endif
215 /* ---- Mips --------------------- */
216 #ifdef MIPS
217 FFI_O32,
218 FFI_N32,
219 FFI_N64,
220 #endif
222 /* ---- Alpha -------------------- */
223 #ifdef ALPHA
224 FFI_OSF,
225 FFI_DEFAULT_ABI = FFI_OSF,
226 #endif
228 /* ---- Motorola m68k ------------ */
229 #ifdef M68K
230 FFI_SYSV,
231 FFI_DEFAULT_ABI = FFI_SYSV,
232 #endif
234 /* ---- PowerPC ------------------ */
235 #ifdef POWERPC
236 FFI_SYSV,
237 FFI_GCC_SYSV,
238 FFI_DEFAULT_ABI = FFI_GCC_SYSV,
239 #endif
241 #ifdef POWERPC_AIX
242 FFI_AIX,
243 FFI_DARWIN,
244 FFI_DEFAULT_ABI = FFI_AIX,
245 #endif
247 #ifdef POWERPC_DARWIN
248 FFI_AIX,
249 FFI_DARWIN,
250 FFI_DEFAULT_ABI = FFI_DARWIN,
251 #endif
253 /* ---- ARM --------------------- */
254 #ifdef ARM
255 FFI_SYSV,
256 FFI_DEFAULT_ABI = FFI_SYSV,
257 #endif
259 /* ---- S390 --------------------- */
260 #ifdef S390
261 FFI_SYSV,
262 FFI_DEFAULT_ABI = FFI_SYSV,
263 #endif
265 /* ---- SuperH ------------------- */
266 #ifdef SH
267 FFI_SYSV,
268 FFI_DEFAULT_ABI = FFI_SYSV,
269 #endif
271 /* Leave this for debugging purposes */
272 FFI_LAST_ABI
274 } ffi_abi;
276 typedef struct _ffi_type
278 size_t size;
279 unsigned short alignment;
280 unsigned short type;
281 /*@null@*/ struct _ffi_type **elements;
282 } ffi_type;
284 /* These are defined in ffi.c */
285 extern ffi_type ffi_type_void;
286 extern ffi_type ffi_type_uint8;
287 extern ffi_type ffi_type_sint8;
288 extern ffi_type ffi_type_uint16;
289 extern ffi_type ffi_type_sint16;
290 extern ffi_type ffi_type_uint32;
291 extern ffi_type ffi_type_sint32;
292 extern ffi_type ffi_type_uint64;
293 extern ffi_type ffi_type_sint64;
294 extern ffi_type ffi_type_float;
295 extern ffi_type ffi_type_double;
296 extern ffi_type ffi_type_longdouble;
297 extern ffi_type ffi_type_pointer;
299 /* Characters are 8 bit integral types */
300 #define ffi_type_schar ffi_type_sint8
301 #define ffi_type_uchar ffi_type_uint8
303 typedef enum {
304 FFI_OK = 0,
305 FFI_BAD_TYPEDEF,
306 FFI_BAD_ABI
307 } ffi_status;
309 typedef unsigned FFI_TYPE;
311 typedef struct {
312 ffi_abi abi;
313 unsigned nargs;
314 /*@dependent@*/ ffi_type **arg_types;
315 /*@dependent@*/ ffi_type *rtype;
316 unsigned bytes;
317 unsigned flags;
319 #ifdef MIPS
320 #if _MIPS_SIM == _ABIN32
321 unsigned rstruct_flag;
322 #endif
323 #endif
325 } ffi_cif;
327 #if SIZEOF_ARG == 4
328 typedef UINT32 ffi_arg;
329 #else
330 #if SIZEOF_ARG == 8
331 typedef UINT64 ffi_arg;
332 #else
333 -- unsupported configuration
334 #endif
335 #endif
337 /* ---- Definitions for the raw API -------------------------------------- */
339 #if !FFI_NO_RAW_API
341 #if SIZEOF_ARG == 4
343 #define UINT_ARG UINT32
344 #define SINT_ARG SINT32
346 #endif
348 #if SIZEOF_ARG == 8
350 #define UINT_ARG UINT64
351 #define SINT_ARG SINT64
353 #endif
355 typedef union {
356 SINT_ARG sint;
357 UINT_ARG uint;
358 float flt;
359 char data[SIZEOF_ARG];
360 void* ptr;
361 } ffi_raw;
363 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
364 void (*fn)(),
365 /*@out@*/ void *rvalue,
366 /*@dependent@*/ ffi_raw *avalue);
368 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
369 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
370 size_t ffi_raw_size (ffi_cif *cif);
372 #if !NO_JAVA_RAW_API
374 /* This is analogous to the raw API, except it uses Java parameter */
375 /* packing, even on 64-bit machines. I.e. on 64-bit machines */
376 /* longs and doubles are followed by an empty 64-bit word. */
378 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
379 void (*fn)(),
380 /*@out@*/ void *rvalue,
381 /*@dependent@*/ ffi_raw *avalue);
383 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
384 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
385 size_t ffi_java_raw_size (ffi_cif *cif);
387 #endif /* !NO_JAVA_RAW_API */
389 #endif /* !FFI_NO_RAW_API */
391 /* ---- Definitions for closures ----------------------------------------- */
393 #ifdef X86
395 #define FFI_CLOSURES 1 /* x86 supports closures */
396 #define FFI_TRAMPOLINE_SIZE 10
397 #define FFI_NATIVE_RAW_API 1 /* and has native raw api support */
399 #elif defined(X86_WIN32)
401 #define FFI_CLOSURES 1 /* x86 supports closures */
402 #define FFI_TRAMPOLINE_SIZE 10
403 #define FFI_NATIVE_RAW_API 1 /* and has native raw api support */
405 #elif defined(IA64)
407 #define FFI_CLOSURES 1
408 #define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
409 /* can be interpreted as a C function */
410 /* decriptor: */
412 struct ffi_ia64_trampoline_struct {
413 void * code_pointer; /* Pointer to ffi_closure_UNIX */
414 void * fake_gp; /* Pointer to closure, installed as gp */
415 void * real_gp; /* Real gp value, reinstalled by */
416 /* ffi_closure_UNIX. */
418 #define FFI_NATIVE_RAW_API 0
420 #elif defined(ALPHA)
422 #define FFI_CLOSURES 1
423 #define FFI_TRAMPOLINE_SIZE 24
424 #define FFI_NATIVE_RAW_API 0
426 #elif defined(POWERPC)
428 #define FFI_CLOSURES 1
429 #define FFI_TRAMPOLINE_SIZE 40
430 #define FFI_NATIVE_RAW_API 0
432 #elif defined(POWERPC_DARWIN)
434 #define FFI_CLOSURES 1
435 #define FFI_TRAMPOLINE_SIZE 40
436 #define FFI_NATIVE_RAW_API 0
438 #elif defined(POWERPC_AIX)
440 #define FFI_CLOSURES 1
441 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */
442 #define FFI_NATIVE_RAW_API 0
444 #elif defined(SH)
446 #define FFI_CLOSURES 1
447 #define FFI_TRAMPOLINE_SIZE 16
448 #define FFI_NATIVE_RAW_API 0
450 #else
452 #define FFI_CLOSURES 0
453 #define FFI_NATIVE_RAW_API 0
455 #endif
457 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
459 struct ffi_aix_trampoline_struct {
460 void * code_pointer; /* Pointer to ffi_closure_ASM */
461 void * toc; /* TOC */
462 void * static_chain; /* Pointer to closure */
465 #endif
469 #if FFI_CLOSURES
471 typedef struct {
472 char tramp[FFI_TRAMPOLINE_SIZE];
473 ffi_cif *cif;
474 void (*fun)(ffi_cif*,void*,void**,void*);
475 void *user_data;
476 } ffi_closure;
478 ffi_status
479 ffi_prep_closure (ffi_closure*,
480 ffi_cif *,
481 void (*fun)(ffi_cif*,void*,void**,void*),
482 void *user_data);
484 #if !FFI_NO_RAW_API
486 typedef struct {
487 char tramp[FFI_TRAMPOLINE_SIZE];
489 ffi_cif *cif;
491 #if !FFI_NATIVE_RAW_API
493 /* if this is enabled, then a raw closure has the same layout
494 as a regular closure. We use this to install an intermediate
495 handler to do the transaltion, void** -> ffi_raw*. */
497 void (*translate_args)(ffi_cif*,void*,void**,void*);
498 void *this_closure;
500 #endif
502 void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
503 void *user_data;
505 } ffi_raw_closure;
507 ffi_status
508 ffi_prep_raw_closure (ffi_raw_closure*,
509 ffi_cif *cif,
510 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
511 void *user_data);
513 #ifndef NO_JAVA_RAW_API
514 ffi_status
515 ffi_prep_java_raw_closure (ffi_raw_closure*,
516 ffi_cif *cif,
517 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
518 void *user_data);
519 #endif
521 #endif /* !FFI_NO_RAW_API */
522 #endif /* FFI_CLOSURES */
524 /* ---- Public interface definition -------------------------------------- */
526 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
527 ffi_abi abi,
528 unsigned int nargs,
529 /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
530 /*@dependent@*/ ffi_type **atypes);
532 void ffi_call(/*@dependent@*/ ffi_cif *cif,
533 void (*fn)(),
534 /*@out@*/ void *rvalue,
535 /*@dependent@*/ void **avalue);
537 /* Useful for eliminating compiler warnings */
538 #define FFI_FN(f) ((void (*)())f)
540 /* ---- Definitions shared with assembly code ---------------------------- */
542 #endif
544 #define FFI_TYPE_VOID 0
545 #define FFI_TYPE_INT 1
546 #define FFI_TYPE_FLOAT 2
547 #define FFI_TYPE_DOUBLE 3
548 #if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
549 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
550 #else
551 #define FFI_TYPE_LONGDOUBLE 4
552 #endif
554 #define FFI_TYPE_UINT8 5 /* If this changes, update ffi_mips.h. */
555 #define FFI_TYPE_SINT8 6 /* If this changes, update ffi_mips.h. */
556 #define FFI_TYPE_UINT16 7
557 #define FFI_TYPE_SINT16 8
558 #define FFI_TYPE_UINT32 9
559 #define FFI_TYPE_SINT32 10
560 #define FFI_TYPE_UINT64 11
561 #define FFI_TYPE_SINT64 12
562 #define FFI_TYPE_STRUCT 13 /* If this changes, update ffi_mips.h. */
563 #define FFI_TYPE_POINTER 14
565 /* This should always refer to the last type code (for sanity checks) */
566 #define FFI_TYPE_LAST FFI_TYPE_POINTER
568 #ifdef __cplusplus
570 #endif
572 #endif