Moved m68k files
This commit is contained in:
184
libffi/m68k/ffi.c
Normal file
184
libffi/m68k/ffi.c
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
ffi.c
|
||||||
|
|
||||||
|
m68k Foreign Function Interface
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <ffi.h>
|
||||||
|
#include <ffi_common.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* ffi_prep_args is called by the assembly routine once stack space has
|
||||||
|
been allocated for the function's arguments. */
|
||||||
|
|
||||||
|
static void *
|
||||||
|
ffi_prep_args (void *stack, extended_cif *ecif)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
int tmp;
|
||||||
|
unsigned int avn;
|
||||||
|
void **p_argv;
|
||||||
|
char *argp;
|
||||||
|
ffi_type **p_arg;
|
||||||
|
void *struct_value_ptr;
|
||||||
|
|
||||||
|
tmp = 0;
|
||||||
|
argp = stack;
|
||||||
|
|
||||||
|
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
|
||||||
|
&& ecif->cif->rtype->size > 8)
|
||||||
|
struct_value_ptr = ecif->rvalue;
|
||||||
|
else
|
||||||
|
struct_value_ptr = NULL;
|
||||||
|
|
||||||
|
avn = ecif->cif->nargs;
|
||||||
|
p_argv = ecif->avalue;
|
||||||
|
|
||||||
|
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||||
|
i != 0 && avn != 0;
|
||||||
|
i--, p_arg++)
|
||||||
|
{
|
||||||
|
size_t z;
|
||||||
|
|
||||||
|
/* Align if necessary. */
|
||||||
|
if (((*p_arg)->alignment - 1) & (unsigned) argp)
|
||||||
|
argp = (char *) ALIGN (argp, (*p_arg)->alignment);
|
||||||
|
|
||||||
|
if (avn != 0)
|
||||||
|
{
|
||||||
|
avn--;
|
||||||
|
z = (*p_arg)->size;
|
||||||
|
if (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:
|
||||||
|
memcpy (argp + sizeof (int) - z, *p_argv, z);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FFI_ASSERT (0);
|
||||||
|
}
|
||||||
|
z = sizeof (int);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
memcpy (argp, *p_argv, z);
|
||||||
|
p_argv++;
|
||||||
|
argp += z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return struct_value_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CIF_FLAGS_INT 1
|
||||||
|
#define CIF_FLAGS_DINT 2
|
||||||
|
#define CIF_FLAGS_FLOAT 4
|
||||||
|
#define CIF_FLAGS_DOUBLE 8
|
||||||
|
#define CIF_FLAGS_LDOUBLE 16
|
||||||
|
#define CIF_FLAGS_POINTER 32
|
||||||
|
#define CIF_FLAGS_STRUCT 64
|
||||||
|
|
||||||
|
/* Perform machine dependent cif processing */
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||||
|
{
|
||||||
|
/* Set the return type flag */
|
||||||
|
switch (cif->rtype->type)
|
||||||
|
{
|
||||||
|
case FFI_TYPE_VOID:
|
||||||
|
cif->flags = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_STRUCT:
|
||||||
|
if (cif->rtype->size > 4 && cif->rtype->size <= 8)
|
||||||
|
cif->flags = CIF_FLAGS_DINT;
|
||||||
|
else if (cif->rtype->size <= 4)
|
||||||
|
cif->flags = CIF_FLAGS_STRUCT;
|
||||||
|
else
|
||||||
|
cif->flags = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_FLOAT:
|
||||||
|
cif->flags = CIF_FLAGS_FLOAT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_DOUBLE:
|
||||||
|
cif->flags = CIF_FLAGS_DOUBLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
cif->flags = CIF_FLAGS_LDOUBLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_POINTER:
|
||||||
|
cif->flags = CIF_FLAGS_POINTER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_SINT64:
|
||||||
|
case FFI_TYPE_UINT64:
|
||||||
|
cif->flags = CIF_FLAGS_DINT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
cif->flags = CIF_FLAGS_INT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FFI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
|
||||||
|
extended_cif *,
|
||||||
|
unsigned, unsigned, unsigned,
|
||||||
|
void *, void (*fn) ());
|
||||||
|
|
||||||
|
void
|
||||||
|
ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
|
||||||
|
{
|
||||||
|
extended_cif ecif;
|
||||||
|
|
||||||
|
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 (rvalue == NULL
|
||||||
|
&& cif->rtype->type == FFI_TYPE_STRUCT
|
||||||
|
&& cif->rtype->size > 8)
|
||||||
|
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, cif->rtype->size * 8,
|
||||||
|
ecif.rvalue, fn);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FFI_ASSERT (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
96
libffi/m68k/sysv.S
Normal file
96
libffi/m68k/sysv.S
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
sysv.S
|
||||||
|
|
||||||
|
m68k Foreign Function Interface
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#define LIBFFI_ASM
|
||||||
|
#include <ffi.h>
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.globl ffi_call_SYSV
|
||||||
|
.type ffi_call_SYSV,@function
|
||||||
|
|
||||||
|
ffi_call_SYSV:
|
||||||
|
link %fp,#0
|
||||||
|
move.l %d2,-(%sp)
|
||||||
|
|
||||||
|
| Make room for all of the new args.
|
||||||
|
sub.l 16(%fp),%sp
|
||||||
|
|
||||||
|
| Call ffi_prep_args
|
||||||
|
move.l 12(%fp),-(%sp)
|
||||||
|
pea 4(%sp)
|
||||||
|
move.l 8(%fp),%a0
|
||||||
|
jsr (%a0)
|
||||||
|
addq.l #8,%sp
|
||||||
|
|
||||||
|
| Pass pointer to struct value, if any
|
||||||
|
move.l %a0,%a1
|
||||||
|
|
||||||
|
| Call the function
|
||||||
|
move.l 32(%fp),%a0
|
||||||
|
jsr (%a0)
|
||||||
|
|
||||||
|
| Remove the space we pushed for the args
|
||||||
|
add.l 16(%fp),%sp
|
||||||
|
|
||||||
|
| Load the pointer to storage for the return value
|
||||||
|
move.l 28(%fp),%a1
|
||||||
|
|
||||||
|
| Load the return type code
|
||||||
|
move.l 20(%fp),%d2
|
||||||
|
|
||||||
|
| If the return value pointer is NULL, assume no return value.
|
||||||
|
tst.l %a1
|
||||||
|
jbeq noretval
|
||||||
|
|
||||||
|
btst #0,%d2
|
||||||
|
jbeq retlongint
|
||||||
|
move.l %d0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retlongint:
|
||||||
|
btst #1,%d2
|
||||||
|
jbeq retfloat
|
||||||
|
move.l %d0,(%a1)
|
||||||
|
move.l %d1,4(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retfloat:
|
||||||
|
btst #2,%d2
|
||||||
|
jbeq retdouble
|
||||||
|
fmove.s %fp0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retdouble:
|
||||||
|
btst #3,%d2
|
||||||
|
jbeq retlongdouble
|
||||||
|
fmove.d %fp0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retlongdouble:
|
||||||
|
btst #4,%d2
|
||||||
|
jbeq retpointer
|
||||||
|
fmove.x %fp0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retpointer:
|
||||||
|
btst #5,%d2
|
||||||
|
jbeq retstruct
|
||||||
|
move.l %a0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retstruct:
|
||||||
|
btst #6,%d2
|
||||||
|
jbeq noretval
|
||||||
|
move.l 24(%fp),%d2
|
||||||
|
bfins %d0,(%a1){#0,%d2}
|
||||||
|
|
||||||
|
noretval:
|
||||||
|
epilogue:
|
||||||
|
move.l (%sp)+,%d2
|
||||||
|
unlk %a6
|
||||||
|
rts
|
||||||
|
.size ffi_call_SYSV,.-ffi_call_SYSV
|
||||||
Reference in New Issue
Block a user