Moved m68k files

This commit is contained in:
green
2001-04-22 18:13:22 +00:00
parent 688ddfeced
commit f893d22733
2 changed files with 280 additions and 0 deletions

184
libffi/m68k/ffi.c Normal file
View 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
View 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