Rebase
This commit is contained in:
@@ -1,130 +0,0 @@
|
||||
10
|
||||
|
||||
dir
|
||||
161959
|
||||
svn://gcc.gnu.org/svn/gcc/trunk/libffi/src/sh
|
||||
svn://gcc.gnu.org/svn/gcc
|
||||
|
||||
|
||||
|
||||
2009-06-04T15:43:03.499507Z
|
||||
148172
|
||||
aph
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
138bc75d-0d04-0410-961f-82ee72b054a4
|
||||
|
||||
ffitarget.h
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-06-10T05:25:03.000000Z
|
||||
29f9e59db3e60996e10aa894d106e08a
|
||||
2009-06-04T15:11:12.475454Z
|
||||
148171
|
||||
aph
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1797
|
||||
|
||||
ffi.c
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-06-10T05:25:03.000000Z
|
||||
2d1bfc8959e6b3ba92e32cbad5ea94b6
|
||||
2009-06-04T15:43:03.499507Z
|
||||
148172
|
||||
aph
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
15253
|
||||
|
||||
sysv.S
|
||||
file
|
||||
|
||||
|
||||
|
||||
|
||||
2009-06-10T05:25:03.000000Z
|
||||
7e0990b03e6cff0ed4b1c69ca758a1fe
|
||||
2009-06-04T15:11:12.475454Z
|
||||
148171
|
||||
aph
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
14687
|
||||
|
||||
@@ -1,716 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Kaz Kojima
|
||||
Copyright (c) 2008 Red Hat, Inc.
|
||||
|
||||
SuperH Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NGREGARG 4
|
||||
#if defined(__SH4__)
|
||||
#define NFREGARG 8
|
||||
#endif
|
||||
|
||||
#if defined(__HITACHI__)
|
||||
#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
|
||||
#else
|
||||
#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
|
||||
#endif
|
||||
|
||||
/* If the structure has essentialy an unique element, return its type. */
|
||||
static int
|
||||
simple_type (ffi_type *arg)
|
||||
{
|
||||
if (arg->type != FFI_TYPE_STRUCT)
|
||||
return arg->type;
|
||||
else if (arg->elements[1])
|
||||
return FFI_TYPE_STRUCT;
|
||||
|
||||
return simple_type (arg->elements[0]);
|
||||
}
|
||||
|
||||
static int
|
||||
return_type (ffi_type *arg)
|
||||
{
|
||||
unsigned short type;
|
||||
|
||||
if (arg->type != FFI_TYPE_STRUCT)
|
||||
return arg->type;
|
||||
|
||||
type = simple_type (arg->elements[0]);
|
||||
if (! arg->elements[1])
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
return FFI_TYPE_INT;
|
||||
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
/* gcc uses r0/r1 pair for some kind of structures. */
|
||||
if (arg->size <= 2 * sizeof (int))
|
||||
{
|
||||
int i = 0;
|
||||
ffi_type *e;
|
||||
|
||||
while ((e = arg->elements[i++]))
|
||||
{
|
||||
type = simple_type (e);
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_INT:
|
||||
case FFI_TYPE_FLOAT:
|
||||
return FFI_TYPE_UINT64;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FFI_TYPE_STRUCT;
|
||||
}
|
||||
|
||||
/* ffi_prep_args is called by the assembly routine once stack space
|
||||
has been allocated for the function's arguments */
|
||||
|
||||
void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
{
|
||||
register unsigned int i;
|
||||
register int tmp;
|
||||
register unsigned int avn;
|
||||
register void **p_argv;
|
||||
register char *argp;
|
||||
register ffi_type **p_arg;
|
||||
int greg, ireg;
|
||||
#if defined(__SH4__)
|
||||
int freg = 0;
|
||||
#endif
|
||||
|
||||
tmp = 0;
|
||||
argp = stack;
|
||||
|
||||
if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
|
||||
{
|
||||
*(void **) argp = ecif->rvalue;
|
||||
argp += 4;
|
||||
ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
|
||||
}
|
||||
else
|
||||
ireg = 0;
|
||||
|
||||
/* Set arguments for registers. */
|
||||
greg = ireg;
|
||||
avn = ecif->cif->nargs;
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof(int))
|
||||
{
|
||||
if (greg++ >= NGREGARG)
|
||||
continue;
|
||||
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
argp += z;
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
#if defined(__SH4__)
|
||||
if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
{
|
||||
if (freg++ >= NFREGARG)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (greg++ >= NGREGARG)
|
||||
continue;
|
||||
}
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
argp += z;
|
||||
}
|
||||
#if defined(__SH4__)
|
||||
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
||||
{
|
||||
if (freg + 1 >= NFREGARG)
|
||||
continue;
|
||||
freg = (freg + 1) & ~1;
|
||||
freg += 2;
|
||||
memcpy (argp, *p_argv, z);
|
||||
argp += z;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
int n = (z + sizeof (int) - 1) / sizeof (int);
|
||||
#if defined(__SH4__)
|
||||
if (greg + n - 1 >= NGREGARG)
|
||||
continue;
|
||||
#else
|
||||
if (greg >= NGREGARG)
|
||||
continue;
|
||||
#endif
|
||||
greg += n;
|
||||
memcpy (argp, *p_argv, z);
|
||||
argp += n * sizeof (int);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set arguments on stack. */
|
||||
greg = ireg;
|
||||
#if defined(__SH4__)
|
||||
freg = 0;
|
||||
#endif
|
||||
p_argv = ecif->avalue;
|
||||
|
||||
for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof(int))
|
||||
{
|
||||
if (greg++ < NGREGARG)
|
||||
continue;
|
||||
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
*(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT8:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
*(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_UINT16:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
argp += z;
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
#if defined(__SH4__)
|
||||
if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
{
|
||||
if (freg++ < NFREGARG)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (greg++ < NGREGARG)
|
||||
continue;
|
||||
}
|
||||
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
|
||||
argp += z;
|
||||
}
|
||||
#if defined(__SH4__)
|
||||
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
||||
{
|
||||
if (freg + 1 < NFREGARG)
|
||||
{
|
||||
freg = (freg + 1) & ~1;
|
||||
freg += 2;
|
||||
continue;
|
||||
}
|
||||
memcpy (argp, *p_argv, z);
|
||||
argp += z;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
int n = (z + sizeof (int) - 1) / sizeof (int);
|
||||
if (greg + n - 1 < NGREGARG)
|
||||
{
|
||||
greg += n;
|
||||
continue;
|
||||
}
|
||||
#if (! defined(__SH4__))
|
||||
else if (greg < NGREGARG)
|
||||
{
|
||||
greg = NGREGARG;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
memcpy (argp, *p_argv, z);
|
||||
argp += n * sizeof (int);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
|
||||
{
|
||||
int i, j;
|
||||
int size, type;
|
||||
int n, m;
|
||||
int greg;
|
||||
#if defined(__SH4__)
|
||||
int freg = 0;
|
||||
#endif
|
||||
|
||||
cif->flags = 0;
|
||||
|
||||
greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
|
||||
STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
|
||||
|
||||
#if defined(__SH4__)
|
||||
for (i = j = 0; i < cif->nargs && j < 12; i++)
|
||||
{
|
||||
type = (cif->arg_types)[i]->type;
|
||||
switch (type)
|
||||
{
|
||||
case FFI_TYPE_FLOAT:
|
||||
if (freg >= NFREGARG)
|
||||
continue;
|
||||
freg++;
|
||||
cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
|
||||
j++;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_DOUBLE:
|
||||
if ((freg + 1) >= NFREGARG)
|
||||
continue;
|
||||
freg = (freg + 1) & ~1;
|
||||
freg += 2;
|
||||
cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
|
||||
j++;
|
||||
break;
|
||||
|
||||
default:
|
||||
size = (cif->arg_types)[i]->size;
|
||||
n = (size + sizeof (int) - 1) / sizeof (int);
|
||||
if (greg + n - 1 >= NGREGARG)
|
||||
continue;
|
||||
greg += n;
|
||||
for (m = 0; m < n; m++)
|
||||
cif->flags += FFI_TYPE_INT << (2 * j++);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (i = j = 0; i < cif->nargs && j < 4; i++)
|
||||
{
|
||||
size = (cif->arg_types)[i]->size;
|
||||
n = (size + sizeof (int) - 1) / sizeof (int);
|
||||
if (greg >= NGREGARG)
|
||||
continue;
|
||||
else if (greg + n - 1 >= NGREGARG)
|
||||
n = NGREGARG - greg;
|
||||
greg += n;
|
||||
for (m = 0; m < n; m++)
|
||||
cif->flags += FFI_TYPE_INT << (2 * j++);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set the return type flag */
|
||||
switch (cif->rtype->type)
|
||||
{
|
||||
case FFI_TYPE_STRUCT:
|
||||
cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
|
||||
break;
|
||||
|
||||
case FFI_TYPE_VOID:
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
cif->flags += (unsigned) cif->rtype->type << 24;
|
||||
break;
|
||||
|
||||
default:
|
||||
cif->flags += FFI_TYPE_INT << 24;
|
||||
break;
|
||||
}
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
|
||||
unsigned, unsigned, unsigned *, void (*fn)(void));
|
||||
|
||||
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
|
||||
{
|
||||
extended_cif ecif;
|
||||
UINT64 trvalue;
|
||||
|
||||
ecif.cif = cif;
|
||||
ecif.avalue = avalue;
|
||||
|
||||
/* If the return value is a struct and we don't have a return */
|
||||
/* value address then we need to make one */
|
||||
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
|
||||
ecif.rvalue = &trvalue;
|
||||
else if ((rvalue == NULL) &&
|
||||
(cif->rtype->type == FFI_TYPE_STRUCT))
|
||||
{
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
|
||||
fn);
|
||||
break;
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rvalue
|
||||
&& cif->rtype->type == FFI_TYPE_STRUCT
|
||||
&& return_type (cif->rtype) != FFI_TYPE_STRUCT)
|
||||
memcpy (rvalue, &trvalue, cif->rtype->size);
|
||||
}
|
||||
|
||||
extern void ffi_closure_SYSV (void);
|
||||
#if defined(__SH4__)
|
||||
extern void __ic_invalidate (void *line);
|
||||
#endif
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure_loc (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data,
|
||||
void *codeloc)
|
||||
{
|
||||
unsigned int *tramp;
|
||||
unsigned int insn;
|
||||
|
||||
FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
|
||||
|
||||
tramp = (unsigned int *) &closure->tramp[0];
|
||||
/* Set T bit if the function returns a struct pointed with R2. */
|
||||
insn = (return_type (cif->rtype) == FFI_TYPE_STRUCT
|
||||
? 0x0018 /* sett */
|
||||
: 0x0008 /* clrt */);
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
tramp[0] = 0xd301d102;
|
||||
tramp[1] = 0x0000412b | (insn << 16);
|
||||
#else
|
||||
tramp[0] = 0xd102d301;
|
||||
tramp[1] = 0x412b0000 | insn;
|
||||
#endif
|
||||
*(void **) &tramp[2] = (void *)codeloc; /* ctx */
|
||||
*(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
|
||||
|
||||
closure->cif = cif;
|
||||
closure->fun = fun;
|
||||
closure->user_data = user_data;
|
||||
|
||||
#if defined(__SH4__)
|
||||
/* Flush the icache. */
|
||||
__ic_invalidate(codeloc);
|
||||
#endif
|
||||
|
||||
return FFI_OK;
|
||||
}
|
||||
|
||||
/* Basically the trampoline invokes ffi_closure_SYSV, and on
|
||||
* entry, r3 holds the address of the closure.
|
||||
* After storing the registers that could possibly contain
|
||||
* parameters to be passed into the stack frame and setting
|
||||
* up space for a return value, ffi_closure_SYSV invokes the
|
||||
* following helper function to do most of the work.
|
||||
*/
|
||||
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#define OFS_INT8 0
|
||||
#define OFS_INT16 0
|
||||
#else
|
||||
#define OFS_INT8 3
|
||||
#define OFS_INT16 2
|
||||
#endif
|
||||
|
||||
int
|
||||
ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
|
||||
unsigned long *pgr, unsigned long *pfr,
|
||||
unsigned long *pst)
|
||||
{
|
||||
void **avalue;
|
||||
ffi_type **p_arg;
|
||||
int i, avn;
|
||||
int ireg, greg = 0;
|
||||
#if defined(__SH4__)
|
||||
int freg = 0;
|
||||
#endif
|
||||
ffi_cif *cif;
|
||||
|
||||
cif = closure->cif;
|
||||
avalue = alloca(cif->nargs * sizeof(void *));
|
||||
|
||||
/* Copy the caller's structure return value address so that the closure
|
||||
returns the data directly to the caller. */
|
||||
if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
|
||||
{
|
||||
rvalue = (void *) *pgr++;
|
||||
ireg = 1;
|
||||
}
|
||||
else
|
||||
ireg = 0;
|
||||
|
||||
cif = closure->cif;
|
||||
greg = ireg;
|
||||
avn = cif->nargs;
|
||||
|
||||
/* Grab the addresses of the arguments from the stack frame. */
|
||||
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof(int))
|
||||
{
|
||||
if (greg++ >= NGREGARG)
|
||||
continue;
|
||||
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
avalue[i] = (((char *)pgr) + OFS_INT8);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
avalue[i] = (((char *)pgr) + OFS_INT16);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
avalue[i] = pgr;
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
pgr++;
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
#if defined(__SH4__)
|
||||
if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
{
|
||||
if (freg++ >= NFREGARG)
|
||||
continue;
|
||||
avalue[i] = pfr;
|
||||
pfr++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (greg++ >= NGREGARG)
|
||||
continue;
|
||||
avalue[i] = pgr;
|
||||
pgr++;
|
||||
}
|
||||
}
|
||||
#if defined(__SH4__)
|
||||
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
||||
{
|
||||
if (freg + 1 >= NFREGARG)
|
||||
continue;
|
||||
if (freg & 1)
|
||||
pfr++;
|
||||
freg = (freg + 1) & ~1;
|
||||
freg += 2;
|
||||
avalue[i] = pfr;
|
||||
pfr += 2;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
int n = (z + sizeof (int) - 1) / sizeof (int);
|
||||
#if defined(__SH4__)
|
||||
if (greg + n - 1 >= NGREGARG)
|
||||
continue;
|
||||
#else
|
||||
if (greg >= NGREGARG)
|
||||
continue;
|
||||
#endif
|
||||
greg += n;
|
||||
avalue[i] = pgr;
|
||||
pgr += n;
|
||||
}
|
||||
}
|
||||
|
||||
greg = ireg;
|
||||
#if defined(__SH4__)
|
||||
freg = 0;
|
||||
#endif
|
||||
|
||||
for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
|
||||
{
|
||||
size_t z;
|
||||
|
||||
z = (*p_arg)->size;
|
||||
if (z < sizeof(int))
|
||||
{
|
||||
if (greg++ < NGREGARG)
|
||||
continue;
|
||||
|
||||
z = sizeof(int);
|
||||
switch ((*p_arg)->type)
|
||||
{
|
||||
case FFI_TYPE_SINT8:
|
||||
case FFI_TYPE_UINT8:
|
||||
avalue[i] = (((char *)pst) + OFS_INT8);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_SINT16:
|
||||
case FFI_TYPE_UINT16:
|
||||
avalue[i] = (((char *)pst) + OFS_INT16);
|
||||
break;
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
avalue[i] = pst;
|
||||
break;
|
||||
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
}
|
||||
pst++;
|
||||
}
|
||||
else if (z == sizeof(int))
|
||||
{
|
||||
#if defined(__SH4__)
|
||||
if ((*p_arg)->type == FFI_TYPE_FLOAT)
|
||||
{
|
||||
if (freg++ < NFREGARG)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (greg++ < NGREGARG)
|
||||
continue;
|
||||
}
|
||||
avalue[i] = pst;
|
||||
pst++;
|
||||
}
|
||||
#if defined(__SH4__)
|
||||
else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
|
||||
{
|
||||
if (freg + 1 < NFREGARG)
|
||||
{
|
||||
freg = (freg + 1) & ~1;
|
||||
freg += 2;
|
||||
continue;
|
||||
}
|
||||
avalue[i] = pst;
|
||||
pst += 2;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
int n = (z + sizeof (int) - 1) / sizeof (int);
|
||||
if (greg + n - 1 < NGREGARG)
|
||||
{
|
||||
greg += n;
|
||||
continue;
|
||||
}
|
||||
#if (! defined(__SH4__))
|
||||
else if (greg < NGREGARG)
|
||||
{
|
||||
greg += n;
|
||||
pst += greg - NGREGARG;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
avalue[i] = pst;
|
||||
pst += n;
|
||||
}
|
||||
}
|
||||
|
||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Tell ffi_closure_SYSV how to perform return type promotions. */
|
||||
return return_type (cif->rtype);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/* -----------------------------------------------------------------*-C-*-
|
||||
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
|
||||
Target configuration macros for SuperH.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_TARGET_H
|
||||
#define LIBFFI_TARGET_H
|
||||
|
||||
/* ---- Generic type definitions ----------------------------------------- */
|
||||
|
||||
#ifndef LIBFFI_ASM
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
|
||||
typedef enum ffi_abi {
|
||||
FFI_FIRST_ABI = 0,
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
|
||||
} ffi_abi;
|
||||
#endif
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,850 +0,0 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 2002, 2003, 2004, 2006, 2008 Kaz Kojima
|
||||
|
||||
SuperH Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#ifdef HAVE_MACHINE_ASM_H
|
||||
#include <machine/asm.h>
|
||||
#else
|
||||
/* XXX these lose for some platforms, I'm sure. */
|
||||
#define CNAME(x) x
|
||||
#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
|
||||
#endif
|
||||
|
||||
#if defined(__HITACHI__)
|
||||
#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
|
||||
#else
|
||||
#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
||||
# r4: ffi_prep_args
|
||||
# r5: &ecif
|
||||
# r6: bytes
|
||||
# r7: flags
|
||||
# sp+0: rvalue
|
||||
# sp+4: fn
|
||||
|
||||
# This assumes we are using gas.
|
||||
ENTRY(ffi_call_SYSV)
|
||||
# Save registers
|
||||
.LFB1:
|
||||
mov.l r8,@-r15
|
||||
.LCFI0:
|
||||
mov.l r9,@-r15
|
||||
.LCFI1:
|
||||
mov.l r10,@-r15
|
||||
.LCFI2:
|
||||
mov.l r12,@-r15
|
||||
.LCFI3:
|
||||
mov.l r14,@-r15
|
||||
.LCFI4:
|
||||
sts.l pr,@-r15
|
||||
.LCFI5:
|
||||
mov r15,r14
|
||||
.LCFI6:
|
||||
#if defined(__SH4__)
|
||||
mov r6,r8
|
||||
mov r7,r9
|
||||
|
||||
sub r6,r15
|
||||
add #-16,r15
|
||||
mov #~7,r0
|
||||
and r0,r15
|
||||
|
||||
mov r4,r0
|
||||
jsr @r0
|
||||
mov r15,r4
|
||||
|
||||
mov r9,r1
|
||||
shlr8 r9
|
||||
shlr8 r9
|
||||
shlr8 r9
|
||||
|
||||
mov #FFI_TYPE_STRUCT,r2
|
||||
cmp/eq r2,r9
|
||||
bf 1f
|
||||
#if STRUCT_VALUE_ADDRESS_WITH_ARG
|
||||
mov.l @r15+,r4
|
||||
bra 2f
|
||||
mov #5,r2
|
||||
#else
|
||||
mov.l @r15+,r10
|
||||
#endif
|
||||
1:
|
||||
mov #4,r2
|
||||
2:
|
||||
mov #4,r3
|
||||
|
||||
L_pass:
|
||||
cmp/pl r8
|
||||
bf L_call_it
|
||||
|
||||
mov r1,r0
|
||||
and #3,r0
|
||||
|
||||
L_pass_d:
|
||||
cmp/eq #FFI_TYPE_DOUBLE,r0
|
||||
bf L_pass_f
|
||||
|
||||
mov r3,r0
|
||||
and #1,r0
|
||||
tst r0,r0
|
||||
bt 1f
|
||||
add #1,r3
|
||||
1:
|
||||
mov #12,r0
|
||||
cmp/hs r0,r3
|
||||
bt/s 3f
|
||||
shlr2 r1
|
||||
bsr L_pop_d
|
||||
nop
|
||||
3:
|
||||
add #2,r3
|
||||
bra L_pass
|
||||
add #-8,r8
|
||||
|
||||
L_pop_d:
|
||||
mov r3,r0
|
||||
add r0,r0
|
||||
add r3,r0
|
||||
add #-12,r0
|
||||
braf r0
|
||||
nop
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
fmov.s @r15+,fr5
|
||||
rts
|
||||
fmov.s @r15+,fr4
|
||||
fmov.s @r15+,fr7
|
||||
rts
|
||||
fmov.s @r15+,fr6
|
||||
fmov.s @r15+,fr9
|
||||
rts
|
||||
fmov.s @r15+,fr8
|
||||
fmov.s @r15+,fr11
|
||||
rts
|
||||
fmov.s @r15+,fr10
|
||||
#else
|
||||
fmov.s @r15+,fr4
|
||||
rts
|
||||
fmov.s @r15+,fr5
|
||||
fmov.s @r15+,fr6
|
||||
rts
|
||||
fmov.s @r15+,fr7
|
||||
fmov.s @r15+,fr8
|
||||
rts
|
||||
fmov.s @r15+,fr9
|
||||
fmov.s @r15+,fr10
|
||||
rts
|
||||
fmov.s @r15+,fr11
|
||||
#endif
|
||||
|
||||
L_pass_f:
|
||||
cmp/eq #FFI_TYPE_FLOAT,r0
|
||||
bf L_pass_i
|
||||
|
||||
mov #12,r0
|
||||
cmp/hs r0,r3
|
||||
bt/s 2f
|
||||
shlr2 r1
|
||||
bsr L_pop_f
|
||||
nop
|
||||
2:
|
||||
add #1,r3
|
||||
bra L_pass
|
||||
add #-4,r8
|
||||
|
||||
L_pop_f:
|
||||
mov r3,r0
|
||||
shll2 r0
|
||||
add #-16,r0
|
||||
braf r0
|
||||
nop
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
rts
|
||||
fmov.s @r15+,fr5
|
||||
rts
|
||||
fmov.s @r15+,fr4
|
||||
rts
|
||||
fmov.s @r15+,fr7
|
||||
rts
|
||||
fmov.s @r15+,fr6
|
||||
rts
|
||||
fmov.s @r15+,fr9
|
||||
rts
|
||||
fmov.s @r15+,fr8
|
||||
rts
|
||||
fmov.s @r15+,fr11
|
||||
rts
|
||||
fmov.s @r15+,fr10
|
||||
#else
|
||||
rts
|
||||
fmov.s @r15+,fr4
|
||||
rts
|
||||
fmov.s @r15+,fr5
|
||||
rts
|
||||
fmov.s @r15+,fr6
|
||||
rts
|
||||
fmov.s @r15+,fr7
|
||||
rts
|
||||
fmov.s @r15+,fr8
|
||||
rts
|
||||
fmov.s @r15+,fr9
|
||||
rts
|
||||
fmov.s @r15+,fr10
|
||||
rts
|
||||
fmov.s @r15+,fr11
|
||||
#endif
|
||||
|
||||
L_pass_i:
|
||||
cmp/eq #FFI_TYPE_INT,r0
|
||||
bf L_call_it
|
||||
|
||||
mov #8,r0
|
||||
cmp/hs r0,r2
|
||||
bt/s 2f
|
||||
shlr2 r1
|
||||
bsr L_pop_i
|
||||
nop
|
||||
2:
|
||||
add #1,r2
|
||||
bra L_pass
|
||||
add #-4,r8
|
||||
|
||||
L_pop_i:
|
||||
mov r2,r0
|
||||
shll2 r0
|
||||
add #-16,r0
|
||||
braf r0
|
||||
nop
|
||||
rts
|
||||
mov.l @r15+,r4
|
||||
rts
|
||||
mov.l @r15+,r5
|
||||
rts
|
||||
mov.l @r15+,r6
|
||||
rts
|
||||
mov.l @r15+,r7
|
||||
|
||||
L_call_it:
|
||||
# call function
|
||||
#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
|
||||
mov r10, r2
|
||||
#endif
|
||||
mov.l @(28,r14),r1
|
||||
jsr @r1
|
||||
nop
|
||||
|
||||
L_ret_d:
|
||||
mov #FFI_TYPE_DOUBLE,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_ret_ll
|
||||
|
||||
mov.l @(24,r14),r1
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
fmov.s fr1,@r1
|
||||
add #4,r1
|
||||
bra L_epilogue
|
||||
fmov.s fr0,@r1
|
||||
#else
|
||||
fmov.s fr0,@r1
|
||||
add #4,r1
|
||||
bra L_epilogue
|
||||
fmov.s fr1,@r1
|
||||
#endif
|
||||
|
||||
L_ret_ll:
|
||||
mov #FFI_TYPE_SINT64,r2
|
||||
cmp/eq r2,r9
|
||||
bt/s 1f
|
||||
mov #FFI_TYPE_UINT64,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_ret_f
|
||||
|
||||
1:
|
||||
mov.l @(24,r14),r2
|
||||
mov.l r0,@r2
|
||||
bra L_epilogue
|
||||
mov.l r1,@(4,r2)
|
||||
|
||||
L_ret_f:
|
||||
mov #FFI_TYPE_FLOAT,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_ret_i
|
||||
|
||||
mov.l @(24,r14),r1
|
||||
bra L_epilogue
|
||||
fmov.s fr0,@r1
|
||||
|
||||
L_ret_i:
|
||||
mov #FFI_TYPE_INT,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_epilogue
|
||||
|
||||
mov.l @(24,r14),r1
|
||||
bra L_epilogue
|
||||
mov.l r0,@r1
|
||||
|
||||
L_epilogue:
|
||||
# Remove the space we pushed for the args
|
||||
mov r14,r15
|
||||
|
||||
lds.l @r15+,pr
|
||||
mov.l @r15+,r14
|
||||
mov.l @r15+,r12
|
||||
mov.l @r15+,r10
|
||||
mov.l @r15+,r9
|
||||
rts
|
||||
mov.l @r15+,r8
|
||||
#else
|
||||
mov r6,r8
|
||||
mov r7,r9
|
||||
|
||||
sub r6,r15
|
||||
add #-16,r15
|
||||
mov #~7,r0
|
||||
and r0,r15
|
||||
|
||||
mov r4,r0
|
||||
jsr @r0
|
||||
mov r15,r4
|
||||
|
||||
mov r9,r3
|
||||
shlr8 r9
|
||||
shlr8 r9
|
||||
shlr8 r9
|
||||
|
||||
mov #FFI_TYPE_STRUCT,r2
|
||||
cmp/eq r2,r9
|
||||
bf 1f
|
||||
#if STRUCT_VALUE_ADDRESS_WITH_ARG
|
||||
mov.l @r15+,r4
|
||||
bra 2f
|
||||
mov #5,r2
|
||||
#else
|
||||
mov.l @r15+,r10
|
||||
#endif
|
||||
1:
|
||||
mov #4,r2
|
||||
2:
|
||||
|
||||
L_pass:
|
||||
cmp/pl r8
|
||||
bf L_call_it
|
||||
|
||||
mov r3,r0
|
||||
and #3,r0
|
||||
|
||||
L_pass_d:
|
||||
cmp/eq #FFI_TYPE_DOUBLE,r0
|
||||
bf L_pass_i
|
||||
|
||||
mov r15,r0
|
||||
and #7,r0
|
||||
tst r0,r0
|
||||
bt 1f
|
||||
add #4,r15
|
||||
1:
|
||||
mov #8,r0
|
||||
cmp/hs r0,r2
|
||||
bt/s 2f
|
||||
shlr2 r3
|
||||
bsr L_pop_d
|
||||
nop
|
||||
2:
|
||||
add #2,r2
|
||||
bra L_pass
|
||||
add #-8,r8
|
||||
|
||||
L_pop_d:
|
||||
mov r2,r0
|
||||
add r0,r0
|
||||
add r2,r0
|
||||
add #-12,r0
|
||||
add r0,r0
|
||||
braf r0
|
||||
nop
|
||||
mov.l @r15+,r4
|
||||
rts
|
||||
mov.l @r15+,r5
|
||||
mov.l @r15+,r5
|
||||
rts
|
||||
mov.l @r15+,r6
|
||||
mov.l @r15+,r6
|
||||
rts
|
||||
mov.l @r15+,r7
|
||||
rts
|
||||
mov.l @r15+,r7
|
||||
|
||||
L_pass_i:
|
||||
cmp/eq #FFI_TYPE_INT,r0
|
||||
bf L_call_it
|
||||
|
||||
mov #8,r0
|
||||
cmp/hs r0,r2
|
||||
bt/s 2f
|
||||
shlr2 r3
|
||||
bsr L_pop_i
|
||||
nop
|
||||
2:
|
||||
add #1,r2
|
||||
bra L_pass
|
||||
add #-4,r8
|
||||
|
||||
L_pop_i:
|
||||
mov r2,r0
|
||||
shll2 r0
|
||||
add #-16,r0
|
||||
braf r0
|
||||
nop
|
||||
rts
|
||||
mov.l @r15+,r4
|
||||
rts
|
||||
mov.l @r15+,r5
|
||||
rts
|
||||
mov.l @r15+,r6
|
||||
rts
|
||||
mov.l @r15+,r7
|
||||
|
||||
L_call_it:
|
||||
# call function
|
||||
#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
|
||||
mov r10, r2
|
||||
#endif
|
||||
mov.l @(28,r14),r1
|
||||
jsr @r1
|
||||
nop
|
||||
|
||||
L_ret_d:
|
||||
mov #FFI_TYPE_DOUBLE,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_ret_ll
|
||||
|
||||
mov.l @(24,r14),r2
|
||||
mov.l r0,@r2
|
||||
bra L_epilogue
|
||||
mov.l r1,@(4,r2)
|
||||
|
||||
L_ret_ll:
|
||||
mov #FFI_TYPE_SINT64,r2
|
||||
cmp/eq r2,r9
|
||||
bt/s 1f
|
||||
mov #FFI_TYPE_UINT64,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_ret_i
|
||||
|
||||
1:
|
||||
mov.l @(24,r14),r2
|
||||
mov.l r0,@r2
|
||||
bra L_epilogue
|
||||
mov.l r1,@(4,r2)
|
||||
|
||||
L_ret_i:
|
||||
mov #FFI_TYPE_FLOAT,r2
|
||||
cmp/eq r2,r9
|
||||
bt 1f
|
||||
mov #FFI_TYPE_INT,r2
|
||||
cmp/eq r2,r9
|
||||
bf L_epilogue
|
||||
1:
|
||||
mov.l @(24,r14),r1
|
||||
bra L_epilogue
|
||||
mov.l r0,@r1
|
||||
|
||||
L_epilogue:
|
||||
# Remove the space we pushed for the args
|
||||
mov r14,r15
|
||||
|
||||
lds.l @r15+,pr
|
||||
mov.l @r15+,r14
|
||||
mov.l @r15+,r12
|
||||
mov.l @r15+,r10
|
||||
mov.l @r15+,r9
|
||||
rts
|
||||
mov.l @r15+,r8
|
||||
#endif
|
||||
.LFE1:
|
||||
.ffi_call_SYSV_end:
|
||||
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
|
||||
|
||||
.globl ffi_closure_helper_SYSV
|
||||
|
||||
ENTRY(ffi_closure_SYSV)
|
||||
.LFB2:
|
||||
mov.l r7,@-r15
|
||||
.LCFI7:
|
||||
mov.l r6,@-r15
|
||||
.LCFI8:
|
||||
mov.l r5,@-r15
|
||||
.LCFI9:
|
||||
mov.l r4,@-r15
|
||||
.LCFIA:
|
||||
mov.l r14,@-r15
|
||||
.LCFIB:
|
||||
sts.l pr,@-r15
|
||||
|
||||
/* Stack layout:
|
||||
xx bytes (on stack parameters)
|
||||
16 bytes (register parameters)
|
||||
4 bytes (saved frame pointer)
|
||||
4 bytes (saved return address)
|
||||
32 bytes (floating register parameters, SH-4 only)
|
||||
8 bytes (result)
|
||||
4 bytes (pad)
|
||||
4 bytes (5th arg)
|
||||
<- new stack pointer
|
||||
*/
|
||||
.LCFIC:
|
||||
#if defined(__SH4__)
|
||||
add #-48,r15
|
||||
#else
|
||||
add #-16,r15
|
||||
#endif
|
||||
.LCFID:
|
||||
mov r15,r14
|
||||
.LCFIE:
|
||||
|
||||
#if defined(__SH4__)
|
||||
mov r14,r1
|
||||
add #48,r1
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
fmov.s fr10,@-r1
|
||||
fmov.s fr11,@-r1
|
||||
fmov.s fr8,@-r1
|
||||
fmov.s fr9,@-r1
|
||||
fmov.s fr6,@-r1
|
||||
fmov.s fr7,@-r1
|
||||
fmov.s fr4,@-r1
|
||||
fmov.s fr5,@-r1
|
||||
#else
|
||||
fmov.s fr11,@-r1
|
||||
fmov.s fr10,@-r1
|
||||
fmov.s fr9,@-r1
|
||||
fmov.s fr8,@-r1
|
||||
fmov.s fr7,@-r1
|
||||
fmov.s fr6,@-r1
|
||||
fmov.s fr5,@-r1
|
||||
fmov.s fr4,@-r1
|
||||
#endif
|
||||
mov r1,r7
|
||||
mov r14,r6
|
||||
add #56,r6
|
||||
#else
|
||||
mov r14,r6
|
||||
add #24,r6
|
||||
#endif
|
||||
|
||||
bt/s 10f
|
||||
mov r2, r5
|
||||
mov r14,r1
|
||||
add #8,r1
|
||||
mov r1,r5
|
||||
10:
|
||||
|
||||
mov r14,r1
|
||||
#if defined(__SH4__)
|
||||
add #72,r1
|
||||
#else
|
||||
add #40,r1
|
||||
#endif
|
||||
mov.l r1,@r14
|
||||
|
||||
#ifdef PIC
|
||||
mov.l L_got,r1
|
||||
mova L_got,r0
|
||||
add r0,r1
|
||||
mov.l L_helper,r0
|
||||
add r1,r0
|
||||
#else
|
||||
mov.l L_helper,r0
|
||||
#endif
|
||||
jsr @r0
|
||||
mov r3,r4
|
||||
|
||||
shll r0
|
||||
mov r0,r1
|
||||
mova L_table,r0
|
||||
add r1,r0
|
||||
mov.w @r0,r0
|
||||
mov r14,r2
|
||||
braf r0
|
||||
add #8,r2
|
||||
0:
|
||||
.align 2
|
||||
#ifdef PIC
|
||||
L_got:
|
||||
.long _GLOBAL_OFFSET_TABLE_
|
||||
L_helper:
|
||||
.long ffi_closure_helper_SYSV@GOTOFF
|
||||
#else
|
||||
L_helper:
|
||||
.long ffi_closure_helper_SYSV
|
||||
#endif
|
||||
L_table:
|
||||
.short L_case_v - 0b /* FFI_TYPE_VOID */
|
||||
.short L_case_i - 0b /* FFI_TYPE_INT */
|
||||
#if defined(__SH4__)
|
||||
.short L_case_f - 0b /* FFI_TYPE_FLOAT */
|
||||
.short L_case_d - 0b /* FFI_TYPE_DOUBLE */
|
||||
.short L_case_d - 0b /* FFI_TYPE_LONGDOUBLE */
|
||||
#else
|
||||
.short L_case_i - 0b /* FFI_TYPE_FLOAT */
|
||||
.short L_case_ll - 0b /* FFI_TYPE_DOUBLE */
|
||||
.short L_case_ll - 0b /* FFI_TYPE_LONGDOUBLE */
|
||||
#endif
|
||||
.short L_case_uq - 0b /* FFI_TYPE_UINT8 */
|
||||
.short L_case_q - 0b /* FFI_TYPE_SINT8 */
|
||||
.short L_case_uh - 0b /* FFI_TYPE_UINT16 */
|
||||
.short L_case_h - 0b /* FFI_TYPE_SINT16 */
|
||||
.short L_case_i - 0b /* FFI_TYPE_UINT32 */
|
||||
.short L_case_i - 0b /* FFI_TYPE_SINT32 */
|
||||
.short L_case_ll - 0b /* FFI_TYPE_UINT64 */
|
||||
.short L_case_ll - 0b /* FFI_TYPE_SINT64 */
|
||||
.short L_case_v - 0b /* FFI_TYPE_STRUCT */
|
||||
.short L_case_i - 0b /* FFI_TYPE_POINTER */
|
||||
|
||||
#if defined(__SH4__)
|
||||
L_case_d:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
fmov.s @r2+,fr1
|
||||
bra L_case_v
|
||||
fmov.s @r2,fr0
|
||||
#else
|
||||
fmov.s @r2+,fr0
|
||||
bra L_case_v
|
||||
fmov.s @r2,fr1
|
||||
#endif
|
||||
|
||||
L_case_f:
|
||||
bra L_case_v
|
||||
fmov.s @r2,fr0
|
||||
#endif
|
||||
|
||||
L_case_ll:
|
||||
mov.l @r2+,r0
|
||||
bra L_case_v
|
||||
mov.l @r2,r1
|
||||
|
||||
L_case_i:
|
||||
bra L_case_v
|
||||
mov.l @r2,r0
|
||||
|
||||
L_case_q:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#else
|
||||
add #3,r2
|
||||
#endif
|
||||
bra L_case_v
|
||||
mov.b @r2,r0
|
||||
|
||||
L_case_uq:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#else
|
||||
add #3,r2
|
||||
#endif
|
||||
mov.b @r2,r0
|
||||
bra L_case_v
|
||||
extu.b r0,r0
|
||||
|
||||
L_case_h:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#else
|
||||
add #2,r2
|
||||
#endif
|
||||
bra L_case_v
|
||||
mov.w @r2,r0
|
||||
|
||||
L_case_uh:
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
#else
|
||||
add #2,r2
|
||||
#endif
|
||||
mov.w @r2,r0
|
||||
extu.w r0,r0
|
||||
/* fall through */
|
||||
|
||||
L_case_v:
|
||||
#if defined(__SH4__)
|
||||
add #48,r15
|
||||
#else
|
||||
add #16,r15
|
||||
#endif
|
||||
lds.l @r15+,pr
|
||||
mov.l @r15+,r14
|
||||
rts
|
||||
add #16,r15
|
||||
.LFE2:
|
||||
.ffi_closure_SYSV_end:
|
||||
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#endif
|
||||
|
||||
.section ".eh_frame","aw",@progbits
|
||||
__FRAME_BEGIN__:
|
||||
.4byte .LECIE1-.LSCIE1 /* Length of Common Information Entry */
|
||||
.LSCIE1:
|
||||
.4byte 0x0 /* CIE Identifier Tag */
|
||||
.byte 0x1 /* CIE Version */
|
||||
#ifdef PIC
|
||||
.ascii "zR\0" /* CIE Augmentation */
|
||||
#else
|
||||
.byte 0x0 /* CIE Augmentation */
|
||||
#endif
|
||||
.byte 0x1 /* uleb128 0x1; CIE Code Alignment Factor */
|
||||
.byte 0x7c /* sleb128 -4; CIE Data Alignment Factor */
|
||||
.byte 0x11 /* CIE RA Column */
|
||||
#ifdef PIC
|
||||
.uleb128 0x1 /* Augmentation size */
|
||||
.byte 0x10 /* FDE Encoding (pcrel) */
|
||||
#endif
|
||||
.byte 0xc /* DW_CFA_def_cfa */
|
||||
.byte 0xf /* uleb128 0xf */
|
||||
.byte 0x0 /* uleb128 0x0 */
|
||||
.align 2
|
||||
.LECIE1:
|
||||
.LSFDE1:
|
||||
.4byte .LEFDE1-.LASFDE1 /* FDE Length */
|
||||
.LASFDE1:
|
||||
.4byte .LASFDE1-__FRAME_BEGIN__ /* FDE CIE offset */
|
||||
#ifdef PIC
|
||||
.4byte .LFB1-. /* FDE initial location */
|
||||
#else
|
||||
.4byte .LFB1 /* FDE initial location */
|
||||
#endif
|
||||
.4byte .LFE1-.LFB1 /* FDE address range */
|
||||
#ifdef PIC
|
||||
.uleb128 0x0 /* Augmentation size */
|
||||
#endif
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI0-.LFB1
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x4 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI1-.LCFI0
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x8 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI2-.LCFI1
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0xc /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI3-.LCFI2
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x10 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI4-.LCFI3
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x14 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI5-.LCFI4
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x18 /* uleb128 0x4 */
|
||||
.byte 0x91 /* DW_CFA_offset, column 0x11 */
|
||||
.byte 0x6 /* uleb128 0x6 */
|
||||
.byte 0x8e /* DW_CFA_offset, column 0xe */
|
||||
.byte 0x5 /* uleb128 0x5 */
|
||||
.byte 0x8c /* DW_CFA_offset, column 0xc */
|
||||
.byte 0x4 /* uleb128 0x4 */
|
||||
.byte 0x8a /* DW_CFA_offset, column 0xa */
|
||||
.byte 0x3 /* uleb128 0x3 */
|
||||
.byte 0x89 /* DW_CFA_offset, column 0x9 */
|
||||
.byte 0x2 /* uleb128 0x2 */
|
||||
.byte 0x88 /* DW_CFA_offset, column 0x8 */
|
||||
.byte 0x1 /* uleb128 0x1 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI6-.LCFI5
|
||||
.byte 0xd /* DW_CFA_def_cfa_register */
|
||||
.byte 0xe /* uleb128 0xe */
|
||||
.align 2
|
||||
.LEFDE1:
|
||||
|
||||
.LSFDE3:
|
||||
.4byte .LEFDE3-.LASFDE3 /* FDE Length */
|
||||
.LASFDE3:
|
||||
.4byte .LASFDE3-__FRAME_BEGIN__ /* FDE CIE offset */
|
||||
#ifdef PIC
|
||||
.4byte .LFB2-. /* FDE initial location */
|
||||
#else
|
||||
.4byte .LFB2 /* FDE initial location */
|
||||
#endif
|
||||
.4byte .LFE2-.LFB2 /* FDE address range */
|
||||
#ifdef PIC
|
||||
.uleb128 0x0 /* Augmentation size */
|
||||
#endif
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI7-.LFB2
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x4 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI8-.LCFI7
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x8 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFI9-.LCFI8
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0xc /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFIA-.LCFI9
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x10 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFIB-.LCFIA
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x14 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFIC-.LCFIB
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
.byte 0x18 /* uleb128 0x4 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFID-.LCFIC
|
||||
.byte 0xe /* DW_CFA_def_cfa_offset */
|
||||
#if defined(__SH4__)
|
||||
.byte 24+48 /* uleb128 24+48 */
|
||||
#else
|
||||
.byte 24+16 /* uleb128 24+16 */
|
||||
#endif
|
||||
.byte 0x91 /* DW_CFA_offset, column 0x11 */
|
||||
.byte 0x6 /* uleb128 0x6 */
|
||||
.byte 0x8e /* DW_CFA_offset, column 0xe */
|
||||
.byte 0x5 /* uleb128 0x5 */
|
||||
.byte 0x84 /* DW_CFA_offset, column 0x4 */
|
||||
.byte 0x4 /* uleb128 0x4 */
|
||||
.byte 0x85 /* DW_CFA_offset, column 0x5 */
|
||||
.byte 0x3 /* uleb128 0x3 */
|
||||
.byte 0x86 /* DW_CFA_offset, column 0x6 */
|
||||
.byte 0x2 /* uleb128 0x2 */
|
||||
.byte 0x87 /* DW_CFA_offset, column 0x7 */
|
||||
.byte 0x1 /* uleb128 0x1 */
|
||||
.byte 0x4 /* DW_CFA_advance_loc4 */
|
||||
.4byte .LCFIE-.LCFID
|
||||
.byte 0xd /* DW_CFA_def_cfa_register */
|
||||
.byte 0xe /* uleb128 0xe */
|
||||
.align 2
|
||||
.LEFDE3:
|
||||
Reference in New Issue
Block a user