Makefile.am: Add Linux for S/390 support.
authorGerhard Tonn <GerhardTonn@swol.de>
Mon, 29 Apr 2002 04:14:44 +0000 (04:14 +0000)
committerBryce McKinlay <bryce@gcc.gnu.org>
Mon, 29 Apr 2002 04:14:44 +0000 (05:14 +0100)
2002-04-29  Gerhard Tonn  <GerhardTonn@swol.de>

* Makefile.am: Add Linux for S/390 support.
* Makefile.in: Regenerate.
* configure.in: Add Linux for S/390 support.
* configure: Regenerate.
* include/ffi.h.in: Add Linux for S/390 support.
* src/s390/ffi.c: New file from libffi CVS tree.
* src/s390/sysv.S: New file from libffi CVS tree.

From-SVN: r52873

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

index cd5a456..dc7cedd 100644 (file)
@@ -1,3 +1,13 @@
+2002-04-29  Gerhard Tonn  <GerhardTonn@swol.de>
+
+       * Makefile.am: Add Linux for S/390 support.
+       * Makefile.in: Regenerate.
+       * configure.in: Add Linux for S/390 support.
+       * configure: Regenerate.
+       * include/ffi.h.in: Add Linux for S/390 support.
+       * src/s390/ffi.c: New file from libffi CVS tree.
+       * src/s390/sysv.S: New file from libffi CVS tree.
+
 2002-04-28  Jakub Jelinek  <jakub@redhat.com>
 
        * configure.in (HAVE_AS_SPARC_UA_PCREL): Check for working
index 4d1120d..5281c58 100644 (file)
@@ -15,7 +15,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
                src/powerpc/ffi_darwin.c \
                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/arm/ffi.c src/arm/sysv.S \
+               src/s390/ffi.c src/s390/sysv.S
 
 VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
 
@@ -103,6 +104,7 @@ TARGET_SRC_POWERPC = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closur
 TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
 TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
 TARGET_SRC_ARM =  src/arm/sysv.S src/arm/ffi.c
+TARGET_SRC_S390 =  src/s390/sysv.S src/s390/ffi.c
 
 ##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c $(TARGET_SRC_@TARGET@)
 ## Work around automake deficiency
@@ -156,6 +158,10 @@ if ARM
 libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
 libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
 endif
+if S390
+libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
+libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
+endif
 
 AM_CFLAGS = -fexceptions
 
index 24f2930..0e61ec2 100644 (file)
@@ -96,7 +96,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
                src/powerpc/ffi_darwin.c \
                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/arm/ffi.c src/arm/sysv.S \
+               src/s390/ffi.c src/s390/sysv.S
 
 
 VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
@@ -174,6 +175,7 @@ TARGET_SRC_POWERPC = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closur
 TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
 TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
 TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
+TARGET_SRC_S390 = src/s390/sysv.S src/s390/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
@@ -190,6 +192,7 @@ libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
 @POWERPC_AIX_TRUE@libffi_la_SOURCES = @POWERPC_AIX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
 @POWERPC_DARWIN_TRUE@libffi_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
 @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)
 @MIPS_GCC_TRUE@libffi_convenience_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
 @MIPS_SGI_TRUE@libffi_convenience_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
 @X86_TRUE@libffi_convenience_la_SOURCES = @X86_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86)
@@ -202,6 +205,7 @@ libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
 @POWERPC_AIX_TRUE@libffi_convenience_la_SOURCES = @POWERPC_AIX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_AIX)
 @POWERPC_DARWIN_TRUE@libffi_convenience_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
 @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)
 
 AM_CFLAGS = -fexceptions
 
@@ -244,6 +248,9 @@ libffi_convenience_la_LIBADD =
 @MIPS_SGI_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @MIPS_SGI_TRUE@src/java_raw_api.lo src/mips/ffi.lo src/mips/o32.lo \
 @MIPS_SGI_TRUE@src/mips/n32.lo
+@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
 @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
@@ -285,6 +292,9 @@ libffi_la_LIBADD =
 @MIPS_SGI_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @MIPS_SGI_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @MIPS_SGI_TRUE@src/mips/ffi.lo src/mips/o32.lo src/mips/n32.lo
+@S390_TRUE@libffi_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
 @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
@@ -579,8 +589,8 @@ distdir: $(DISTFILES)
        -chmod 777 $(distdir)
        $(mkinstalldirs) $(distdir)/src/alpha $(distdir)/src/arm \
           $(distdir)/src/m68k $(distdir)/src/mips \
-          $(distdir)/src/powerpc $(distdir)/src/sparc \
-          $(distdir)/src/x86
+          $(distdir)/src/powerpc $(distdir)/src/s390 \
+          $(distdir)/src/sparc $(distdir)/src/x86
        @for file in $(DISTFILES); do \
          if test -f $$file; then d=.; else d=$(srcdir); fi; \
          if test -d $$d/$$file; then \
index 9649aba..7e3d5ed 100755 (executable)
@@ -2386,6 +2386,7 @@ powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
 powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -2501,8 +2502,17 @@ else
   ARM_FALSE=
 fi
 
+
+if test x$TARGET = xS390; then
+  S390_TRUE=
+  S390_FALSE='#'
+else
+  S390_TRUE='#'
+  S390_FALSE=
+fi
+
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:2506: checking how to run the C preprocessor" >&5
+echo "configure:2516: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -2517,13 +2527,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 2521 "configure"
+#line 2531 "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:2527: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2537: \"$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
   :
@@ -2534,13 +2544,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 2538 "configure"
+#line 2548 "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:2544: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2554: \"$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
   :
@@ -2551,13 +2561,13 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 2555 "configure"
+#line 2565 "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:2561: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2571: \"$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
   :
@@ -2582,12 +2592,12 @@ fi
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2586: checking for ANSI C header files" >&5
+echo "configure:2596: 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 2591 "configure"
+#line 2601 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2595,7 +2605,7 @@ else
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2599: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2609: \"$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*
@@ -2612,7 +2622,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 2616 "configure"
+#line 2626 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2630,7 +2640,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 2634 "configure"
+#line 2644 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2651,7 +2661,7 @@ if test "$cross_compiling" = yes; then
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2655 "configure"
+#line 2665 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2662,7 +2672,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
 exit (0); }
 
 EOF
-if { (eval echo configure:2666: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2688,12 +2698,12 @@ fi
 for ac_func in memcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2692: checking for $ac_func" >&5
+echo "configure:2702: 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 2697 "configure"
+#line 2707 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2716,7 +2726,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2730: \"$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
@@ -2743,19 +2753,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:2747: checking for working alloca.h" >&5
+echo "configure:2757: 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 2752 "configure"
+#line 2762 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:2759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2769: \"$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
@@ -2776,12 +2786,12 @@ EOF
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:2780: checking for alloca" >&5
+echo "configure:2790: 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 2785 "configure"
+#line 2795 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -2809,7 +2819,7 @@ int main() {
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:2813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2823: \"$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
@@ -2841,12 +2851,12 @@ EOF
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2845: checking whether alloca needs Cray hooks" >&5
+echo "configure:2855: 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 2850 "configure"
+#line 2860 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -2871,12 +2881,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:2875: checking for $ac_func" >&5
+echo "configure:2885: 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 2880 "configure"
+#line 2890 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2899,7 +2909,7 @@ $ac_func();
 
 ; return 0; }
 EOF
-if { (eval echo configure:2903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2913: \"$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
@@ -2926,7 +2936,7 @@ done
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2930: checking stack direction for C alloca" >&5
+echo "configure:2940: 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
@@ -2934,7 +2944,7 @@ else
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2938 "configure"
+#line 2948 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -2953,7 +2963,7 @@ main ()
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:2957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2967: \"$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
@@ -2976,13 +2986,13 @@ fi
 
 
 echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:2980: checking size of short" >&5
+echo "configure:2990: 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 2986 "configure"
+#line 2996 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -2992,7 +3002,7 @@ int main() {
 switch (0) case 0: case (sizeof (short) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:2996: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_short=$ac_size
 else
@@ -3015,13 +3025,13 @@ EOF
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:3019: checking size of int" >&5
+echo "configure:3029: 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 3025 "configure"
+#line 3035 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3031,7 +3041,7 @@ int main() {
 switch (0) case 0: case (sizeof (int) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3035: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_int=$ac_size
 else
@@ -3054,13 +3064,13 @@ EOF
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:3058: checking size of long" >&5
+echo "configure:3068: 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 3064 "configure"
+#line 3074 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3070,7 +3080,7 @@ int main() {
 switch (0) case 0: case (sizeof (long) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3074: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3084: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long=$ac_size
 else
@@ -3093,13 +3103,13 @@ EOF
 
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:3097: checking size of long long" >&5
+echo "configure:3107: 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 3103 "configure"
+#line 3113 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3109,7 +3119,7 @@ int main() {
 switch (0) case 0: case (sizeof (long long) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3123: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long_long=$ac_size
 else
@@ -3132,13 +3142,13 @@ EOF
 
 
 echo $ac_n "checking size of float""... $ac_c" 1>&6
-echo "configure:3136: checking size of float" >&5
+echo "configure:3146: 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 3142 "configure"
+#line 3152 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3148,7 +3158,7 @@ int main() {
 switch (0) case 0: case (sizeof (float) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3152: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_float=$ac_size
 else
@@ -3171,13 +3181,13 @@ EOF
 
 
 echo $ac_n "checking size of double""... $ac_c" 1>&6
-echo "configure:3175: checking size of double" >&5
+echo "configure:3185: 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 3181 "configure"
+#line 3191 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3187,7 +3197,7 @@ int main() {
 switch (0) case 0: case (sizeof (double) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3191: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_double=$ac_size
 else
@@ -3210,13 +3220,13 @@ EOF
 
 
 echo $ac_n "checking size of long double""... $ac_c" 1>&6
-echo "configure:3214: checking size of long double" >&5
+echo "configure:3224: 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 3220 "configure"
+#line 3230 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3226,7 +3236,7 @@ int main() {
 switch (0) case 0: case (sizeof (long double) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3230: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3240: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long_double=$ac_size
 else
@@ -3250,13 +3260,13 @@ EOF
 
 
 echo $ac_n "checking size of void *""... $ac_c" 1>&6
-echo "configure:3254: checking size of void *" >&5
+echo "configure:3264: 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 3260 "configure"
+#line 3270 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3266,7 +3276,7 @@ int main() {
 switch (0) case 0: case (sizeof (void *) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3270: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3280: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_void_p=$ac_size
 else
@@ -3289,14 +3299,14 @@ EOF
 
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:3293: checking whether byte ordering is bigendian" >&5
+echo "configure:3303: 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 3300 "configure"
+#line 3310 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -3307,11 +3317,11 @@ int main() {
 #endif
 ; 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*
   # It does; now see whether it defined to BIG_ENDIAN or not.
 cat > conftest.$ac_ext <<EOF
-#line 3315 "configure"
+#line 3325 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -3322,7 +3332,7 @@ int main() {
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:3326: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3336: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -3342,7 +3352,7 @@ if test "$cross_compiling" = yes; then
    echo $ac_n "cross-compiling... " 2>&6 
 else
   cat > conftest.$ac_ext <<EOF
-#line 3346 "configure"
+#line 3356 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -3355,7 +3365,7 @@ main () {
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:3359: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3369: \"$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
@@ -3373,7 +3383,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:3377: checking to probe for byte ordering" >&5
+echo "configure:3387: checking to probe for byte ordering" >&5
 
 cat >conftest.c <<EOF
 short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
@@ -3423,7 +3433,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:3426: checking assembler and linker support unaligned pc related relocs" >&5
+echo "configure:3437: 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
@@ -3433,14 +3443,14 @@ else
        CFLAGS="$CFLAGS -fpic"
        LDFLAGS="$LDFLAGS -shared"
        cat > conftest.$ac_ext <<EOF
-#line 3436 "configure"
+#line 3447 "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:3442: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3454: \"$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
@@ -3721,6 +3731,8 @@ s%@POWERPC_DARWIN_TRUE@%$POWERPC_DARWIN_TRUE%g
 s%@POWERPC_DARWIN_FALSE@%$POWERPC_DARWIN_FALSE%g
 s%@ARM_TRUE@%$ARM_TRUE%g
 s%@ARM_FALSE@%$ARM_FALSE%g
+s%@S390_TRUE@%$S390_TRUE%g
+s%@S390_FALSE@%$S390_FALSE%g
 s%@CPP@%$CPP%g
 s%@ALLOCA@%$ALLOCA%g
 s%@TARGET@%$TARGET%g
index 9e9ab1c..b2cb516 100644 (file)
@@ -61,6 +61,7 @@ powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
 powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
+s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -79,6 +80,7 @@ AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
 AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
 AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
+AM_CONDITIONAL(S390, test x$TARGET = xS390)
 
 AC_HEADER_STDC
 AC_CHECK_FUNCS(memcpy)
index 4f75451..13aa274 100644 (file)
@@ -99,7 +99,7 @@ DIST_COMMON =  Makefile.am Makefile.in ffi.h.in
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gnutar
+TAR = gtar
 GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
index 8097917..90dfa51 100644 (file)
@@ -251,6 +251,12 @@ typedef enum ffi_abi {
   FFI_DEFAULT_ABI = FFI_SYSV,
 #endif
 
+  /* ---- S390 --------------------- */
+#ifdef S390
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
   /* Leave this for debugging purposes */
   FFI_LAST_ABI
 
diff --git a/libffi/src/s390/ffi.c b/libffi/src/s390/ffi.c
new file mode 100644 (file)
index 0000000..8b514e3
--- /dev/null
@@ -0,0 +1,589 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2000 Software AG
+   S390 Foreign Function Interface
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL THE AUTHOR 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.
+   ----------------------------------------------------------------------- */
+/*====================================================================*/
+/*                          Includes                                  */
+/*                          --------                                  */
+/*====================================================================*/
+#include <ffi.h>
+#include <ffi_common.h>
+#include <stdlib.h>
+#include <stdio.h>
+/*====================== End of Includes =============================*/
+/*====================================================================*/
+/*                           Defines                                  */
+/*                           -------                                  */
+/*====================================================================*/
+#define MAX_GPRARGS 5        /* Max. no. of GPR available             */
+#define MAX_FPRARGS 2        /* Max. no. of FPR available             */
+#define STR_GPR     1        /* Structure will fit in 1 or 2 GPR      */
+#define STR_FPR     2        /* Structure will fit in a FPR           */
+#define STR_STACK   3        /* Structure needs to go on stack        */
+/*===================== End of Defines ===============================*/
+/*====================================================================*/
+/*                            Types                                   */
+/*                            -----                                   */
+/*====================================================================*/
+typedef struct stackLayout
+{
+  int   *backChain;
+  int   *endOfStack;
+  int   glue[2];
+  int   scratch[2];
+  int   gprArgs[MAX_GPRARGS];
+  int   notUsed;
+  union
+  {
+    float  f;
+    double d;
+  } fprArgs[MAX_FPRARGS];
+  int   unUsed[8];
+  int   outArgs[100];
+} stackLayout;
+/*======================== End of Types ==============================*/
+/*====================================================================*/
+/*                          Prototypes                                */
+/*                          ----------                                */
+/*====================================================================*/
+void ffi_prep_args(stackLayout *, extended_cif *);
+static int  ffi_check_struct(ffi_type *, unsigned int *);
+static void ffi_insert_int(int, stackLayout *, int *, int *);
+static void ffi_insert_int64(long long, stackLayout *, int *, int *);
+static void ffi_insert_double(double, stackLayout *, int *, int *);
+/*====================== End of Prototypes ===========================*/
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          ---------                                 */
+/*====================================================================*/
+extern void ffi_call_SYSV(void (*)(stackLayout *, extended_cif *),
+                         extended_cif *,
+                         unsigned, unsigned,
+                         unsigned *,
+                         void (*fn)());
+/*====================== End of Externals ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_check_struct.                                       */
+/*                                                                    */
+/* Function - Determine if a structure can be passed within a         */
+/*            general or floating point register.                     */
+/*                                                                    */
+/*====================================================================*/
+int
+ffi_check_struct(ffi_type *arg, unsigned int *strFlags)
+{
+ ffi_type *element;
+ int      i_Element;
+ for (i_Element = 0; arg->elements[i_Element]; i_Element++) {
+   element = arg->elements[i_Element];
+   switch (element->type) {
+   case FFI_TYPE_DOUBLE :
+     *strFlags |= STR_FPR;
+     break;
+     
+   case FFI_TYPE_STRUCT :
+     *strFlags |= ffi_check_struct(element, strFlags);
+     break;
+     
+   default :
+     *strFlags |= STR_GPR;
+   }
+ }
+ return (*strFlags);
+}
+/*======================== End of Routine ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_int.                                         */
+/*                                                                    */
+/* Function - Insert an integer parameter in a register if there are  */
+/*            spares else on the stack.                               */
+/*                                                                    */
+/*====================================================================*/
+void
+ffi_insert_int(int gprValue, stackLayout *stack,
+               int *intArgC, int *outArgC)
+{
+  if (*intArgC < MAX_GPRARGS) {
+    stack->gprArgs[*intArgC] = gprValue;
+    *intArgC += 1;
+  }
+  else {
+    stack->outArgs[*outArgC++] = gprValue;
+    *outArgC += 1;
+  }
+}
+/*======================== End of Routine ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_int64.                                       */
+/*                                                                    */
+/* Function - Insert a long long parameter in registers if there are  */
+/*            spares else on the stack.                               */
+/*                                                                    */
+/*====================================================================*/
+void
+ffi_insert_int64(long long llngValue, stackLayout *stack,
+                 int *intArgC, int *outArgC)
+{
+  if (*intArgC < (MAX_GPRARGS-1)) {
+    memcpy(&stack->gprArgs[*intArgC],
+          &llngValue, sizeof(long long));      
+    *intArgC += 2;
+  }
+  else {
+    memcpy(&stack->outArgs[*outArgC],
+          &llngValue, sizeof(long long));
+    *outArgC += 2;
+  }
+}
+/*======================== End of Routine ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_insert_double.                                      */
+/*                                                                    */
+/* Function - Insert a double parameter in a FP register if there is  */
+/*            a spare else on the stack.                              */
+/*                                                                    */
+/*====================================================================*/
+void
+ffi_insert_double(double dblValue, stackLayout *stack,
+                  int *fprArgC, int *outArgC)
+{
+  if (*fprArgC < MAX_FPRARGS) {
+    stack->fprArgs[*fprArgC].d = dblValue;
+    *fprArgC += 1;
+  }
+  else {
+    memcpy(&stack->outArgs[*outArgC],
+          &dblValue,sizeof(double));
+    *outArgC += 2;
+  }
+}
+/*======================== End of Routine ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_args.                                          */
+/*                                                                    */
+/* Function - Prepare parameters for call to function.                */
+/*                                                                    */
+/* ffi_prep_args is called by the assembly routine once stack space   */
+/* has been allocated for the function's arguments.                   */
+/*                                                                    */
+/* The stack layout we want looks like this:                          */
+/* *------------------------------------------------------------*     */
+/* |  0     | Back chain (a 0 here signifies end of back chain) |     */
+/* +--------+---------------------------------------------------+     */
+/* |  4     | EOS (end of stack, not used on Linux for S390)    |     */
+/* +--------+---------------------------------------------------+     */
+/* |  8     | Glue used in other linkage formats                |     */
+/* +--------+---------------------------------------------------+     */
+/* | 12     | Glue used in other linkage formats                |     */
+/* +--------+---------------------------------------------------+     */
+/* | 16     | Scratch area                                      |     */
+/* +--------+---------------------------------------------------+     */
+/* | 20     | Scratch area                                      |     */
+/* +--------+---------------------------------------------------+     */
+/* | 24     | GPR parameter register 1                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 28     | GPR parameter register 2                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 32     | GPR parameter register 3                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 36     | GPR parameter register 4                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 40     | GPR parameter register 5                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 44     | Unused                                            |     */
+/* +--------+---------------------------------------------------+     */
+/* | 48     | FPR parameter register 1                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 56     | FPR parameter register 2                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 64     | Unused                                            |     */
+/* +--------+---------------------------------------------------+     */
+/* | 96     | Outgoing args (length x)                          |     */
+/* +--------+---------------------------------------------------+     */
+/* | 96+x   | Copy area for structures (length y)               |     */
+/* +--------+---------------------------------------------------+     */
+/* | 96+x+y | Possible stack alignment                          |     */
+/* *------------------------------------------------------------*     */
+/*                                                                    */
+/*====================================================================*/
+void
+ffi_prep_args(stackLayout *stack, extended_cif *ecif)
+{
+  const unsigned bytes = ecif->cif->bytes;
+  const unsigned flags = ecif->cif->flags;
+  /*----------------------------------------------------------*/
+  /* Pointer to the copy area on stack for structures         */
+  /*----------------------------------------------------------*/
+  char *copySpace = (char *) stack + bytes + sizeof(stackLayout);
+  /*----------------------------------------------------------*/
+  /* Count of general and floating point register usage       */
+  /*----------------------------------------------------------*/
+  int intArgC = 0,
+    fprArgC = 0,
+    outArgC = 0;
+  int      i;
+  ffi_type **ptr;
+  void     **p_argv;
+  size_t   structCopySize;
+  unsigned gprValue, strFlags = 0;
+  unsigned long long llngValue;
+  double   dblValue;
+  /* Now for the arguments.  */
+  p_argv  = ecif->avalue;
+  /*----------------------------------------------------------------------*/
+  /* If we returning a structure then we set the first parameter register */
+  /* to the address of where we are returning this structure              */
+  /*----------------------------------------------------------------------*/
+  if (flags == FFI_TYPE_STRUCT)
+    stack->gprArgs[intArgC++] = (int) ecif->rvalue;
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      switch ((*ptr)->type) {
+      case FFI_TYPE_FLOAT:
+       if (fprArgC < MAX_FPRARGS)
+         stack->fprArgs[fprArgC++].f = *(float *) *p_argv;
+       else
+         stack->outArgs[outArgC++] = *(int *) *p_argv;
+       break;
+      case FFI_TYPE_DOUBLE:
+       dblValue = *(double *) *p_argv;
+       ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
+       break;
+       
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+       llngValue = *(unsigned long long *) *p_argv;
+       ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
+       break;
+      case FFI_TYPE_UINT8:
+       gprValue = *(unsigned char *)*p_argv;
+       ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+       break;
+      case FFI_TYPE_SINT8:
+       gprValue = *(signed char *)*p_argv;
+       ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+       break;
+      case FFI_TYPE_UINT16:
+       gprValue = *(unsigned short *)*p_argv;
+       ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+       break;
+      case FFI_TYPE_SINT16:
+       gprValue = *(signed short *)*p_argv;
+       ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+       break;
+      case FFI_TYPE_STRUCT:
+       /*--------------------------------------------------*/
+       /* If structure > 8 bytes then it goes on the stack */
+       /*--------------------------------------------------*/
+       if (((*ptr)->size > 8) ||
+           ((*ptr)->size > 4  &&
+            (*ptr)->size < 8))
+         strFlags = STR_STACK;
+       else
+         strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags);
+       switch (strFlags) {
+       /*-------------------------------------------*/
+       /* Structure that will fit in one or two GPR */
+       /*-------------------------------------------*/
+       case STR_GPR :
+         if ((*ptr)->size <= 4) {
+           gprValue = *(unsigned int *) *p_argv;
+           gprValue = gprValue >> ((4 - (*ptr)->size) * 8);
+           ffi_insert_int(gprValue, stack, &intArgC, &outArgC);
+         }
+         else {
+           llngValue = *(unsigned long long *) *p_argv;
+           ffi_insert_int64(llngValue, stack, &intArgC, &outArgC);
+         }
+         break;
+       /*-------------------------------------------*/
+       /* Structure that will fit in one FPR        */
+       /*-------------------------------------------*/
+       case STR_FPR :
+         dblValue = *(double *) *p_argv;
+         ffi_insert_double(dblValue, stack, &fprArgC, &outArgC);
+         break;
+       /*-------------------------------------------*/
+       /* Structure that must be copied to stack    */
+       /*-------------------------------------------*/
+       default :
+         structCopySize = (((*ptr)->size + 15) & ~0xF);
+         copySpace -= structCopySize;
+         memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+         gprValue = (unsigned) copySpace;
+         if (intArgC < MAX_GPRARGS)
+           stack->gprArgs[intArgC++] = gprValue;
+         else
+           stack->outArgs[outArgC++] = gprValue;
+       }
+       break;
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+      case FFI_TYPE_LONGDOUBLE:
+       structCopySize = (((*ptr)->size + 15) & ~0xF);
+       copySpace -= structCopySize;
+       memcpy(copySpace, (char *)*p_argv, (*ptr)->size);
+       gprValue = (unsigned) copySpace;
+       if (intArgC < MAX_GPRARGS)
+         stack->gprArgs[intArgC++] = gprValue;
+       else
+         stack->outArgs[outArgC++] = gprValue;
+       break;
+#endif
+      case FFI_TYPE_INT:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_POINTER:
+       gprValue = *(unsigned *)*p_argv;
+       if (intArgC < MAX_GPRARGS)
+         stack->gprArgs[intArgC++] = gprValue;
+       else
+         stack->outArgs[outArgC++] = gprValue;
+       break;
+      }
+    }
+}
+
+/*======================== End of Routine ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_cif_machdep.                                   */
+/*                                                                    */
+/* Function - Perform machine dependent CIF processing.               */
+/*                                                                    */
+/*====================================================================*/
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i;
+  ffi_type **ptr;
+  unsigned bytes;
+  int fpArgC  = 0,
+    intArgC = 0;
+  unsigned flags = 0;
+  unsigned structCopySize = 0;
+  /*-----------------------------------------------------------------*/
+  /* Extra space required in stack for overflow parameters.          */
+  /*-----------------------------------------------------------------*/
+  bytes = 0;
+  /*--------------------------------------------------------*/
+  /* Return value handling.  The rules are as follows:     */
+  /* - 32-bit (or less) integer values are returned in gpr2 */
+  /* - Structures are returned as pointers in gpr2         */
+  /* - 64-bit integer values are returned in gpr2 and 3            */
+  /* - Single/double FP values are returned in fpr0        */
+  /*--------------------------------------------------------*/
+  flags = cif->rtype->type;
+  /*------------------------------------------------------------------------*/
+  /* The first MAX_GPRARGS words of integer arguments, and the             */
+  /* first MAX_FPRARGS floating point arguments, go in registers; the rest  */
+  /* goes on the stack.  Structures and long doubles (if not equivalent     */
+  /* to double) are passed as a pointer to a copy of the structure.        */
+  /* Stuff on the stack needs to keep proper alignment.                    */
+  /*------------------------------------------------------------------------*/
+  for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
+    {
+      switch ((*ptr)->type)
+       {
+       case FFI_TYPE_FLOAT:
+       case FFI_TYPE_DOUBLE:
+         fpArgC++;
+         if (fpArgC > MAX_FPRARGS && intArgC%2 != 0)
+           intArgC++;
+         break;
+       case FFI_TYPE_UINT64:
+       case FFI_TYPE_SINT64:
+         /*----------------------------------------------------*/
+         /* 'long long' arguments are passed as two words, but */
+         /* either both words must fit in registers or both go */
+         /* on the stack.  If they go on the stack, they must  */
+         /* be 8-byte-aligned.                                       */
+         /*----------------------------------------------------*/
+         if ((intArgC == MAX_GPRARGS-1) ||
+             (intArgC >= MAX_GPRARGS)   &&
+             (intArgC%2 != 0))
+           intArgC++;
+         intArgC += 2;
+         break;
+       case FFI_TYPE_STRUCT:
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+       case FFI_TYPE_LONGDOUBLE:
+#endif
+         /*----------------------------------------------------*/
+         /* We must allocate space for a copy of these to      */
+         /* enforce pass-by-value. Pad the space up to a       */
+         /* multiple of 16 bytes (the maximum alignment              */
+         /* required for anything under the SYSV ABI).               */
+         /*----------------------------------------------------*/
+         structCopySize += ((*ptr)->size + 15) & ~0xF;
+         /*----------------------------------------------------*/
+         /* Fall through (allocate space for the pointer).     */
+         /*----------------------------------------------------*/
+       default:
+         /*----------------------------------------------------*/
+         /* Everything else is passed as a 4-byte word in a    */
+         /* GPR either the object itself or a pointer to it.   */
+         /*----------------------------------------------------*/
+         intArgC++;
+         break;
+       }
+    }
+  /*-----------------------------------------------------------------*/
+  /* Stack space.                                                    */
+  /*-----------------------------------------------------------------*/
+  if (intArgC > MAX_GPRARGS)
+    bytes += (intArgC - MAX_GPRARGS) * sizeof(int);
+  if (fpArgC > MAX_FPRARGS)
+    bytes += (fpArgC - MAX_FPRARGS) * sizeof(double);
+  /*-----------------------------------------------------------------*/
+  /* The stack space allocated needs to be a multiple of 16 bytes.   */
+  /*-----------------------------------------------------------------*/
+  bytes = (bytes + 15) & ~0xF;
+  /*-----------------------------------------------------------------*/
+  /* Add in the space for the copied structures.                     */
+  /*-----------------------------------------------------------------*/
+  bytes += structCopySize;
+  cif->flags = flags;
+  cif->bytes = bytes;
+  return FFI_OK;
+}
+/*======================== End of Routine ============================*/
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_call.                                               */
+/*                                                                    */
+/* Function - Call the FFI routine.                                   */
+/*                                                                    */
+/*====================================================================*/
+void
+ffi_call(ffi_cif *cif,
+        void (*fn)(),
+        void *rvalue,
+        void **avalue)
+{
+  extended_cif ecif;
+  ecif.cif    = cif;
+  ecif.avalue = avalue;
+  /*-----------------------------------------------------------------*/
+  /* If the return value is a struct and we don't have a return      */
+  /* value address then we need to make one                          */
+  /*-----------------------------------------------------------------*/
+  if ((rvalue == NULL) &&
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    ecif.rvalue = alloca(cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+  switch (cif->abi)
+    {
+    case FFI_SYSV:
+      ffi_call_SYSV(ffi_prep_args,
+                   &ecif, cif->bytes,
+                   cif->flags, ecif.rvalue, fn);
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+/*======================== End of Routine ============================*/
diff --git a/libffi/src/s390/sysv.S b/libffi/src/s390/sysv.S
new file mode 100644 (file)
index 0000000..afaf1ea
--- /dev/null
@@ -0,0 +1,161 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2000 Software AG
+   S390 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>
+#endif
+       
+.text
+       # r2:   ffi_prep_args
+       # r3:   &ecif
+       # r4:   cif->bytes
+       # r5:   fig->flags
+       # r6:   ecif.rvalue
+       # sp+0: fn
+       # This assumes we are using gas.
+       .globl  ffi_call_SYSV
+       .type   ffi_call_SYSV,%function
+ffi_call_SYSV:
+       # Save registers
+       stm     %r7,%r15,28(%r15)
+       l       %r7,96(%r15)           # Get A(fn)
+       lr      %r0,%r15
+       ahi     %r15,-128              # Make room for my args
+       st      %r0,0(%r15)            # Set backchain
+       lr      %r11,%r15              # Establish my stack register
+       sr      %r15,%r4               # Make room for fn args
+       ahi     %r15,-96               # Make room for new frame
+       lr      %r10,%r15              # Establish stack build area
+       ahi     %r15,-96               # Stack for next call
+       lr      %r1,%r7
+       stm     %r2,%r7,96(%r11)       # Save args on my stack
+#------------------------------------------------------------------
+#      move first 3 parameters in registers
+#------------------------------------------------------------------
+       lr      %r9,%r2                # r9:     &ffi_prep_args
+       lr      %r2,%r10               # Parm 1: &stack Parm 2: &ecif
+       basr    %r14,%r9               # call ffi_prep_args
+#------------------------------------------------------------------
+#      load  first 5 parameter registers
+#------------------------------------------------------------------
+       lm      %r2,%r6,24(%r10)
+#------------------------------------------------------------------
+#      load  fp parameter registers
+#------------------------------------------------------------------
+       ld      %f0,48(%r10)
+       ld      %f2,56(%r10)
+#------------------------------------------------------------------
+#      call  function
+#------------------------------------------------------------------
+       lr      %r15,%r10              # Set new stack
+       l       %r9,116(%r11)          # Get &fn
+       basr    %r14,%r9               # Call function
+#------------------------------------------------------------------
+#      On return:
+#         r2: Return value (r3: Return value + 4 for long long)
+#------------------------------------------------------------------
+#------------------------------------------------------------------
+#      If the return value pointer is NULL, assume no return value.
+#------------------------------------------------------------------
+       icm     %r6,15,112(%r11)
+       jz      .Lepilogue
+       l       %r5,108(%r11)          # Get return type
+#------------------------------------------------------------------
+#      return INT
+#------------------------------------------------------------------
+       chi     %r5,FFI_TYPE_INT
+       jne     .Lchk64
+       st      %r2,0(%r6)
+       j       .Lepilogue
+.Lchk64:
+#------------------------------------------------------------------
+#      return LONG LONG (signed/unsigned)
+#------------------------------------------------------------------
+       chi     %r5,FFI_TYPE_UINT64
+       je      .LdoLongLong
+       chi     %r5,FFI_TYPE_SINT64
+       jne     .LchkFloat
+.LdoLongLong:
+       stm     %r2,%r3,0(%r6)
+       j       .Lepilogue
+.LchkFloat:
+#------------------------------------------------------------------
+#      return FLOAT
+#------------------------------------------------------------------
+       chi     %r5,FFI_TYPE_FLOAT
+       jne     .LchkDouble
+       std     %f0,0(%r6)
+       j       .Lepilogue
+.LchkDouble:
+#------------------------------------------------------------------
+#      return DOUBLE or LONGDOUBLE
+#------------------------------------------------------------------
+       chi     %r5,FFI_TYPE_DOUBLE
+       jne     .LchkStruct
+       std     %f0,0(%r6)
+       std     %f2,8(%r6)
+       j       .Lepilogue
+.LchkStruct:
+#------------------------------------------------------------------
+# Structure - rvalue already set as sent as 1st parm to routine
+#------------------------------------------------------------------
+       chi     %r5,FFI_TYPE_STRUCT
+       je      .Lepilogue
+.Ldefault:
+#------------------------------------------------------------------
+#      return a pointer
+#------------------------------------------------------------------
+       st      %r2,0(%r6)
+       j       .Lepilogue
+.Lepilogue:
+       l       %r15,0(%r11)
+       l       %r4,56(%r15)
+       lm      %r7,%r15,28(%r15)
+       br      %r4
+.ffi_call_SYSV_end:
+       .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV