OSDN Git Service

* src/powerpc/ppc_closure.S: New file.
[pf3gnuchains/gcc-fork.git] / libffi / include / ffi.h.in
1 /* -----------------------------------------------------------------*-C-*-
2    libffi @VERSION@ - Copyright (c) 1996-1999  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 SPARC
162 #if defined(__arch64__) || defined(__sparcv9)
163 #define SPARC64
164 #endif
165 #endif
166
167 #ifndef LIBFFI_ASM
168
169 /* ---- Generic type definitions ----------------------------------------- */
170
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.                                                  */
174
175 typedef enum ffi_abi {
176
177   /* Leave this for debugging purposes */
178   FFI_FIRST_ABI = 0,
179
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
191
192   /* ---- Intel x86 ---------------- */
193 #ifdef X86
194   FFI_SYSV,
195   FFI_DEFAULT_ABI = FFI_SYSV,
196 #endif
197
198   /* ---- Intel ia64 ---------------- */
199 #ifdef IA64
200   FFI_UNIX,     /* Linux and all Unix variants use the same conventions */
201   FFI_DEFAULT_ABI = FFI_UNIX,
202 #endif
203
204   /* ---- Mips --------------------- */
205 #ifdef MIPS
206   FFI_O32,
207   FFI_N32,
208   FFI_N64,
209 #endif
210
211   /* ---- Alpha -------------------- */
212 #ifdef ALPHA
213   FFI_OSF,
214   FFI_DEFAULT_ABI = FFI_OSF,
215 #endif
216
217   /* ---- Motorola m68k ------------ */
218 #ifdef M68K
219   FFI_SYSV,
220   FFI_DEFAULT_ABI = FFI_SYSV,
221 #endif
222
223   /* ---- PowerPC ------------------ */
224 #ifdef POWERPC
225   FFI_SYSV,
226   FFI_GCC_SYSV,
227   FFI_DEFAULT_ABI = FFI_GCC_SYSV,
228 #endif
229
230   /* ---- ARM  --------------------- */
231 #ifdef ARM
232   FFI_SYSV,
233   FFI_DEFAULT_ABI = FFI_SYSV,
234 #endif
235
236   /* Leave this for debugging purposes */
237   FFI_LAST_ABI
238
239 } ffi_abi;
240
241 typedef struct _ffi_type
242 {
243   size_t size;
244   unsigned short alignment;
245   unsigned short type;
246   /*@null@*/ struct _ffi_type **elements;
247 } ffi_type;
248
249 /* These are defined in ffi.c */
250 extern ffi_type ffi_type_void;
251 extern ffi_type ffi_type_uint8;
252 extern ffi_type ffi_type_sint8;
253 extern ffi_type ffi_type_uint16;
254 extern ffi_type ffi_type_sint16;
255 extern ffi_type ffi_type_uint32;
256 extern ffi_type ffi_type_sint32;
257 extern ffi_type ffi_type_uint64;
258 extern ffi_type ffi_type_sint64;
259 extern ffi_type ffi_type_float;
260 extern ffi_type ffi_type_double;
261 extern ffi_type ffi_type_longdouble;
262 extern ffi_type ffi_type_pointer;
263
264 /* Characters are 8 bit integral types */
265 #define ffi_type_schar ffi_type_sint8
266 #define ffi_type_uchar ffi_type_uint8
267
268 typedef enum {
269   FFI_OK = 0,
270   FFI_BAD_TYPEDEF,
271   FFI_BAD_ABI 
272 } ffi_status;
273
274 typedef unsigned FFI_TYPE;
275
276 typedef struct {
277   ffi_abi abi;
278   unsigned nargs;
279   /*@dependent@*/ ffi_type **arg_types;
280   /*@dependent@*/ ffi_type *rtype;
281   unsigned bytes;
282   unsigned flags;
283
284 #ifdef MIPS
285 #if _MIPS_SIM == _ABIN32
286   unsigned rstruct_flag;
287 #endif
288 #endif
289
290 } ffi_cif;
291
292 /* ---- Definitions for the raw API -------------------------------------- */
293
294 #if !FFI_NO_RAW_API
295
296 #if SIZEOF_ARG == 4
297
298 #define UINT_ARG UINT32
299 #define SINT_ARG SINT32
300
301 #endif
302
303 #if SIZEOF_ARG == 8
304
305 #define UINT_ARG UINT64
306 #define SINT_ARG SINT64
307
308 #endif
309
310 typedef union {
311   SINT_ARG sint;
312   UINT_ARG uint;
313   float    flt;
314   char     data[SIZEOF_ARG];
315   void*    ptr;
316 } ffi_raw;
317
318 void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, 
319                    void (*fn)(), 
320                    /*@out@*/ void *rvalue, 
321                    /*@dependent@*/ ffi_raw *avalue);
322
323 void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
324 void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
325 size_t ffi_raw_size (ffi_cif *cif);
326
327 #if !NO_JAVA_RAW_API
328
329 /* This is analogous to the raw API, except it uses Java parameter      */
330 /* packing, even on 64-bit machines.  I.e. on 64-bit machines           */
331 /* longs and doubles are followed by an empty 64-bit word.              */
332
333 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, 
334                         void (*fn)(), 
335                         /*@out@*/ void *rvalue, 
336                         /*@dependent@*/ ffi_raw *avalue);
337
338 void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
339 void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
340 size_t ffi_java_raw_size (ffi_cif *cif);
341
342 #endif /* !NO_JAVA_RAW_API */
343
344 #endif /* !FFI_NO_RAW_API */
345
346 /* ---- Definitions for closures ----------------------------------------- */
347
348 #ifdef X86
349
350 #define FFI_CLOSURES 1          /* x86 supports closures */
351 #define FFI_TRAMPOLINE_SIZE 10
352 #define FFI_NATIVE_RAW_API 1    /* and has native raw api support */
353
354 #elif defined(IA64)
355
356 #define FFI_CLOSURES 1
357 #define FFI_TRAMPOLINE_SIZE 24  /* Really the following struct, which   */
358                                 /* can be interpreted as a C function   */
359                                 /* decriptor:                           */
360
361 struct ffi_ia64_trampoline_struct {
362     void * code_pointer;        /* Pointer to ffi_closure_UNIX  */
363     void * fake_gp;             /* Pointer to closure, installed as gp  */
364     void * real_gp;             /* Real gp value, reinstalled by        */
365                                 /* ffi_closure_UNIX.                    */
366 };
367 #define FFI_NATIVE_RAW_API 0
368
369 #elif defined(ALPHA)
370
371 #define FFI_CLOSURES 1
372 #define FFI_TRAMPOLINE_SIZE 24
373 #define FFI_NATIVE_RAW_API 0
374
375 #elif defined(POWERPC)
376
377 #define FFI_CLOSURES 1
378 #define FFI_TRAMPOLINE_SIZE 40
379 #define FFI_NATIVE_RAW_API 0
380
381 #else 
382
383 #define FFI_CLOSURES 0
384 #define FFI_NATIVE_RAW_API 0
385
386 #endif
387
388
389
390 #if FFI_CLOSURES
391
392 typedef struct {
393   char tramp[FFI_TRAMPOLINE_SIZE];
394   ffi_cif   *cif;
395   void     (*fun)(ffi_cif*,void*,void**,void*);
396   void      *user_data;
397 } ffi_closure;
398
399 ffi_status
400 ffi_prep_closure (ffi_closure*,
401                   ffi_cif *,
402                   void (*fun)(ffi_cif*,void*,void**,void*),
403                   void *user_data);
404
405 #if !FFI_NO_RAW_API
406
407 typedef struct {
408   char tramp[FFI_TRAMPOLINE_SIZE];
409
410   ffi_cif   *cif;
411
412 #if !FFI_NATIVE_RAW_API
413
414   /* if this is enabled, then a raw closure has the same layout 
415      as a regular closure.  We use this to install an intermediate 
416      handler to do the transaltion, void** -> ffi_raw*. */
417
418   void     (*translate_args)(ffi_cif*,void*,void**,void*);
419   void      *this_closure;
420
421 #endif
422
423   void     (*fun)(ffi_cif*,void*,ffi_raw*,void*);
424   void      *user_data;
425
426 } ffi_raw_closure;
427
428 ffi_status
429 ffi_prep_raw_closure (ffi_raw_closure*,
430                       ffi_cif *cif,
431                       void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
432                       void *user_data);
433
434 #ifndef NO_JAVA_RAW_API
435 ffi_status
436 ffi_prep_java_raw_closure (ffi_raw_closure*,
437                            ffi_cif *cif,
438                            void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
439                            void *user_data);
440 #endif
441
442 #endif /* !FFI_NO_RAW_API */
443 #endif /* FFI_CLOSURES */
444
445 /* ---- Public interface definition -------------------------------------- */
446
447 ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, 
448                         ffi_abi abi,
449                         unsigned int nargs, 
450                         /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, 
451                         /*@dependent@*/ ffi_type **atypes);
452
453 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
454               void (*fn)(), 
455               /*@out@*/ void *rvalue, 
456               /*@dependent@*/ void **avalue);
457
458 /* Useful for eliminating compiler warnings */
459 #define FFI_FN(f) ((void (*)())f)
460
461 /* ---- Definitions shared with assembly code ---------------------------- */
462
463 #endif
464
465 #define FFI_TYPE_VOID       0    
466 #define FFI_TYPE_INT        1
467 #define FFI_TYPE_FLOAT      2    
468 #define FFI_TYPE_DOUBLE     3
469 #if SIZEOF_LONG_DOUBLE == SIZEOF_DOUBLE
470 #define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
471 #else
472 #define FFI_TYPE_LONGDOUBLE 4
473 #endif
474
475 #define FFI_TYPE_UINT8      5   /* If this changes, update ffi_mips.h. */
476 #define FFI_TYPE_SINT8      6   /* If this changes, update ffi_mips.h. */
477 #define FFI_TYPE_UINT16     7 
478 #define FFI_TYPE_SINT16     8
479 #define FFI_TYPE_UINT32     9
480 #define FFI_TYPE_SINT32     10
481 #define FFI_TYPE_UINT64     11
482 #define FFI_TYPE_SINT64     12
483 #define FFI_TYPE_STRUCT     13  /* If this changes, update ffi_mips.h. */
484 #define FFI_TYPE_POINTER    14
485
486 /* This should always refer to the last type code (for sanity checks) */
487 #define FFI_TYPE_LAST       FFI_TYPE_POINTER
488
489 #ifdef __cplusplus
490 }
491 #endif
492
493 #endif
494