1
/* -----------------------------------------------------------------------
2
ffi.c - Copyright (c) 2002, 2003, 2004, 2005 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)
214
if (greg >= NGREGARG)
218
memcpy (argp, *p_argv, z);
219
argp += n * sizeof (int);
223
/* Set arguments on stack. */
228
p_argv = ecif->avalue;
230
for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
237
if (greg++ < NGREGARG)
241
switch ((*p_arg)->type)
244
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
248
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
251
case FFI_TYPE_SINT16:
252
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
255
case FFI_TYPE_UINT16:
256
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
259
case FFI_TYPE_STRUCT:
260
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
268
else if (z == sizeof(int))
271
if ((*p_arg)->type == FFI_TYPE_FLOAT)
273
if (freg++ < NFREGARG)
279
if (greg++ < NGREGARG)
282
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
286
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
288
if (freg + 1 < NFREGARG)
290
freg = (freg + 1) & ~1;
294
memcpy (argp, *p_argv, z);
300
int n = (z + sizeof (int) - 1) / sizeof (int);
301
if (greg + n - 1 < NGREGARG)
306
#if (! defined(__SH4__))
307
else if (greg < NGREGARG)
313
memcpy (argp, *p_argv, z);
314
argp += n * sizeof (int);
321
/* Perform machine dependent cif processing */
322
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
334
greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
335
STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
338
for (i = j = 0; i < cif->nargs && j < 12; i++)
340
type = (cif->arg_types)[i]->type;
344
if (freg >= NFREGARG)
347
cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
351
case FFI_TYPE_DOUBLE:
352
if ((freg + 1) >= NFREGARG)
354
freg = (freg + 1) & ~1;
356
cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
361
size = (cif->arg_types)[i]->size;
362
n = (size + sizeof (int) - 1) / sizeof (int);
363
if (greg + n - 1 >= NGREGARG)
366
for (m = 0; m < n; m++)
367
cif->flags += FFI_TYPE_INT << (2 * j++);
372
for (i = j = 0; i < cif->nargs && j < 4; i++)
374
size = (cif->arg_types)[i]->size;
375
n = (size + sizeof (int) - 1) / sizeof (int);
376
if (greg >= NGREGARG)
378
else if (greg + n - 1 >= NGREGARG)
381
for (m = 0; m < n; m++)
382
cif->flags += FFI_TYPE_INT << (2 * j++);
386
/* Set the return type flag */
387
switch (cif->rtype->type)
389
case FFI_TYPE_STRUCT:
390
cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
395
case FFI_TYPE_DOUBLE:
396
case FFI_TYPE_SINT64:
397
case FFI_TYPE_UINT64:
398
cif->flags += (unsigned) cif->rtype->type << 24;
402
cif->flags += FFI_TYPE_INT << 24;
411
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
412
/*@out@*/ extended_cif *,
414
/*@out@*/ unsigned *,
419
void ffi_call(/*@dependent@*/ ffi_cif *cif,
421
/*@out@*/ void *rvalue,
422
/*@dependent@*/ void **avalue)
428
ecif.avalue = avalue;
430
/* If the return value is a struct and we don't have a return */
431
/* value address then we need to make one */
433
if (cif->rtype->type == FFI_TYPE_STRUCT
434
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
435
ecif.rvalue = &trvalue;
436
else if ((rvalue == NULL) &&
437
(cif->rtype->type == FFI_TYPE_STRUCT))
440
ecif.rvalue = alloca(cif->rtype->size);
444
ecif.rvalue = rvalue;
450
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
451
cif->flags, ecif.rvalue, fn);
460
&& cif->rtype->type == FFI_TYPE_STRUCT
461
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
462
memcpy (rvalue, &trvalue, cif->rtype->size);
465
extern void ffi_closure_SYSV (void);
467
extern void __ic_invalidate (void *line);
471
ffi_prep_closure (ffi_closure* closure,
473
void (*fun)(ffi_cif*, void*, void**, void*),
479
FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
481
tramp = (unsigned int *) &closure->tramp[0];
482
/* Set T bit if the function returns a struct pointed with R2. */
483
insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
485
: 0x0008 /* clrt */);
487
#ifdef __LITTLE_ENDIAN__
488
tramp[0] = 0xd301d102;
489
tramp[1] = 0x0000412b | (insn << 16);
491
tramp[0] = 0xd102d301;
492
tramp[1] = 0x412b0000 | insn;
494
*(void **) &tramp[2] = (void *)closure; /* ctx */
495
*(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
499
closure->user_data = user_data;
502
/* Flush the icache. */
503
__ic_invalidate(&closure->tramp[0]);
509
/* Basically the trampoline invokes ffi_closure_SYSV, and on
510
* entry, r3 holds the address of the closure.
511
* After storing the registers that could possibly contain
512
* parameters to be passed into the stack frame and setting
513
* up space for a return value, ffi_closure_SYSV invokes the
514
* following helper function to do most of the work.
517
#ifdef __LITTLE_ENDIAN__
526
ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
527
unsigned long *pgr, unsigned long *pfr,
541
avalue = alloca(cif->nargs * sizeof(void *));
543
/* Copy the caller's structure return value address so that the closure
544
returns the data directly to the caller. */
545
if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
557
/* Grab the addresses of the arguments from the stack frame. */
558
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
565
if (greg++ >= NGREGARG)
569
switch ((*p_arg)->type)
573
avalue[i] = (((char *)pgr) + OFS_INT8);
576
case FFI_TYPE_SINT16:
577
case FFI_TYPE_UINT16:
578
avalue[i] = (((char *)pgr) + OFS_INT16);
581
case FFI_TYPE_STRUCT:
590
else if (z == sizeof(int))
593
if ((*p_arg)->type == FFI_TYPE_FLOAT)
595
if (freg++ >= NFREGARG)
603
if (greg++ >= NGREGARG)
610
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
612
if (freg + 1 >= NFREGARG)
614
freg = (freg + 1) & ~1;
622
int n = (z + sizeof (int) - 1) / sizeof (int);
624
if (greg + n - 1 >= NGREGARG)
627
if (greg >= NGREGARG)
641
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
648
if (greg++ < NGREGARG)
652
switch ((*p_arg)->type)
656
avalue[i] = (((char *)pst) + OFS_INT8);
659
case FFI_TYPE_SINT16:
660
case FFI_TYPE_UINT16:
661
avalue[i] = (((char *)pst) + OFS_INT16);
664
case FFI_TYPE_STRUCT:
673
else if (z == sizeof(int))
676
if ((*p_arg)->type == FFI_TYPE_FLOAT)
678
if (freg++ < NFREGARG)
684
if (greg++ < NGREGARG)
691
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
693
if (freg + 1 < NFREGARG)
695
freg = (freg + 1) & ~1;
705
int n = (z + sizeof (int) - 1) / sizeof (int);
706
if (greg + n - 1 < NGREGARG)
711
#if (! defined(__SH4__))
712
else if (greg < NGREGARG)
715
pst += 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);