]> git.ipfire.org Git - thirdparty/gcc.git/blob - libffi/include/ffi.h.in
Makefile.am: Add SHmedia support.
[thirdparty/gcc.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 #ifdef LIBFFI_ASM
187
188 #ifdef HAVE_RO_EH_FRAME
189 #define EH_FRAME_FLAGS "a"
190 #else
191 #define EH_FRAME_FLAGS "aw"
192 #endif
193
194 #else
195
196 /* ---- Generic type definitions ----------------------------------------- */
197
198 #define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
199 /* The closure code assumes that this works on pointers, i.e. a size_t */
200 /* can hold a pointer. */
201
202 typedef enum ffi_abi {
203
204 /* Leave this for debugging purposes */
205 FFI_FIRST_ABI = 0,
206
207 /* ---- Sparc -------------------- */
208 #ifdef SPARC
209 FFI_V8,
210 FFI_V8PLUS,
211 FFI_V9,
212 #ifdef SPARC64
213 FFI_DEFAULT_ABI = FFI_V9,
214 #else
215 FFI_DEFAULT_ABI = FFI_V8,
216 #endif
217 #endif
218
219 /* ---- Intel x86 Win32 ---------- */
220 #ifdef X86_WIN32
221 FFI_SYSV,
222 FFI_STDCALL,
223 /* TODO: Add fastcall support for the sake of completeness */
224 FFI_DEFAULT_ABI = FFI_SYSV,
225 #endif
226
227 /* ---- Intel x86 and AMD x86-64 - */
228 #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
229 FFI_SYSV,
230 FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
231 #ifdef __i386__
232 FFI_DEFAULT_ABI = FFI_SYSV,
233 #else
234 FFI_DEFAULT_ABI = FFI_UNIX64,
235 #endif
236 #endif
237
238 /* ---- Intel ia64 ---------------- */
239 #ifdef IA64
240 FFI_UNIX, /* Linux and all Unix variants use the same conventions */
241 FFI_DEFAULT_ABI = FFI_UNIX,
242 #endif
243
244 /* ---- Mips --------------------- */
245 #ifdef MIPS
246 FFI_O32,
247 FFI_N32,
248 FFI_N64,
249 #endif
250
251 /* ---- Alpha -------------------- */
252 #ifdef ALPHA
253 FFI_OSF,
254 FFI_DEFAULT_ABI = FFI_OSF,
255 #endif
256
257 /* ---- Motorola m68k ------------ */
258 #ifdef M68K
259 FFI_SYSV,
260 FFI_DEFAULT_ABI = FFI_SYSV,
261 #endif
262
263 /* ---- PowerPC ------------------ */
264 #ifdef POWERPC
265 FFI_SYSV,
266 FFI_GCC_SYSV,
267 FFI_LINUX64,
268 # ifdef POWERPC64
269 FFI_DEFAULT_ABI = FFI_LINUX64,
270 # else
271 FFI_DEFAULT_ABI = FFI_GCC_SYSV,
272 # endif
273 #endif
274
275 #ifdef POWERPC_AIX
276 FFI_AIX,
277 FFI_DARWIN,
278 FFI_DEFAULT_ABI = FFI_AIX,
279 #endif
280
281 #ifdef POWERPC_DARWIN
282 FFI_AIX,
283 FFI_DARWIN,
284 FFI_DEFAULT_ABI = FFI_DARWIN,
285 #endif
286
287 /* ---- ARM --------------------- */
288 #ifdef ARM
289 FFI_SYSV,
290 FFI_DEFAULT_ABI = FFI_SYSV,
291 #endif
292
293 /* ---- S390 --------------------- */
294 #ifdef S390
295 FFI_SYSV,
296 FFI_DEFAULT_ABI = FFI_SYSV,
297 #endif
298
299 /* ---- SuperH ------------------- */
300 #ifdef SH
301 FFI_SYSV,
302 FFI_DEFAULT_ABI = FFI_SYSV,
303 #endif
304
305 /* ---- SuperH - SHmedia --------- */
306 #ifdef SH64
307 FFI_SYSV,
308 FFI_DEFAULT_ABI = FFI_SYSV,
309 #endif
310
311 /* Leave this for debugging purposes */
312 FFI_LAST_ABI
313
314 } ffi_abi;
315
316 typedef struct _ffi_type
317 {
318 size_t size;
319 unsigned short alignment;
320 unsigned short type;
321 /*@null@*/ struct _ffi_type **elements;
322 } ffi_type;
323
324 /* These are defined in types.c */
325 extern ffi_type ffi_type_void;
326 extern ffi_type ffi_type_uint8;
327 extern ffi_type ffi_type_sint8;
328 extern ffi_type ffi_type_uint16;
329 extern ffi_type ffi_type_sint16;
330 extern ffi_type ffi_type_uint32;
331 extern ffi_type ffi_type_sint32;
332 extern ffi_type ffi_type_uint64;
333 extern ffi_type ffi_type_sint64;
334 extern ffi_type ffi_type_float;
335 extern ffi_type ffi_type_double;
336 extern ffi_type ffi_type_longdouble;
337 extern ffi_type ffi_type_pointer;
338
339 /* Characters are 8 bit integral types */
340 #define ffi_type_schar ffi_type_sint8
341 #define ffi_type_uchar ffi_type_uint8
342
343 typedef enum {
344 FFI_OK = 0,
345 FFI_BAD_TYPEDEF,
346 FFI_BAD_ABI
347 } ffi_status;
348
349 typedef unsigned FFI_TYPE;
350
351 typedef struct {
352 ffi_abi abi;
353 unsigned nargs;
354 /*@dependent@*/ ffi_type **arg_types;
355 /*@dependent@*/ ffi_type *rtype;
356 unsigned bytes;
357 unsigned flags;
358
359 #ifdef MIPS
360 #if _MIPS_SIM == _ABIN32
361 unsigned rstruct_flag;
362 #endif
363 #endif
364
365 #ifdef SH64
366 long long flags2;
367 #endif
368
369 } ffi_cif;
370
371 #if SIZEOF_ARG == 4
372 typedef UINT32 ffi_arg;
373 #else
374 #if SIZEOF_ARG == 8
375 typedef UINT64 ffi_arg;
376 #else
377 -- unsupported configuration
378 #endif
379 #endif
380
381 /* ---- Definitions for the raw API -------------------------------------- */
382
383 #if !FFI_NO_RAW_API
384
385 #if SIZEOF_ARG == 4
386
387 #define UINT_ARG UINT32
388 #define SINT_ARG SINT32
389
390 #endif
391
392 #if SIZEOF_ARG == 8
393
394 #define UINT_ARG UINT64
395 #define SINT_ARG SINT64
396
397 #endif
398
399 typedef union {
400 SINT_ARG sint;
401 UINT_ARG uint;
402 float flt;
403 char data[SIZEOF_ARG];
404 void* ptr;
405 } ffi_raw;
406
407 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif,
408 void (*fn)(),
409 /*@out@*/ void *rvalue,
410 /*@dependent@*/ ffi_raw *avalue);
411
412 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
413 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
414 size_t ffi_raw_size (ffi_cif *cif);
415
416 #if !NO_JAVA_RAW_API
417
418 /* This is analogous to the raw API, except it uses Java parameter */
419 /* packing, even on 64-bit machines. I.e. on 64-bit machines */
420 /* longs and doubles are followed by an empty 64-bit word. */
421
422 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
423 void (*fn)(),
424 /*@out@*/ void *rvalue,
425 /*@dependent@*/ ffi_raw *avalue);
426
427 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
428 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
429 size_t ffi_java_raw_size (ffi_cif *cif);
430
431 #endif /* !NO_JAVA_RAW_API */
432
433 #endif /* !FFI_NO_RAW_API */
434
435 /* ---- Definitions for closures ----------------------------------------- */
436
437 #ifdef __i386__
438
439 #define FFI_CLOSURES 1 /* x86 supports closures */
440 #define FFI_TRAMPOLINE_SIZE 10
441 #define FFI_NATIVE_RAW_API 1 /* and has native raw api support */
442
443 #elif defined(IA64)
444
445 #define FFI_CLOSURES 1
446 #define FFI_TRAMPOLINE_SIZE 24 /* Really the following struct, which */
447 /* can be interpreted as a C function */
448 /* decriptor: */
449
450 struct ffi_ia64_trampoline_struct {
451 void * code_pointer; /* Pointer to ffi_closure_UNIX */
452 void * fake_gp; /* Pointer to closure, installed as gp */
453 void * real_gp; /* Real gp value, reinstalled by */
454 /* ffi_closure_UNIX. */
455 };
456 #define FFI_NATIVE_RAW_API 0
457
458 #elif defined(ALPHA)
459
460 #define FFI_CLOSURES 1
461 #define FFI_TRAMPOLINE_SIZE 24
462 #define FFI_NATIVE_RAW_API 0
463
464 #elif defined(POWERPC)
465
466 #define FFI_CLOSURES 1
467 #ifdef POWERPC64
468 #define FFI_TRAMPOLINE_SIZE 24
469 #else
470 #define FFI_TRAMPOLINE_SIZE 40
471 #endif
472 #define FFI_NATIVE_RAW_API 0
473
474 #elif defined(POWERPC_DARWIN)
475
476 #define FFI_CLOSURES 1
477 #define FFI_TRAMPOLINE_SIZE 40
478 #define FFI_NATIVE_RAW_API 0
479
480 #elif defined(POWERPC_AIX)
481
482 #define FFI_CLOSURES 1
483 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */
484 #define FFI_NATIVE_RAW_API 0
485
486 #elif defined(SPARC64)
487
488 #define FFI_CLOSURES 1
489 #define FFI_TRAMPOLINE_SIZE 24
490 #define FFI_NATIVE_RAW_API 0
491
492 #elif defined(SPARC)
493
494 #define FFI_CLOSURES 1
495 #define FFI_TRAMPOLINE_SIZE 16
496 #define FFI_NATIVE_RAW_API 0
497
498 #elif defined(S390)
499
500 #define FFI_CLOSURES 1
501 #ifdef S390X
502 #define FFI_TRAMPOLINE_SIZE 32
503 #else
504 #define FFI_TRAMPOLINE_SIZE 16
505 #endif
506 #define FFI_NATIVE_RAW_API 0
507
508 #elif defined(SH)
509
510 #define FFI_CLOSURES 1
511 #define FFI_TRAMPOLINE_SIZE 16
512 #define FFI_NATIVE_RAW_API 0
513
514 #elif defined(SH64)
515
516 #define FFI_CLOSURES 1
517 #define FFI_TRAMPOLINE_SIZE 32
518 #define FFI_NATIVE_RAW_API 0
519
520 #elif defined(__x86_64__)
521
522 #define FFI_CLOSURES 1
523 #define FFI_TRAMPOLINE_SIZE 24
524 #define FFI_NATIVE_RAW_API 0
525
526 #else
527
528 #define FFI_CLOSURES 0
529 #define FFI_NATIVE_RAW_API 0
530
531 #endif
532
533 #if defined(POWERPC_DARWIN) || defined(POWERPC_AIX)
534
535 struct ffi_aix_trampoline_struct {
536 void * code_pointer; /* Pointer to ffi_closure_ASM */
537 void * toc; /* TOC */
538 void * static_chain; /* Pointer to closure */
539 };
540
541 #endif
542
543
544
545 #if FFI_CLOSURES
546
547 typedef struct {
548 char tramp[FFI_TRAMPOLINE_SIZE];
549 ffi_cif *cif;
550 void (*fun)(ffi_cif*,void*,void**,void*);
551 void *user_data;
552 } ffi_closure;
553
554 ffi_status
555 ffi_prep_closure (ffi_closure*,
556 ffi_cif *,
557 void (*fun)(ffi_cif*,void*,void**,void*),
558 void *user_data);
559
560 #if !FFI_NO_RAW_API
561
562 typedef struct {
563 char tramp[FFI_TRAMPOLINE_SIZE];
564
565 ffi_cif *cif;
566
567 #if !FFI_NATIVE_RAW_API
568
569 /* if this is enabled, then a raw closure has the same layout
570 as a regular closure. We use this to install an intermediate
571 handler to do the transaltion, void** -> ffi_raw*. */
572
573 void (*translate_args)(ffi_cif*,void*,void**,void*);
574 void *this_closure;
575
576 #endif
577
578 void (*fun)(ffi_cif*,void*,ffi_raw*,void*);
579 void *user_data;
580
581 } ffi_raw_closure;
582
583 ffi_status
584 ffi_prep_raw_closure (ffi_raw_closure*,
585 ffi_cif *cif,
586 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
587 void *user_data);
588
589 #ifndef NO_JAVA_RAW_API
590 ffi_status
591 ffi_prep_java_raw_closure (ffi_raw_closure*,
592 ffi_cif *cif,
593 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
594 void *user_data);
595 #endif
596
597 #endif /* !FFI_NO_RAW_API */
598 #endif /* FFI_CLOSURES */
599
600 /* ---- Public interface definition -------------------------------------- */
601
602 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
603 ffi_abi abi,
604 unsigned int nargs,
605 /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
606 /*@dependent@*/ ffi_type **atypes);
607
608 void ffi_call(/*@dependent@*/ ffi_cif *cif,
609 void (*fn)(),
610 /*@out@*/ void *rvalue,
611 /*@dependent@*/ void **avalue);
612
613 /* Useful for eliminating compiler warnings */
614 #define FFI_FN(f) ((void (*)())f)
615
616 /* ---- Definitions shared with assembly code ---------------------------- */
617
618 #endif
619
620 #define FFI_TYPE_VOID 0
621 #define FFI_TYPE_INT 1
622 #define FFI_TYPE_FLOAT 2
623 #define FFI_TYPE_DOUBLE 3
624 #if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
625 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
626 #else
627 #define FFI_TYPE_LONGDOUBLE 4
628 #endif
629
630 #define FFI_TYPE_UINT8 5 /* If this changes, update ffi_mips.h. */
631 #define FFI_TYPE_SINT8 6 /* If this changes, update ffi_mips.h. */
632 #define FFI_TYPE_UINT16 7
633 #define FFI_TYPE_SINT16 8
634 #define FFI_TYPE_UINT32 9
635 #define FFI_TYPE_SINT32 10
636 #define FFI_TYPE_UINT64 11
637 #define FFI_TYPE_SINT64 12
638 #define FFI_TYPE_STRUCT 13 /* If this changes, update ffi_mips.h. */
639 #define FFI_TYPE_POINTER 14
640
641 /* This should always refer to the last type code (for sanity checks) */
642 #define FFI_TYPE_LAST FFI_TYPE_POINTER
643
644 #ifdef __cplusplus
645 }
646 #endif
647
648 #endif
649