mirror of
https://github.com/partic2/libffi
synced 2026-11-11 02:27:19 +00:00
m68k fixes
This commit is contained in:
@@ -36,3 +36,4 @@ interix-patch
|
|||||||
remove-debug-code
|
remove-debug-code
|
||||||
powerpc-ffi-softfloat
|
powerpc-ffi-softfloat
|
||||||
variadic
|
variadic
|
||||||
|
m68k-patches
|
||||||
|
|||||||
@@ -0,0 +1,288 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
ffi.c
|
||||||
|
|
||||||
|
m68k Foreign Function Interface
|
||||||
|
----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <ffi.h>
|
||||||
|
#include <ffi_common.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef __rtems__
|
||||||
|
void rtems_cache_flush_multiple_data_lines( const void *, size_t );
|
||||||
|
#else
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <asm/cachectl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ffi_call_SYSV (extended_cif *,
|
||||||
|
unsigned, unsigned,
|
||||||
|
void *, void (*fn) ());
|
||||||
|
void *ffi_prep_args (void *stack, extended_cif *ecif);
|
||||||
|
void ffi_closure_SYSV (ffi_closure *);
|
||||||
|
void ffi_closure_struct_SYSV (ffi_closure *);
|
||||||
|
unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
|
||||||
|
void *resp, void *args);
|
||||||
|
|
||||||
|
/* ffi_prep_args is called by the assembly routine once stack space has
|
||||||
|
been allocated for the function's arguments. */
|
||||||
|
|
||||||
|
void *
|
||||||
|
ffi_prep_args (void *stack, extended_cif *ecif)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
void **p_argv;
|
||||||
|
char *argp;
|
||||||
|
ffi_type **p_arg;
|
||||||
|
void *struct_value_ptr;
|
||||||
|
|
||||||
|
argp = stack;
|
||||||
|
|
||||||
|
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
|
||||||
|
&& !ecif->cif->flags)
|
||||||
|
struct_value_ptr = ecif->rvalue;
|
||||||
|
else
|
||||||
|
struct_value_ptr = NULL;
|
||||||
|
|
||||||
|
p_argv = ecif->avalue;
|
||||||
|
|
||||||
|
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
|
||||||
|
i != 0;
|
||||||
|
i--, p_arg++)
|
||||||
|
{
|
||||||
|
size_t z;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* Align if necessary. */
|
||||||
|
if ((sizeof(int) - 1) & z)
|
||||||
|
z = ALIGN(z, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
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_STRUCT1 64
|
||||||
|
#define CIF_FLAGS_STRUCT2 128
|
||||||
|
|
||||||
|
/* 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:
|
||||||
|
switch (cif->rtype->size)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
cif->flags = CIF_FLAGS_STRUCT1;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
cif->flags = CIF_FLAGS_STRUCT2;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
cif->flags = CIF_FLAGS_INT;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
cif->flags = CIF_FLAGS_DINT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cif->flags = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_FLOAT:
|
||||||
|
cif->flags = CIF_FLAGS_FLOAT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FFI_TYPE_DOUBLE:
|
||||||
|
cif->flags = CIF_FLAGS_DOUBLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if (FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE)
|
||||||
|
case FFI_TYPE_LONGDOUBLE:
|
||||||
|
cif->flags = CIF_FLAGS_LDOUBLE;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 (&ecif, cif->bytes, cif->flags,
|
||||||
|
ecif.rvalue, fn);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FFI_ASSERT (0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
void **p_argv;
|
||||||
|
char *argp;
|
||||||
|
ffi_type **p_arg;
|
||||||
|
|
||||||
|
argp = stack;
|
||||||
|
p_argv = avalue;
|
||||||
|
|
||||||
|
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
|
||||||
|
{
|
||||||
|
size_t z;
|
||||||
|
|
||||||
|
z = (*p_arg)->size;
|
||||||
|
if (z <= 4)
|
||||||
|
{
|
||||||
|
*p_argv = (void *) (argp + 4 - z);
|
||||||
|
|
||||||
|
z = 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*p_argv = (void *) argp;
|
||||||
|
|
||||||
|
/* Align if necessary */
|
||||||
|
if ((sizeof(int) - 1) & z)
|
||||||
|
z = ALIGN(z, sizeof(int));
|
||||||
|
}
|
||||||
|
|
||||||
|
p_argv++;
|
||||||
|
argp += z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int
|
||||||
|
ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
|
||||||
|
{
|
||||||
|
ffi_cif *cif;
|
||||||
|
void **arg_area;
|
||||||
|
|
||||||
|
cif = closure->cif;
|
||||||
|
arg_area = (void**) alloca (cif->nargs * sizeof (void *));
|
||||||
|
|
||||||
|
ffi_prep_incoming_args_SYSV(args, arg_area, cif);
|
||||||
|
|
||||||
|
(closure->fun) (cif, resp, arg_area, closure->user_data);
|
||||||
|
|
||||||
|
return cif->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
ffi_status
|
||||||
|
ffi_prep_closure_loc (ffi_closure* closure,
|
||||||
|
ffi_cif* cif,
|
||||||
|
void (*fun)(ffi_cif*,void*,void**,void*),
|
||||||
|
void *user_data,
|
||||||
|
void *codeloc)
|
||||||
|
{
|
||||||
|
FFI_ASSERT (cif->abi == FFI_SYSV);
|
||||||
|
|
||||||
|
*(unsigned short *)closure->tramp = 0x207c;
|
||||||
|
*(void **)(closure->tramp + 2) = codeloc;
|
||||||
|
*(unsigned short *)(closure->tramp + 6) = 0x4ef9;
|
||||||
|
if (cif->rtype->type == FFI_TYPE_STRUCT
|
||||||
|
&& !cif->flags)
|
||||||
|
*(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
|
||||||
|
else
|
||||||
|
*(void **)(closure->tramp + 8) = ffi_closure_SYSV;
|
||||||
|
|
||||||
|
#ifdef __rtems__
|
||||||
|
rtems_cache_flush_multiple_data_lines( codeloc, FFI_TRAMPOLINE_SIZE );
|
||||||
|
#else
|
||||||
|
syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
|
||||||
|
FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
closure->cif = cif;
|
||||||
|
closure->user_data = user_data;
|
||||||
|
closure->fun = fun;
|
||||||
|
|
||||||
|
return FFI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
/* -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
sysv.S - Copyright (c) 1998 Andreas Schwab
|
||||||
|
Copyright (c) 2008 Red Hat, Inc.
|
||||||
|
|
||||||
|
m68k 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_AS_CFI_PSEUDO_OP
|
||||||
|
#define CFI_STARTPROC() .cfi_startproc
|
||||||
|
#define CFI_OFFSET(reg,off) .cfi_offset reg,off
|
||||||
|
#define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off
|
||||||
|
#define CFI_ENDPROC() .cfi_endproc
|
||||||
|
#else
|
||||||
|
#define CFI_STARTPROC()
|
||||||
|
#define CFI_OFFSET(reg,off)
|
||||||
|
#define CFI_DEF_CFA(reg,off)
|
||||||
|
#define CFI_ENDPROC()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.globl ffi_call_SYSV
|
||||||
|
.type ffi_call_SYSV,@function
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
ffi_call_SYSV:
|
||||||
|
CFI_STARTPROC()
|
||||||
|
link %fp,#0
|
||||||
|
CFI_OFFSET(14,-8)
|
||||||
|
CFI_DEF_CFA(14,8)
|
||||||
|
move.l %d2,-(%sp)
|
||||||
|
CFI_OFFSET(2,-12)
|
||||||
|
|
||||||
|
| Make room for all of the new args.
|
||||||
|
sub.l 12(%fp),%sp
|
||||||
|
|
||||||
|
| Call ffi_prep_args
|
||||||
|
move.l 8(%fp),-(%sp)
|
||||||
|
pea 4(%sp)
|
||||||
|
#if !defined __PIC__
|
||||||
|
jsr ffi_prep_args
|
||||||
|
#else
|
||||||
|
bsr.l ffi_prep_args@PLTPC
|
||||||
|
#endif
|
||||||
|
addq.l #8,%sp
|
||||||
|
|
||||||
|
| Pass pointer to struct value, if any
|
||||||
|
move.l %a0,%a1
|
||||||
|
|
||||||
|
| Call the function
|
||||||
|
move.l 24(%fp),%a0
|
||||||
|
jsr (%a0)
|
||||||
|
|
||||||
|
| Remove the space we pushed for the args
|
||||||
|
add.l 12(%fp),%sp
|
||||||
|
|
||||||
|
| Load the pointer to storage for the return value
|
||||||
|
move.l 20(%fp),%a1
|
||||||
|
|
||||||
|
| Load the return type code
|
||||||
|
move.l 16(%fp),%d2
|
||||||
|
|
||||||
|
| If the return value pointer is NULL, assume no return value.
|
||||||
|
| NOTE: On the mc68000, tst on an address register is not supported.
|
||||||
|
#if defined(__mc68000__) && !defined(__mcoldfire__)
|
||||||
|
cmp.w #0, %a1
|
||||||
|
#else
|
||||||
|
tst.l %a1
|
||||||
|
#endif
|
||||||
|
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
|
||||||
|
#if defined(__MC68881__)
|
||||||
|
fmove.s %fp0,(%a1)
|
||||||
|
#else
|
||||||
|
move.l %d0,(%a1)
|
||||||
|
#endif
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retdouble:
|
||||||
|
btst #3,%d2
|
||||||
|
jbeq retlongdouble
|
||||||
|
#if defined(__MC68881__)
|
||||||
|
fmove.d %fp0,(%a1)
|
||||||
|
#else
|
||||||
|
move.l %d0,(%a1)+
|
||||||
|
move.l %d1,(%a1)
|
||||||
|
#endif
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retlongdouble:
|
||||||
|
btst #4,%d2
|
||||||
|
jbeq retpointer
|
||||||
|
#if defined(__MC68881__)
|
||||||
|
fmove.x %fp0,(%a1)
|
||||||
|
#else
|
||||||
|
move.l %d0,(%a1)+
|
||||||
|
move.l %d1,(%a1)+
|
||||||
|
move.l %d2,(%a1)
|
||||||
|
#endif
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retpointer:
|
||||||
|
btst #5,%d2
|
||||||
|
jbeq retstruct1
|
||||||
|
move.l %a0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retstruct1:
|
||||||
|
btst #6,%d2
|
||||||
|
jbeq retstruct2
|
||||||
|
move.b %d0,(%a1)
|
||||||
|
jbra epilogue
|
||||||
|
|
||||||
|
retstruct2:
|
||||||
|
btst #7,%d2
|
||||||
|
jbeq noretval
|
||||||
|
move.w %d0,(%a1)
|
||||||
|
|
||||||
|
noretval:
|
||||||
|
epilogue:
|
||||||
|
move.l (%sp)+,%d2
|
||||||
|
unlk %fp
|
||||||
|
rts
|
||||||
|
CFI_ENDPROC()
|
||||||
|
.size ffi_call_SYSV,.-ffi_call_SYSV
|
||||||
|
|
||||||
|
.globl ffi_closure_SYSV
|
||||||
|
.type ffi_closure_SYSV, @function
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
ffi_closure_SYSV:
|
||||||
|
CFI_STARTPROC()
|
||||||
|
link %fp,#-12
|
||||||
|
CFI_OFFSET(14,-8)
|
||||||
|
CFI_DEF_CFA(14,8)
|
||||||
|
move.l %sp,-12(%fp)
|
||||||
|
pea 8(%fp)
|
||||||
|
pea -12(%fp)
|
||||||
|
move.l %a0,-(%sp)
|
||||||
|
#if !defined __PIC__
|
||||||
|
jsr ffi_closure_SYSV_inner
|
||||||
|
#else
|
||||||
|
bsr.l ffi_closure_SYSV_inner@PLTPC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
lsr.l #1,%d0
|
||||||
|
jne 1f
|
||||||
|
jcc .Lcls_epilogue
|
||||||
|
move.l -12(%fp),%d0
|
||||||
|
.Lcls_epilogue:
|
||||||
|
unlk %fp
|
||||||
|
rts
|
||||||
|
1:
|
||||||
|
lea -12(%fp),%a0
|
||||||
|
lsr.l #2,%d0
|
||||||
|
jne 1f
|
||||||
|
jcs .Lcls_ret_float
|
||||||
|
move.l (%a0)+,%d0
|
||||||
|
move.l (%a0),%d1
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
.Lcls_ret_float:
|
||||||
|
#if defined(__MC68881__)
|
||||||
|
fmove.s (%a0),%fp0
|
||||||
|
#else
|
||||||
|
move.l (%a0),%d0
|
||||||
|
#endif
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
1:
|
||||||
|
lsr.l #2,%d0
|
||||||
|
jne 1f
|
||||||
|
jcs .Lcls_ret_ldouble
|
||||||
|
#if defined(__MC68881__)
|
||||||
|
fmove.d (%a0),%fp0
|
||||||
|
#else
|
||||||
|
move.l (%a0)+,%d0
|
||||||
|
move.l (%a0),%d1
|
||||||
|
#endif
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
.Lcls_ret_ldouble:
|
||||||
|
#if defined(__MC68881__)
|
||||||
|
fmove.x (%a0),%fp0
|
||||||
|
#else
|
||||||
|
move.l (%a0)+,%d0
|
||||||
|
move.l (%a0)+,%d1
|
||||||
|
move.l (%a0),%d2
|
||||||
|
#endif
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
1:
|
||||||
|
lsr.l #2,%d0
|
||||||
|
jne .Lcls_ret_struct2
|
||||||
|
jcs .Lcls_ret_struct1
|
||||||
|
move.l (%a0),%a0
|
||||||
|
move.l %a0,%d0
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
.Lcls_ret_struct1:
|
||||||
|
move.b (%a0),%d0
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
.Lcls_ret_struct2:
|
||||||
|
move.w (%a0),%d0
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
CFI_ENDPROC()
|
||||||
|
|
||||||
|
.size ffi_closure_SYSV,.-ffi_closure_SYSV
|
||||||
|
|
||||||
|
.globl ffi_closure_struct_SYSV
|
||||||
|
.type ffi_closure_struct_SYSV, @function
|
||||||
|
.align 4
|
||||||
|
|
||||||
|
ffi_closure_struct_SYSV:
|
||||||
|
CFI_STARTPROC()
|
||||||
|
link %fp,#0
|
||||||
|
CFI_OFFSET(14,-8)
|
||||||
|
CFI_DEF_CFA(14,8)
|
||||||
|
move.l %sp,-12(%fp)
|
||||||
|
pea 8(%fp)
|
||||||
|
move.l %a1,-(%sp)
|
||||||
|
move.l %a0,-(%sp)
|
||||||
|
#if !defined __PIC__
|
||||||
|
jsr ffi_closure_SYSV_inner
|
||||||
|
#else
|
||||||
|
bsr.l ffi_closure_SYSV_inner@PLTPC
|
||||||
|
#endif
|
||||||
|
unlk %fp
|
||||||
|
rts
|
||||||
|
CFI_ENDPROC()
|
||||||
|
.size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV
|
||||||
|
|
||||||
|
#if defined __ELF__ && defined __linux__
|
||||||
|
.section .note.GNU-stack,"",@progbits
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/* Area: ffi_call
|
||||||
|
Purpose: Check return value signed char.
|
||||||
|
Limitations: none.
|
||||||
|
PR: none.
|
||||||
|
Originator: From the original ffitest.c */
|
||||||
|
|
||||||
|
/* { dg-do run } */
|
||||||
|
#include "ffitest.h"
|
||||||
|
|
||||||
|
static signed char return_sc(signed char sc)
|
||||||
|
{
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
int main (void)
|
||||||
|
{
|
||||||
|
ffi_cif cif;
|
||||||
|
ffi_type *args[MAX_ARGS];
|
||||||
|
void *values[MAX_ARGS];
|
||||||
|
ffi_arg rint;
|
||||||
|
signed char sc;
|
||||||
|
|
||||||
|
args[0] = &ffi_type_schar;
|
||||||
|
values[0] = ≻
|
||||||
|
|
||||||
|
/* Initialize the cif */
|
||||||
|
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
|
||||||
|
&ffi_type_schar, args) == FFI_OK);
|
||||||
|
|
||||||
|
for (sc = (signed char) -127;
|
||||||
|
sc < (signed char) 127; sc++)
|
||||||
|
{
|
||||||
|
ffi_call(&cif, FFI_FN(return_sc), &rint, values);
|
||||||
|
CHECK(rint == (ffi_arg) sc);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
@@ -1,3 +1,9 @@
|
|||||||
|
2012-01-23 Alan Hourihane <alanh@fairlite.co.uk>
|
||||||
|
|
||||||
|
* src/m68k/ffi.c (ffi_prep_closure_loc): Fix ABI check.
|
||||||
|
* src/m68k/sysv.S: Support 68881.
|
||||||
|
* testsuite/libffi.call/return_sc.c (main): Fix test check.
|
||||||
|
|
||||||
2012-01-19 Jakub Jelinek <jakub@redhat.com>
|
2012-01-19 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR rtl-optimization/48496
|
PR rtl-optimization/48496
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
Index: libffi/src/m68k/ffi.c
|
||||||
|
===================================================================
|
||||||
|
--- libffi.orig/src/m68k/ffi.c
|
||||||
|
+++ libffi/src/m68k/ffi.c
|
||||||
|
@@ -261,7 +261,8 @@ ffi_prep_closure_loc (ffi_closure* closu
|
||||||
|
void *user_data,
|
||||||
|
void *codeloc)
|
||||||
|
{
|
||||||
|
- FFI_ASSERT (cif->abi == FFI_SYSV);
|
||||||
|
+ if (cif->abi != FFI_SYSV)
|
||||||
|
+ return FFI_BAD_ABI;
|
||||||
|
|
||||||
|
*(unsigned short *)closure->tramp = 0x207c;
|
||||||
|
*(void **)(closure->tramp + 2) = codeloc;
|
||||||
|
Index: libffi/src/m68k/sysv.S
|
||||||
|
===================================================================
|
||||||
|
--- libffi.orig/src/m68k/sysv.S
|
||||||
|
+++ libffi/src/m68k/sysv.S
|
||||||
|
@@ -109,7 +109,7 @@ retlongint:
|
||||||
|
retfloat:
|
||||||
|
btst #2,%d2
|
||||||
|
jbeq retdouble
|
||||||
|
-#if defined(__MC68881__)
|
||||||
|
+#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
|
fmove.s %fp0,(%a1)
|
||||||
|
#else
|
||||||
|
move.l %d0,(%a1)
|
||||||
|
@@ -119,7 +119,7 @@ retfloat:
|
||||||
|
retdouble:
|
||||||
|
btst #3,%d2
|
||||||
|
jbeq retlongdouble
|
||||||
|
-#if defined(__MC68881__)
|
||||||
|
+#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
|
fmove.d %fp0,(%a1)
|
||||||
|
#else
|
||||||
|
move.l %d0,(%a1)+
|
||||||
|
@@ -130,7 +130,7 @@ retdouble:
|
||||||
|
retlongdouble:
|
||||||
|
btst #4,%d2
|
||||||
|
jbeq retpointer
|
||||||
|
-#if defined(__MC68881__)
|
||||||
|
+#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
|
fmove.x %fp0,(%a1)
|
||||||
|
#else
|
||||||
|
move.l %d0,(%a1)+
|
||||||
|
@@ -199,7 +199,7 @@ ffi_closure_SYSV:
|
||||||
|
move.l (%a0),%d1
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
.Lcls_ret_float:
|
||||||
|
-#if defined(__MC68881__)
|
||||||
|
+#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
|
fmove.s (%a0),%fp0
|
||||||
|
#else
|
||||||
|
move.l (%a0),%d0
|
||||||
|
@@ -209,7 +209,7 @@ ffi_closure_SYSV:
|
||||||
|
lsr.l #2,%d0
|
||||||
|
jne 1f
|
||||||
|
jcs .Lcls_ret_ldouble
|
||||||
|
-#if defined(__MC68881__)
|
||||||
|
+#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
|
fmove.d (%a0),%fp0
|
||||||
|
#else
|
||||||
|
move.l (%a0)+,%d0
|
||||||
|
@@ -217,7 +217,7 @@ ffi_closure_SYSV:
|
||||||
|
#endif
|
||||||
|
jra .Lcls_epilogue
|
||||||
|
.Lcls_ret_ldouble:
|
||||||
|
-#if defined(__MC68881__)
|
||||||
|
+#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
|
fmove.x (%a0),%fp0
|
||||||
|
#else
|
||||||
|
move.l (%a0)+,%d0
|
||||||
|
Index: libffi/testsuite/libffi.call/return_sc.c
|
||||||
|
===================================================================
|
||||||
|
--- libffi.orig/testsuite/libffi.call/return_sc.c
|
||||||
|
+++ libffi/testsuite/libffi.call/return_sc.c
|
||||||
|
@@ -30,7 +30,7 @@ int main (void)
|
||||||
|
sc < (signed char) 127; sc++)
|
||||||
|
{
|
||||||
|
ffi_call(&cif, FFI_FN(return_sc), &rint, values);
|
||||||
|
- CHECK(rint == (ffi_arg) sc);
|
||||||
|
+ CHECK((signed char)rint == sc);
|
||||||
|
}
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
@@ -37,3 +37,4 @@ interix-patch
|
|||||||
remove-debug-code
|
remove-debug-code
|
||||||
powerpc-ffi-softfloat
|
powerpc-ffi-softfloat
|
||||||
variadic
|
variadic
|
||||||
|
m68k-patches
|
||||||
|
|||||||
+2
-1
@@ -261,7 +261,8 @@ ffi_prep_closure_loc (ffi_closure* closure,
|
|||||||
void *user_data,
|
void *user_data,
|
||||||
void *codeloc)
|
void *codeloc)
|
||||||
{
|
{
|
||||||
FFI_ASSERT (cif->abi == FFI_SYSV);
|
if (cif->abi != FFI_SYSV)
|
||||||
|
return FFI_BAD_ABI;
|
||||||
|
|
||||||
*(unsigned short *)closure->tramp = 0x207c;
|
*(unsigned short *)closure->tramp = 0x207c;
|
||||||
*(void **)(closure->tramp + 2) = codeloc;
|
*(void **)(closure->tramp + 2) = codeloc;
|
||||||
|
|||||||
+6
-6
@@ -109,7 +109,7 @@ retlongint:
|
|||||||
retfloat:
|
retfloat:
|
||||||
btst #2,%d2
|
btst #2,%d2
|
||||||
jbeq retdouble
|
jbeq retdouble
|
||||||
#if defined(__MC68881__)
|
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
fmove.s %fp0,(%a1)
|
fmove.s %fp0,(%a1)
|
||||||
#else
|
#else
|
||||||
move.l %d0,(%a1)
|
move.l %d0,(%a1)
|
||||||
@@ -119,7 +119,7 @@ retfloat:
|
|||||||
retdouble:
|
retdouble:
|
||||||
btst #3,%d2
|
btst #3,%d2
|
||||||
jbeq retlongdouble
|
jbeq retlongdouble
|
||||||
#if defined(__MC68881__)
|
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
fmove.d %fp0,(%a1)
|
fmove.d %fp0,(%a1)
|
||||||
#else
|
#else
|
||||||
move.l %d0,(%a1)+
|
move.l %d0,(%a1)+
|
||||||
@@ -130,7 +130,7 @@ retdouble:
|
|||||||
retlongdouble:
|
retlongdouble:
|
||||||
btst #4,%d2
|
btst #4,%d2
|
||||||
jbeq retpointer
|
jbeq retpointer
|
||||||
#if defined(__MC68881__)
|
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
fmove.x %fp0,(%a1)
|
fmove.x %fp0,(%a1)
|
||||||
#else
|
#else
|
||||||
move.l %d0,(%a1)+
|
move.l %d0,(%a1)+
|
||||||
@@ -199,7 +199,7 @@ ffi_closure_SYSV:
|
|||||||
move.l (%a0),%d1
|
move.l (%a0),%d1
|
||||||
jra .Lcls_epilogue
|
jra .Lcls_epilogue
|
||||||
.Lcls_ret_float:
|
.Lcls_ret_float:
|
||||||
#if defined(__MC68881__)
|
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
fmove.s (%a0),%fp0
|
fmove.s (%a0),%fp0
|
||||||
#else
|
#else
|
||||||
move.l (%a0),%d0
|
move.l (%a0),%d0
|
||||||
@@ -209,7 +209,7 @@ ffi_closure_SYSV:
|
|||||||
lsr.l #2,%d0
|
lsr.l #2,%d0
|
||||||
jne 1f
|
jne 1f
|
||||||
jcs .Lcls_ret_ldouble
|
jcs .Lcls_ret_ldouble
|
||||||
#if defined(__MC68881__)
|
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
fmove.d (%a0),%fp0
|
fmove.d (%a0),%fp0
|
||||||
#else
|
#else
|
||||||
move.l (%a0)+,%d0
|
move.l (%a0)+,%d0
|
||||||
@@ -217,7 +217,7 @@ ffi_closure_SYSV:
|
|||||||
#endif
|
#endif
|
||||||
jra .Lcls_epilogue
|
jra .Lcls_epilogue
|
||||||
.Lcls_ret_ldouble:
|
.Lcls_ret_ldouble:
|
||||||
#if defined(__MC68881__)
|
#if defined(__MC68881__) || defined(__HAVE_68881__)
|
||||||
fmove.x (%a0),%fp0
|
fmove.x (%a0),%fp0
|
||||||
#else
|
#else
|
||||||
move.l (%a0)+,%d0
|
move.l (%a0)+,%d0
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ int main (void)
|
|||||||
sc < (signed char) 127; sc++)
|
sc < (signed char) 127; sc++)
|
||||||
{
|
{
|
||||||
ffi_call(&cif, FFI_FN(return_sc), &rint, values);
|
ffi_call(&cif, FFI_FN(return_sc), &rint, values);
|
||||||
CHECK(rint == (ffi_arg) sc);
|
CHECK((signed char)rint == sc);
|
||||||
}
|
}
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user