summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-29 04:14:44 +0000
committerbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>2002-04-29 04:14:44 +0000
commitea1f83c547ade869a8ac885d061426c4b0e77fb0 (patch)
treef39e5328a9363e97902877aab9e253339d93ad1c
parent6f0ae5446034ae364d9599e051a1f81ae9b61e1f (diff)
downloadgcc-ea1f83c547ade869a8ac885d061426c4b0e77fb0.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@52873 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libffi/ChangeLog10
-rw-r--r--libffi/Makefile.am8
-rw-r--r--libffi/Makefile.in16
-rwxr-xr-xlibffi/configure144
-rw-r--r--libffi/configure.in2
-rw-r--r--libffi/include/Makefile.in2
-rw-r--r--libffi/include/ffi.h.in6
-rw-r--r--libffi/src/s390/ffi.c589
-rw-r--r--libffi/src/s390/sysv.S161
9 files changed, 867 insertions, 71 deletions
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index cd5a456e2bc..dc7ceddd058 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -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
diff --git a/libffi/Makefile.am b/libffi/Makefile.am
index 4d1120d100e..5281c58b7c2 100644
--- a/libffi/Makefile.am
+++ b/libffi/Makefile.am
@@ -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
diff --git a/libffi/Makefile.in b/libffi/Makefile.in
index 24f2930d85e..0e61ec2e277 100644
--- a/libffi/Makefile.in
+++ b/libffi/Makefile.in
@@ -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 \
diff --git a/libffi/configure b/libffi/configure
index 9649abaf3a4..7e3d5edea4b 100755
--- a/libffi/configure
+++ b/libffi/configure
@@ -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
diff --git a/libffi/configure.in b/libffi/configure.in
index 9e9ab1c1425..b2cb516b84a 100644
--- a/libffi/configure.in
+++ b/libffi/configure.in
@@ -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)
diff --git a/libffi/include/Makefile.in b/libffi/include/Makefile.in
index 4f75451d5f7..13aa274f405 100644
--- a/libffi/include/Makefile.in
+++ b/libffi/include/Makefile.in
@@ -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:
diff --git a/libffi/include/ffi.h.in b/libffi/include/ffi.h.in
index 8097917fe10..90dfa5189b9 100644
--- a/libffi/include/ffi.h.in
+++ b/libffi/include/ffi.h.in
@@ -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
index 00000000000..8b514e36c26
--- /dev/null
+++ b/libffi/src/s390/ffi.c
@@ -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
index 00000000000..afaf1ea1ca3
--- /dev/null
+++ b/libffi/src/s390/sysv.S
@@ -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