1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006 Kaz Kojima
4 SuperH Foreign Function Interface
6 Permission is hereby granted, free of charge, to any person obtaining
7 a copy of this software and associated documentation files (the
8 ``Software''), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sublicense, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice shall be included
15 in all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 OTHER DEALINGS IN THE SOFTWARE.
24 ----------------------------------------------------------------------- */
27 #include <ffi_common.h>
36 #if defined(__HITACHI__)
37 #define STRUCT_VALUE_ADDRESS_WITH_ARG 1
39 #define STRUCT_VALUE_ADDRESS_WITH_ARG 0
42 /* If the structure has essentialy an unique element, return its type. */
44 simple_type (ffi_type *arg)
46 if (arg->type != FFI_TYPE_STRUCT)
48 else if (arg->elements[1])
49 return FFI_TYPE_STRUCT;
51 return simple_type (arg->elements[0]);
55 return_type (ffi_type *arg)
59 if (arg->type != FFI_TYPE_STRUCT)
62 type = simple_type (arg->elements[0]);
63 if (! arg->elements[1])
80 /* gcc uses r0/r1 pair for some kind of structures. */
81 if (arg->size <= 2 * sizeof (int))
86 while ((e = arg->elements[i++]))
88 type = simple_type (e);
95 return FFI_TYPE_UINT64;
103 return FFI_TYPE_STRUCT;
106 /* ffi_prep_args is called by the assembly routine once stack space
107 has been allocated for the function's arguments */
109 void ffi_prep_args(char *stack, extended_cif *ecif)
111 register unsigned int i;
113 register unsigned int avn;
114 register void **p_argv;
116 register ffi_type **p_arg;
125 if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
127 *(void **) argp = ecif->rvalue;
129 ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
134 /* Set arguments for registers. */
136 avn = ecif->cif->nargs;
137 p_argv = ecif->avalue;
139 for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
146 if (greg++ >= NGREGARG)
150 switch ((*p_arg)->type)
153 *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
157 *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
160 case FFI_TYPE_SINT16:
161 *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
164 case FFI_TYPE_UINT16:
165 *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
168 case FFI_TYPE_STRUCT:
169 *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
177 else if (z == sizeof(int))
180 if ((*p_arg)->type == FFI_TYPE_FLOAT)
182 if (freg++ >= NFREGARG)
188 if (greg++ >= NGREGARG)
191 *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
195 else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
197 if (freg + 1 >= NFREGARG)
199 freg = (freg + 1) & ~1;
201 memcpy (argp, *p_argv, z);
207 int n = (z + sizeof (int) - 1) / sizeof (int);
209 if (greg + n - 1 >= NGREGARG)
212 if (greg >= NGREGARG)
216 memcpy (argp, *p_argv, z);
217 argp += n * sizeof (int);
221 /* Set arguments on stack. */
226 p_argv = ecif->avalue;
228 for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
235 if (greg++ < NGREGARG)
239 switch ((*p_arg)->type)
242 *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
246 *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
249 case FFI_TYPE_SINT16:
250 *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
253 case FFI_TYPE_UINT16:
254 *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
257 case FFI_TYPE_STRUCT:
258 *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
266 else if (z == sizeof(int))
269 if ((*p_arg)->type == FFI_TYPE_FLOAT)
271 if (freg++ < NFREGARG)
277 if (greg++ < NGREGARG)
280 *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
284 else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
286 if (freg + 1 < NFREGARG)
288 freg = (freg + 1) & ~1;
292 memcpy (argp, *p_argv, z);
298 int n = (z + sizeof (int) - 1) / sizeof (int);
299 if (greg + n - 1 < NGREGARG)
304 #if (! defined(__SH4__))
305 else if (greg < NGREGARG)
311 memcpy (argp, *p_argv, z);
312 argp += n * sizeof (int);
319 /* Perform machine dependent cif processing */
320 ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
332 greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
333 STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
336 for (i = j = 0; i < cif->nargs && j < 12; i++)
338 type = (cif->arg_types)[i]->type;
342 if (freg >= NFREGARG)
345 cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
349 case FFI_TYPE_DOUBLE:
350 if ((freg + 1) >= NFREGARG)
352 freg = (freg + 1) & ~1;
354 cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
359 size = (cif->arg_types)[i]->size;
360 n = (size + sizeof (int) - 1) / sizeof (int);
361 if (greg + n - 1 >= NGREGARG)
364 for (m = 0; m < n; m++)
365 cif->flags += FFI_TYPE_INT << (2 * j++);
370 for (i = j = 0; i < cif->nargs && j < 4; i++)
372 size = (cif->arg_types)[i]->size;
373 n = (size + sizeof (int) - 1) / sizeof (int);
374 if (greg >= NGREGARG)
376 else if (greg + n - 1 >= NGREGARG)
379 for (m = 0; m < n; m++)
380 cif->flags += FFI_TYPE_INT << (2 * j++);
384 /* Set the return type flag */
385 switch (cif->rtype->type)
387 case FFI_TYPE_STRUCT:
388 cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
393 case FFI_TYPE_DOUBLE:
394 case FFI_TYPE_SINT64:
395 case FFI_TYPE_UINT64:
396 cif->flags += (unsigned) cif->rtype->type << 24;
400 cif->flags += FFI_TYPE_INT << 24;
407 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
408 unsigned, unsigned, unsigned *, void (*fn)());
410 void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
416 ecif.avalue = avalue;
418 /* If the return value is a struct and we don't have a return */
419 /* value address then we need to make one */
421 if (cif->rtype->type == FFI_TYPE_STRUCT
422 && return_type (cif->rtype) != FFI_TYPE_STRUCT)
423 ecif.rvalue = &trvalue;
424 else if ((rvalue == NULL) &&
425 (cif->rtype->type == FFI_TYPE_STRUCT))
427 ecif.rvalue = alloca(cif->rtype->size);
430 ecif.rvalue = rvalue;
435 ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
444 && cif->rtype->type == FFI_TYPE_STRUCT
445 && return_type (cif->rtype) != FFI_TYPE_STRUCT)
446 memcpy (rvalue, &trvalue, cif->rtype->size);
449 extern void ffi_closure_SYSV (void);
451 extern void __ic_invalidate (void *line);
455 ffi_prep_closure (ffi_closure* closure,
457 void (*fun)(ffi_cif*, void*, void**, void*),
463 FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
465 tramp = (unsigned int *) &closure->tramp[0];
466 /* Set T bit if the function returns a struct pointed with R2. */
467 insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
469 : 0x0008 /* clrt */);
471 #ifdef __LITTLE_ENDIAN__
472 tramp[0] = 0xd301d102;
473 tramp[1] = 0x0000412b | (insn << 16);
475 tramp[0] = 0xd102d301;
476 tramp[1] = 0x412b0000 | insn;
478 *(void **) &tramp[2] = (void *)closure; /* ctx */
479 *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
483 closure->user_data = user_data;
486 /* Flush the icache. */
487 __ic_invalidate(&closure->tramp[0]);
493 /* Basically the trampoline invokes ffi_closure_SYSV, and on
494 * entry, r3 holds the address of the closure.
495 * After storing the registers that could possibly contain
496 * parameters to be passed into the stack frame and setting
497 * up space for a return value, ffi_closure_SYSV invokes the
498 * following helper function to do most of the work.
501 #ifdef __LITTLE_ENDIAN__
510 ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
511 unsigned long *pgr, unsigned long *pfr,
524 avalue = alloca(cif->nargs * sizeof(void *));
526 /* Copy the caller's structure return value address so that the closure
527 returns the data directly to the caller. */
528 if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
530 rvalue = (void *) *pgr++;
540 /* Grab the addresses of the arguments from the stack frame. */
541 for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
548 if (greg++ >= NGREGARG)
552 switch ((*p_arg)->type)
556 avalue[i] = (((char *)pgr) + OFS_INT8);
559 case FFI_TYPE_SINT16:
560 case FFI_TYPE_UINT16:
561 avalue[i] = (((char *)pgr) + OFS_INT16);
564 case FFI_TYPE_STRUCT:
573 else if (z == sizeof(int))
576 if ((*p_arg)->type == FFI_TYPE_FLOAT)
578 if (freg++ >= NFREGARG)
586 if (greg++ >= NGREGARG)
593 else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
595 if (freg + 1 >= NFREGARG)
599 freg = (freg + 1) & ~1;
607 int n = (z + sizeof (int) - 1) / sizeof (int);
609 if (greg + n - 1 >= NGREGARG)
612 if (greg >= NGREGARG)
626 for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
633 if (greg++ < NGREGARG)
637 switch ((*p_arg)->type)
641 avalue[i] = (((char *)pst) + OFS_INT8);
644 case FFI_TYPE_SINT16:
645 case FFI_TYPE_UINT16:
646 avalue[i] = (((char *)pst) + OFS_INT16);
649 case FFI_TYPE_STRUCT:
658 else if (z == sizeof(int))
661 if ((*p_arg)->type == FFI_TYPE_FLOAT)
663 if (freg++ < NFREGARG)
669 if (greg++ < NGREGARG)
676 else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
678 if (freg + 1 < NFREGARG)
680 freg = (freg + 1) & ~1;
690 int n = (z + sizeof (int) - 1) / sizeof (int);
691 if (greg + n - 1 < NGREGARG)
696 #if (! defined(__SH4__))
697 else if (greg < NGREGARG)
700 pst += greg - NGREGARG;
709 (closure->fun) (cif, rvalue, avalue, closure->user_data);
711 /* Tell ffi_closure_SYSV how to perform return type promotions. */
712 return return_type (cif->rtype);