1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2002, 2003, 2004 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 */
110 void ffi_prep_args(char *stack
, extended_cif
*ecif
)
113 register unsigned int i
;
115 register unsigned int avn
;
116 register void **p_argv
;
118 register ffi_type
**p_arg
;
127 if (return_type (ecif
->cif
->rtype
) == FFI_TYPE_STRUCT
)
129 *(void **) argp
= ecif
->rvalue
;
131 ireg
= STRUCT_VALUE_ADDRESS_WITH_ARG
? 1 : 0;
136 /* Set arguments for registers. */
138 avn
= ecif
->cif
->nargs
;
139 p_argv
= ecif
->avalue
;
141 for (i
= 0, p_arg
= ecif
->cif
->arg_types
; i
< avn
; i
++, p_arg
++, p_argv
++)
148 if (greg
++ >= NGREGARG
)
152 switch ((*p_arg
)->type
)
155 *(signed int *) argp
= (signed int)*(SINT8
*)(* p_argv
);
159 *(unsigned int *) argp
= (unsigned int)*(UINT8
*)(* p_argv
);
162 case FFI_TYPE_SINT16
:
163 *(signed int *) argp
= (signed int)*(SINT16
*)(* p_argv
);
166 case FFI_TYPE_UINT16
:
167 *(unsigned int *) argp
= (unsigned int)*(UINT16
*)(* p_argv
);
170 case FFI_TYPE_STRUCT
:
171 *(unsigned int *) argp
= (unsigned int)*(UINT32
*)(* p_argv
);
179 else if (z
== sizeof(int))
182 if ((*p_arg
)->type
== FFI_TYPE_FLOAT
)
184 if (freg
++ >= NFREGARG
)
190 if (greg
++ >= NGREGARG
)
193 *(unsigned int *) argp
= (unsigned int)*(UINT32
*)(* p_argv
);
197 else if ((*p_arg
)->type
== FFI_TYPE_DOUBLE
)
199 if (freg
+ 1 >= NFREGARG
)
201 freg
= (freg
+ 1) & ~1;
203 memcpy (argp
, *p_argv
, z
);
209 int n
= (z
+ sizeof (int) - 1) / sizeof (int);
211 if (greg
+ n
- 1 >= NGREGARG
)
215 if (greg
>= NGREGARG
)
217 else if (greg
+ n
- 1 >= NGREGARG
)
222 memcpy (argp
, *p_argv
, z
);
223 argp
+= n
* sizeof (int);
227 /* Set arguments on stack. */
232 p_argv
= ecif
->avalue
;
234 for (i
= 0, p_arg
= ecif
->cif
->arg_types
; i
< avn
; i
++, p_arg
++, p_argv
++)
241 if (greg
++ < NGREGARG
)
245 switch ((*p_arg
)->type
)
248 *(signed int *) argp
= (signed int)*(SINT8
*)(* p_argv
);
252 *(unsigned int *) argp
= (unsigned int)*(UINT8
*)(* p_argv
);
255 case FFI_TYPE_SINT16
:
256 *(signed int *) argp
= (signed int)*(SINT16
*)(* p_argv
);
259 case FFI_TYPE_UINT16
:
260 *(unsigned int *) argp
= (unsigned int)*(UINT16
*)(* p_argv
);
263 case FFI_TYPE_STRUCT
:
264 *(unsigned int *) argp
= (unsigned int)*(UINT32
*)(* p_argv
);
272 else if (z
== sizeof(int))
275 if ((*p_arg
)->type
== FFI_TYPE_FLOAT
)
277 if (freg
++ < NFREGARG
)
283 if (greg
++ < NGREGARG
)
286 *(unsigned int *) argp
= (unsigned int)*(UINT32
*)(* p_argv
);
290 else if ((*p_arg
)->type
== FFI_TYPE_DOUBLE
)
292 if (freg
+ 1 < NFREGARG
)
294 freg
= (freg
+ 1) & ~1;
298 memcpy (argp
, *p_argv
, z
);
304 int n
= (z
+ sizeof (int) - 1) / sizeof (int);
305 if (greg
+ n
- 1 < NGREGARG
)
310 #if (! defined(__SH4__))
311 else if (greg
< NGREGARG
)
317 memcpy (argp
, *p_argv
, z
);
318 argp
+= n
* sizeof (int);
325 /* Perform machine dependent cif processing */
326 ffi_status
ffi_prep_cif_machdep(ffi_cif
*cif
)
338 greg
= ((return_type (cif
->rtype
) == FFI_TYPE_STRUCT
) &&
339 STRUCT_VALUE_ADDRESS_WITH_ARG
) ? 1 : 0;
342 for (i
= j
= 0; i
< cif
->nargs
&& j
< 12; i
++)
344 type
= (cif
->arg_types
)[i
]->type
;
348 if (freg
>= NFREGARG
)
351 cif
->flags
+= ((cif
->arg_types
)[i
]->type
) << (2 * j
);
355 case FFI_TYPE_DOUBLE
:
356 if ((freg
+ 1) >= NFREGARG
)
358 freg
= (freg
+ 1) & ~1;
360 cif
->flags
+= ((cif
->arg_types
)[i
]->type
) << (2 * j
);
365 size
= (cif
->arg_types
)[i
]->size
;
366 n
= (size
+ sizeof (int) - 1) / sizeof (int);
367 if (greg
+ n
- 1 >= NGREGARG
)
370 for (m
= 0; m
< n
; m
++)
371 cif
->flags
+= FFI_TYPE_INT
<< (2 * j
++);
376 for (i
= j
= 0; i
< cif
->nargs
&& j
< 4; i
++)
378 size
= (cif
->arg_types
)[i
]->size
;
379 n
= (size
+ sizeof (int) - 1) / sizeof (int);
380 if (greg
>= NGREGARG
)
382 else if (greg
+ n
- 1 >= NGREGARG
)
386 for (m
= 0; m
< n
; m
++)
387 cif
->flags
+= FFI_TYPE_INT
<< (2 * j
++);
391 /* Set the return type flag */
392 switch (cif
->rtype
->type
)
394 case FFI_TYPE_STRUCT
:
395 cif
->flags
+= (unsigned) (return_type (cif
->rtype
)) << 24;
400 case FFI_TYPE_DOUBLE
:
401 case FFI_TYPE_SINT64
:
402 case FFI_TYPE_UINT64
:
403 cif
->flags
+= (unsigned) cif
->rtype
->type
<< 24;
407 cif
->flags
+= FFI_TYPE_INT
<< 24;
416 extern void ffi_call_SYSV(void (*)(char *, extended_cif
*),
417 /*@out@*/ extended_cif
*,
419 /*@out@*/ unsigned *,
424 void ffi_call(/*@dependent@*/ ffi_cif
*cif
,
426 /*@out@*/ void *rvalue
,
427 /*@dependent@*/ void **avalue
)
432 ecif
.avalue
= avalue
;
434 /* If the return value is a struct and we don't have a return */
435 /* value address then we need to make one */
437 if ((rvalue
== NULL
) &&
438 (cif
->rtype
->type
== FFI_TYPE_STRUCT
))
441 ecif
.rvalue
= alloca(cif
->rtype
->size
);
445 ecif
.rvalue
= rvalue
;
452 ffi_call_SYSV(ffi_prep_args
, &ecif
, cif
->bytes
,
453 cif
->flags
, ecif
.rvalue
, fn
);
462 extern void ffi_closure_SYSV (void);
464 extern void __ic_invalidate (void *line
);
468 ffi_prep_closure (ffi_closure
* closure
,
470 void (*fun
)(ffi_cif
*, void*, void**, void*),
476 FFI_ASSERT (cif
->abi
== FFI_GCC_SYSV
);
478 tramp
= (unsigned int *) &closure
->tramp
[0];
479 /* Set T bit if the function returns a struct pointed with R2. */
480 insn
= (return_type (cif
->rtype
) == FFI_TYPE_STRUCT
482 : 0x0008 /* clrt */);
484 #ifdef __LITTLE_ENDIAN__
485 tramp
[0] = 0xd301d102;
486 tramp
[1] = 0x0000412b | (insn
<< 16);
488 tramp
[0] = 0xd102d301;
489 tramp
[1] = 0x412b0000 | insn
;
491 *(void **) &tramp
[2] = (void *)closure
; /* ctx */
492 *(void **) &tramp
[3] = (void *)ffi_closure_SYSV
; /* funaddr */
496 closure
->user_data
= user_data
;
499 /* Flush the icache. */
500 __ic_invalidate(&closure
->tramp
[0]);
506 /* Basically the trampoline invokes ffi_closure_SYSV, and on
507 * entry, r3 holds the address of the closure.
508 * After storing the registers that could possibly contain
509 * parameters to be passed into the stack frame and setting
510 * up space for a return value, ffi_closure_SYSV invokes the
511 * following helper function to do most of the work.
514 #ifdef __LITTLE_ENDIAN__
523 ffi_closure_helper_SYSV (ffi_closure
*closure
, void *rvalue
,
524 unsigned long *pgr
, unsigned long *pfr
,
538 avalue
= alloca(cif
->nargs
* sizeof(void *));
540 /* Copy the caller's structure return value address so that the closure
541 returns the data directly to the caller. */
542 if (cif
->rtype
->type
== FFI_TYPE_STRUCT
&& STRUCT_VALUE_ADDRESS_WITH_ARG
)
554 /* Grab the addresses of the arguments from the stack frame. */
555 for (i
= 0, p_arg
= cif
->arg_types
; i
< avn
; i
++, p_arg
++)
562 if (greg
++ >= NGREGARG
)
566 switch ((*p_arg
)->type
)
570 avalue
[i
] = (((char *)pgr
) + OFS_INT8
);
573 case FFI_TYPE_SINT16
:
574 case FFI_TYPE_UINT16
:
575 avalue
[i
] = (((char *)pgr
) + OFS_INT16
);
578 case FFI_TYPE_STRUCT
:
587 else if (z
== sizeof(int))
590 if ((*p_arg
)->type
== FFI_TYPE_FLOAT
)
592 if (freg
++ >= NFREGARG
)
600 if (greg
++ >= NGREGARG
)
607 else if ((*p_arg
)->type
== FFI_TYPE_DOUBLE
)
609 if (freg
+ 1 >= NFREGARG
)
611 freg
= (freg
+ 1) & ~1;
619 int n
= (z
+ sizeof (int) - 1) / sizeof (int);
621 if (greg
+ n
- 1 >= NGREGARG
)
625 if (greg
>= NGREGARG
)
627 else if (greg
+ n
- 1 >= NGREGARG
)
642 for (i
= 0, p_arg
= cif
->arg_types
; i
< avn
; i
++, p_arg
++)
649 if (greg
++ < NGREGARG
)
653 switch ((*p_arg
)->type
)
657 avalue
[i
] = (((char *)pst
) + OFS_INT8
);
660 case FFI_TYPE_SINT16
:
661 case FFI_TYPE_UINT16
:
662 avalue
[i
] = (((char *)pst
) + OFS_INT16
);
665 case FFI_TYPE_STRUCT
:
674 else if (z
== sizeof(int))
677 if ((*p_arg
)->type
== FFI_TYPE_FLOAT
)
679 if (freg
++ < NFREGARG
)
685 if (greg
++ < NGREGARG
)
692 else if ((*p_arg
)->type
== FFI_TYPE_DOUBLE
)
694 if (freg
+ 1 < NFREGARG
)
696 freg
= (freg
+ 1) & ~1;
706 int n
= (z
+ sizeof (int) - 1) / sizeof (int);
707 if (greg
+ n
- 1 < NGREGARG
)
712 #if (! defined(__SH4__))
713 else if (greg
< NGREGARG
)
724 (closure
->fun
) (cif
, rvalue
, avalue
, closure
->user_data
);
726 /* Tell ffi_closure_SYSV how to perform return type promotions. */
727 return return_type (cif
->rtype
);