Makefile.am: Add SH support.
* Makefile.am: Add SH support. * Makefile.in: Regenerate. * configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target. * configure: Regenerate. * include/ffi.h.in: Add SH support. * src/sh/ffi.c: New file. * src/sh/sysv.S: New file. * src/types.c: Add SH support. From-SVN: r55574
This commit is contained in:
parent
7e31e4ae78
commit
ddebdfebad
9 changed files with 1526 additions and 68 deletions
|
@ -1,3 +1,14 @@
|
|||
2002-07-18 Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
* Makefile.am: Add SH support.
|
||||
* Makefile.in: Regenerate.
|
||||
* configure.in (sh-*-linux*, sh[34]*-*-linux*): Add target.
|
||||
* configure: Regenerate.
|
||||
* include/ffi.h.in: Add SH support.
|
||||
* src/sh/ffi.c: New file.
|
||||
* src/sh/sysv.S: New file.
|
||||
* src/types.c: Add SH support.
|
||||
|
||||
2002-07-16 Bo Thorsen <bo@suse.de>
|
||||
|
||||
* src/x86/ffi64.c: New file that adds x86-64 support.
|
||||
|
|
|
@ -17,7 +17,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
|
|||
src/powerpc/darwin.S src/powerpc/aix.S \
|
||||
src/powerpc/darwin_closure.S src/powerpc/aix_closures.S \
|
||||
src/arm/ffi.c src/arm/sysv.S \
|
||||
src/s390/ffi.c src/s390/sysv.S
|
||||
src/s390/ffi.c src/s390/sysv.S \
|
||||
src/sh/ffi.c src/sh/sysv.S
|
||||
|
||||
VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
|
||||
|
||||
|
@ -108,6 +109,7 @@ TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/po
|
|||
TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
|
||||
TARGET_SRC_S390 = src/s390/sysv.S src/s390/ffi.c
|
||||
TARGET_SRC_X86_64 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
|
||||
TARGET_SRC_SH = src/sh/sysv.S src/sh/ffi.c
|
||||
|
||||
##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c $(TARGET_SRC_@TARGET@)
|
||||
## Work around automake deficiency
|
||||
|
@ -173,6 +175,10 @@ if X86_64
|
|||
libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
|
||||
libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
|
||||
endif
|
||||
if SH
|
||||
libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
|
||||
libfficonvenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
|
||||
endif
|
||||
|
||||
AM_CFLAGS = -fexceptions
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
|
|||
src/powerpc/darwin.S src/powerpc/aix.S \
|
||||
src/powerpc/darwin_closure.S src/powerpc/aix_closures.S \
|
||||
src/arm/ffi.c src/arm/sysv.S \
|
||||
src/s390/ffi.c src/s390/sysv.S
|
||||
src/s390/ffi.c src/s390/sysv.S \
|
||||
src/sh/ffi.c src/sh/sysv.S
|
||||
|
||||
|
||||
VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
|
||||
|
@ -179,6 +180,7 @@ TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/po
|
|||
TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
|
||||
TARGET_SRC_S390 = src/s390/sysv.S src/s390/ffi.c
|
||||
TARGET_SRC_X86_64 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
|
||||
TARGET_SRC_SH = src/sh/sysv.S src/sh/ffi.c
|
||||
|
||||
libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
|
||||
src/raw_api.c src/java_raw_api.c
|
||||
|
@ -198,6 +200,7 @@ libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
|
|||
@ARM_TRUE@libffi_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
|
||||
@S390_TRUE@libffi_la_SOURCES = @S390_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
|
||||
@X86_64_TRUE@libffi_la_SOURCES = @X86_64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
|
||||
@SH_TRUE@libffi_la_SOURCES = @SH_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
|
||||
@MIPS_GCC_TRUE@libffi_convenience_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
|
||||
@MIPS_LINUX_TRUE@libffi_convenience_la_SOURCES = @MIPS_LINUX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_LINUX)
|
||||
@MIPS_SGI_TRUE@libffi_convenience_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
|
||||
|
@ -213,6 +216,7 @@ libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
|
|||
@ARM_TRUE@libffi_convenience_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
|
||||
@S390_TRUE@libffi_convenience_la_SOURCES = @S390_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
|
||||
@X86_64_TRUE@libffi_convenience_la_SOURCES = @X86_64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
|
||||
@SH_TRUE@libffi_convenience_la_SOURCES = @SH_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
|
||||
|
||||
AM_CFLAGS = -fexceptions
|
||||
|
||||
|
@ -261,6 +265,9 @@ libffi_convenience_la_LIBADD =
|
|||
@S390_TRUE@libffi_convenience_la_OBJECTS = src/debug.lo src/prep_cif.lo \
|
||||
@S390_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
|
||||
@S390_TRUE@src/s390/sysv.lo src/s390/ffi.lo
|
||||
@SH_TRUE@libffi_convenience_la_OBJECTS = src/debug.lo src/prep_cif.lo \
|
||||
@SH_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
|
||||
@SH_TRUE@src/sh/sysv.lo src/sh/ffi.lo
|
||||
@X86_TRUE@libffi_convenience_la_OBJECTS = src/debug.lo src/prep_cif.lo \
|
||||
@X86_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
|
||||
@X86_TRUE@src/x86/ffi.lo src/x86/sysv.lo
|
||||
|
@ -311,6 +318,8 @@ libffi_la_LIBADD =
|
|||
@X86_64_TRUE@libffi_convenience_la_OBJECTS = src/debug.lo src/prep_cif.lo \
|
||||
@X86_64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
|
||||
@X86_64_TRUE@src/x86/ffi.lo src/x86/sysv.lo src/x86/unix64.lo src/x86/ffi64.lo
|
||||
@SH_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
|
||||
@SH_TRUE@src/raw_api.lo src/java_raw_api.lo src/sh/sysv.lo src/sh/ffi.lo
|
||||
@X86_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
|
||||
@X86_TRUE@src/raw_api.lo src/java_raw_api.lo src/x86/ffi.lo \
|
||||
@X86_TRUE@src/x86/sysv.lo
|
||||
|
|
144
libffi/configure
vendored
144
libffi/configure
vendored
|
@ -2396,6 +2396,7 @@ rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
|
|||
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
|
||||
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
|
||||
x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
|
||||
sh-*-linux* | sh34*-*-linux*) TARGET=SH; TARGETDIR=sh;;
|
||||
esac
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
|
@ -2538,12 +2539,21 @@ else
|
|||
X86_64_FALSE=
|
||||
fi
|
||||
|
||||
|
||||
if test x$TARGET = xSH; then
|
||||
SH_TRUE=
|
||||
SH_FALSE='#'
|
||||
else
|
||||
SH_TRUE='#'
|
||||
SH_FALSE=
|
||||
fi
|
||||
|
||||
if test x$TARGET = xMIPS_LINUX; then
|
||||
TARGET=MIPS
|
||||
fi
|
||||
|
||||
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
|
||||
echo "configure:2547: checking how to run the C preprocessor" >&5
|
||||
echo "configure:2557: checking how to run the C preprocessor" >&5
|
||||
# On Suns, sometimes $CPP names a directory.
|
||||
if test -n "$CPP" && test -d "$CPP"; then
|
||||
CPP=
|
||||
|
@ -2558,13 +2568,13 @@ else
|
|||
# On the NeXT, cc -E runs the code through the compiler's parser,
|
||||
# not just through cpp.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2562 "configure"
|
||||
#line 2572 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:2568: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:2578: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
|
@ -2575,13 +2585,13 @@ else
|
|||
rm -rf conftest*
|
||||
CPP="${CC-cc} -E -traditional-cpp"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2579 "configure"
|
||||
#line 2589 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:2585: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:2595: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
|
@ -2592,13 +2602,13 @@ else
|
|||
rm -rf conftest*
|
||||
CPP="${CC-cc} -nologo -E"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2596 "configure"
|
||||
#line 2606 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:2602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:2612: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
|
@ -2623,12 +2633,12 @@ fi
|
|||
echo "$ac_t""$CPP" 1>&6
|
||||
|
||||
echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
|
||||
echo "configure:2627: checking for ANSI C header files" >&5
|
||||
echo "configure:2637: checking for ANSI C header files" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2632 "configure"
|
||||
#line 2642 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -2636,7 +2646,7 @@ else
|
|||
#include <float.h>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:2640: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:2650: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
|
@ -2653,7 +2663,7 @@ rm -f conftest*
|
|||
if test $ac_cv_header_stdc = yes; then
|
||||
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2657 "configure"
|
||||
#line 2667 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <string.h>
|
||||
EOF
|
||||
|
@ -2671,7 +2681,7 @@ fi
|
|||
if test $ac_cv_header_stdc = yes; then
|
||||
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2675 "configure"
|
||||
#line 2685 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <stdlib.h>
|
||||
EOF
|
||||
|
@ -2692,7 +2702,7 @@ if test "$cross_compiling" = yes; then
|
|||
:
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2696 "configure"
|
||||
#line 2706 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <ctype.h>
|
||||
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
|
||||
|
@ -2703,7 +2713,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
|
|||
exit (0); }
|
||||
|
||||
EOF
|
||||
if { (eval echo configure:2707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
if { (eval echo configure:2717: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
:
|
||||
else
|
||||
|
@ -2729,12 +2739,12 @@ fi
|
|||
for ac_func in memcpy
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:2733: checking for $ac_func" >&5
|
||||
echo "configure:2743: checking for $ac_func" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2738 "configure"
|
||||
#line 2748 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func(); below. */
|
||||
|
@ -2757,7 +2767,7 @@ $ac_func();
|
|||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2761: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:2771: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=yes"
|
||||
else
|
||||
|
@ -2784,19 +2794,19 @@ done
|
|||
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
|
||||
# for constant arguments. Useless!
|
||||
echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
|
||||
echo "configure:2788: checking for working alloca.h" >&5
|
||||
echo "configure:2798: checking for working alloca.h" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2793 "configure"
|
||||
#line 2803 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <alloca.h>
|
||||
int main() {
|
||||
char *p = alloca(2 * sizeof(int));
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:2810: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
ac_cv_header_alloca_h=yes
|
||||
else
|
||||
|
@ -2817,12 +2827,12 @@ EOF
|
|||
fi
|
||||
|
||||
echo $ac_n "checking for alloca""... $ac_c" 1>&6
|
||||
echo "configure:2821: checking for alloca" >&5
|
||||
echo "configure:2831: checking for alloca" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2826 "configure"
|
||||
#line 2836 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -2850,7 +2860,7 @@ int main() {
|
|||
char *p = (char *) alloca(1);
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:2864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
ac_cv_func_alloca_works=yes
|
||||
else
|
||||
|
@ -2882,12 +2892,12 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
|
||||
echo "configure:2886: checking whether alloca needs Cray hooks" >&5
|
||||
echo "configure:2896: checking whether alloca needs Cray hooks" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2891 "configure"
|
||||
#line 2901 "configure"
|
||||
#include "confdefs.h"
|
||||
#if defined(CRAY) && ! defined(CRAY2)
|
||||
webecray
|
||||
|
@ -2912,12 +2922,12 @@ echo "$ac_t""$ac_cv_os_cray" 1>&6
|
|||
if test $ac_cv_os_cray = yes; then
|
||||
for ac_func in _getb67 GETB67 getb67; do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:2916: checking for $ac_func" >&5
|
||||
echo "configure:2926: checking for $ac_func" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2921 "configure"
|
||||
#line 2931 "configure"
|
||||
#include "confdefs.h"
|
||||
/* System header to define __stub macros and hopefully few prototypes,
|
||||
which can conflict with char $ac_func(); below. */
|
||||
|
@ -2940,7 +2950,7 @@ $ac_func();
|
|||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:2954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
eval "ac_cv_func_$ac_func=yes"
|
||||
else
|
||||
|
@ -2967,7 +2977,7 @@ done
|
|||
fi
|
||||
|
||||
echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
|
||||
echo "configure:2971: checking stack direction for C alloca" >&5
|
||||
echo "configure:2981: checking stack direction for C alloca" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
|
@ -2975,7 +2985,7 @@ else
|
|||
ac_cv_c_stack_direction=0
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2979 "configure"
|
||||
#line 2989 "configure"
|
||||
#include "confdefs.h"
|
||||
find_stack_direction ()
|
||||
{
|
||||
|
@ -2994,7 +3004,7 @@ main ()
|
|||
exit (find_stack_direction() < 0);
|
||||
}
|
||||
EOF
|
||||
if { (eval echo configure:2998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
if { (eval echo configure:3008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
ac_cv_c_stack_direction=1
|
||||
else
|
||||
|
@ -3017,13 +3027,13 @@ fi
|
|||
|
||||
|
||||
echo $ac_n "checking size of short""... $ac_c" 1>&6
|
||||
echo "configure:3021: checking size of short" >&5
|
||||
echo "configure:3031: checking size of short" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3027 "configure"
|
||||
#line 3037 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3033,7 +3043,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (short) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3047: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_short=$ac_size
|
||||
else
|
||||
|
@ -3056,13 +3066,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of int""... $ac_c" 1>&6
|
||||
echo "configure:3060: checking size of int" >&5
|
||||
echo "configure:3070: checking size of int" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3066 "configure"
|
||||
#line 3076 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3072,7 +3082,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (int) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3076: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3086: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_int=$ac_size
|
||||
else
|
||||
|
@ -3095,13 +3105,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of long""... $ac_c" 1>&6
|
||||
echo "configure:3099: checking size of long" >&5
|
||||
echo "configure:3109: checking size of long" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3105 "configure"
|
||||
#line 3115 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3111,7 +3121,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (long) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3115: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3125: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_long=$ac_size
|
||||
else
|
||||
|
@ -3134,13 +3144,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of long long""... $ac_c" 1>&6
|
||||
echo "configure:3138: checking size of long long" >&5
|
||||
echo "configure:3148: checking size of long long" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3144 "configure"
|
||||
#line 3154 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3150,7 +3160,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (long long) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3154: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3164: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_long_long=$ac_size
|
||||
else
|
||||
|
@ -3173,13 +3183,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of float""... $ac_c" 1>&6
|
||||
echo "configure:3177: checking size of float" >&5
|
||||
echo "configure:3187: checking size of float" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3183 "configure"
|
||||
#line 3193 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3189,7 +3199,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (float) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3203: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_float=$ac_size
|
||||
else
|
||||
|
@ -3212,13 +3222,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of double""... $ac_c" 1>&6
|
||||
echo "configure:3216: checking size of double" >&5
|
||||
echo "configure:3226: checking size of double" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3222 "configure"
|
||||
#line 3232 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3228,7 +3238,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (double) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3242: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_double=$ac_size
|
||||
else
|
||||
|
@ -3251,13 +3261,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of long double""... $ac_c" 1>&6
|
||||
echo "configure:3255: checking size of long double" >&5
|
||||
echo "configure:3265: checking size of long double" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3261 "configure"
|
||||
#line 3271 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3267,7 +3277,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (long double) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3271: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3281: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_long_double=$ac_size
|
||||
else
|
||||
|
@ -3291,13 +3301,13 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking size of void *""... $ac_c" 1>&6
|
||||
echo "configure:3295: checking size of void *" >&5
|
||||
echo "configure:3305: checking size of void *" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_sizeof_void_p'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3301 "configure"
|
||||
#line 3311 "configure"
|
||||
#include "confdefs.h"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
|
@ -3307,7 +3317,7 @@ int main() {
|
|||
switch (0) case 0: case (sizeof (void *) == $ac_size):;
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3311: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3321: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_sizeof_void_p=$ac_size
|
||||
else
|
||||
|
@ -3330,14 +3340,14 @@ EOF
|
|||
|
||||
|
||||
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
|
||||
echo "configure:3334: checking whether byte ordering is bigendian" >&5
|
||||
echo "configure:3344: checking whether byte ordering is bigendian" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
ac_cv_c_bigendian=unknown
|
||||
# See if sys/param.h defines the BYTE_ORDER macro.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3341 "configure"
|
||||
#line 3351 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -3348,11 +3358,11 @@ int main() {
|
|||
#endif
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3352: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
# It does; now see whether it defined to BIG_ENDIAN or not.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3356 "configure"
|
||||
#line 3366 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -3363,7 +3373,7 @@ int main() {
|
|||
#endif
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3367: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:3377: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
ac_cv_c_bigendian=yes
|
||||
else
|
||||
|
@ -3383,7 +3393,7 @@ if test "$cross_compiling" = yes; then
|
|||
echo $ac_n "cross-compiling... " 2>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3387 "configure"
|
||||
#line 3397 "configure"
|
||||
#include "confdefs.h"
|
||||
main () {
|
||||
/* Are we little or big endian? From Harbison&Steele. */
|
||||
|
@ -3396,7 +3406,7 @@ main () {
|
|||
exit (u.c[sizeof (long) - 1] == 1);
|
||||
}
|
||||
EOF
|
||||
if { (eval echo configure:3400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
if { (eval echo configure:3410: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
|
||||
then
|
||||
ac_cv_c_bigendian=no
|
||||
else
|
||||
|
@ -3414,7 +3424,7 @@ fi
|
|||
echo "$ac_t""$ac_cv_c_bigendian" 1>&6
|
||||
if test $ac_cv_c_bigendian = unknown; then
|
||||
echo $ac_n "checking to probe for byte ordering""... $ac_c" 1>&6
|
||||
echo "configure:3418: checking to probe for byte ordering" >&5
|
||||
echo "configure:3428: checking to probe for byte ordering" >&5
|
||||
|
||||
cat >conftest.c <<EOF
|
||||
short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
|
||||
|
@ -3464,7 +3474,7 @@ fi
|
|||
|
||||
if test x$TARGET = xSPARC; then
|
||||
echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
|
||||
echo "configure:3468: checking assembler and linker support unaligned pc related relocs" >&5
|
||||
echo "configure:3478: checking assembler and linker support unaligned pc related relocs" >&5
|
||||
if eval "test \"`echo '$''{'libffi_cv_as_sparc_ua_pcrel'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
|
@ -3474,14 +3484,14 @@ else
|
|||
CFLAGS="$CFLAGS -fpic"
|
||||
LDFLAGS="$LDFLAGS -shared"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 3478 "configure"
|
||||
#line 3488 "configure"
|
||||
#include "confdefs.h"
|
||||
asm (".text; foo: nop; .data; .align 4; .byte 0; .uaword %r_disp32(foo); .text");
|
||||
int main() {
|
||||
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:3485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
if { (eval echo configure:3495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
|
||||
rm -rf conftest*
|
||||
libffi_cv_as_sparc_ua_pcrel=yes
|
||||
else
|
||||
|
@ -3768,6 +3778,8 @@ s%@S390_TRUE@%$S390_TRUE%g
|
|||
s%@S390_FALSE@%$S390_FALSE%g
|
||||
s%@X86_64_TRUE@%$X86_64_TRUE%g
|
||||
s%@X86_64_FALSE@%$X86_64_FALSE%g
|
||||
s%@SH_TRUE@%$SH_TRUE%g
|
||||
s%@SH_FALSE@%$SH_FALSE%g
|
||||
s%@CPP@%$CPP%g
|
||||
s%@ALLOCA@%$ALLOCA%g
|
||||
s%@TARGET@%$TARGET%g
|
||||
|
|
|
@ -71,6 +71,7 @@ rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
|
|||
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
|
||||
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
|
||||
x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
|
||||
sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
|
||||
esac
|
||||
|
||||
if test $TARGETDIR = unknown; then
|
||||
|
@ -92,6 +93,7 @@ AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
|
|||
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
|
||||
AM_CONDITIONAL(S390, test x$TARGET = xS390)
|
||||
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
|
||||
AM_CONDITIONAL(SH, test x$TARGET = xSH)
|
||||
|
||||
if test x$TARGET = xMIPS_LINUX; then
|
||||
TARGET=MIPS
|
||||
|
|
|
@ -262,6 +262,12 @@ typedef enum ffi_abi {
|
|||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#endif
|
||||
|
||||
/* ---- SuperH ------------------- */
|
||||
#ifdef SH
|
||||
FFI_SYSV,
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
#endif
|
||||
|
||||
/* Leave this for debugging purposes */
|
||||
FFI_LAST_ABI
|
||||
|
||||
|
@ -435,6 +441,12 @@ struct ffi_ia64_trampoline_struct {
|
|||
#define FFI_TRAMPOLINE_SIZE 24 /* see struct below */
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#elif defined(SH)
|
||||
|
||||
#define FFI_CLOSURES 1
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_NATIVE_RAW_API 0
|
||||
|
||||
#else
|
||||
|
||||
#define FFI_CLOSURES 0
|
||||
|
|
722
libffi/src/sh/ffi.c
Normal file
722
libffi/src/sh/ffi.c
Normal file
|
@ -0,0 +1,722 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
ffi.c - Copyright (c) 2002 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 CYGNUS SOLUTIONS 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 */
|
||||
|
||||
/*@-exportheader@*/
|
||||
void ffi_prep_args(char *stack, extended_cif *ecif)
|
||||
/*@=exportheader@*/
|
||||
{
|
||||
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;
|
||||
greg += n;
|
||||
#else
|
||||
if (greg >= NGREGARG)
|
||||
continue;
|
||||
else if (greg + n - 1 >= NGREGARG)
|
||||
greg = NGREGARG;
|
||||
else
|
||||
greg += n;
|
||||
#endif
|
||||
memcpy (argp, *p_argv, z);
|
||||
argp += z;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 += z;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
greg = NGREGARG;
|
||||
else
|
||||
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;
|
||||
}
|
||||
|
||||
/*@-declundef@*/
|
||||
/*@-exportheader@*/
|
||||
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
|
||||
/*@out@*/ extended_cif *,
|
||||
unsigned, unsigned,
|
||||
/*@out@*/ unsigned *,
|
||||
void (*fn)());
|
||||
/*@=declundef@*/
|
||||
/*@=exportheader@*/
|
||||
|
||||
void ffi_call(/*@dependent@*/ ffi_cif *cif,
|
||||
void (*fn)(),
|
||||
/*@out@*/ void *rvalue,
|
||||
/*@dependent@*/ 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))
|
||||
{
|
||||
/*@-sysunrecog@*/
|
||||
ecif.rvalue = alloca(cif->rtype->size);
|
||||
/*@=sysunrecog@*/
|
||||
}
|
||||
else
|
||||
ecif.rvalue = rvalue;
|
||||
|
||||
|
||||
switch (cif->abi)
|
||||
{
|
||||
case FFI_SYSV:
|
||||
/*@-usedef@*/
|
||||
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
|
||||
cif->flags, ecif.rvalue, fn);
|
||||
/*@=usedef@*/
|
||||
break;
|
||||
default:
|
||||
FFI_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern void ffi_closure_SYSV (void);
|
||||
#if defined(__SH4__)
|
||||
extern void __ic_invalidate (void *line);
|
||||
#endif
|
||||
|
||||
ffi_status
|
||||
ffi_prep_closure (ffi_closure* closure,
|
||||
ffi_cif* cif,
|
||||
void (*fun)(ffi_cif*, void*, void**, void*),
|
||||
void *user_data)
|
||||
{
|
||||
unsigned int *tramp;
|
||||
|
||||
FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
|
||||
|
||||
tramp = (unsigned int *) &closure->tramp[0];
|
||||
#ifdef __LITTLE_ENDIAN__
|
||||
tramp[0] = 0xd301d202;
|
||||
tramp[1] = 0x0009422b;
|
||||
#else
|
||||
tramp[0] = 0xd202d301;
|
||||
tramp[1] = 0x422b0009;
|
||||
#endif
|
||||
*(void **) &tramp[2] = (void *)closure; /* 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(&closure->tramp[0]);
|
||||
#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 2
|
||||
#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;
|
||||
double temp;
|
||||
|
||||
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)
|
||||
{
|
||||
rvalue = *pgr++;
|
||||
ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
|
||||
}
|
||||
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;
|
||||
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;
|
||||
greg += n;
|
||||
#else
|
||||
if (greg >= NGREGARG)
|
||||
continue;
|
||||
else if (greg + n - 1 >= NGREGARG)
|
||||
greg = NGREGARG;
|
||||
else
|
||||
greg += n;
|
||||
#endif
|
||||
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 = NGREGARG;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
avalue[i] = pst;
|
||||
pst += n;
|
||||
}
|
||||
}
|
||||
|
||||
(closure->fun) (cif, rvalue, avalue, closure->user_data);
|
||||
|
||||
/* Tell ffi_closure_osf how to perform return type promotions. */
|
||||
return cif->rtype->type;
|
||||
}
|
674
libffi/src/sh/sysv.S
Normal file
674
libffi/src/sh/sysv.S
Normal file
|
@ -0,0 +1,674 @@
|
|||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 2002 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 CYGNUS SOLUTIONS 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 <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)
|
||||
#if defined(__SH4__)
|
||||
# Save registers
|
||||
mov.l r8,@-r15
|
||||
mov.l r9,@-r15
|
||||
mov.l r10,@-r15
|
||||
mov.l r12,@-r15
|
||||
mov.l r14,@-r15
|
||||
sts.l pr,@-r15
|
||||
mov r15,r14
|
||||
|
||||
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 r15,r0
|
||||
and #7,r0
|
||||
tst r0,r0
|
||||
bt 2f
|
||||
add #4,r15
|
||||
2:
|
||||
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
|
||||
# Save registers
|
||||
mov.l r8,@-r15
|
||||
mov.l r9,@-r15
|
||||
mov.l r10,@-r15
|
||||
mov.l r12,@-r15
|
||||
mov.l r14,@-r15
|
||||
sts.l pr,@-r15
|
||||
mov r15,r14
|
||||
|
||||
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:
|
||||
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
|
||||
|
||||
.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)
|
||||
mov.l r14,@-r15
|
||||
sts.l pr,@-r15
|
||||
|
||||
/* Stack layout:
|
||||
...
|
||||
32 bytes (floating register parameters, SH-4 only)
|
||||
16 bytes (register parameters)
|
||||
4 bytes (result)
|
||||
4 bytes (5th arg)
|
||||
<- new stack pointer
|
||||
*/
|
||||
#if defined(__SH4__)
|
||||
add #-56,r15
|
||||
#else
|
||||
add #-24,r15
|
||||
#endif
|
||||
mov r15,r14
|
||||
|
||||
mov r14,r1
|
||||
add #24,r1
|
||||
mov.l r7,@-r1
|
||||
mov.l r6,@-r1
|
||||
mov.l r5,@-r1
|
||||
mov.l r4,@-r1
|
||||
mov r1,r6
|
||||
|
||||
#if defined(__SH4__)
|
||||
mov r14,r1
|
||||
add #56,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
|
||||
#endif
|
||||
|
||||
mov r14,r1
|
||||
add #4,r1
|
||||
mov r1,r5
|
||||
|
||||
mov r14,r1
|
||||
#if defined(__SH4__)
|
||||
add #64,r1
|
||||
#else
|
||||
add #32,r1
|
||||
#endif
|
||||
mov.l r1,@r14
|
||||
|
||||
mov.l L_helper,r0
|
||||
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 #4,r2
|
||||
0:
|
||||
.align 2
|
||||
L_helper:
|
||||
.long ffi_closure_helper_SYSV
|
||||
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 #56,r15
|
||||
#else
|
||||
add #24,r15
|
||||
#endif
|
||||
lds.l @r15+,pr
|
||||
rts
|
||||
mov.l @r15+,r14
|
||||
|
||||
.ffi_closure_SYSV_end:
|
||||
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
|
|
@ -57,6 +57,11 @@ FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
|
|||
FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
|
||||
FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
|
||||
|
||||
#elif defined SH
|
||||
|
||||
FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
|
||||
FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
|
||||
|
||||
#else
|
||||
|
||||
FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64);
|
||||
|
@ -75,6 +80,11 @@ FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
|
|||
FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
|
||||
FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
|
||||
|
||||
#elif defined SH
|
||||
|
||||
FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
|
||||
FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
|
||||
|
||||
#elif defined SPARC
|
||||
|
||||
FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
|
||||
|
|
Loading…
Add table
Reference in a new issue