* configure.in (arm-*-netbsdelf*): Enable building java libraries.
[official-gcc.git] / libffi / src / java_raw_api.c
blobcb5dd67a78edcf7909c5dc3a90ce72adda81eac4
1 /* -----------------------------------------------------------------------
2 java_raw_api.c - Copyright (c) 1999 Cygnus Solutions
4 Cloned from raw_api.c
6 Raw_api.c author: Kresten Krab Thorup <krab@gnu.org>
7 Java_raw_api.c author: Hans-J. Boehm <hboehm@hpl.hp.com>
9 $Id $
11 Permission is hereby granted, free of charge, to any person obtaining
12 a copy of this software and associated documentation files (the
13 ``Software''), to deal in the Software without restriction, including
14 without limitation the rights to use, copy, modify, merge, publish,
15 distribute, sublicense, and/or sell copies of the Software, and to
16 permit persons to whom the Software is furnished to do so, subject to
17 the following conditions:
19 The above copyright notice and this permission notice shall be included
20 in all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 OTHER DEALINGS IN THE SOFTWARE.
29 ----------------------------------------------------------------------- */
31 /* This defines a Java- and 64-bit specific variant of the raw API. */
32 /* It assumes that "raw" argument blocks look like Java stacks on a */
33 /* 64-bit machine. Arguments that can be stored in a single stack */
34 /* stack slots (longs, doubles) occupy 128 bits, but only the first */
35 /* 64 bits are actually used. */
37 #include <ffi.h>
38 #include <ffi_common.h>
40 #if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API)
42 size_t
43 ffi_java_raw_size (ffi_cif *cif)
45 size_t result = 0;
46 int i;
48 ffi_type **at = cif->arg_types;
50 for (i = cif->nargs-1; i >= 0; i--, at++)
52 switch((*at) -> type) {
53 case FFI_TYPE_UINT64:
54 case FFI_TYPE_SINT64:
55 case FFI_TYPE_DOUBLE:
56 result += 2 * SIZEOF_ARG;
57 break;
58 case FFI_TYPE_STRUCT:
59 /* No structure parameters in Java. */
60 abort();
61 default:
62 result += SIZEOF_ARG;
66 return result;
70 void
71 ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
73 unsigned i;
74 ffi_type **tp = cif->arg_types;
76 #if WORDS_BIGENDIAN
78 for (i = 0; i < cif->nargs; i++, tp++, args++)
80 switch ((*tp)->type)
82 case FFI_TYPE_UINT8:
83 case FFI_TYPE_SINT8:
84 *args = (void*) ((char*)(raw++) + 3);
85 break;
87 case FFI_TYPE_UINT16:
88 case FFI_TYPE_SINT16:
89 *args = (void*) ((char*)(raw++) + 2);
90 break;
92 #if SIZEOF_ARG == 8
93 case FFI_TYPE_UINT64:
94 case FFI_TYPE_SINT64:
95 case FFI_TYPE_DOUBLE:
96 *args = (void *)raw;
97 raw += 2;
98 break;
99 #endif
101 case FFI_TYPE_POINTER:
102 *args = (void*) &(raw++)->ptr;
103 break;
105 default:
106 *args = raw;
107 raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
111 #else /* WORDS_BIGENDIAN */
113 #if !PDP
115 /* then assume little endian */
116 for (i = 0; i < cif->nargs; i++, tp++, args++)
118 #if SIZEOF_ARG == 8
119 switch((*tp)->type) {
120 case FFI_TYPE_UINT64:
121 case FFI_TYPE_SINT64:
122 case FFI_TYPE_DOUBLE:
123 *args = (void*) raw;
124 raw += 2;
125 break;
126 default:
127 *args = (void*) raw++;
129 #else /* SIZEOF_ARG != 8 */
130 *args = (void*) raw;
131 raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*);
132 #endif /* SIZEOF_ARG == 8 */
135 #else
136 #error "pdp endian not supported"
137 #endif /* ! PDP */
139 #endif /* WORDS_BIGENDIAN */
142 void
143 ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
145 unsigned i;
146 ffi_type **tp = cif->arg_types;
148 for (i = 0; i < cif->nargs; i++, tp++, args++)
150 switch ((*tp)->type)
152 case FFI_TYPE_UINT8:
153 #if WORDS_BIGENDIAN
154 *(UINT32*)(raw++) = *(UINT8*) (*args);
155 #else
156 (raw++)->uint = *(UINT8*) (*args);
157 #endif
158 break;
160 case FFI_TYPE_SINT8:
161 #if WORDS_BIGENDIAN
162 *(SINT32*)(raw++) = *(SINT8*) (*args);
163 #else
164 (raw++)->sint = *(SINT8*) (*args);
165 #endif
166 break;
168 case FFI_TYPE_UINT16:
169 #if WORDS_BIGENDIAN
170 *(UINT32*)(raw++) = *(UINT16*) (*args);
171 #else
172 (raw++)->uint = *(UINT16*) (*args);
173 #endif
174 break;
176 case FFI_TYPE_SINT16:
177 #if WORDS_BIGENDIAN
178 *(SINT32*)(raw++) = *(SINT16*) (*args);
179 #else
180 (raw++)->sint = *(SINT16*) (*args);
181 #endif
182 break;
184 case FFI_TYPE_UINT32:
185 #if WORDS_BIGENDIAN
186 *(UINT32*)(raw++) = *(UINT32*) (*args);
187 #else
188 (raw++)->uint = *(UINT32*) (*args);
189 #endif
190 break;
192 case FFI_TYPE_SINT32:
193 #if WORDS_BIGENDIAN
194 *(SINT32*)(raw++) = *(SINT32*) (*args);
195 #else
196 (raw++)->sint = *(SINT32*) (*args);
197 #endif
198 break;
200 case FFI_TYPE_FLOAT:
201 (raw++)->flt = *(FLOAT32*) (*args);
202 break;
204 #if SIZEOF_ARG == 8
205 case FFI_TYPE_UINT64:
206 case FFI_TYPE_SINT64:
207 case FFI_TYPE_DOUBLE:
208 raw->uint = *(UINT64*) (*args);
209 raw += 2;
210 break;
211 #endif
213 case FFI_TYPE_POINTER:
214 (raw++)->ptr = **(void***) args;
215 break;
217 default:
218 #if SIZEOF_ARG == 8
219 FFI_ASSERT(FALSE); /* Should have covered all cases */
220 #else
221 memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
222 raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG;
223 #endif
228 #if !FFI_NATIVE_RAW_API
230 static void
231 ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
233 #if WORDS_BIGENDIAN && SIZEOF_ARG == 8
234 switch (cif->rtype->type)
236 case FFI_TYPE_UINT8:
237 case FFI_TYPE_UINT16:
238 case FFI_TYPE_UINT32:
239 *(UINT64 *)rvalue <<= 32;
240 break;
242 case FFI_TYPE_SINT8:
243 case FFI_TYPE_SINT16:
244 case FFI_TYPE_SINT32:
245 case FFI_TYPE_INT:
246 *(SINT64 *)rvalue <<= 32;
247 break;
249 default:
250 break;
252 #endif
255 static void
256 ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
258 #if WORDS_BIGENDIAN && SIZEOF_ARG == 8
259 switch (cif->rtype->type)
261 case FFI_TYPE_UINT8:
262 case FFI_TYPE_UINT16:
263 case FFI_TYPE_UINT32:
264 *(UINT64 *)rvalue >>= 32;
265 break;
267 case FFI_TYPE_SINT8:
268 case FFI_TYPE_SINT16:
269 case FFI_TYPE_SINT32:
270 case FFI_TYPE_INT:
271 *(SINT64 *)rvalue >>= 32;
272 break;
274 default:
275 break;
277 #endif
280 /* This is a generic definition of ffi_raw_call, to be used if the
281 * native system does not provide a machine-specific implementation.
282 * Having this, allows code to be written for the raw API, without
283 * the need for system-specific code to handle input in that format;
284 * these following couple of functions will handle the translation forth
285 * and back automatically. */
287 void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif,
288 void (*fn)(),
289 /*@out@*/ void *rvalue,
290 /*@dependent@*/ ffi_raw *raw)
292 void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
293 ffi_java_raw_to_ptrarray (cif, raw, avalue);
294 ffi_call (cif, fn, rvalue, avalue);
295 ffi_java_rvalue_to_raw (cif, rvalue);
298 #if FFI_CLOSURES /* base system provides closures */
300 static void
301 ffi_java_translate_args (ffi_cif *cif, void *rvalue,
302 void **avalue, void *user_data)
304 ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif));
305 ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
307 ffi_java_ptrarray_to_raw (cif, avalue, raw);
308 (*cl->fun) (cif, rvalue, raw, cl->user_data);
309 ffi_java_raw_to_rvalue (cif, rvalue);
312 /* Again, here is the generic version of ffi_prep_raw_closure, which
313 * will install an intermediate "hub" for translation of arguments from
314 * the pointer-array format, to the raw format */
316 ffi_status
317 ffi_prep_java_raw_closure (ffi_raw_closure* cl,
318 ffi_cif *cif,
319 void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
320 void *user_data)
322 ffi_status status;
324 status = ffi_prep_closure ((ffi_closure*) cl,
325 cif,
326 &ffi_java_translate_args,
327 (void*)cl);
328 if (status == FFI_OK)
330 cl->fun = fun;
331 cl->user_data = user_data;
334 return status;
337 #endif /* FFI_CLOSURES */
338 #endif /* !FFI_NATIVE_RAW_API */
339 #endif /* !FFI_NO_RAW_API */