OSDN Git Service

* Makefile.am: Add SH support.
authorkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Jul 2002 01:08:43 +0000 (01:08 +0000)
committerkkojima <kkojima@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Jul 2002 01:08:43 +0000 (01:08 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55574 138bc75d-0d04-0410-961f-82ee72b054a4

libffi/ChangeLog
libffi/Makefile.am
libffi/Makefile.in
libffi/configure
libffi/configure.in
libffi/include/ffi.h.in
libffi/src/sh/ffi.c [new file with mode: 0644]
libffi/src/sh/sysv.S [new file with mode: 0644]
libffi/src/types.c

index bee2111..ee4e9b8 100644 (file)
@@ -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.
index d21c933..cafeab7 100644 (file)
@@ -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
 
index 793c3aa..47d1353 100644 (file)
@@ -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
index d18f6dd..0926aa9 100755 (executable)
@@ -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
index 7852a98..8db6634 100644 (file)
@@ -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
index 49e4570..8fc37f5 100644 (file)
@@ -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
diff --git a/libffi/src/sh/ffi.c b/libffi/src/sh/ffi.c
new file mode 100644 (file)
index 0000000..eb59446
--- /dev/null
@@ -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;
+}
diff --git a/libffi/src/sh/sysv.S b/libffi/src/sh/sysv.S
new file mode 100644 (file)
index 0000000..b6a06b8
--- /dev/null
@@ -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)
index a4a2d06..81a2be6 100644 (file)
@@ -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);