diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/Makefile.am gcc/libffi/Makefile.am
--- gcc-3.2.2.orig/libffi/Makefile.am	Tue Jan 28 10:43:56 2003
+++ gcc/libffi/Makefile.am	Tue Jan 28 10:48:33 2003
@@ -8,14 +8,17 @@
 		src/mips/n32.s src/mips/o32.S src/mips/o32.s \
 		src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S \
 		src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \
+		src/x86/ffi64.c src/x86/unix64.S \
 		src/alpha/ffi.c src/alpha/osf.S \
 		src/m68k/ffi.c src/m68k/sysv.S \
 		src/powerpc/ffi.c src/powerpc/sysv.S \
 		src/powerpc/ppc_closure.S src/powerpc/asm.h \
 		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/powerpc/darwin_closure.S src/powerpc/aix_closure.S \
+		src/arm/ffi.c src/arm/sysv.S \
+		src/s390/ffi.c src/s390/sysv.S \
+		src/sh/ffi.c src/sh/sysv.S
 
 VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
 
@@ -83,6 +86,7 @@
 ffitest_LDFLAGS = -shared-libgcc
 
 TARGET_SRC_MIPS_GCC = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
+TARGET_SRC_MIPS_LINUX = src/mips/ffi.c src/mips/o32.S
 TARGET_SRC_MIPS_SGI = src/mips/ffi.c src/mips/o32.s src/mips/n32.s
 TARGET_SRC_X86 = src/x86/ffi.c src/x86/sysv.S
 TARGET_SRC_X86_WIN32 = src/x86/ffi.c src/x86/win32.S
@@ -91,9 +95,12 @@
 TARGET_SRC_IA64 = src/ia64/ffi.c src/ia64/unix.S
 TARGET_SRC_M68K = src/m68k/ffi.c src/m68k/sysv.S
 TARGET_SRC_POWERPC = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
-TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
+TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.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
+TARGET_SRC_X86_64 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+TARGET_SRC_SH =  src/sh/sysv.S src/sh/ffi.c
 
 ##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c $(TARGET_SRC_@TARGET@)
 ## Work around automake deficiency
@@ -103,6 +110,10 @@
 libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
 libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
 endif
+if MIPS_LINUX
+libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_LINUX)
+libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_LINUX)
+endif
 if MIPS_SGI
 libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
 libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
@@ -147,6 +158,18 @@
 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
+if X86_64
+libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
+libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
+endif
+if SH
+libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
+libfficonvenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
+endif
 
 AM_CFLAGS = -fexceptions
 
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/Makefile.in gcc/libffi/Makefile.in
--- gcc-3.2.2.orig/libffi/Makefile.in	Wed Jan 29 07:59:05 2003
+++ gcc/libffi/Makefile.in	Wed Jan 29 07:58:58 2003
@@ -91,14 +91,17 @@
 		src/mips/n32.s src/mips/o32.S src/mips/o32.s \
 		src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S \
 		src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \
+		src/x86/ffi64.c src/x86/unix64.S \
 		src/alpha/ffi.c src/alpha/osf.S \
 		src/m68k/ffi.c src/m68k/sysv.S \
 		src/powerpc/ffi.c src/powerpc/sysv.S \
 		src/powerpc/ppc_closure.S src/powerpc/asm.h \
 		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/powerpc/darwin_closure.S src/powerpc/aix_closure.S \
+		src/arm/ffi.c src/arm/sysv.S \
+		src/s390/ffi.c src/s390/sysv.S \
+		src/sh/ffi.c src/sh/sysv.S
 
 
 VPATH = @srcdir@:@srcdir@/src:@srcdir@/src/@TARGETDIR@
@@ -162,6 +165,7 @@
 ffitest_LDFLAGS = -shared-libgcc
 
 TARGET_SRC_MIPS_GCC = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
+TARGET_SRC_MIPS_LINUX = src/mips/ffi.c src/mips/o32.S
 TARGET_SRC_MIPS_SGI = src/mips/ffi.c src/mips/o32.s src/mips/n32.s
 TARGET_SRC_X86 = src/x86/ffi.c src/x86/sysv.S
 TARGET_SRC_X86_WIN32 = src/x86/ffi.c src/x86/win32.S
@@ -170,14 +174,18 @@
 TARGET_SRC_IA64 = src/ia64/ffi.c src/ia64/unix.S
 TARGET_SRC_M68K = src/m68k/ffi.c src/m68k/sysv.S
 TARGET_SRC_POWERPC = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
-TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closures.S
+TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.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
+TARGET_SRC_X86_64 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+TARGET_SRC_SH = src/sh/sysv.S src/sh/ffi.c
 
 libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
 		src/raw_api.c src/java_raw_api.c
 
 @MIPS_GCC_TRUE@libffi_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
+@MIPS_LINUX_TRUE@libffi_la_SOURCES = @MIPS_LINUX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_LINUX)
 @MIPS_SGI_TRUE@libffi_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
 @X86_TRUE@libffi_la_SOURCES = @X86_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86)
 @X86_WIN32_TRUE@libffi_la_SOURCES = @X86_WIN32_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_WIN32)
@@ -189,7 +197,11 @@
 @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)
+@X86_64_TRUE@libffi_la_SOURCES = @X86_64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
+@SH_TRUE@libffi_la_SOURCES = @SH_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
 @MIPS_GCC_TRUE@libffi_convenience_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
+@MIPS_LINUX_TRUE@libffi_convenience_la_SOURCES = @MIPS_LINUX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_LINUX)
 @MIPS_SGI_TRUE@libffi_convenience_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
 @X86_TRUE@libffi_convenience_la_SOURCES = @X86_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86)
 @X86_WIN32_TRUE@libffi_convenience_la_SOURCES = @X86_WIN32_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_WIN32)
@@ -201,6 +213,9 @@
 @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)
+@X86_64_TRUE@libffi_convenience_la_SOURCES = @X86_64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
+@SH_TRUE@libfficonvenience_la_SOURCES = @SH_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_SH)
 
 AM_CFLAGS = -fexceptions
 
@@ -208,7 +223,7 @@
 
 INCLUDES = -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+mkinstalldirs = $(SHELL) $(top_srcdir)/${libffi_basedir}/../mkinstalldirs
 CONFIG_HEADER = fficonfig.h
 CONFIG_CLEAN_FILES = 
 LTLIBRARIES =  $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
@@ -220,10 +235,6 @@
 LIBS = @LIBS@
 libffi_convenience_la_LDFLAGS = 
 libffi_convenience_la_LIBADD = 
-@POWERPC_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
-@POWERPC_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
-@POWERPC_TRUE@src/java_raw_api.lo src/powerpc/ffi.lo \
-@POWERPC_TRUE@src/powerpc/sysv.lo src/powerpc/ppc_closure.lo
 @ALPHA_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
 @ALPHA_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @ALPHA_TRUE@src/java_raw_api.lo src/alpha/ffi.lo src/alpha/osf.lo
@@ -234,12 +245,29 @@
 @MIPS_GCC_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @MIPS_GCC_TRUE@src/java_raw_api.lo src/mips/ffi.lo src/mips/o32.lo \
 @MIPS_GCC_TRUE@src/mips/n32.lo
-@X86_WIN32_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
-@X86_WIN32_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
-@X86_WIN32_TRUE@src/java_raw_api.lo src/x86/ffi.lo src/x86/win32.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
 @M68K_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @M68K_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @M68K_TRUE@src/m68k/ffi.lo src/m68k/sysv.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
+@POWERPC_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
+@POWERPC_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
+@POWERPC_TRUE@src/java_raw_api.lo src/powerpc/ffi.lo \
+@POWERPC_TRUE@src/powerpc/sysv.lo src/powerpc/ppc_closure.lo
+@MIPS_LINUX_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
+@MIPS_LINUX_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
+@MIPS_LINUX_TRUE@src/java_raw_api.lo src/mips/ffi.lo src/mips/o32.lo
+@X86_WIN32_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
+@X86_WIN32_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
+@X86_WIN32_TRUE@src/java_raw_api.lo src/x86/ffi.lo src/x86/win32.lo
+@X86_64_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
+@X86_64_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
+@X86_64_TRUE@src/java_raw_api.lo src/x86/ffi64.lo src/x86/unix64.lo \
+@X86_64_TRUE@src/x86/ffi.lo src/x86/sysv.lo
 @SPARC_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
 @SPARC_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @SPARC_TRUE@src/java_raw_api.lo src/sparc/ffi.lo src/sparc/v8.lo \
@@ -247,62 +275,75 @@
 @POWERPC_AIX_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
 @POWERPC_AIX_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @POWERPC_AIX_TRUE@src/java_raw_api.lo src/powerpc/ffi_darwin.lo \
-@POWERPC_AIX_TRUE@src/powerpc/aix.lo src/powerpc/aix_closures.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
-@ARM_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
-@ARM_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@ARM_TRUE@src/arm/sysv.lo src/arm/ffi.lo
+@POWERPC_AIX_TRUE@src/powerpc/aix.lo src/powerpc/aix_closure.lo
+@MIPS_SGI_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
+@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
 @POWERPC_DARWIN_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
 @POWERPC_DARWIN_TRUE@src/prep_cif.lo src/types.lo src/raw_api.lo \
 @POWERPC_DARWIN_TRUE@src/java_raw_api.lo src/powerpc/ffi_darwin.lo \
 @POWERPC_DARWIN_TRUE@src/powerpc/darwin.lo \
 @POWERPC_DARWIN_TRUE@src/powerpc/darwin_closure.lo
-@MIPS_SGI_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo \
-@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
+@ARM_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@ARM_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@ARM_TRUE@src/arm/sysv.lo src/arm/ffi.lo
+@SH_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@SH_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@SH_TRUE@src/sh/sysv.lo src/sh/ffi.lo
 libffi_la_LIBADD = 
+@SH_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo src/types.lo \
+@SH_TRUE@src/raw_api.lo src/java_raw_api.lo src/sh/sysv.lo \
+@SH_TRUE@src/sh/ffi.lo
+@IA64_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@IA64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@IA64_TRUE@src/ia64/ffi.lo src/ia64/unix.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
 @POWERPC_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @POWERPC_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @POWERPC_TRUE@src/powerpc/ffi.lo src/powerpc/sysv.lo \
 @POWERPC_TRUE@src/powerpc/ppc_closure.lo
-@ALPHA_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
-@ALPHA_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@ALPHA_TRUE@src/alpha/ffi.lo src/alpha/osf.lo
-@IA64_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
-@IA64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@IA64_TRUE@src/ia64/ffi.lo src/ia64/unix.lo
-@MIPS_GCC_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
-@MIPS_GCC_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@MIPS_GCC_TRUE@src/mips/ffi.lo src/mips/o32.lo src/mips/n32.lo
-@X86_WIN32_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
-@X86_WIN32_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@X86_WIN32_TRUE@src/x86/ffi.lo src/x86/win32.lo
-@M68K_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
-@M68K_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@M68K_TRUE@src/m68k/ffi.lo src/m68k/sysv.lo
+@MIPS_LINUX_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@MIPS_LINUX_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@MIPS_LINUX_TRUE@src/mips/ffi.lo src/mips/o32.lo
 @SPARC_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @SPARC_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @SPARC_TRUE@src/sparc/ffi.lo src/sparc/v8.lo src/sparc/v9.lo
 @POWERPC_AIX_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @POWERPC_AIX_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @POWERPC_AIX_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/aix.lo \
-@POWERPC_AIX_TRUE@src/powerpc/aix_closures.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
+@POWERPC_AIX_TRUE@src/powerpc/aix_closure.lo
+@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
 @ARM_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo src/types.lo \
 @ARM_TRUE@src/raw_api.lo src/java_raw_api.lo src/arm/sysv.lo \
 @ARM_TRUE@src/arm/ffi.lo
+@ALPHA_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@ALPHA_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@ALPHA_TRUE@src/alpha/ffi.lo src/alpha/osf.lo
+@MIPS_GCC_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@MIPS_GCC_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@MIPS_GCC_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
+@M68K_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@M68K_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@M68K_TRUE@src/m68k/ffi.lo src/m68k/sysv.lo
+@X86_WIN32_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@X86_WIN32_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@X86_WIN32_TRUE@src/x86/ffi.lo src/x86/win32.lo
+@X86_64_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@X86_64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@X86_64_TRUE@src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffi.lo \
+@X86_64_TRUE@src/x86/sysv.lo
 @POWERPC_DARWIN_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @POWERPC_DARWIN_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @POWERPC_DARWIN_TRUE@src/powerpc/ffi_darwin.lo src/powerpc/darwin.lo \
 @POWERPC_DARWIN_TRUE@src/powerpc/darwin_closure.lo
-@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
 noinst_PROGRAMS =  ffitest$(EXEEXT)
 PROGRAMS =  $(noinst_PROGRAMS)
 
@@ -578,8 +616,8 @@
 	-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/sh \
+	   $(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 -ruN --exclude=CVS gcc-3.2.2.orig/libffi/acinclude.m4 gcc/libffi/acinclude.m4
--- gcc-3.2.2.orig/libffi/acinclude.m4	Sun Sep 10 16:43:14 2000
+++ gcc/libffi/acinclude.m4	Tue Dec 17 03:22:47 2002
@@ -4,5 +4,8 @@
 dnl to add a definition of LIBTOOL to Makefile.in.
 ifelse(yes,no,[
 AC_DEFUN([AC_PROG_LIBTOOL],)
+AC_DEFUN([AM_PROG_LIBTOOL],)
 AC_SUBST(LIBTOOL)
 ])
+
+sinclude(../config/accross.m4)
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/aclocal.m4 gcc/libffi/aclocal.m4
--- gcc-3.2.2.orig/libffi/aclocal.m4	Fri Feb  1 07:25:31 2002
+++ gcc/libffi/aclocal.m4	Tue Dec 17 03:22:47 2002
@@ -1,6 +1,6 @@
-dnl aclocal.m4 generated automatically by aclocal 1.4
+dnl aclocal.m4 generated automatically by aclocal 1.4-p5
 
-dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
@@ -16,108 +16,15 @@
 dnl to add a definition of LIBTOOL to Makefile.in.
 ifelse(yes,no,[
 AC_DEFUN([AC_PROG_LIBTOOL],)
+AC_DEFUN([AM_PROG_LIBTOOL],)
 AC_SUBST(LIBTOOL)
 ])
 
-AC_DEFUN([AC_COMPILE_CHECK_SIZEOF],
-[changequote(<<, >>)dnl
-dnl The name to #define.
-define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl
-dnl The cache variable name.
-define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl
-changequote([, ])dnl
-AC_MSG_CHECKING(size of $1)
-AC_CACHE_VAL(AC_CV_NAME,
-[for ac_size in 4 8 1 2 16 12 $2 ; do # List sizes in rough order of prevalence.
-  AC_TRY_COMPILE([#include "confdefs.h"
-#include <sys/types.h>
-$2
-], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size)
-  if test x$AC_CV_NAME != x ; then break; fi
-done
-])
-if test x$AC_CV_NAME = x ; then
-  AC_MSG_ERROR([cannot determine a size for $1])
-fi
-AC_MSG_RESULT($AC_CV_NAME)
-AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1])
-undefine([AC_TYPE_NAME])dnl
-undefine([AC_CV_NAME])dnl
-])
-
-AC_DEFUN([AC_C_BIGENDIAN_CROSS],
-[AC_CACHE_CHECK(whether byte ordering is bigendian, ac_cv_c_bigendian,
-[ac_cv_c_bigendian=unknown
-# See if sys/param.h defines the BYTE_ORDER macro.
-AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/param.h>], [
-#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
-#endif], [# It does; now see whether it defined to BIG_ENDIAN or not.
-AC_TRY_COMPILE([#include <sys/types.h>
-#include <sys/param.h>], [
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif], ac_cv_c_bigendian=yes, ac_cv_c_bigendian=no)])
-if test $ac_cv_c_bigendian = unknown; then
-AC_TRY_RUN([main () {
-  /* Are we little or big endian?  From Harbison&Steele.  */
-  union
-  {
-    long l;
-    char c[sizeof (long)];
-  } u;
-  u.l = 1;
-  exit (u.c[sizeof (long) - 1] == 1);
-}], ac_cv_c_bigendian=no, ac_cv_c_bigendian=yes,
-[ echo $ac_n "cross-compiling... " 2>&AC_FD_MSG ])
-fi])
-if test $ac_cv_c_bigendian = unknown; then
-AC_MSG_CHECKING(to probe for byte ordering)
-[
-cat >conftest.c <<EOF
-short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-void _ascii() { char* s = (char*) ascii_mm; s = (char*) ascii_ii; }
-short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-void _ebcdic() { char* s = (char*) ebcdic_mm; s = (char*) ebcdic_ii; }
-int main() { _ascii (); _ebcdic (); return 0; }
-EOF
-] if test -f conftest.c ; then
-     if ${CC-cc} ${CFLAGS} conftest.c -o conftest.o && test -f conftest.o ; then
-        if test `grep -l BIGenDianSyS conftest.o` ; then
-           echo $ac_n ' big endian probe OK, ' 1>&AC_FD_MSG
-           ac_cv_c_bigendian=yes
-        fi
-        if test `grep -l LiTTleEnDian conftest.o` ; then
-           echo $ac_n ' little endian probe OK, ' 1>&AC_FD_MSG
-           if test $ac_cv_c_bigendian = yes ; then
-            ac_cv_c_bigendian=unknown;
-           else
-            ac_cv_c_bigendian=no
-           fi
-        fi
-        echo $ac_n 'guessing bigendian ...  ' >&AC_FD_MSG
-     fi
-  fi
-AC_MSG_RESULT($ac_cv_c_bigendian)
-fi
-if test $ac_cv_c_bigendian = yes; then
-  AC_DEFINE(WORDS_BIGENDIAN, 1, [whether byteorder is bigendian])
-  BYTEORDER=4321
-else
-  BYTEORDER=1234
-fi
-AC_DEFINE_UNQUOTED(BYTEORDER, $BYTEORDER, [1234 = LIL_ENDIAN, 4321 = BIGENDIAN])
-if test $ac_cv_c_bigendian = unknown; then
-  AC_MSG_ERROR(unknown endianess - sorry, please pre-set ac_cv_c_bigendian)
-fi
-])
+sinclude(../config/accross.m4)
 
 # Like AC_CONFIG_HEADER, but automatically create stamp file.
 
-AC_DEFUN(AM_CONFIG_HEADER,
+AC_DEFUN([AM_CONFIG_HEADER],
 [AC_PREREQ([2.12])
 AC_CONFIG_HEADER([$1])
 dnl When config.status generates a header, we must update the stamp-h file.
@@ -147,7 +54,7 @@
 dnl Usage:
 dnl AM_INIT_AUTOMAKE(package,version, [no-define])
 
-AC_DEFUN(AM_INIT_AUTOMAKE,
+AC_DEFUN([AM_INIT_AUTOMAKE],
 [AC_REQUIRE([AC_PROG_INSTALL])
 PACKAGE=[$1]
 AC_SUBST(PACKAGE)
@@ -175,7 +82,7 @@
 # Check to make sure that the build environment is sane.
 #
 
-AC_DEFUN(AM_SANITY_CHECK,
+AC_DEFUN([AM_SANITY_CHECK],
 [AC_MSG_CHECKING([whether build environment is sane])
 # Just in case
 sleep 1
@@ -216,7 +123,7 @@
 
 dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
 dnl The program must properly implement --version.
-AC_DEFUN(AM_MISSING_PROG,
+AC_DEFUN([AM_MISSING_PROG],
 [AC_MSG_CHECKING(for working $2)
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
@@ -235,7 +142,7 @@
 
 # serial 1
 
-AC_DEFUN(AM_MAINTAINER_MODE,
+AC_DEFUN([AM_MAINTAINER_MODE],
 [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
   dnl maintainer-mode is disabled by default
   AC_ARG_ENABLE(maintainer-mode,
@@ -252,7 +159,7 @@
 
 # Define a conditional.
 
-AC_DEFUN(AM_CONDITIONAL,
+AC_DEFUN([AM_CONDITIONAL],
 [AC_SUBST($1_TRUE)
 AC_SUBST($1_FALSE)
 if $2; then
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/configure gcc/libffi/configure
--- gcc-3.2.2.orig/libffi/configure	Wed Jan 29 07:59:05 2003
+++ gcc/libffi/configure	Sat Feb  1 20:16:19 2003
@@ -633,17 +633,16 @@
 
 if test "${srcdir}" = "."; then
   if test "${with_target_subdir}" != "."; then
-    libffi_basedir="${srcdir}/${with_multisrctop}.."
+    libffi_basedir="${with_multisrctop}../"
   else
-    libffi_basedir="${srcdir}/${with_multisrctop}"
+    libffi_basedir="${with_multisrctop}"
   fi
 else
-  libffi_basedir="${srcdir}"
+  libffi_basedir=
 fi
 
-
 ac_aux_dir=
-for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+for ac_dir in ${libffi_basedir}.. $srcdir/${libffi_basedir}..; do
   if test -f $ac_dir/install-sh; then
     ac_aux_dir=$ac_dir
     ac_install_sh="$ac_aux_dir/install-sh -c"
@@ -655,13 +654,14 @@
   fi
 done
 if test -z "$ac_aux_dir"; then
-  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+  { echo "configure: error: can not find install-sh or install.sh in ${libffi_basedir}.. $srcdir/${libffi_basedir}.." 1>&2; exit 1; }
 fi
 ac_config_guess=$ac_aux_dir/config.guess
 ac_config_sub=$ac_aux_dir/config.sub
 ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
 
 
+
 # Make sure we can run config.sub.
 if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
 else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
@@ -1238,9 +1238,18 @@
   ;;
 
 hpux10.20*|hpux11*)
-  lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
-  lt_cv_file_magic_cmd=/usr/bin/file
-  lt_cv_file_magic_test_file=/usr/lib/libc.sl
+  case $host_cpu in
+  hppa*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_cmd=/usr/bin/file
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_cmd=/usr/bin/file
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  esac
   ;;
 
 irix5* | irix6*)
@@ -1267,7 +1276,7 @@
 # This must be Linux ELF.
 linux-gnu*)
   case $host_cpu in
-  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* )
+  alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | sh* )
     lt_cv_deplibs_check_method=pass_all ;;
   *)
     # glibc up to 2.1.1 does not perform some relocations on ARM
@@ -1330,13 +1339,13 @@
 deplibs_check_method=$lt_cv_deplibs_check_method
 
 echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:1334: checking for object suffix" >&5
+echo "configure:1343: checking for object suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   rm -f conftest*
 echo 'int i = 1;' > conftest.$ac_ext
-if { (eval echo configure:1340: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1349: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   for ac_file in conftest.*; do
     case $ac_file in
     *.c) ;;
@@ -1356,7 +1365,7 @@
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1360: checking for executable suffix" >&5
+echo "configure:1369: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1366,7 +1375,7 @@
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:1370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:1379: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
       *.c | *.o | *.obj) ;;
@@ -1399,7 +1408,7 @@
 file_magic*)
   if test "$file_magic_cmd" = '$MAGIC_CMD'; then
     echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
-echo "configure:1403: checking for ${ac_tool_prefix}file" >&5
+echo "configure:1412: checking for ${ac_tool_prefix}file" >&5
 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1461,7 +1470,7 @@
 if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
     echo $ac_n "checking for file""... $ac_c" 1>&6
-echo "configure:1465: checking for file" >&5
+echo "configure:1474: checking for file" >&5
 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1532,7 +1541,7 @@
 # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
 set dummy ${ac_tool_prefix}ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1536: checking for $ac_word" >&5
+echo "configure:1545: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1564,7 +1573,7 @@
   # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1568: checking for $ac_word" >&5
+echo "configure:1577: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1599,7 +1608,7 @@
 # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1603: checking for $ac_word" >&5
+echo "configure:1612: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1631,7 +1640,7 @@
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1635: checking for $ac_word" >&5
+echo "configure:1644: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1698,8 +1707,8 @@
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 1702 "configure"' > conftest.$ac_ext
-  if { (eval echo configure:1703: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  echo '#line 1711 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1712: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
     case `/usr/bin/file conftest.$ac_objext` in
     *32-bit*)
       LD="${LD-ld} -32"
@@ -1715,12 +1724,70 @@
   rm -rf conftest*
   ;;
 
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo configure:1731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case "`/usr/bin/file conftest.o`" in
+    *ELF-32*)
+      HPUX_IA64_MODE="32"
+      ;;
+    *ELF-64*)
+      HPUX_IA64_MODE="64"
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { (eval echo configure:1747: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+    case "`/usr/bin/file conftest.o`" in
+    *32-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_i386"
+          ;;
+        ppc64-*linux*)
+          LD="${LD-ld} -m elf32ppclinux"
+          ;;
+        s390x-*linux*)
+          LD="${LD-ld} -m elf_s390"
+          ;;
+        sparc64-*linux*)
+          LD="${LD-ld} -m elf32_sparc"
+          ;;
+      esac
+      ;;
+    *64-bit*)
+      case $host in
+        x86_64-*linux*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        ppc*-*linux*|powerpc*-*linux*)
+          LD="${LD-ld} -m elf64ppc"
+          ;;
+        s390*-*linux*)
+          LD="${LD-ld} -m elf64_s390"
+          ;;
+        sparc*-*linux*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
 *-*-sco3.2v5*)
   # On SCO OpenServer 5, we need -belf to get full-featured binaries.
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:1724: checking whether the C compiler needs -belf" >&5
+echo "configure:1791: checking whether the C compiler needs -belf" >&5
 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1733,14 +1800,14 @@
 cross_compiling=$ac_cv_prog_cc_cross
 
      cat > conftest.$ac_ext <<EOF
-#line 1737 "configure"
+#line 1804 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1744: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1811: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   lt_cv_cc_needs_belf=yes
 else
@@ -1868,7 +1935,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1872: checking for a BSD compatible install" >&5
+echo "configure:1939: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1921,7 +1988,7 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
-echo "configure:1925: checking whether build environment is sane" >&5
+echo "configure:1992: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -1978,7 +2045,7 @@
 test "$program_transform_name" = "" && program_transform_name="s,x,x,"
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:1982: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:2049: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2017,7 +2084,7 @@
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:2021: checking for working aclocal" >&5
+echo "configure:2088: checking for working aclocal" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -2030,7 +2097,7 @@
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:2034: checking for working autoconf" >&5
+echo "configure:2101: checking for working autoconf" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -2043,7 +2110,7 @@
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:2047: checking for working automake" >&5
+echo "configure:2114: checking for working automake" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -2056,7 +2123,7 @@
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:2060: checking for working autoheader" >&5
+echo "configure:2127: checking for working autoheader" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -2069,7 +2136,7 @@
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:2073: checking for working makeinfo" >&5
+echo "configure:2140: checking for working makeinfo" >&5
 # Run test in a subshell; some versions of sh will print an error if
 # an executable is not found, even if stderr is redirected.
 # Redirect stdin to placate older versions of autoconf.  Sigh.
@@ -2086,7 +2153,7 @@
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:2090: checking for executable suffix" >&5
+echo "configure:2157: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2096,7 +2163,7 @@
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:2100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+  if { (eval echo configure:2167: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
     for file in conftest.*; do
       case $file in
       *.c | *.o | *.obj) ;;
@@ -2117,7 +2184,7 @@
 ac_exeext=$EXEEXT
 
 echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
-echo "configure:2121: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo "configure:2188: checking whether to enable maintainer-specific portions of Makefiles" >&5
     # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
 if test "${enable_maintainer_mode+set}" = set; then
   enableval="$enable_maintainer_mode"
@@ -2143,7 +2210,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2147: checking for $ac_word" >&5
+echo "configure:2214: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2173,7 +2240,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2177: checking for $ac_word" >&5
+echo "configure:2244: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2224,7 +2291,7 @@
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:2228: checking for $ac_word" >&5
+echo "configure:2295: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2256,7 +2323,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:2260: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:2327: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -2267,12 +2334,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 2271 "configure"
+#line 2338 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:2276: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -2298,12 +2365,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
-echo "configure:2302: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "configure:2369: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:2307: checking whether we are using GNU C" >&5
+echo "configure:2374: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2312,7 +2379,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2316: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -2331,7 +2398,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:2335: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:2402: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2381,17 +2448,23 @@
 i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;;
 sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
 sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
-sparc-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
-sparc64-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
-alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd*) TARGET=ALPHA; TARGETDIR=alpha;;
+sparc-*-linux* | sparc-*-netbsdelf*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux* | sparc64-*-netbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-netbsd*) TARGET=ALPHA; TARGETDIR=alpha;;
 ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
 m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
+mips64*-*);;
+mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;;
 powerpc-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
 powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
 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;;
+s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
+sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -2418,6 +2491,15 @@
 fi
 
 
+if test x$TARGET = xMIPS_LINUX; then
+  MIPS_LINUX_TRUE=
+  MIPS_LINUX_FALSE='#'
+else
+  MIPS_LINUX_TRUE='#'
+  MIPS_LINUX_FALSE=
+fi
+
+
 if test x$TARGET = xSPARC; then
   SPARC_TRUE=
   SPARC_FALSE='#'
@@ -2507,8 +2589,39 @@
   ARM_FALSE=
 fi
 
+
+if test x$TARGET = xS390; then
+  S390_TRUE=
+  S390_FALSE='#'
+else
+  S390_TRUE='#'
+  S390_FALSE=
+fi
+
+
+if test x$TARGET = xX86_64; then
+  X86_64_TRUE=
+  X86_64_FALSE='#'
+else
+  X86_64_TRUE='#'
+  X86_64_FALSE=
+fi
+
+
+if test x$TARGET = xSH; then
+  SH_TRUE=
+  SH_FALSE='#'
+else
+  SH_TRUE='#'
+  SH_FALSE=
+fi
+
+if test x$TARGET = xMIPS_LINUX; then
+  TARGET=MIPS
+fi
+
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:2512: checking how to run the C preprocessor" >&5
+echo "configure:2625: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -2523,13 +2636,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 2527 "configure"
+#line 2640 "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:2533: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2646: \"$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
   :
@@ -2540,13 +2653,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 2544 "configure"
+#line 2657 "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:2550: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2663: \"$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
   :
@@ -2557,13 +2670,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 2561 "configure"
+#line 2674 "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:2567: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2680: \"$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
   :
@@ -2588,12 +2701,12 @@
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2592: checking for ANSI C header files" >&5
+echo "configure:2705: 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 2597 "configure"
+#line 2710 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2601,7 +2714,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2605: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2718: \"$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*
@@ -2618,7 +2731,7 @@
 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 2622 "configure"
+#line 2735 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2636,7 +2749,7 @@
 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 2640 "configure"
+#line 2753 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2657,7 +2770,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2661 "configure"
+#line 2774 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2668,7 +2781,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2694,12 +2807,12 @@
 for ac_func in memcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2698: checking for $ac_func" >&5
+echo "configure:2811: 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 2703 "configure"
+#line 2816 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2722,7 +2835,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2839: \"$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
@@ -2749,19 +2862,19 @@
 # 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:2753: checking for working alloca.h" >&5
+echo "configure:2866: 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 2758 "configure"
+#line 2871 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:2765: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2878: \"$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
@@ -2782,12 +2895,12 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:2786: checking for alloca" >&5
+echo "configure:2899: 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 2791 "configure"
+#line 2904 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -2815,7 +2928,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:2819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2932: \"$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
@@ -2847,12 +2960,12 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2851: checking whether alloca needs Cray hooks" >&5
+echo "configure:2964: 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 2856 "configure"
+#line 2969 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -2877,12 +2990,12 @@
 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:2881: checking for $ac_func" >&5
+echo "configure:2994: 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 2886 "configure"
+#line 2999 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2905,7 +3018,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2909: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3022: \"$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
@@ -2932,7 +3045,7 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2936: checking stack direction for C alloca" >&5
+echo "configure:3049: 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
@@ -2940,7 +3053,7 @@
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2944 "configure"
+#line 3057 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -2959,7 +3072,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:2963: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3076: \"$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
@@ -2982,13 +3095,13 @@
 
 
 echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:2986: checking size of short" >&5
+echo "configure:3099: 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 2992 "configure"
+#line 3105 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -2998,7 +3111,7 @@
 switch (0) case 0: case (sizeof (short) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3002: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3115: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_short=$ac_size
 else
@@ -3021,13 +3134,13 @@
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:3025: checking size of int" >&5
+echo "configure:3138: 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 3031 "configure"
+#line 3144 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3037,7 +3150,7 @@
 switch (0) case 0: case (sizeof (int) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3041: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3154: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_int=$ac_size
 else
@@ -3060,13 +3173,13 @@
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:3064: checking size of long" >&5
+echo "configure:3177: 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 3070 "configure"
+#line 3183 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3076,7 +3189,7 @@
 switch (0) case 0: case (sizeof (long) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3080: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3193: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long=$ac_size
 else
@@ -3099,13 +3212,13 @@
 
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:3103: checking size of long long" >&5
+echo "configure:3216: 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 3109 "configure"
+#line 3222 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3115,7 +3228,7 @@
 switch (0) case 0: case (sizeof (long long) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3119: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3232: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long_long=$ac_size
 else
@@ -3138,13 +3251,13 @@
 
 
 echo $ac_n "checking size of float""... $ac_c" 1>&6
-echo "configure:3142: checking size of float" >&5
+echo "configure:3255: 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 3148 "configure"
+#line 3261 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3154,7 +3267,7 @@
 switch (0) case 0: case (sizeof (float) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3158: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3271: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_float=$ac_size
 else
@@ -3177,13 +3290,13 @@
 
 
 echo $ac_n "checking size of double""... $ac_c" 1>&6
-echo "configure:3181: checking size of double" >&5
+echo "configure:3294: 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 3187 "configure"
+#line 3300 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3193,7 +3306,7 @@
 switch (0) case 0: case (sizeof (double) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3197: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3310: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_double=$ac_size
 else
@@ -3216,13 +3329,13 @@
 
 
 echo $ac_n "checking size of long double""... $ac_c" 1>&6
-echo "configure:3220: checking size of long double" >&5
+echo "configure:3333: 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 3226 "configure"
+#line 3339 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3232,7 +3345,7 @@
 switch (0) case 0: case (sizeof (long double) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3236: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3349: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long_double=$ac_size
 else
@@ -3256,13 +3369,13 @@
 
 
 echo $ac_n "checking size of void *""... $ac_c" 1>&6
-echo "configure:3260: checking size of void *" >&5
+echo "configure:3373: 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 3266 "configure"
+#line 3379 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3272,7 +3385,7 @@
 switch (0) case 0: case (sizeof (void *) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_void_p=$ac_size
 else
@@ -3295,14 +3408,14 @@
 
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:3299: checking whether byte ordering is bigendian" >&5
+echo "configure:3412: 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 3306 "configure"
+#line 3419 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -3313,11 +3426,11 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:3317: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3430: \"$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 3321 "configure"
+#line 3434 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -3328,7 +3441,7 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:3332: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3445: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -3348,7 +3461,7 @@
    echo $ac_n "cross-compiling... " 2>&6 
 else
   cat > conftest.$ac_ext <<EOF
-#line 3352 "configure"
+#line 3465 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -3361,7 +3474,7 @@
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:3365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3478: \"$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
@@ -3379,7 +3492,7 @@
 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:3383: checking to probe for byte ordering" >&5
+echo "configure:3496: checking to probe for byte ordering" >&5
 
 cat >conftest.c <<EOF
 short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
@@ -3414,6 +3527,10 @@
 #define WORDS_BIGENDIAN 1
 EOF
 
+  cat >> confdefs.h <<\EOF
+#define HOST_WORDS_BIG_ENDIAN 1
+EOF
+
   BYTEORDER=4321
 else
   BYTEORDER=1234
@@ -3429,7 +3546,7 @@
 
 if test x$TARGET = xSPARC; then
     echo $ac_n "checking assembler and linker support unaligned pc related relocs""... $ac_c" 1>&6
-echo "configure:3433: checking assembler and linker support unaligned pc related relocs" >&5
+echo "configure:3550: 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
@@ -3439,14 +3556,14 @@
 	CFLAGS="$CFLAGS -fpic"
 	LDFLAGS="$LDFLAGS -shared"
 	cat > conftest.$ac_ext <<EOF
-#line 3443 "configure"
+#line 3560 "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:3450: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3567: \"$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
@@ -3709,6 +3826,8 @@
 s%@MIPS_GCC_FALSE@%$MIPS_GCC_FALSE%g
 s%@MIPS_SGI_TRUE@%$MIPS_SGI_TRUE%g
 s%@MIPS_SGI_FALSE@%$MIPS_SGI_FALSE%g
+s%@MIPS_LINUX_TRUE@%$MIPS_LINUX_TRUE%g
+s%@MIPS_LINUX_FALSE@%$MIPS_LINUX_FALSE%g
 s%@SPARC_TRUE@%$SPARC_TRUE%g
 s%@SPARC_FALSE@%$SPARC_FALSE%g
 s%@X86_TRUE@%$X86_TRUE%g
@@ -3729,6 +3848,12 @@
 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%@X86_64_TRUE@%$X86_64_TRUE%g
+s%@X86_64_FALSE@%$X86_64_FALSE%g
+s%@SH_TRUE@%$SH_TRUE%g
+s%@SH_FALSE@%$SH_FALSE%g
 s%@CPP@%$CPP%g
 s%@ALLOCA@%$ALLOCA%g
 s%@TARGET@%$TARGET%g
@@ -3969,7 +4094,7 @@
 
 if test -n "$CONFIG_FILES"; then
    LD="${ORIGINAL_LD_FOR_MULTILIBS}"
-   ac_file=Makefile . ${libffi_basedir}/../config-ml.in
+   ac_file=Makefile . ${srcdir}/${libffi_basedir}../config-ml.in
 fi
 
 exit 0
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/configure.in gcc/libffi/configure.in
--- gcc-3.2.2.orig/libffi/configure.in	Tue Jan 28 10:43:56 2003
+++ gcc/libffi/configure.in	Sat Feb  1 20:16:19 2003
@@ -22,14 +22,15 @@
 
 if test "${srcdir}" = "."; then
   if test "${with_target_subdir}" != "."; then
-    libffi_basedir="${srcdir}/${with_multisrctop}.."
+    libffi_basedir="${with_multisrctop}../"
   else
-    libffi_basedir="${srcdir}/${with_multisrctop}"
+    libffi_basedir="${with_multisrctop}"
   fi
 else
-  libffi_basedir="${srcdir}"
+  libffi_basedir=
 fi
 AC_SUBST(libffi_basedir)
+AC_CONFIG_AUX_DIR(${libffi_basedir}..)
 
 AC_CANONICAL_HOST
 
@@ -56,17 +57,23 @@
 i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;;
 sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;;
 sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
-sparc-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
-sparc64-*-linux*) TARGET=SPARC; TARGETDIR=sparc;;
-alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd*) TARGET=ALPHA; TARGETDIR=alpha;;
+sparc-*-linux* | sparc-*-netbsdelf*) TARGET=SPARC; TARGETDIR=sparc;;
+sparc64-*-linux* | sparc64-*-netbsd*) TARGET=SPARC; TARGETDIR=sparc;;
+alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-netbsd*) TARGET=ALPHA; TARGETDIR=alpha;;
 ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;;
 m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;;
+mips64*-*);;
+mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;;
 powerpc-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
 powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
 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;;
+s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
+sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -75,6 +82,7 @@
 
 AM_CONDITIONAL(MIPS_GCC, test ${TARGET}${ac_cv_prog_gcc} = MIPSyes)
 AM_CONDITIONAL(MIPS_SGI, test ${TARGET}${ac_cv_prog_gcc} = MIPSno)
+AM_CONDITIONAL(MIPS_LINUX, test x$TARGET = xMIPS_LINUX)
 AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
 AM_CONDITIONAL(X86, test x$TARGET = xX86)
 AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
@@ -85,6 +93,13 @@
 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)
+AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
+AM_CONDITIONAL(SH, test x$TARGET = xSH)
+
+if test x$TARGET = xMIPS_LINUX; then
+  TARGET=MIPS
+fi
 
 AC_HEADER_STDC
 AC_CHECK_FUNCS(memcpy)
@@ -171,7 +186,7 @@
 [
 if test -n "$CONFIG_FILES"; then
    LD="${ORIGINAL_LD_FOR_MULTILIBS}"
-   ac_file=Makefile . ${libffi_basedir}/../config-ml.in
+   ac_file=Makefile . ${srcdir}/${libffi_basedir}../config-ml.in
 fi
 ],
 srcdir=${srcdir}
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/include/Makefile.in gcc/libffi/include/Makefile.in
--- gcc-3.2.2.orig/libffi/include/Makefile.in	Tue Oct  9 14:32:16 2001
+++ gcc/libffi/include/Makefile.in	Mon Apr 29 13:14:44 2002
@@ -99,7 +99,7 @@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gnutar
+TAR = gtar
 GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/include/ffi.h.in gcc/libffi/include/ffi.h.in
--- gcc-3.2.2.orig/libffi/include/ffi.h.in	Wed Mar 13 07:35:56 2002
+++ gcc/libffi/include/ffi.h.in	Wed Jan 29 00:54:28 2003
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------*-C-*-
-   libffi @VERSION@ - Copyright (c) 1996-2002  Cygnus Solutions
+   libffi @VERSION@ - Copyright (c) 1996-2003  Cygnus Solutions
 
    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files (the
@@ -164,6 +164,12 @@
 #endif
 #endif
 
+#ifdef S390
+#if defined (__s390x__)
+#define S390X
+#endif
+#endif
+
 #ifndef LIBFFI_ASM
 
 /* ---- Generic type definitions ----------------------------------------- */
@@ -189,16 +195,23 @@
 #endif
 #endif
 
-  /* ---- Intel x86 ---------------- */
-#ifdef X86
+  /* ---- Intel x86 Win32 ---------- */
+#ifdef X86_WIN32
   FFI_SYSV,
+  FFI_STDCALL,
+  /* TODO: Add fastcall support for the sake of completeness */
   FFI_DEFAULT_ABI = FFI_SYSV,
 #endif
 
-  /* ---- Intel x86 Win32 ---------- */
-#ifdef X86_WIN32
+  /* ---- Intel x86 and AMD x86-64 - */
+#if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__))
   FFI_SYSV,
+  FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
+#ifdef __i386__
   FFI_DEFAULT_ABI = FFI_SYSV,
+#else
+  FFI_DEFAULT_ABI = FFI_UNIX64,
+#endif
 #endif
 
   /* ---- Intel ia64 ---------------- */
@@ -251,6 +264,18 @@
   FFI_DEFAULT_ABI = FFI_SYSV,
 #endif
 
+  /* ---- S390 --------------------- */
+#ifdef S390
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
+  /* ---- SuperH ------------------- */
+#ifdef SH
+  FFI_SYSV,
+  FFI_DEFAULT_ABI = FFI_SYSV,
+#endif
+
   /* Leave this for debugging purposes */
   FFI_LAST_ABI
 
@@ -264,7 +289,7 @@
   /*@null@*/ struct _ffi_type **elements;
 } ffi_type;
 
-/* These are defined in ffi.c */
+/* These are defined in types.c */
 extern ffi_type ffi_type_void;
 extern ffi_type ffi_type_uint8;
 extern ffi_type ffi_type_sint8;
@@ -373,13 +398,7 @@
 
 /* ---- Definitions for closures ----------------------------------------- */
 
-#ifdef X86
-
-#define FFI_CLOSURES 1		/* x86 supports closures */
-#define FFI_TRAMPOLINE_SIZE 10
-#define FFI_NATIVE_RAW_API 1	/* and has native raw api support */
-
-#elif defined(X86_WIN32)
+#ifdef __i386__
 
 #define FFI_CLOSURES 1		/* x86 supports closures */
 #define FFI_TRAMPOLINE_SIZE 10
@@ -424,6 +443,40 @@
 #define FFI_TRAMPOLINE_SIZE 24 /* see struct below */ 
 #define FFI_NATIVE_RAW_API 0
 
+#elif defined(SPARC64)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(SPARC)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(S390)
+
+#define FFI_CLOSURES 1
+#ifdef S390X
+#define FFI_TRAMPOLINE_SIZE 32
+#else
+#define FFI_TRAMPOLINE_SIZE 16
+#endif
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(SH)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 16
+#define FFI_NATIVE_RAW_API 0
+
+#elif defined(__x86_64__)
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 24
+#define FFI_NATIVE_RAW_API 0
+
 #else 
 
 #define FFI_CLOSURES 0
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/arm/ffi.c gcc/libffi/src/arm/ffi.c
--- gcc-3.2.2.orig/libffi/src/arm/ffi.c	Sat Mar  3 07:21:23 2001
+++ gcc/libffi/src/arm/ffi.c	Fri Jul 19 08:08:30 2002
@@ -36,13 +36,10 @@
 /*@=exportheader@*/
 {
   register unsigned int i;
-  register int tmp;
-  register unsigned int avn;
   register void **p_argv;
   register char *argp;
   register ffi_type **p_arg;
 
-  tmp = 0;
   argp = stack;
 
   if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
@@ -50,11 +47,10 @@
     argp += 4;
   }
 
-  avn = ecif->cif->nargs;
   p_argv = ecif->avalue;
 
   for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
-       (i != 0) && (avn != 0);
+       (i != 0);
        i--, p_arg++)
     {
       size_t z;
@@ -64,9 +60,6 @@
 	argp = (char *) ALIGN(argp, (*p_arg)->alignment);
       }
 
-      if (avn != 0) 
-	{
-	  avn--;
 	  z = (*p_arg)->size;
 	  if (z < sizeof(int))
 	    {
@@ -107,7 +100,6 @@
 	    }
 	  p_argv++;
 	  argp += z;
-	}
     }
   
   return;
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/arm/sysv.S gcc/libffi/src/arm/sysv.S
--- gcc-3.2.2.orig/libffi/src/arm/sysv.S	Sat Mar  3 07:21:23 2001
+++ gcc/libffi/src/arm/sysv.S	Mon Sep 30 03:08:58 2002
@@ -28,8 +28,15 @@
 #ifdef HAVE_MACHINE_ASM_H
 #include <machine/asm.h>
 #else
-/* XXX these lose for some platforms, I'm sure. */
+#ifdef __USER_LABEL_PREFIX__
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define CONCAT2(a, b) a ## b
+
+/* Use the right prefix for global labels.  */
+#define CNAME(x) CONCAT1 (__USER_LABEL_PREFIX__, x)
+#else
 #define CNAME(x) x
+#endif
 #define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
 #endif
 	
@@ -96,12 +103,20 @@
 
 # return FLOAT
 	cmp     a4, #FFI_TYPE_FLOAT
+#ifdef __SOFTFP__
+	streq	a1, [a3]
+#else
 	stfeqs  f0, [a3]
+#endif
 	beq     epilogue
 
 # return DOUBLE or LONGDOUBLE
 	cmp     a4, #FFI_TYPE_DOUBLE
+#ifdef __SOFTFP__
+	stmeqia	a3, {a1, a2}
+#else
 	stfeqd  f0, [a3]
+#endif
 
 epilogue:
         ldmfd sp!, {a1-a4, fp, pc}
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/java_raw_api.c gcc/libffi/src/java_raw_api.c
--- gcc-3.2.2.orig/libffi/src/java_raw_api.c	Tue Apr  9 07:31:14 2002
+++ gcc/libffi/src/java_raw_api.c	Tue Oct  8 23:55:02 2002
@@ -81,21 +81,14 @@
 	{
 	case FFI_TYPE_UINT8:
 	case FFI_TYPE_SINT8:
-	  *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1);
+	  *args = (void*) ((char*)(raw++) + 3);
 	  break;
 	  
 	case FFI_TYPE_UINT16:
 	case FFI_TYPE_SINT16:
-	  *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2);
+	  *args = (void*) ((char*)(raw++) + 2);
 	  break;
 
-#if SIZEOF_ARG >= 4	  
-	case FFI_TYPE_UINT32:
-	case FFI_TYPE_SINT32:
-	  *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4);
-	  break;
-#endif
-	
 #if SIZEOF_ARG == 8	  
 	case FFI_TYPE_UINT64:
 	case FFI_TYPE_SINT64:
@@ -157,31 +150,54 @@
       switch ((*tp)->type)
 	{
 	case FFI_TYPE_UINT8:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT8*) (*args);
+#else
 	  (raw++)->uint = *(UINT8*) (*args);
+#endif
 	  break;
 
 	case FFI_TYPE_SINT8:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT8*) (*args);
+#else
 	  (raw++)->sint = *(SINT8*) (*args);
+#endif
 	  break;
 
 	case FFI_TYPE_UINT16:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT16*) (*args);
+#else
 	  (raw++)->uint = *(UINT16*) (*args);
+#endif
 	  break;
 
 	case FFI_TYPE_SINT16:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT16*) (*args);
+#else
 	  (raw++)->sint = *(SINT16*) (*args);
+#endif
 	  break;
 
-#if SIZEOF_ARG >= 4
 	case FFI_TYPE_UINT32:
+#if WORDS_BIGENDIAN
+	  *(UINT32*)(raw++) = *(UINT32*) (*args);
+#else
 	  (raw++)->uint = *(UINT32*) (*args);
+#endif
 	  break;
 
 	case FFI_TYPE_SINT32:
+#if WORDS_BIGENDIAN
+	  *(SINT32*)(raw++) = *(SINT32*) (*args);
+#else
 	  (raw++)->sint = *(SINT32*) (*args);
-	  break;
 #endif
-        case FFI_TYPE_FLOAT:
+	  break;
+
+	case FFI_TYPE_FLOAT:
 	  (raw++)->flt = *(FLOAT32*) (*args);
 	  break;
 
@@ -211,6 +227,55 @@
 
 #if !FFI_NATIVE_RAW_API
 
+static void
+ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
+{
+#if WORDS_BIGENDIAN && SIZEOF_ARG == 8
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_UINT32:
+      *(UINT64 *)rvalue <<= 32;
+      break;
+
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+      *(SINT64 *)rvalue <<= 32;
+      break;
+
+    default:
+      break;
+    }
+#endif
+}
+
+static void
+ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
+{
+#if WORDS_BIGENDIAN && SIZEOF_ARG == 8
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_UINT32:
+      *(UINT64 *)rvalue >>= 32;
+      break;
+
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_INT:
+      *(SINT64 *)rvalue >>= 32;
+      break;
+
+    default:
+      break;
+    }
+#endif
+}
 
 /* This is a generic definition of ffi_raw_call, to be used if the
  * native system does not provide a machine-specific implementation.
@@ -227,6 +292,7 @@
   void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
   ffi_java_raw_to_ptrarray (cif, raw, avalue);
   ffi_call (cif, fn, rvalue, avalue);
+  ffi_java_rvalue_to_raw (cif, rvalue);
 }
 
 #if FFI_CLOSURES		/* base system provides closures */
@@ -240,6 +306,7 @@
 
   ffi_java_ptrarray_to_raw (cif, avalue, raw);
   (*cl->fun) (cif, rvalue, raw, cl->user_data);
+  ffi_java_raw_to_rvalue (cif, rvalue);
 }
 
 /* Again, here is the generic version of ffi_prep_raw_closure, which
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/m68k/ffi.c gcc/libffi/src/m68k/ffi.c
--- gcc-3.2.2.orig/libffi/src/m68k/ffi.c	Sun Aug  8 22:27:19 1999
+++ gcc/libffi/src/m68k/ffi.c	Fri Jul 19 08:08:30 2002
@@ -16,14 +16,11 @@
 ffi_prep_args (void *stack, extended_cif *ecif)
 {
   unsigned int i;
-  int tmp;
-  unsigned int avn;
   void **p_argv;
   char *argp;
   ffi_type **p_arg;
   void *struct_value_ptr;
 
-  tmp = 0;
   argp = stack;
 
   if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
@@ -32,11 +29,10 @@
   else
     struct_value_ptr = NULL;
 
-  avn = ecif->cif->nargs;
   p_argv = ecif->avalue;
 
   for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
-       i != 0 && avn != 0;
+       i != 0;
        i--, p_arg++)
     {
       size_t z;
@@ -45,9 +41,6 @@
       if (((*p_arg)->alignment - 1) & (unsigned) argp)
 	argp = (char *) ALIGN (argp, (*p_arg)->alignment);
 
-      if (avn != 0) 
-	{
-	  avn--;
 	  z = (*p_arg)->size;
 	  if (z < sizeof (int))
 	    {
@@ -82,7 +75,6 @@
 	    memcpy (argp, *p_argv, z);
 	  p_argv++;
 	  argp += z;
-	}
     }
 
   return struct_value_ptr;
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/mips/ffi.c gcc/libffi/src/mips/ffi.c
--- gcc-3.2.2.orig/libffi/src/mips/ffi.c	Sat Mar  3 07:21:23 2001
+++ gcc/libffi/src/mips/ffi.c	Fri Jul 19 08:08:31 2002
@@ -23,6 +23,7 @@
    OTHER DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
+#include <sgidefs.h>
 #include <ffi.h>
 #include <ffi_common.h>
 
@@ -50,7 +51,6 @@
 			  int flags)
 {
   register int i;
-  register int avn;
   register void **p_argv;
   register char *argp;
   register ffi_type **p_arg;
@@ -80,12 +80,9 @@
       FIX_ARGP;
     }
 
-  avn = ecif->cif->nargs;
   p_argv = ecif->avalue;
 
-  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
-       i && avn;
-       i--, p_arg++)
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
     {
       size_t z;
 
@@ -101,9 +98,6 @@
 #define OFFSET sizeof(int)
 #endif      
 
-      if (avn) 
-	{
-	  avn--;
 	  z = (*p_arg)->size;
 	  if (z < sizeof(SLOT_TYPE_UNSIGNED))
 	    {
@@ -179,7 +173,6 @@
 	  p_argv++;
 	  argp += z;
 	  FIX_ARGP;
-	}
     }
   
   return;
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/powerpc/darwin.S gcc/libffi/src/powerpc/darwin.S
--- gcc-3.2.2.orig/libffi/src/powerpc/darwin.S	Sat Jan 19 01:22:34 2002
+++ gcc/libffi/src/powerpc/darwin.S	Thu Jan 23 03:21:55 2003
@@ -3,8 +3,6 @@
    
    PowerPC Assembly glue.
 
-   $Id: darwin.S,v 1.2 2002/01/18 16:22:34 dje Exp $
-
    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
@@ -39,30 +37,34 @@
 .text
 	.align 2
 _ffi_call_DARWIN:
-	mr      r12,r8 // We only need r12 until the call, so it doesn't have to be saved...
+LFB0:	
+	mr      r12,r8		/* We only need r12 until the call,
+				so it doesn't have to be saved...  */
+LFB1:	
 	/* Save the old stack pointer as AP.  */
 	mr	r8,r1
-
+LCFI0:	
 	/* Allocate the stack space we need.  */
 	stwux	r1,r1,r4	
 	
 	/* Save registers we use.  */
 	mflr	r9
 
-	stw	r28,-16(r8)
+	stw	r28,-16(r8)	
 	stw	r29,-12(r8)
 	stw	r30, -8(r8)
 	stw	r31, -4(r8)
-	
-	stw	r9,  8(r8)
+
+	stw	r9,  8(r8)	
 	stw	r2, 20(r1)
+LCFI1:	
 
 	/* Save arguments over call...  */
-	mr	r31,r5	/* flags, */
-	mr	r30,r6	/* rvalue, */
-	mr	r29,r7	/* function address, */
-	mr	r28,r8	/* our AP. */
-		
+	mr	r31,r5	/* flags,  */
+	mr	r30,r6	/* rvalue,  */
+	mr	r29,r7	/* function address,  */
+	mr	r28,r8	/* our AP.  */
+LCFI2:		
 	/* Call ffi_prep_args.  */
 	mr	r4,r1
 	li	r9,0
@@ -145,7 +147,8 @@
 L(float_return_value):
 	stfs	f1,0(r30)
 	b	L(done_return_value)
-//END(_ffi_call_DARWIN)
+LFE1:	
+/* END(_ffi_call_DARWIN)  */
 
 /* Provide a null definition of _ffi_call_AIX.  */
 .text
@@ -155,5 +158,61 @@
 	.align 2
 _ffi_call_AIX:
 	blr
-//END(_ffi_call_AIX)
+/* END(_ffi_call_AIX)  */
 
+.data
+.section __TEXT,__eh_frame
+Lframe1:
+	.set	L$set$0,LECIE1-LSCIE1
+	.long	L$set$0	; Length of Common Information Entry
+LSCIE1:
+	.long	0x0	; CIE Identifier Tag
+	.byte	0x1	; CIE Version
+	.ascii	"zR\0"	; CIE Augmentation
+	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
+	.byte	0x7c	; sleb128 -4; CIE Data Alignment Factor
+	.byte	0x41	; CIE RA Column
+	.byte   0x1     ; uleb128 0x1; Augmentation size
+	.byte   0x10    ; FDE Encoding (pcrel)
+	.byte	0xc	; DW_CFA_def_cfa
+	.byte	0x1	; uleb128 0x1
+	.byte	0x0	; uleb128 0x0
+	.align	2
+LECIE1:
+LSFDE1:
+	.set	L$set$1,LEFDE1-LASFDE1
+	.long	L$set$1	; FDE Length
+LASFDE1:
+	.set	L$set$2,LASFDE1-Lframe1
+	.long	L$set$2	; FDE CIE offset
+	.long	LFB0-.	; FDE initial location
+	.set	L$set$3,LFE1-LFB0
+	.long	L$set$3	; FDE address range
+	.byte   0x0     ; uleb128 0x0; Augmentation size
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$4,LCFI0-LFB1
+	.long	L$set$4
+	.byte	0xd	; DW_CFA_def_cfa_register
+	.byte	0x08	; uleb128 0x08 
+	.byte	0x4	; DW_CFA_advance_loc4
+	.set	L$set$5,LCFI1-LCFI0
+	.long	L$set$5
+	.byte   0x11    ; DW_CFA_offset_extended_sf
+	.byte	0x41	; uleb128 0x41
+	.byte   0x7e    ; sleb128 -2
+	.byte	0x9f	; DW_CFA_offset, column 0x1f 
+	.byte	0x1	; uleb128 0x1 
+	.byte	0x9e	; DW_CFA_offset, column 0x1e
+	.byte	0x2	; uleb128 0x2
+	.byte	0x9d	; DW_CFA_offset, column 0x1d 
+	.byte	0x3	; uleb128 0x3 
+	.byte	0x9c	; DW_CFA_offset, column 0x1c 
+	.byte	0x4	; uleb128 0x4
+	.byte	0x4	; DW_CFA_advance_loc4 
+	.set	L$set$6,LCFI2-LCFI1
+	.long	L$set$6
+	.byte	0xd	; DW_CFA_def_cfa_register 
+	.byte	0x1c	; uleb128 0x1c 
+	.align 2
+LEFDE1:
+	
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/prep_cif.c gcc/libffi/src/prep_cif.c
--- gcc-3.2.2.orig/libffi/src/prep_cif.c	Sat Mar  3 07:21:22 2001
+++ gcc/libffi/src/prep_cif.c	Mon Sep 30 20:59:42 2002
@@ -103,7 +103,8 @@
   /* Perform a sanity check on the return type */
   FFI_ASSERT(ffi_type_test(cif->rtype));
 
-#ifndef M68K
+  /* x86-64 and s390 stack space allocation is handled in prep_machdep.  */
+#if !defined M68K && !defined __x86_64__ && !defined S390
   /* Make space for the return structure pointer */
   if (cif->rtype->type == FFI_TYPE_STRUCT
 #ifdef SPARC
@@ -122,6 +123,7 @@
       if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
 	return FFI_BAD_TYPEDEF;
 
+#if !defined __x86_64__ && !defined S390
 #ifdef SPARC
       if (((*ptr)->type == FFI_TYPE_STRUCT
 	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
@@ -137,6 +139,7 @@
 	  
 	  bytes += STACK_ARG_SIZE((*ptr)->size);
 	}
+#endif
     }
 
   cif->bytes = bytes;
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/s390/ffi.c gcc/libffi/src/s390/ffi.c
--- gcc-3.2.2.orig/libffi/src/s390/ffi.c	Thu Jan  1 09:00:00 1970
+++ gcc/libffi/src/s390/ffi.c	Thu Feb  6 08:58:57 2003
@@ -0,0 +1,753 @@
+/* -----------------------------------------------------------------------
+   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                                  */
+/*                           -------                                  */
+/*====================================================================*/
+
+/* Maximum number of GPRs available for argument passing.  */ 
+#define MAX_GPRARGS 5
+
+/* Maximum number of FPRs available for argument passing.  */ 
+#ifdef __s390x__
+#define MAX_FPRARGS 4
+#else
+#define MAX_FPRARGS 2
+#endif
+
+/* Round to multiple of 16.  */
+#define ROUND_SIZE(size) (((size) + 15) & ~15)
+
+/* If these values change, sysv.S must be adapted!  */
+#define FFI390_RET_VOID		0
+#define FFI390_RET_STRUCT	1
+#define FFI390_RET_FLOAT	2
+#define FFI390_RET_DOUBLE	3
+#define FFI390_RET_INT32	4
+#define FFI390_RET_INT64	5
+
+/*===================== End of Defines ===============================*/
+ 
+/*====================================================================*/
+/*                          Prototypes                                */
+/*                          ----------                                */
+/*====================================================================*/
+ 
+static void ffi_prep_args (unsigned char *, extended_cif *);
+static int ffi_check_float_struct (ffi_type *);
+void
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2)
+__attribute__ ((visibility ("hidden")))
+#endif
+ffi_closure_helper_SYSV (ffi_closure *, unsigned long *, 
+			 unsigned long long *, unsigned long *);
+
+/*====================== End of Prototypes ===========================*/
+ 
+/*====================================================================*/
+/*                          Externals                                 */
+/*                          ---------                                 */
+/*====================================================================*/
+ 
+extern void ffi_call_SYSV(unsigned,
+			  extended_cif *,
+			  void (*)(unsigned char *, extended_cif *),
+			  unsigned,
+			  void *,
+			  void (*fn)());
+
+extern void ffi_closure_SYSV(void);
+ 
+/*====================== End of Externals ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_check_struct_type.                                  */
+/*                                                                    */
+/* Function - Determine if a structure can be passed within a         */
+/*            general purpose or floating point register.             */
+/*                                                                    */
+/*====================================================================*/
+ 
+static int
+ffi_check_struct_type (ffi_type *arg)
+{
+  size_t size = arg->size;
+
+  /* If the struct has just one element, look at that element
+     to find out whether to consider the struct as floating point.  */
+  while (arg->type == FFI_TYPE_STRUCT 
+         && arg->elements[0] && !arg->elements[1])
+    arg = arg->elements[0];
+
+  /* Structs of size 1, 2, 4, and 8 are passed in registers,
+     just like the corresponding int/float types.  */
+  switch (size)
+    {
+      case 1:
+        return FFI_TYPE_UINT8;
+
+      case 2:
+        return FFI_TYPE_UINT16;
+
+      case 4:
+	if (arg->type == FFI_TYPE_FLOAT)
+          return FFI_TYPE_FLOAT;
+	else
+	  return FFI_TYPE_UINT32;
+
+      case 8:
+	if (arg->type == FFI_TYPE_DOUBLE)
+          return FFI_TYPE_DOUBLE;
+	else
+	  return FFI_TYPE_UINT64;
+
+      default:
+	break;
+    }
+
+  /* Other structs are passed via a pointer to the data.  */
+  return FFI_TYPE_POINTER;
+}
+ 
+/*======================== 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.                   */
+/*                                                                    */
+/*====================================================================*/
+ 
+static void
+ffi_prep_args (unsigned char *stack, extended_cif *ecif)
+{
+  /* The stack space will be filled with those areas:
+
+	FPR argument register save area     (highest addresses)
+	GPR argument register save area
+	temporary struct copies
+	overflow argument area              (lowest addresses)
+
+     We set up the following pointers:
+
+        p_fpr: bottom of the FPR area (growing upwards)
+	p_gpr: bottom of the GPR area (growing upwards)
+	p_ov: bottom of the overflow area (growing upwards)
+	p_struct: top of the struct copy area (growing downwards)
+
+     All areas are kept aligned to twice the word size.  */
+
+  int gpr_off = ecif->cif->bytes;
+  int fpr_off = gpr_off + ROUND_SIZE (MAX_GPRARGS * sizeof (long));
+
+  unsigned long long *p_fpr = (unsigned long long *)(stack + fpr_off);
+  unsigned long *p_gpr = (unsigned long *)(stack + gpr_off);
+  unsigned char *p_struct = (unsigned char *)p_gpr;
+  unsigned long *p_ov = (unsigned long *)stack;
+
+  int n_fpr = 0;
+  int n_gpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  void **p_argv = ecif->avalue;
+  int i;
+ 
+  /* If we returning a structure then we set the first parameter register
+     to the address of where we are returning this structure.  */
+
+  if (ecif->cif->flags == FFI390_RET_STRUCT)
+    p_gpr[n_gpr++] = (unsigned long) ecif->rvalue;
+
+  /* Now for the arguments.  */
+ 
+  for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs;
+       i > 0;
+       i--, ptr++, p_argv++)
+    {
+      void *arg = *p_argv;
+      int type = (*ptr)->type;
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, copy the data.  */
+	  if (type == FFI_TYPE_POINTER)
+	    {
+	      p_struct -= ROUND_SIZE ((*ptr)->size);
+	      memcpy (p_struct, (char *)arg, (*ptr)->size);
+	      arg = &p_struct;
+	    }
+	}
+
+      /* Pointers are passed like UINTs of the same size.  */
+      if (type == FFI_TYPE_POINTER)
+#ifdef __s390x__
+	type = FFI_TYPE_UINT64;
+#else
+	type = FFI_TYPE_UINT32;
+#endif
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      p_fpr[n_fpr++] = *(unsigned long long *) arg;
+	    else
+#ifdef __s390x__
+	      p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+	      p_ov[n_ov++] = ((unsigned long *) arg)[0],
+	      p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      p_fpr[n_fpr++] = (long long) *(unsigned int *) arg << 32;
+	    else
+	      p_ov[n_ov++] = *(unsigned int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned long *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned long *) arg;
+#else
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = ((unsigned long *) arg)[0],
+	      p_gpr[n_gpr++] = ((unsigned long *) arg)[1];
+	    else
+	      p_ov[n_ov++] = ((unsigned long *) arg)[0],
+	      p_ov[n_ov++] = ((unsigned long *) arg)[1];
+#endif
+	    break;
+ 
+	  case FFI_TYPE_UINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned int *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_INT:
+	  case FFI_TYPE_SINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed int *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed int *) arg;
+	    break;
+ 
+	  case FFI_TYPE_UINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned short *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned short *) arg;
+	    break;
+ 
+	  case FFI_TYPE_SINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed short *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed short *) arg;
+	    break;
+
+	  case FFI_TYPE_UINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(unsigned char *) arg;
+	    else
+	      p_ov[n_ov++] = *(unsigned char *) arg;
+	    break;
+ 
+	  case FFI_TYPE_SINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      p_gpr[n_gpr++] = *(signed char *) arg;
+	    else
+	      p_ov[n_ov++] = *(signed char *) arg;
+	    break;
+ 
+	  default:
+	    FFI_ASSERT (0);
+	    break;
+        }
+    }
+}
+
+/*======================== End of Routine ============================*/
+ 
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_cif_machdep.                                   */
+/*                                                                    */
+/* Function - Perform machine dependent CIF processing.               */
+/*                                                                    */
+/*====================================================================*/
+ 
+ffi_status
+ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  size_t struct_size = 0;
+  int n_gpr = 0;
+  int n_fpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  int i;
+
+  /* Determine return value handling.  */ 
+
+  switch (cif->rtype->type)
+    {
+      /* Void is easy.  */
+      case FFI_TYPE_VOID:
+	cif->flags = FFI390_RET_VOID;
+	break;
+
+      /* Structures are returned via a hidden pointer.  */
+      case FFI_TYPE_STRUCT:
+	cif->flags = FFI390_RET_STRUCT;
+	n_gpr++;  /* We need one GPR to pass the pointer.  */
+	break; 
+
+      /* Floating point values are returned in fpr 0.  */
+      case FFI_TYPE_FLOAT:
+	cif->flags = FFI390_RET_FLOAT;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	cif->flags = FFI390_RET_DOUBLE;
+	break;
+
+      /* Integer values are returned in gpr 2 (and gpr 3
+	 for 64-bit values on 31-bit machines).  */
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+	cif->flags = FFI390_RET_INT64;
+	break;
+
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_INT:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_SINT16:
+      case FFI_TYPE_UINT8:
+      case FFI_TYPE_SINT8:
+	/* These are to be extended to word size.  */
+#ifdef __s390x__
+	cif->flags = FFI390_RET_INT64;
+#else
+	cif->flags = FFI390_RET_INT32;
+#endif
+	break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+
+  /* Now for the arguments.  */
+ 
+  for (ptr = cif->arg_types, i = cif->nargs;
+       i > 0;
+       i--, ptr++)
+    {
+      int type = (*ptr)->type;
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, we must reserve space
+	     to copy its data for proper call-by-value semantics.  */
+	  if (type == FFI_TYPE_POINTER)
+	    struct_size += ROUND_SIZE ((*ptr)->size);
+	}
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  /* The first MAX_FPRARGS floating point arguments
+	     go in FPRs, the rest overflow to the stack.  */
+
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      n_fpr++;
+	    else
+	      n_ov += sizeof (double) / sizeof (long);
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      n_fpr++;
+	    else
+	      n_ov++;
+	    break;
+
+	  /* On 31-bit machines, 64-bit integers are passed in GPR pairs,
+	     if one is still available, or else on the stack.  If only one
+	     register is free, skip the register (it won't be used for any 
+	     subsequent argument either).  */
+	      
+#ifndef __s390x__
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      n_gpr += 2;
+	    else
+	      n_ov += 2;
+	    break;
+#endif
+
+	  /* Everything else is passed in GPRs (until MAX_GPRARGS
+	     have been used) or overflows to the stack.  */
+
+	  default: 
+	    if (n_gpr < MAX_GPRARGS)
+	      n_gpr++;
+	    else
+	      n_ov++;
+	    break;
+        }
+    }
+
+  /* Total stack space as required for overflow arguments
+     and temporary structure copies.  */
+
+  cif->bytes = ROUND_SIZE (n_ov * sizeof (long)) + struct_size;
+ 
+  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)
+{
+  int ret_type = cif->flags;
+  extended_cif ecif;
+ 
+  ecif.cif    = cif;
+  ecif.avalue = avalue;
+  ecif.rvalue = rvalue;
+
+  /* If we don't have a return value, we need to fake one.  */
+  if (rvalue == NULL)
+    {
+      if (ret_type == FFI390_RET_STRUCT)
+	ecif.rvalue = alloca (cif->rtype->size);
+      else
+	ret_type = FFI390_RET_VOID;
+    } 
+
+  switch (cif->abi)
+    {
+      case FFI_SYSV:
+        ffi_call_SYSV (cif->bytes, &ecif, ffi_prep_args,
+		       ret_type, ecif.rvalue, fn);
+        break;
+ 
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+}
+ 
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_closure_helper_SYSV.                                */
+/*                                                                    */
+/* Function - Call a FFI closure target function.                     */
+/*                                                                    */
+/*====================================================================*/
+ 
+void
+ffi_closure_helper_SYSV (ffi_closure *closure,
+			 unsigned long *p_gpr,
+			 unsigned long long *p_fpr,
+			 unsigned long *p_ov)
+{
+  unsigned long long ret_buffer;
+
+  void *rvalue = &ret_buffer;
+  void **avalue;
+  void **p_arg;
+
+  int n_gpr = 0;
+  int n_fpr = 0;
+  int n_ov = 0;
+
+  ffi_type **ptr;
+  int i;
+
+  /* Allocate buffer for argument list pointers.  */
+
+  p_arg = avalue = alloca (closure->cif->nargs * sizeof (void *));
+
+  /* If we returning a structure, pass the structure address 
+     directly to the target function.  Otherwise, have the target 
+     function store the return value to the GPR save area.  */
+
+  if (closure->cif->flags == FFI390_RET_STRUCT)
+    rvalue = (void *) p_gpr[n_gpr++];
+
+  /* Now for the arguments.  */
+
+  for (ptr = closure->cif->arg_types, i = closure->cif->nargs;
+       i > 0;
+       i--, p_arg++, ptr++)
+    {
+      int deref_struct_pointer = 0;
+      int type = (*ptr)->type;
+
+      /* Check how a structure type is passed.  */
+      if (type == FFI_TYPE_STRUCT)
+	{
+	  type = ffi_check_struct_type (*ptr);
+
+	  /* If we pass the struct via pointer, remember to 
+	     retrieve the pointer later.  */
+	  if (type == FFI_TYPE_POINTER)
+	    deref_struct_pointer = 1;
+	}
+
+      /* Pointers are passed like UINTs of the same size.  */
+      if (type == FFI_TYPE_POINTER)
+#ifdef __s390x__
+	type = FFI_TYPE_UINT64;
+#else
+	type = FFI_TYPE_UINT32;
+#endif
+
+      /* Now handle all primitive int/float data types.  */
+      switch (type) 
+	{
+	  case FFI_TYPE_DOUBLE:
+	    if (n_fpr < MAX_FPRARGS)
+	      *p_arg = &p_fpr[n_fpr++];
+	    else
+	      *p_arg = &p_ov[n_ov], 
+	      n_ov += sizeof (double) / sizeof (long);
+	    break;
+	
+	  case FFI_TYPE_FLOAT:
+	    if (n_fpr < MAX_FPRARGS)
+	      *p_arg = &p_fpr[n_fpr++];
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+	    break;
+ 
+	  case FFI_TYPE_UINT64:
+	  case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = &p_gpr[n_gpr++];
+	    else
+	      *p_arg = &p_ov[n_ov++];
+#else
+	    if (n_gpr == MAX_GPRARGS-1)
+	      n_gpr = MAX_GPRARGS;
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = &p_gpr[n_gpr], n_gpr += 2;
+	    else
+	      *p_arg = &p_ov[n_ov], n_ov += 2;
+#endif
+	    break;
+ 
+	  case FFI_TYPE_INT:
+	  case FFI_TYPE_UINT32:
+	  case FFI_TYPE_SINT32:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 4;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 4;
+	    break;
+ 
+	  case FFI_TYPE_UINT16:
+	  case FFI_TYPE_SINT16:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 2;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 2;
+	    break;
+
+	  case FFI_TYPE_UINT8:
+	  case FFI_TYPE_SINT8:
+	    if (n_gpr < MAX_GPRARGS)
+	      *p_arg = (char *)&p_gpr[n_gpr++] + sizeof (long) - 1;
+	    else
+	      *p_arg = (char *)&p_ov[n_ov++] + sizeof (long) - 1;
+	    break;
+ 
+	  default:
+	    FFI_ASSERT (0);
+	    break;
+        }
+
+      /* If this is a struct passed via pointer, we need to
+	 actually retrieve that pointer.  */
+      if (deref_struct_pointer)
+	*p_arg = *(void **)*p_arg;
+    }
+
+
+  /* Call the target function.  */
+  (closure->fun) (closure->cif, rvalue, avalue, closure->user_data);
+
+  /* Convert the return value.  */
+  switch (closure->cif->rtype->type)
+    {
+      /* Void is easy, and so is struct.  */
+      case FFI_TYPE_VOID:
+      case FFI_TYPE_STRUCT:
+	break;
+
+      /* Floating point values are returned in fpr 0.  */
+      case FFI_TYPE_FLOAT:
+	p_fpr[0] = (long long) *(unsigned int *) rvalue << 32;
+	break;
+
+      case FFI_TYPE_DOUBLE:
+	p_fpr[0] = *(unsigned long long *) rvalue;
+	break;
+
+      /* Integer values are returned in gpr 2 (and gpr 3
+	 for 64-bit values on 31-bit machines).  */
+      case FFI_TYPE_UINT64:
+      case FFI_TYPE_SINT64:
+#ifdef __s390x__
+	p_gpr[0] = *(unsigned long *) rvalue;
+#else
+	p_gpr[0] = ((unsigned long *) rvalue)[0],
+	p_gpr[1] = ((unsigned long *) rvalue)[1];
+#endif
+	break;
+
+      case FFI_TYPE_POINTER:
+      case FFI_TYPE_UINT32:
+      case FFI_TYPE_UINT16:
+      case FFI_TYPE_UINT8:
+	p_gpr[0] = *(unsigned long *) rvalue;
+	break;
+
+      case FFI_TYPE_INT:
+      case FFI_TYPE_SINT32:
+      case FFI_TYPE_SINT16:
+      case FFI_TYPE_SINT8:
+	p_gpr[0] = *(signed long *) rvalue;
+	break;
+
+      default:
+        FFI_ASSERT (0);
+        break;
+    }
+}
+ 
+/*======================== End of Routine ============================*/
+
+/*====================================================================*/
+/*                                                                    */
+/* Name     - ffi_prep_closure.                                       */
+/*                                                                    */
+/* Function - Prepare a FFI closure.                                  */
+/*                                                                    */
+/*====================================================================*/
+ 
+ffi_status
+ffi_prep_closure (ffi_closure *closure,
+                  ffi_cif *cif,
+                  void (*fun) (ffi_cif *, void *, void **, void *),
+                  void *user_data)
+{
+  FFI_ASSERT (cif->abi == FFI_SYSV);
+
+#ifndef __s390x__
+  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */
+  *(short *)&closure->tramp [2] = 0x9801;   /* lm %r0,%r1,6(%r1) */
+  *(short *)&closure->tramp [4] = 0x1006;
+  *(short *)&closure->tramp [6] = 0x07f1;   /* br %r1 */
+  *(long  *)&closure->tramp [8] = (long)closure;
+  *(long  *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
+#else
+  *(short *)&closure->tramp [0] = 0x0d10;   /* basr %r1,0 */
+  *(short *)&closure->tramp [2] = 0xeb01;   /* lmg %r0,%r1,14(%r1) */
+  *(short *)&closure->tramp [4] = 0x100e;
+  *(short *)&closure->tramp [6] = 0x0004;
+  *(short *)&closure->tramp [8] = 0x07f1;   /* br %r1 */
+  *(long  *)&closure->tramp[16] = (long)closure;
+  *(long  *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
+#endif 
+ 
+  closure->cif = cif;
+  closure->user_data = user_data;
+  closure->fun = fun;
+ 
+  return FFI_OK;
+}
+
+/*======================== End of Routine ============================*/
+ 
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/s390/sysv.S gcc/libffi/src/s390/sysv.S
--- gcc-3.2.2.orig/libffi/src/s390/sysv.S	Thu Jan  1 09:00:00 1970
+++ gcc/libffi/src/s390/sysv.S	Thu Nov 28 01:44:35 2002
@@ -0,0 +1,425 @@
+/* -----------------------------------------------------------------------
+   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.
+   ----------------------------------------------------------------------- */
+
+#ifndef __s390x__
+ 
+.text
+
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+	stm	%r6,%r15,24(%r15)		# Save registers
+.LCFI0:
+	basr	%r13,0				# Set up base register
+.Lbase:
+	lr	%r11,%r15			# Set up frame pointer
+.LCFI1:
+	sr	%r15,%r2
+	ahi	%r15,-96-48			# Allocate stack
+	lr	%r8,%r6				# Save ecif.rvalue
+	sr	%r9,%r9
+	ic	%r9,.Ltable-.Lbase(%r13,%r5)	# Load epilog address
+	l	%r7,96(%r11)			# Load function address
+	st	%r11,0(%r15)			# Set up back chain
+	ahi	%r11,-48			# Register save area
+.LCFI2:
+
+	la	%r2,96(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
+
+	lm	%r2,%r6,0(%r11)			# Load arguments
+	ld	%f0,32(%r11)
+	ld	%f2,40(%r11)
+	la	%r14,0(%r13,%r9)		# Set return address
+	br	%r7				# ... and call function
+
+.LretNone:					# Return void
+	l	%r4,48+56(%r11)
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+
+.LretFloat:
+	l	%r4,48+56(%r11)
+	ste	%f0,0(%r8)			# Return float
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.LretDouble:
+	l	%r4,48+56(%r11)
+	std	%f0,0(%r8)			# Return double
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+
+.LretInt32:
+	l	%r4,48+56(%r11)
+	st	%r2,0(%r8)			# Return int
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.LretInt64:
+	l	%r4,48+56(%r11)
+	stm	%r2,%r3,0(%r8)			# Return long long
+	lm	%r6,%r15,48+24(%r11)
+	br	%r4
+ 
+.Ltable:
+	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
+	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
+	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
+	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
+	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
+
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+	stm	%r12,%r15,48(%r15)		# Save registers
+.LCFI10:
+	basr	%r13,0				# Set up base register
+.Lcbase:
+	stm	%r2,%r6,8(%r15)			# Save arguments
+	std	%f0,64(%r15)
+	std	%f2,72(%r15)
+	lr	%r1,%r15			# Set up stack frame
+	ahi	%r15,-96
+.LCFI11:
+	l	%r12,.Lchelper-.Lcbase(%r13)	# Get helper function
+	lr	%r2,%r0				# Closure
+	la	%r3,8(%r1)			# GPRs
+	la	%r4,64(%r1)			# FPRs
+	la	%r5,96(%r1)			# Overflow
+	st	%r1,0(%r15)			# Set up back chain
+
+	bas	%r14,0(%r12,%r13)		# Call helper
+
+	l	%r4,96+56(%r15)
+	ld	%f0,96+64(%r15)			# Load return registers
+	lm	%r2,%r3,96+8(%r15)
+	lm	%r12,%r15,96+48(%r15)
+	br	%r4
+
+	.align 4
+.Lchelper:
+	.long	ffi_closure_helper_SYSV-.Lcbase
+
+.LFE2: 
+
+.ffi_closure_SYSV_end:
+	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+	.section	.eh_frame,"a",@progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "zR\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -4	# CIE Data Alignment Factor
+	.byte	0xe	# CIE RA Column
+	.uleb128 0x1	# Augmentation size
+	.byte	0x1b	# FDE Encoding (pcrel sdata4)
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0x60
+	.align	4
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	# FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
+	.4byte	.LFB1-.	# FDE initial location
+	.4byte	.LFE1-.LFB1	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x9
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0xa
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0xb
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0xc
+	.byte	0x8b	# DW_CFA_offset, column 0xb
+	.uleb128 0xd
+	.byte	0x8a	# DW_CFA_offset, column 0xa
+	.uleb128 0xe
+	.byte	0x89	# DW_CFA_offset, column 0x9
+	.uleb128 0xf
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0x10
+	.byte	0x87	# DW_CFA_offset, column 0x7
+	.uleb128 0x11
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0x12
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0xb
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x90
+	.align	4
+.LEFDE1:
+.LSFDE2:
+	.4byte	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
+	.4byte	.LFB2-.	# FDE initial location
+	.4byte	.LFE2-.LFB2	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI10-.LFB2
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x9
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0xa
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0xb
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0xc
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI11-.LCFI10
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0xc0
+	.align	4
+.LEFDE2:
+
+#else
+ 
+.text
+ 
+	# r2:	cif->bytes
+	# r3:	&ecif
+	# r4:	ffi_prep_args
+	# r5:	ret_type
+	# r6:	ecif.rvalue
+	# ov:	fn 
+ 
+	# This assumes we are using gas.
+	.globl	ffi_call_SYSV
+	.type	ffi_call_SYSV,%function
+ffi_call_SYSV:
+.LFB1:
+	stmg	%r6,%r15,48(%r15)		# Save registers
+.LCFI0:
+	larl	%r13,.Lbase			# Set up base register
+	lgr	%r11,%r15			# Set up frame pointer
+.LCFI1:
+	sgr	%r15,%r2
+	aghi	%r15,-160-80			# Allocate stack
+	lgr	%r8,%r6				# Save ecif.rvalue
+	llgc	%r9,.Ltable-.Lbase(%r13,%r5)	# Load epilog address
+	lg	%r7,160(%r11)			# Load function address
+	stg	%r11,0(%r15)			# Set up back chain
+	aghi	%r11,-80			# Register save area
+.LCFI2:
+
+	la	%r2,160(%r15)			# Save area
+						# r3 already holds &ecif
+	basr	%r14,%r4			# Call ffi_prep_args
+
+	lmg	%r2,%r6,0(%r11)			# Load arguments
+	ld	%f0,48(%r11)
+	ld	%f2,56(%r11)
+	ld	%f4,64(%r11)
+	ld	%f6,72(%r11)
+	la	%r14,0(%r13,%r9)		# Set return address
+	br	%r7				# ... and call function
+
+.Lbase:
+.LretNone:					# Return void
+	lg	%r4,80+112(%r11)
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+
+.LretFloat:
+	lg	%r4,80+112(%r11)
+	ste	%f0,0(%r8)			# Return float
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.LretDouble:
+	lg	%r4,80+112(%r11)
+	std	%f0,0(%r8)			# Return double
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+
+.LretInt32:
+	lg	%r4,80+112(%r11)
+	st	%r2,0(%r8)			# Return int
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.LretInt64:
+	lg	%r4,80+112(%r11)
+	stg	%r2,0(%r8)			# Return long
+	lmg	%r6,%r15,80+48(%r11)
+	br	%r4
+ 
+.Ltable:
+	.byte	.LretNone-.Lbase		# FFI390_RET_VOID
+	.byte	.LretNone-.Lbase		# FFI390_RET_STRUCT
+	.byte	.LretFloat-.Lbase		# FFI390_RET_FLOAT
+	.byte	.LretDouble-.Lbase		# FFI390_RET_DOUBLE
+	.byte	.LretInt32-.Lbase		# FFI390_RET_INT32
+	.byte	.LretInt64-.Lbase		# FFI390_RET_INT64
+
+.LFE1: 
+.ffi_call_SYSV_end:
+	.size	 ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
+
+
+	.globl	ffi_closure_SYSV
+	.type	ffi_closure_SYSV,%function
+ffi_closure_SYSV:
+.LFB2:
+	stmg	%r14,%r15,112(%r15)		# Save registers
+.LCFI10:
+	stmg	%r2,%r6,16(%r15)		# Save arguments
+	std	%f0,128(%r15)
+	std	%f2,136(%r15)
+	std	%f4,144(%r15)
+	std	%f6,152(%r15)
+	lgr	%r1,%r15			# Set up stack frame
+	aghi	%r15,-160
+.LCFI11:
+	lgr	%r2,%r0				# Closure
+	la	%r3,16(%r1)			# GPRs
+	la	%r4,128(%r1)			# FPRs
+	la	%r5,160(%r1)			# Overflow
+	stg	%r1,0(%r15)			# Set up back chain
+
+	brasl	%r14,ffi_closure_helper_SYSV	# Call helper
+
+	lg	%r14,160+112(%r15)
+	ld	%f0,160+128(%r15)		# Load return registers
+	lg	%r2,160+16(%r15)
+	la	%r15,160(%r15)
+	br	%r14
+.LFE2: 
+
+.ffi_closure_SYSV_end:
+	.size	 ffi_closure_SYSV,.ffi_closure_SYSV_end-ffi_closure_SYSV
+
+
+
+	.section	.eh_frame,"a",@progbits
+.Lframe1:
+	.4byte	.LECIE1-.LSCIE1	# Length of Common Information Entry
+.LSCIE1:
+	.4byte	0x0	# CIE Identifier Tag
+	.byte	0x1	# CIE Version
+	.ascii "zR\0"	# CIE Augmentation
+	.uleb128 0x1	# CIE Code Alignment Factor
+	.sleb128 -8	# CIE Data Alignment Factor
+	.byte	0xe	# CIE RA Column
+	.uleb128 0x1	# Augmentation size
+	.byte	0x1b	# FDE Encoding (pcrel sdata4)
+	.byte	0xc	# DW_CFA_def_cfa
+	.uleb128 0xf
+	.uleb128 0xa0
+	.align	8
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	# FDE Length
+.LASFDE1:
+	.4byte	.LASFDE1-.Lframe1	# FDE CIE offset
+	.4byte	.LFB1-.	# FDE initial location
+	.4byte	.LFE1-.LFB1	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI0-.LFB1
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x5
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0x6
+	.byte	0x8d	# DW_CFA_offset, column 0xd
+	.uleb128 0x7
+	.byte	0x8c	# DW_CFA_offset, column 0xc
+	.uleb128 0x8
+	.byte	0x8b	# DW_CFA_offset, column 0xb
+	.uleb128 0x9
+	.byte	0x8a	# DW_CFA_offset, column 0xa
+	.uleb128 0xa
+	.byte	0x89	# DW_CFA_offset, column 0x9
+	.uleb128 0xb
+	.byte	0x88	# DW_CFA_offset, column 0x8
+	.uleb128 0xc
+	.byte	0x87	# DW_CFA_offset, column 0x7
+	.uleb128 0xd
+	.byte	0x86	# DW_CFA_offset, column 0x6
+	.uleb128 0xe
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xd	# DW_CFA_def_cfa_register
+	.uleb128 0xb
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0xf0
+	.align	8
+.LEFDE1:
+.LSFDE2:
+	.4byte	.LEFDE2-.LASFDE2	# FDE Length
+.LASFDE2:
+	.4byte	.LASFDE2-.Lframe1	# FDE CIE offset
+	.4byte	.LFB2-.	# FDE initial location
+	.4byte	.LFE2-.LFB2	# FDE address range
+	.uleb128 0x0	# Augmentation size
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI10-.LFB2
+	.byte	0x8f	# DW_CFA_offset, column 0xf
+	.uleb128 0x5
+	.byte	0x8e	# DW_CFA_offset, column 0xe
+	.uleb128 0x6
+	.byte	0x4	# DW_CFA_advance_loc4
+	.4byte	.LCFI11-.LCFI10
+	.byte	0xe	# DW_CFA_def_cfa_offset
+	.uleb128 0x140
+	.align	8
+.LEFDE2:
+
+#endif
+
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/sh/ffi.c gcc/libffi/src/sh/ffi.c
--- gcc-3.2.2.orig/libffi/src/sh/ffi.c	Thu Jan  1 09:00:00 1970
+++ gcc/libffi/src/sh/ffi.c	Fri Jul 19 10:08:43 2002
@@ -0,0 +1,722 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2002 Kaz Kojima
+   
+   SuperH Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+#define NGREGARG 4
+#if defined(__SH4__)
+#define NFREGARG 8
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+/* If the structure has essentialy an unique element, return its type.  */
+static int
+simple_type (ffi_type *arg)
+{
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+  else if (arg->elements[1])
+    return FFI_TYPE_STRUCT;
+
+  return simple_type (arg->elements[0]);
+}
+
+static int
+return_type (ffi_type *arg)
+{
+  unsigned short type;
+
+  if (arg->type != FFI_TYPE_STRUCT)
+    return arg->type;
+
+  type = simple_type (arg->elements[0]);
+  if (! arg->elements[1])
+    {
+      switch (type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	  return FFI_TYPE_INT;
+
+	default:
+	  return type;
+	}
+    }
+
+  /* gcc uses r0/r1 pair for some kind of structures.  */
+  if (arg->size <= 2 * sizeof (int))
+    {
+      int i = 0;
+      ffi_type *e;
+
+      while ((e = arg->elements[i++]))
+	{
+	  type = simple_type (e);
+	  switch (type)
+	    {
+	    case FFI_TYPE_SINT32:
+	    case FFI_TYPE_UINT32:
+	    case FFI_TYPE_INT:
+	    case FFI_TYPE_FLOAT:
+	      return FFI_TYPE_UINT64;
+
+	    default:
+	      break;
+	    }
+	}
+    }
+
+  return FFI_TYPE_STRUCT;
+}
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+/*@-exportheader@*/
+void ffi_prep_args(char *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  register unsigned int i;
+  register int tmp;
+  register unsigned int avn;
+  register void **p_argv;
+  register char *argp;
+  register ffi_type **p_arg;
+  int greg, ireg;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+
+  tmp = 0;
+  argp = stack;
+
+  if (return_type (ecif->cif->rtype) == FFI_TYPE_STRUCT)
+    {
+      *(void **) argp = ecif->rvalue;
+      argp += 4;
+      ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
+    }
+  else
+    ireg = 0;
+
+  /* Set arguments for registers.  */
+  greg = ireg;
+  avn = ecif->cif->nargs;
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ >= NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += z;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ >= NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ >= NGREGARG)
+		continue;
+	    }
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	  argp += z;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+	  if (greg + n - 1 >= NGREGARG)
+	    continue;
+	  greg += n;
+#else
+	  if (greg >= NGREGARG)
+	    continue;
+	  else if (greg + n - 1 >= NGREGARG)
+	    greg = NGREGARG;
+	  else
+	    greg += n;
+#endif
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+    }
+
+  /* Set arguments on stack.  */
+  greg = ireg;
+#if defined(__SH4__)
+  freg = 0;
+#endif
+  p_argv = ecif->avalue;
+
+  for (i = 0, p_arg = ecif->cif->arg_types; i < avn; i++, p_arg++, p_argv++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ < NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	      *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT8:
+	      *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	      *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_UINT16:
+	      *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  argp += z;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ < NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ < NGREGARG)
+		continue;
+	    }
+	  *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv);
+	  argp += z;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      continue;
+	    }
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 < NGREGARG)
+	    {
+	      greg += n;
+	      continue;
+	    }
+#if (! defined(__SH4__))
+	  else if (greg < NGREGARG)
+	    {
+	      greg = NGREGARG;
+	      continue;
+	    }
+#endif
+	  memcpy (argp, *p_argv, z);
+	  argp += z;
+	}
+    }
+
+  return;
+}
+
+/* Perform machine dependent cif processing */
+ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+{
+  int i, j;
+  int size, type;
+  int n, m;
+  int greg;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+
+  cif->flags = 0;
+
+  greg = ((return_type (cif->rtype) == FFI_TYPE_STRUCT) &&
+	  STRUCT_VALUE_ADDRESS_WITH_ARG) ? 1 : 0;
+
+#if defined(__SH4__)
+  for (i = j = 0; i < cif->nargs && j < 12; i++)
+    {
+      type = (cif->arg_types)[i]->type;
+      switch (type)
+	{
+	case FFI_TYPE_FLOAT:
+	  if (freg >= NFREGARG)
+	    continue;
+	  freg++;
+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+	  j++;
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if ((freg + 1) >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  cif->flags += ((cif->arg_types)[i]->type) << (2 * j);
+	  j++;
+	  break;
+	      
+	default:
+	  size = (cif->arg_types)[i]->size;
+	  n = (size + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 >= NGREGARG)
+		continue;
+	  greg += n;
+	  for (m = 0; m < n; m++)
+	    cif->flags += FFI_TYPE_INT << (2 * j++);
+	  break;
+	}
+    }
+#else
+  for (i = j = 0; i < cif->nargs && j < 4; i++)
+    {
+      size = (cif->arg_types)[i]->size;
+      n = (size + sizeof (int) - 1) / sizeof (int);
+      if (greg >= NGREGARG)
+	continue;
+      else if (greg + n - 1 >= NGREGARG)
+	greg = NGREGARG;
+      else
+	greg += n;
+      for (m = 0; m < n; m++)
+        cif->flags += FFI_TYPE_INT << (2 * j++);
+    }
+#endif
+
+  /* Set the return type flag */
+  switch (cif->rtype->type)
+    {
+    case FFI_TYPE_STRUCT:
+      cif->flags += (unsigned) (return_type (cif->rtype)) << 24;
+      break;
+
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_UINT64:
+      cif->flags += (unsigned) cif->rtype->type << 24;
+      break;
+
+    default:
+      cif->flags += FFI_TYPE_INT << 24;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
+			  /*@out@*/ extended_cif *, 
+			  unsigned, unsigned, 
+			  /*@out@*/ unsigned *, 
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+  
+  /* If the return value is a struct and we don't have a return	*/
+  /* value address then we need to make one		        */
+
+  if ((rvalue == NULL) && 
+      (cif->rtype->type == FFI_TYPE_STRUCT))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /*@-usedef@*/
+      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+extern void ffi_closure_SYSV (void);
+#if defined(__SH4__)
+extern void __ic_invalidate (void *line);
+#endif
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp;
+
+  FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
+
+  tramp = (unsigned int *) &closure->tramp[0];
+#ifdef __LITTLE_ENDIAN__
+  tramp[0] = 0xd301d202;
+  tramp[1] = 0x0009422b;
+#else
+  tramp[0] = 0xd202d301;
+  tramp[1] = 0x422b0009;
+#endif
+  *(void **) &tramp[2] = (void *)closure;          /* ctx */
+  *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+#if defined(__SH4__)
+  /* Flush the icache.  */
+  __ic_invalidate(&closure->tramp[0]);
+#endif
+
+  return FFI_OK;
+}
+
+/* Basically the trampoline invokes ffi_closure_SYSV, and on 
+ * entry, r3 holds the address of the closure.
+ * After storing the registers that could possibly contain
+ * parameters to be passed into the stack frame and setting
+ * up space for a return value, ffi_closure_SYSV invokes the 
+ * following helper function to do most of the work.
+ */
+
+#ifdef __LITTLE_ENDIAN__
+#define OFS_INT8	0
+#define OFS_INT16	2
+#else
+#define OFS_INT8	3
+#define OFS_INT16	2
+#endif
+
+int
+ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue, 
+			 unsigned long *pgr, unsigned long *pfr, 
+			 unsigned long *pst)
+{
+  void **avalue;
+  ffi_type **p_arg;
+  int i, avn;
+  int ireg, greg = 0;
+#if defined(__SH4__)
+  int freg = 0;
+#endif
+  ffi_cif *cif; 
+  double temp; 
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  /* Copy the caller's structure return value address so that the closure
+     returns the data directly to the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT)
+    {
+      rvalue = *pgr++;
+      ireg = STRUCT_VALUE_ADDRESS_WITH_ARG ? 1 : 0;
+    }
+  else
+    ireg = 0;
+
+  cif = closure->cif;
+  greg = ireg;
+  avn = cif->nargs;
+
+  /* Grab the addresses of the arguments from the stack frame.  */
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ >= NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	      avalue[i] = (((char *)pgr) + OFS_INT8);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	      avalue[i] = (((char *)pgr) + OFS_INT16);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      avalue[i] = pgr;
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  pgr++;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ >= NFREGARG)
+		continue;
+	      avalue[i] = pfr;
+	      pfr++;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ >= NGREGARG)
+		continue;
+	      avalue[i] = pgr;
+	      pgr++;
+	    }
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 >= NFREGARG)
+	    continue;
+	  freg = (freg + 1) & ~1;
+	  freg += 2;
+	  avalue[i] = pfr;
+	  pfr += 2;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+#if defined(__SH4__)
+	  if (greg + n - 1 >= NGREGARG)
+	    continue;
+	  greg += n;
+#else
+	  if (greg >= NGREGARG)
+	    continue;
+	  else if (greg + n - 1 >= NGREGARG)
+	    greg = NGREGARG;
+	  else
+	    greg += n;
+#endif
+	  avalue[i] = pgr;
+	  pgr += n;
+	}
+    }
+
+  greg = ireg;
+#if defined(__SH4__)
+  freg = 0;
+#endif
+
+  for (i = 0, p_arg = cif->arg_types; i < avn; i++, p_arg++)
+    {
+      size_t z;
+
+      z = (*p_arg)->size;
+      if (z < sizeof(int))
+	{
+	  if (greg++ < NGREGARG)
+	    continue;
+
+	  z = sizeof(int);
+	  switch ((*p_arg)->type)
+	    {
+	    case FFI_TYPE_SINT8:
+	    case FFI_TYPE_UINT8:
+	      avalue[i] = (((char *)pst) + OFS_INT8);
+	      break;
+  
+	    case FFI_TYPE_SINT16:
+	    case FFI_TYPE_UINT16:
+	      avalue[i] = (((char *)pst) + OFS_INT16);
+	      break;
+  
+	    case FFI_TYPE_STRUCT:
+	      avalue[i] = pst;
+	      break;
+
+	    default:
+	      FFI_ASSERT(0);
+	    }
+	  pst++;
+	}
+      else if (z == sizeof(int))
+	{
+#if defined(__SH4__)
+	  if ((*p_arg)->type == FFI_TYPE_FLOAT)
+	    {
+	      if (freg++ < NFREGARG)
+		continue;
+	    }
+	  else
+#endif
+	    {
+	      if (greg++ < NGREGARG)
+		continue;
+	    }
+	  avalue[i] = pst;
+	  pst++;
+	}
+#if defined(__SH4__)
+      else if ((*p_arg)->type == FFI_TYPE_DOUBLE)
+	{
+	  if (freg + 1 < NFREGARG)
+	    {
+	      freg = (freg + 1) & ~1;
+	      freg += 2;
+	      continue;
+	    }
+	  avalue[i] = pst;
+	  pst += 2;
+	}
+#endif
+      else
+	{
+	  int n = (z + sizeof (int) - 1) / sizeof (int);
+	  if (greg + n - 1 < NGREGARG)
+	    {
+	      greg += n;
+	      continue;
+	    }
+#if (! defined(__SH4__))
+	  else if (greg < NGREGARG)
+	    {
+	      greg = NGREGARG;
+	      continue;
+	    }
+#endif
+	  avalue[i] = pst;
+	  pst += n;
+	}
+    }
+
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_osf how to perform return type promotions.  */
+  return cif->rtype->type;
+}
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/sh/sysv.S gcc/libffi/src/sh/sysv.S
--- gcc-3.2.2.orig/libffi/src/sh/sysv.S	Thu Jan  1 09:00:00 1970
+++ gcc/libffi/src/sh/sysv.S	Tue Dec 17 03:22:48 2002
@@ -0,0 +1,773 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2002 Kaz Kojima
+   
+   SuperH Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM	
+#include <ffi.h>
+#ifdef HAVE_MACHINE_ASM_H
+#include <machine/asm.h>
+#else
+/* XXX these lose for some platforms, I'm sure. */
+#define CNAME(x) x
+#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x):
+#endif
+
+#if defined(__HITACHI__)
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 1
+#else
+#define STRUCT_VALUE_ADDRESS_WITH_ARG 0
+#endif
+
+.text
+
+	# r4:	ffi_prep_args
+	# r5:	&ecif
+	# r6:	bytes
+	# r7:	flags
+	# sp+0: rvalue
+	# sp+4: fn
+
+	# This assumes we are using gas.
+ENTRY(ffi_call_SYSV)
+	# Save registers
+.LFB1:
+	mov.l	r8,@-r15
+.LCFI0:
+	mov.l	r9,@-r15
+.LCFI1:
+	mov.l	r10,@-r15
+.LCFI2:
+	mov.l	r12,@-r15
+.LCFI3:
+	mov.l	r14,@-r15
+.LCFI4:
+	sts.l	pr,@-r15
+.LCFI5:
+	mov	r15,r14
+.LCFI6:
+#if defined(__SH4__)
+	mov	r6,r8
+	mov	r7,r9
+
+	sub	r6,r15
+	add	#-16,r15
+	mov	#~7,r0
+	and	r0,r15
+
+	mov	r4,r0
+	jsr	@r0
+	 mov	r15,r4
+
+	mov	r9,r1
+	shlr8	r9
+	shlr8	r9
+	shlr8	r9
+
+	mov	#FFI_TYPE_STRUCT,r2
+	cmp/eq	r2,r9
+	bf	1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+ 	mov.l	@r15+,r4
+	bra	2f
+	 mov	#5,r2
+#else
+ 	mov.l	@r15+,r10
+#endif
+1:
+	mov	#4,r2
+2:
+	mov	#4,r3
+
+L_pass:
+	cmp/pl	r8
+	bf	L_call_it
+
+	mov	r1,r0
+	and	#3,r0
+
+L_pass_d:
+	cmp/eq	#FFI_TYPE_DOUBLE,r0
+	bf	L_pass_f
+
+	mov	r3,r0
+	and	#1,r0
+	tst	r0,r0
+	bt	1f
+	add	#1,r3
+1:
+	mov	r15,r0
+	and	#7,r0
+	tst	r0,r0
+	bt	2f
+	add	#4,r15
+2:
+	mov	#12,r0
+	cmp/hs	r0,r3
+	bt/s	3f
+	 shlr2	r1
+	bsr	L_pop_d
+	 nop
+3:
+	add	#2,r3
+	bra	L_pass
+	 add	#-8,r8
+
+L_pop_d:
+	mov	r3,r0
+	add	r0,r0
+	add	r3,r0
+	add	#-12,r0
+	braf	r0
+	 nop
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr4
+	fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr6
+	fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr8
+	fmov.s	@r15+,fr11
+	rts
+	 fmov.s	@r15+,fr10
+#else
+	fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr5
+	fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr7
+	fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr9
+	fmov.s	@r15+,fr10
+	rts
+	 fmov.s	@r15+,fr11
+#endif
+
+L_pass_f:
+	cmp/eq	#FFI_TYPE_FLOAT,r0
+	bf	L_pass_i
+
+	mov	#12,r0
+	cmp/hs	r0,r3
+	bt/s	2f
+	 shlr2	r1
+	bsr	L_pop_f
+	 nop
+2:
+	add	#1,r3
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_f:
+	mov	r3,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+#ifdef __LITTLE_ENDIAN__
+	rts
+	 fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr11
+	rts
+	 fmov.s	@r15+,fr10
+#else
+	rts
+	 fmov.s	@r15+,fr4
+	rts
+	 fmov.s	@r15+,fr5
+	rts
+	 fmov.s	@r15+,fr6
+	rts
+	 fmov.s	@r15+,fr7
+	rts
+	 fmov.s	@r15+,fr8
+	rts
+	 fmov.s	@r15+,fr9
+	rts
+	 fmov.s	@r15+,fr10
+	rts
+	 fmov.s	@r15+,fr11
+#endif
+
+L_pass_i:
+	cmp/eq	#FFI_TYPE_INT,r0
+	bf	L_call_it
+
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r1
+	bsr	L_pop_i
+	 nop
+2:
+	add	#1,r2
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_i:
+	mov	r2,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+	rts
+	 mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+
+L_call_it:
+	# call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+	mov	r10, r2
+#endif
+	mov.l  @(28,r14),r1
+	jsr    @r1
+	 nop
+
+L_ret_d:
+	mov	#FFI_TYPE_DOUBLE,r2
+	cmp/eq	r2,r9
+	bf	L_ret_ll
+
+	mov.l	@(24,r14),r1
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	fr1,@r1
+	add	#4,r1
+	bra	L_epilogue
+	 fmov.s	fr0,@r1
+#else
+	fmov.s	fr0,@r1
+	add	#4,r1
+	bra	L_epilogue
+	 fmov.s	fr1,@r1
+#endif
+
+L_ret_ll:
+	mov	#FFI_TYPE_SINT64,r2
+	cmp/eq	r2,r9
+	bt/s	1f
+	 mov	#FFI_TYPE_UINT64,r2
+	cmp/eq	r2,r9
+	bf	L_ret_f
+
+1:
+	mov.l	@(24,r14),r2
+	mov.l	r0,@r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_f:
+	mov	#FFI_TYPE_FLOAT,r2
+	cmp/eq	r2,r9
+	bf	L_ret_i
+
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 fmov.s	fr0,@r1
+
+L_ret_i:
+	mov	#FFI_TYPE_INT,r2
+	cmp/eq	r2,r9
+	bf	L_epilogue
+
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 mov.l	r0,@r1
+
+L_epilogue:
+	# Remove the space we pushed for the args
+	mov   r14,r15
+
+	lds.l  @r15+,pr
+	mov.l  @r15+,r14
+	mov.l  @r15+,r12
+	mov.l  @r15+,r10
+	mov.l  @r15+,r9
+	rts
+	 mov.l  @r15+,r8
+#else
+	mov	r6,r8
+	mov	r7,r9
+
+	sub	r6,r15
+	add	#-16,r15
+	mov	#~7,r0
+	and	r0,r15
+
+	mov	r4,r0
+	jsr	@r0
+	 mov	r15,r4
+
+	mov	r9,r3
+	shlr8	r9
+	shlr8	r9
+	shlr8	r9
+
+	mov	#FFI_TYPE_STRUCT,r2
+	cmp/eq	r2,r9
+	bf	1f
+#if STRUCT_VALUE_ADDRESS_WITH_ARG
+	mov.l	@r15+,r4
+	bra	2f
+	 mov	#5,r2
+#else
+	mov.l	@r15+,r10
+#endif
+1:
+	mov	#4,r2
+2:
+
+L_pass:
+	cmp/pl	r8
+	bf	L_call_it
+
+	mov	r3,r0
+	and	#3,r0
+
+L_pass_d:
+	cmp/eq	#FFI_TYPE_DOUBLE,r0
+	bf	L_pass_i
+
+	mov	r15,r0
+	and	#7,r0
+	tst	r0,r0
+	bt	1f
+	add	#4,r15
+1:
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r3
+	bsr	L_pop_d
+	 nop
+2:
+	add	#2,r2
+	bra	L_pass
+	 add	#-8,r8
+
+L_pop_d:
+	mov	r2,r0
+	add	r0,r0
+	add	r2,r0
+	add	#-12,r0
+	add	r0,r0
+	braf	r0
+	 nop
+	mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+	rts
+	 mov.l	@r15+,r7
+
+L_pass_i:
+	mov	#8,r0
+	cmp/hs	r0,r2
+	bt/s	2f
+	 shlr2	r3
+	bsr	L_pop_i
+	 nop
+2:
+	add	#1,r2
+	bra	L_pass
+	 add	#-4,r8
+
+L_pop_i:
+	mov	r2,r0
+	shll2	r0
+	add	#-16,r0
+	braf	r0
+	 nop
+	rts
+	 mov.l	@r15+,r4
+	rts
+	 mov.l	@r15+,r5
+	rts
+	 mov.l	@r15+,r6
+	rts
+	 mov.l	@r15+,r7
+
+L_call_it:
+	# call function
+#if (! STRUCT_VALUE_ADDRESS_WITH_ARG)
+	mov	r10, r2
+#endif
+	mov.l  @(28,r14),r1
+	jsr    @r1
+	 nop
+
+L_ret_d:
+	mov	#FFI_TYPE_DOUBLE,r2
+	cmp/eq	r2,r9
+	bf	L_ret_ll
+
+	mov.l	@(24,r14),r2
+	mov.l	r0,@r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_ll:
+	mov	#FFI_TYPE_SINT64,r2
+	cmp/eq	r2,r9
+	bt/s	1f
+	 mov	#FFI_TYPE_UINT64,r2
+	cmp/eq	r2,r9
+	bf	L_ret_i
+
+1:
+	mov.l	@(24,r14),r2
+	mov.l	r0,@r2
+	bra	L_epilogue
+	 mov.l	r1,@(4,r2)
+
+L_ret_i:
+	mov	#FFI_TYPE_FLOAT,r2
+	cmp/eq	r2,r9
+	bt	1f
+	mov	#FFI_TYPE_INT,r2
+	cmp/eq	r2,r9
+	bf	L_epilogue
+1:
+	mov.l	@(24,r14),r1
+	bra	L_epilogue
+	 mov.l	r0,@r1
+
+L_epilogue:
+	# Remove the space we pushed for the args
+	mov   r14,r15
+
+	lds.l  @r15+,pr
+	mov.l  @r15+,r14
+	mov.l  @r15+,r12
+	mov.l  @r15+,r10
+	mov.l  @r15+,r9
+	rts
+	 mov.l  @r15+,r8
+#endif
+.LFE1:
+.ffi_call_SYSV_end:
+        .size    CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
+
+.globl	ffi_closure_helper_SYSV
+
+ENTRY(ffi_closure_SYSV)
+.LFB2:
+	mov.l	r14,@-r15
+.LCFI7:
+	sts.l	pr,@-r15
+
+	/* Stack layout:	
+	   ...
+	   32 bytes (floating register parameters, SH-4 only)
+	   16 bytes (register parameters)
+	    4 bytes (result)
+	    4 bytes (5th arg)
+	   <- new stack pointer
+	*/
+.LCFI8:
+#if defined(__SH4__)
+	add	#-56,r15
+#else
+	add	#-24,r15
+#endif
+.LCFI9:
+	mov	r15,r14
+.LCFIA:
+	mov	r14,r1
+	add	#24,r1
+	mov.l	r7,@-r1
+	mov.l	r6,@-r1
+	mov.l	r5,@-r1
+	mov.l	r4,@-r1
+	mov	r1,r6
+
+#if defined(__SH4__)
+	mov	r14,r1
+	add	#56,r1
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	fr10,@-r1
+	fmov.s	fr11,@-r1
+	fmov.s	fr8,@-r1
+	fmov.s	fr9,@-r1
+	fmov.s	fr6,@-r1
+	fmov.s	fr7,@-r1
+	fmov.s	fr4,@-r1
+	fmov.s	fr5,@-r1
+#else
+	fmov.s	fr11,@-r1
+	fmov.s	fr10,@-r1
+	fmov.s	fr9,@-r1
+	fmov.s	fr8,@-r1
+	fmov.s	fr7,@-r1
+	fmov.s	fr6,@-r1
+	fmov.s	fr5,@-r1
+	fmov.s	fr4,@-r1
+#endif
+	mov	r1,r7
+#endif
+
+	mov	r14,r1
+	add	#4,r1
+	mov	r1,r5
+
+	mov	r14,r1
+#if defined(__SH4__)
+	add	#64,r1
+#else
+	add	#32,r1
+#endif
+	mov.l	r1,@r14
+
+	mov.l	L_helper,r0
+	jsr	@r0
+	 mov	r3,r4
+
+	shll	r0
+	mov	r0,r1
+	mova	L_table,r0
+	add	r1,r0
+	mov.w	@r0,r0
+	mov	r14,r2
+	braf	r0
+	 add	#4,r2
+0:
+	.align 2
+L_helper:
+	.long	ffi_closure_helper_SYSV
+L_table:
+	.short L_case_v - 0b	/* FFI_TYPE_VOID */
+	.short L_case_i - 0b	/* FFI_TYPE_INT */
+#if defined(__SH4__)
+	.short L_case_f - 0b	/* FFI_TYPE_FLOAT */
+	.short L_case_d - 0b	/* FFI_TYPE_DOUBLE */
+	.short L_case_d - 0b	/* FFI_TYPE_LONGDOUBLE */
+#else
+	.short L_case_i - 0b	/* FFI_TYPE_FLOAT */
+	.short L_case_ll - 0b	/* FFI_TYPE_DOUBLE */
+	.short L_case_ll - 0b	/* FFI_TYPE_LONGDOUBLE */
+#endif
+	.short L_case_uq - 0b	/* FFI_TYPE_UINT8 */
+	.short L_case_q - 0b	/* FFI_TYPE_SINT8 */
+	.short L_case_uh - 0b	/* FFI_TYPE_UINT16 */
+	.short L_case_h - 0b	/* FFI_TYPE_SINT16 */
+	.short L_case_i - 0b	/* FFI_TYPE_UINT32 */
+	.short L_case_i - 0b	/* FFI_TYPE_SINT32 */
+	.short L_case_ll - 0b	/* FFI_TYPE_UINT64 */
+	.short L_case_ll - 0b	/* FFI_TYPE_SINT64 */
+	.short L_case_v - 0b	/* FFI_TYPE_STRUCT */
+	.short L_case_i - 0b	/* FFI_TYPE_POINTER */
+
+#if defined(__SH4__)
+L_case_d:
+#ifdef __LITTLE_ENDIAN__
+	fmov.s	@r2+,fr1
+	bra	L_case_v
+	 fmov.s	@r2,fr0
+#else
+	fmov.s	@r2+,fr0
+	bra	L_case_v
+	 fmov.s	@r2,fr1
+#endif
+
+L_case_f:
+	bra	L_case_v
+	 fmov.s	@r2,fr0
+#endif
+	
+L_case_ll:
+	mov.l	@r2+,r0
+	bra	L_case_v
+	 mov.l	@r2,r1
+	
+L_case_i:
+	bra	L_case_v
+	 mov.l	@r2,r0
+	
+L_case_q:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#3,r2
+#endif
+	bra	L_case_v
+	 mov.b	@r2,r0
+
+L_case_uq:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#3,r2
+#endif
+	mov.b	@r2,r0
+	bra	L_case_v
+	 extu.b r0,r0
+
+L_case_h:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#2,r2
+#endif
+	bra	L_case_v
+	 mov.w	@r2,r0
+
+L_case_uh:
+#ifdef __LITTLE_ENDIAN__
+#else
+	add	#2,r2
+#endif
+	mov.w	@r2,r0
+	extu.w	r0,r0
+	/* fall through */
+
+L_case_v:
+#if defined(__SH4__)
+	add	#56,r15
+#else
+	add	#24,r15
+#endif
+	lds.l	@r15+,pr
+	rts
+	 mov.l	@r15+,r14
+.LFE2:
+.ffi_closure_SYSV_end:
+        .size    CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)
+
+	.section	".eh_frame","aw",@progbits
+__FRAME_BEGIN__:
+	.4byte	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
+.LSCIE1:
+	.4byte	0x0	/* CIE Identifier Tag */
+	.byte	0x1	/* CIE Version */
+	.byte	0x0	/* CIE Augmentation */
+	.byte	0x1	/* uleb128 0x1; CIE Code Alignment Factor */
+	.byte	0x7c	/* sleb128 -4; CIE Data Alignment Factor */
+	.byte	0x11	/* CIE RA Column */
+	.byte	0xc	/* DW_CFA_def_cfa */
+	.byte	0xf	/* uleb128 0xf */
+	.byte	0x0	/* uleb128 0x0 */
+	.align	2
+.LECIE1:
+.LSFDE1:
+	.4byte	.LEFDE1-.LASFDE1	/* FDE Length */
+.LASFDE1:
+	.4byte	.LASFDE1-__FRAME_BEGIN__	/* FDE CIE offset */
+	.4byte	.LFB1	/* FDE initial location */
+	.4byte	.LFE1-.LFB1	 /* FDE address range */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI0-.LFB1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI1-.LCFI0
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI2-.LCFI1
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0xc	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI3-.LCFI2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x10	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI4-.LCFI3
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x14	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI5-.LCFI4
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x18	/* uleb128 0x4 */
+	.byte	0x91	/* DW_CFA_offset, column 0x11 */
+	.byte	0x6	/* uleb128 0x6 */
+	.byte	0x8e	/* DW_CFA_offset, column 0xe */
+	.byte	0x5	/* uleb128 0x5 */
+	.byte	0x8c	/* DW_CFA_offset, column 0xc */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x8a	/* DW_CFA_offset, column 0xa */
+	.byte	0x3	/* uleb128 0x3 */
+	.byte	0x89	/* DW_CFA_offset, column 0x9 */
+	.byte	0x2	/* uleb128 0x2 */
+	.byte	0x88	/* DW_CFA_offset, column 0x8 */
+	.byte	0x1	/* uleb128 0x1 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI6-.LCFI5
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0xe	/* uleb128 0xe */
+	.align	2
+.LEFDE1:
+
+.LSFDE3:
+	.4byte	.LEFDE3-.LASFDE3	/* FDE Length */
+.LASFDE3:
+	.4byte	.LASFDE3-__FRAME_BEGIN__	/* FDE CIE offset */
+	.4byte	.LFB2	/* FDE initial location */
+	.4byte	.LFE2-.LFB2	 /* FDE address range */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI7-.LFB2
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x4	/* uleb128 0x4 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI8-.LCFI7
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+	.byte	0x8	/* uleb128 0x8 */
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFI9-.LCFI8
+	.byte	0xe	/* DW_CFA_def_cfa_offset */
+#if defined(__SH4__)
+	.byte	8+56	/* uleb128 8+56 */
+#else
+	.byte	8+24	/* uleb128 8+24 */
+#endif
+	.byte	0x91	/* DW_CFA_offset, column 0x11 */
+        .byte	0x2
+        .byte	0x8e	/* DW_CFA_offset, column 0xe */
+        .byte	0x1
+	.byte	0x4	/* DW_CFA_advance_loc4 */
+	.4byte	.LCFIA-.LCFI9
+	.byte	0xd	/* DW_CFA_def_cfa_register */
+	.byte	0xe	/* uleb128 0xe */
+	.align	2
+.LEFDE3:
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/sparc/ffi.c gcc/libffi/src/sparc/ffi.c
--- gcc-3.2.2.orig/libffi/src/sparc/ffi.c	Sat Mar  3 07:21:23 2001
+++ gcc/libffi/src/sparc/ffi.c	Sat Jan  4 08:08:56 2003
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 1996 Cygnus Solutions
+   ffi.c - Copyright (c) 1996, 2003 Cygnus Solutions
    
    Sparc Foreign Function Interface 
 
@@ -28,20 +28,22 @@
 
 #include <stdlib.h>
 
+#ifdef SPARC64
+extern void ffi_closure_v9(void);
+#else
+extern void ffi_closure_v8(void);
+#endif
+
 /* ffi_prep_args is called by the assembly routine once stack space
    has been allocated for the function's arguments */
 
 void ffi_prep_args_v8(char *stack, extended_cif *ecif)
 {
   int i;
-  int tmp;
-  int avn;
   void **p_argv;
   char *argp;
   ffi_type **p_arg;
 
-  tmp = 0;
-
   /* Skip 16 words for the window save area */
   argp = stack + 16*sizeof(int);
 
@@ -66,18 +68,12 @@
   ((int*)argp)[5] = 0;
 #endif
 
-  avn = ecif->cif->nargs;
   p_argv = ecif->avalue;
 
-  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
-       i && avn;
-       i--, p_arg++)
+  for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
     {
       size_t z;
 
-      if (avn) 
-	{
-	  avn--;
 	  if ((*p_arg)->type == FFI_TYPE_STRUCT
 #if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
 	      || (*p_arg)->type == FFI_TYPE_LONGDOUBLE
@@ -122,7 +118,6 @@
 	    }
 	  p_argv++;
 	  argp += z;
-	}
     }
   
   return;
@@ -420,3 +415,101 @@
     }
 
 }
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  unsigned long fn;
+  unsigned long ctx = (unsigned long) closure;
+
+#ifdef SPARC64
+  /* Trampoline address is equal to the closure address.  We take advantage
+     of that to reduce the trampoline size by 8 bytes. */
+  FFI_ASSERT (cif->abi == FFI_V9);
+  fn = (unsigned long) ffi_closure_v9;
+  tramp[0] = 0x83414000;	/* rd	%pc, %g1	*/
+  tramp[1] = 0xca586010;	/* ldx	[%g1+16], %g5	*/
+  tramp[2] = 0x81c14000;	/* jmp	%g5		*/
+  tramp[3] = 0x01000000;	/* nop			*/
+  *((unsigned long *) &tramp[4]) = fn;
+#else
+  FFI_ASSERT (cif->abi == FFI_V8);
+  fn = (unsigned long) ffi_closure_v8;
+  tramp[0] = 0x03000000 | fn >> 10;	/* sethi %hi(fn), %g1	*/
+  tramp[1] = 0x05000000 | ctx >> 10;	/* sethi %hi(ctx), %g2	*/
+  tramp[2] = 0x81c06000 | (fn & 0x3ff);	/* jmp   %g1+%lo(fn)	*/
+  tramp[3] = 0x8410a000 | (ctx & 0x3ff);/* or    %g2, %lo(ctx)	*/
+#endif
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  /* Flush the Icache.  FIXME: alignment isn't certain, assume 8 bytes */
+#ifdef SPARC64
+  asm volatile ("flush	%0" : : "r" (closure) : "memory");
+  asm volatile ("flush	%0" : : "r" (((char *) closure) + 8) : "memory");
+#else
+  asm volatile ("iflush	%0" : : "r" (closure) : "memory");
+  asm volatile ("iflush	%0" : : "r" (((char *) closure) + 8) : "memory");
+#endif
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_sparc_inner(ffi_closure *closure,
+  void *rvalue, unsigned long *gpr, double *fpr)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  int i, avn, argn;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  argn = 0;
+
+  /* Copy the caller's structure return address to that the closure
+     returns the data directly to the caller.  */
+  if (cif->flags == FFI_TYPE_STRUCT)
+    {
+      rvalue = (void *) gpr[0];
+      argn = 1;
+    }
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+  
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      /* Assume big-endian.  FIXME */
+      argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+
+#ifdef SPARC64
+      if (i < 6 && (arg_types[i]->type == FFI_TYPE_FLOAT
+		 || arg_types[i]->type == FFI_TYPE_DOUBLE
+#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
+		 || arg_types[i]->type == FFI_TYPE_LONGDOUBLE
+#endif
+		))
+        avalue[i] = ((char *) &fpr[argn]) - arg_types[i]->size;
+      else
+#endif
+        avalue[i] = ((char *) &gpr[argn]) - arg_types[i]->size;
+      i++;
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rvalue, avalue, closure->user_data);
+
+  /* Tell ffi_closure_sparc how to perform return type promotions.  */
+  return cif->rtype->type;
+}
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/sparc/v8.S gcc/libffi/src/sparc/v8.S
--- gcc-3.2.2.orig/libffi/src/sparc/v8.S	Mon Apr 29 05:12:04 2002
+++ gcc/libffi/src/sparc/v8.S	Sat Jan  4 08:08:56 2003
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   v8.S - Copyright (c) 1996, 1997 Cygnus Solutions
+   v8.S - Copyright (c) 1996, 1997, 2003 Cygnus Solutions
    
    Sparc Foreign Function Interface 
 
@@ -94,6 +94,72 @@
 .ffi_call_V8_end:
 	.size	ffi_call_V8,.ffi_call_V8_end-ffi_call_V8
 
+
+#define	STACKFRAME	104	/* 16*4 register window +
+				   1*4 struct return +	
+				   6*4 args backing store +
+				   3*4 locals */
+
+/* ffi_closure_v8(...)
+
+   Receives the closure argument in %g2.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v8
+
+ffi_closure_v8:
+	.register	%g2, #scratch
+.LLFB2:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	st	%i0, [%fp+68+0]
+	st	%i1, [%fp+68+4]
+	st	%i2, [%fp+68+8]
+	st	%i3, [%fp+68+12]
+	st	%i4, [%fp+68+16]
+	st	%i5, [%fp+68+20]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g2, %o0
+	add	%fp, -8, %o1
+	add	%fp,  68, %o2
+	call	ffi_closure_sparc_inner
+	 mov	0, %o3
+
+	! Load up the return value in the proper type.
+	cmp	%o0, FFI_TYPE_VOID
+	be	done1
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a	done1
+	 ld	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a	done1
+	 ldd	[%fp-8], %f0
+
+	cmp	%o0, FFI_TYPE_SINT64
+	be,a	integer
+	 ld	[%fp-4], %i1
+
+	cmp	%o0, FFI_TYPE_UINT64
+	be,a	integer
+	 ld	[%fp-4], %i1
+
+integer:
+	ld	[%fp-8], %i0
+
+done1:
+	ret
+	 restore
+.LLFE2:
+
+.ffi_closure_v8_end:
+	.size	ffi_closure_v8,.ffi_closure_v8_end-ffi_closure_v8
+
 #ifdef SPARC64
 #define WS 8
 #define nword	xword
@@ -148,3 +214,26 @@
 	.byte	0x1f	! uleb128 0x1f
 	.align	WS
 .LLEFDE1:
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2	! FDE address range
+#else
+	.align	WS
+	.nword	.LLFB2
+	.uanword .LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align	WS
+.LLEFDE2:
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/sparc/v9.S gcc/libffi/src/sparc/v9.S
--- gcc-3.2.2.orig/libffi/src/sparc/v9.S	Mon Apr 29 05:12:04 2002
+++ gcc/libffi/src/sparc/v9.S	Sat Jan  4 08:08:56 2003
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   v9.S - Copyright (c) 2000 Cygnus Solutions
+   v9.S - Copyright (c) 2000, 2003 Cygnus Solutions
    
    Sparc 64bit Foreign Function Interface 
 
@@ -99,7 +99,7 @@
 	cmp	%i3, FFI_TYPE_STRUCT
 	be,pn	%icc, dostruct
 
-	 cmp	%i3, FFI_TYPE_LONGDOUBLE
+	cmp	%i3, FFI_TYPE_LONGDOUBLE
 	bne,pt	%icc, done
 	 nop
 	std	%f0, [%i4+0]
@@ -125,6 +125,88 @@
 .ffi_call_V9_end:
 	.size	ffi_call_V9,.ffi_call_V9_end-ffi_call_V9
 
+
+#define	STACKFRAME	 240	/* 16*8 register window +
+				   6*8 args backing store +
+				   8*8 locals */
+#define	FP		%fp+STACK_BIAS
+
+/* ffi_closure_v9(...)
+
+   Receives the closure argument in %g1.   */
+
+	.text
+	.align 8
+	.globl ffi_closure_v9
+
+ffi_closure_v9:
+.LLFB2:
+	save	%sp, -STACKFRAME, %sp
+.LLCFI1:
+
+	! Store all of the potential argument registers in va_list format.
+	stx	%i0, [FP+128+0]
+	stx	%i1, [FP+128+8]
+	stx	%i2, [FP+128+16]
+	stx	%i3, [FP+128+24]
+	stx	%i4, [FP+128+32]
+	stx	%i5, [FP+128+40]
+
+	! Store possible floating point argument registers too.
+	std	%f0, [FP-48]
+	std	%f2, [FP-40]
+	std	%f4, [FP-32]
+	std	%f6, [FP-24]
+	std	%f8, [FP-16]
+	std	%f10, [FP-8]
+
+	! Call ffi_closure_sparc_inner to do the bulk of the work.
+	mov	%g1, %o0
+	add	%fp, STACK_BIAS-64, %o1
+	add	%fp, STACK_BIAS+128, %o2
+	call	ffi_closure_sparc_inner
+	 add	%fp, STACK_BIAS-48, %o3
+
+	! Load up the return value in the proper type.
+	cmp	%o0, FFI_TYPE_VOID
+	be,pn	%icc, done1
+
+	cmp	%o0, FFI_TYPE_FLOAT
+	be,a,pn	%icc, done1
+	 ld	[FP-64], %f0
+
+	cmp	%o0, FFI_TYPE_DOUBLE
+	be,a,pn	%icc, done1
+	 ldd	[FP-64], %f0
+
+	cmp	%o0, FFI_TYPE_LONGDOUBLE
+	be,a,pn	%icc, longdouble1
+	 ldd	[FP-64], %f0
+
+	cmp	%o0, FFI_TYPE_STRUCT
+	be,pn	%icc, struct1
+
+	! FFI_TYPE_UINT64 | FFI_TYPE_SINT64 | FFI_TYPE_POINTER
+	ldx	[FP-64], %i0
+
+done1:
+	ret
+	 restore
+
+struct1:
+	ldx [FP-56], %i2
+	ret
+	 restore
+
+longdouble1:
+	ldd	[FP-56], %f2
+	ret
+	 restore
+.LLFE2:
+
+.ffi_closure_v9_end:
+	.size	ffi_closure_v9,.ffi_closure_v9_end-ffi_closure_v9
+
 	.section	".eh_frame",#alloc,#write
 .LLframe1:
 	.uaword	.LLECIE1-.LLSCIE1	! Length of Common Information Entry
@@ -169,5 +251,27 @@
 	.byte	0x1f	! uleb128 0x1f
 	.align 8
 .LLEFDE1:
-
+.LLSFDE2:
+	.uaword	.LLEFDE2-.LLASFDE2	! FDE Length
+.LLASFDE2:
+	.uaword	.LLASFDE2-.LLframe1	! FDE CIE offset
+#ifdef HAVE_AS_SPARC_UA_PCREL
+	.uaword	%r_disp32(.LLFB2)
+	.uaword	.LLFE2-.LLFB2		! FDE address range
+#else
+	.align 8
+	.xword	.LLFB2
+	.uaxword	.LLFE2-.LLFB2	! FDE address range
+#endif
+	.byte	0x0	! uleb128 0x0; Augmentation size
+	.byte	0x4	! DW_CFA_advance_loc4
+	.uaword	.LLCFI1-.LLFB2
+	.byte	0xd	! DW_CFA_def_cfa_register
+	.byte	0x1e	! uleb128 0x1e
+	.byte	0x2d	! DW_CFA_GNU_window_save
+	.byte	0x9	! DW_CFA_register
+	.byte	0xf	! uleb128 0xf
+	.byte	0x1f	! uleb128 0x1f
+	.align 8
+.LLEFDE2:
 #endif
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/types.c gcc/libffi/src/types.c
--- gcc-3.2.2.orig/libffi/src/types.c	Tue Mar 27 11:39:16 2001
+++ gcc/libffi/src/types.c	Wed Nov 27 07:24:05 2002
@@ -42,7 +42,8 @@
 FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
 FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
 
-#if defined ALPHA || defined SPARC64
+#if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \
+    || defined IA64
 
 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
 
@@ -52,22 +53,12 @@
 
 #endif
 
-#ifdef X86
+#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K
 
 FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
 FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
 
-#elif defined X86_WIN32
-
-FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
-FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
-
-#elif defined ARM
-
-FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
-FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
-
-#elif defined M68K
+#elif defined SH
 
 FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
 FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
@@ -80,12 +71,7 @@
 #endif
 
 
-#ifdef X86
-
-FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
-FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
-
-#elif defined X86_WIN32
+#if defined X86 || defined X86_WIN32 || defined M68K
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
 FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
@@ -95,25 +81,25 @@
 FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
 FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
 
-#elif defined M68K
+#elif defined SH
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
-FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
 
 #elif defined SPARC
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
-
 #ifdef SPARC64
-
 FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
-
 #else
-
 FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
-
 #endif
 
+#elif defined X86_64
+
+FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
+FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
+
 #else
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/x86/ffi.c gcc/libffi/src/x86/ffi.c
--- gcc-3.2.2.orig/libffi/src/x86/ffi.c	Tue May 28 18:22:08 2002
+++ gcc/libffi/src/x86/ffi.c	Fri Dec  6 10:16:45 2002
@@ -1,5 +1,8 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 1996, 1998, 1999  Cygnus Solutions
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2001  Red Hat, Inc.
+           Copyright (c) 2002  Ranjit Mathew
+           Copyright (c) 2002  Bo Thorsen
+           Copyright (c) 2002  Roger Sayle
    
    x86 Foreign Function Interface 
 
@@ -23,6 +26,8 @@
    OTHER DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
+#ifndef __x86_64__
+
 #include <ffi.h>
 #include <ffi_common.h>
 
@@ -36,12 +41,10 @@
 /*@=exportheader@*/
 {
   register unsigned int i;
-  register int tmp;
   register void **p_argv;
   register char *argp;
   register ffi_type **p_arg;
 
-  tmp = 0;
   argp = stack;
 
   if (ecif->cif->rtype->type == FFI_TYPE_STRUCT)
@@ -148,6 +151,18 @@
 /*@=declundef@*/
 /*@=exportheader@*/
 
+#ifdef X86_WIN32
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
+			  /*@out@*/ extended_cif *,
+			  unsigned, unsigned,
+			  /*@out@*/ unsigned *,
+			  void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+#endif /* X86_WIN32 */
+
 void ffi_call(/*@dependent@*/ ffi_cif *cif, 
 	      void (*fn)(), 
 	      /*@out@*/ void *rvalue, 
@@ -180,6 +195,14 @@
 		    cif->flags, ecif.rvalue, fn);
       /*@=usedef@*/
       break;
+#ifdef X86_WIN32
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif /* X86_WIN32 */
     default:
       FFI_ASSERT(0);
       break;
@@ -266,12 +289,10 @@
 /*@=exportheader@*/
 {
   register unsigned int i;
-  register int tmp;
   register void **p_argv;
   register char *argp;
   register ffi_type **p_arg;
 
-  tmp = 0;
   argp = stack;
 
   if ( cif->rtype->type == FFI_TYPE_STRUCT ) {
@@ -281,13 +302,14 @@
 
   p_argv = avalue;
 
-  for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++)
+  for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
     {
       size_t z;
 
       /* Align if necessary */
-      if (((*p_arg)->alignment - 1) & (unsigned) argp)
+      if (((*p_arg)->alignment - 1) & (unsigned) argp) {
 	argp = (char *) ALIGN(argp, (*p_arg)->alignment);
+      }
 
       z = (*p_arg)->size;
 
@@ -298,7 +320,7 @@
       p_argv++;
       argp += z;
     }
-
+  
   return;
 }
 
@@ -449,6 +471,15 @@
 	      /*@out@*/ unsigned *, 
 	      void (*fn)());
 
+#ifdef X86_WIN32
+extern void
+ffi_call_STDCALL(void (*)(char *, extended_cif *),
+	      /*@out@*/ extended_cif *,
+	      unsigned, unsigned,
+	      /*@out@*/ unsigned *,
+	      void (*fn)());
+#endif /* X86_WIN32 */
+
 void
 ffi_raw_call(/*@dependent@*/ ffi_cif *cif, 
 	     void (*fn)(), 
@@ -483,6 +514,14 @@
 		    cif->flags, ecif.rvalue, fn);
       /*@=usedef@*/
       break;
+#ifdef X86_WIN32
+    case FFI_STDCALL:
+      /*@-usedef@*/
+      ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes,
+		    cif->flags, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+#endif /* X86_WIN32 */
     default:
       FFI_ASSERT(0);
       break;
@@ -490,3 +529,5 @@
 }
 
 #endif
+
+#endif /* __x86_64__  */
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/x86/ffi64.c gcc/libffi/src/x86/ffi64.c
--- gcc-3.2.2.orig/libffi/src/x86/ffi64.c	Thu Jan  1 09:00:00 1970
+++ gcc/libffi/src/x86/ffi64.c	Wed Jan 29 00:54:28 2003
@@ -0,0 +1,706 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2002  Bo Thorsen <bo@suse.de>
+   
+   x86-64 Foreign Function Interface 
+
+   Permission is hereby granted, free of charge, to any person obtaining
+   a copy of this software and associated documentation files (the
+   ``Software''), to deal in the Software without restriction, including
+   without limitation the rights to use, copy, modify, merge, publish,
+   distribute, sublicense, and/or sell copies of the Software, and to
+   permit persons to whom the Software is furnished to do so, subject to
+   the following conditions:
+
+   The above copyright notice and this permission notice shall be included
+   in all copies or substantial portions of the Software.
+
+   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+   OTHER DEALINGS IN THE SOFTWARE.
+   ----------------------------------------------------------------------- */
+
+#include <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+
+#ifdef __x86_64__
+
+#define MAX_GPR_REGS 6
+#define MAX_SSE_REGS 8
+typedef struct
+{
+  /* Registers for argument passing.  */
+  long gpr[MAX_GPR_REGS];
+  __int128_t sse[MAX_SSE_REGS];
+
+  /* Stack space for arguments.  */
+  char argspace[0];
+} stackLayout;
+
+/* All reference to register classes here is identical to the code in
+   gcc/config/i386/i386.c. Do *not* change one without the other.  */
+
+/* Register class used for passing given 64bit part of the argument.
+   These represent classes as documented by the PS ABI, with the exception
+   of SSESF, SSEDF classes, that are basically SSE class, just gcc will
+   use SF or DFmode move instead of DImode to avoid reformating penalties.
+
+   Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
+   whenever possible (upper half does contain padding).
+ */
+enum x86_64_reg_class
+  {
+    X86_64_NO_CLASS,
+    X86_64_INTEGER_CLASS,
+    X86_64_INTEGERSI_CLASS,
+    X86_64_SSE_CLASS,
+    X86_64_SSESF_CLASS,
+    X86_64_SSEDF_CLASS,
+    X86_64_SSEUP_CLASS,
+    X86_64_X87_CLASS,
+    X86_64_X87UP_CLASS,
+    X86_64_MEMORY_CLASS
+  };
+
+#define MAX_CLASSES 4
+
+/* x86-64 register passing implementation.  See x86-64 ABI for details.  Goal
+   of this code is to classify each 8bytes of incoming argument by the register
+   class and assign registers accordingly.  */
+
+/* Return the union class of CLASS1 and CLASS2.
+   See the x86-64 PS ABI for details.  */
+
+static enum x86_64_reg_class
+merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
+{
+  /* Rule #1: If both classes are equal, this is the resulting class.  */
+  if (class1 == class2)
+    return class1;
+
+  /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
+     the other class.  */
+  if (class1 == X86_64_NO_CLASS)
+    return class2;
+  if (class2 == X86_64_NO_CLASS)
+    return class1;
+
+  /* Rule #3: If one of the classes is MEMORY, the result is MEMORY.  */
+  if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
+    return X86_64_MEMORY_CLASS;
+
+  /* Rule #4: If one of the classes is INTEGER, the result is INTEGER.  */
+  if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
+      || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
+    return X86_64_INTEGERSI_CLASS;
+  if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
+      || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
+    return X86_64_INTEGER_CLASS;
+
+  /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used.  */
+  if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
+      || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
+    return X86_64_MEMORY_CLASS;
+
+  /* Rule #6: Otherwise class SSE is used.  */
+  return X86_64_SSE_CLASS;
+}
+
+/* Classify the argument of type TYPE and mode MODE.
+   CLASSES will be filled by the register class used to pass each word
+   of the operand.  The number of words is returned.  In case the parameter
+   should be passed in memory, 0 is returned. As a special case for zero
+   sized containers, classes[0] will be NO_CLASS and 1 is returned.
+
+   See the x86-64 PS ABI for details.
+*/
+static int
+classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
+		   int *byte_offset)
+{
+  /* First, align to the right place.  */
+  *byte_offset = ALIGN(*byte_offset, type->alignment);
+
+  switch (type->type)
+    {
+    case FFI_TYPE_UINT8:
+    case FFI_TYPE_SINT8:
+    case FFI_TYPE_UINT16:
+    case FFI_TYPE_SINT16:
+    case FFI_TYPE_UINT32:
+    case FFI_TYPE_SINT32:
+    case FFI_TYPE_UINT64:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_POINTER:
+      if (((*byte_offset) % 8 + type->size) <= 4)
+	classes[0] = X86_64_INTEGERSI_CLASS;
+      else
+	classes[0] = X86_64_INTEGER_CLASS;
+      return 1;
+    case FFI_TYPE_FLOAT:
+      if (((*byte_offset) % 8) == 0)
+	classes[0] = X86_64_SSESF_CLASS;
+      else
+	classes[0] = X86_64_SSE_CLASS;
+      return 1;
+    case FFI_TYPE_DOUBLE:
+      classes[0] = X86_64_SSEDF_CLASS;
+      return 1;
+    case FFI_TYPE_LONGDOUBLE:
+      classes[0] = X86_64_X87_CLASS;
+      classes[1] = X86_64_X87UP_CLASS;
+      return 2;
+    case FFI_TYPE_STRUCT:
+      {
+	const int UNITS_PER_WORD = 8;
+	int words = (type->size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
+	ffi_type **ptr; 
+	int i;
+	enum x86_64_reg_class subclasses[MAX_CLASSES];
+
+	/* If the struct is larger than 16 bytes, pass it on the stack.  */
+	if (type->size > 16)
+	  return 0;
+
+	for (i = 0; i < words; i++)
+	  classes[i] = X86_64_NO_CLASS;
+
+	/* Merge the fields of structure.  */
+	for (ptr=type->elements; (*ptr)!=NULL; ptr++)
+	  {
+	    int num;
+
+	    num = classify_argument (*ptr, subclasses, byte_offset);
+	    if (num == 0)
+	      return 0;
+	    for (i = 0; i < num; i++)
+	      {
+		int pos = *byte_offset / 8;
+		classes[i + pos] =
+		  merge_classes (subclasses[i], classes[i + pos]);
+	      }
+
+	    if ((*ptr)->type != FFI_TYPE_STRUCT)
+	      *byte_offset += (*ptr)->size;
+	  }
+
+	/* Final merger cleanup.  */
+	for (i = 0; i < words; i++)
+	  {
+	    /* If one class is MEMORY, everything should be passed in
+	       memory.  */
+	    if (classes[i] == X86_64_MEMORY_CLASS)
+	      return 0;
+
+	    /* The X86_64_SSEUP_CLASS should be always preceded by
+	       X86_64_SSE_CLASS.  */
+	    if (classes[i] == X86_64_SSEUP_CLASS
+		&& (i == 0 || classes[i - 1] != X86_64_SSE_CLASS))
+	      classes[i] = X86_64_SSE_CLASS;
+
+	    /*  X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS.  */
+	    if (classes[i] == X86_64_X87UP_CLASS
+		&& (i == 0 || classes[i - 1] != X86_64_X87_CLASS))
+	      classes[i] = X86_64_SSE_CLASS;
+	  }
+	return words;
+      }
+
+    default:
+      FFI_ASSERT(0);
+    }
+  return 0; /* Never reached.  */
+}
+
+/* Examine the argument and return set number of register required in each
+   class.  Return 0 iff parameter should be passed in memory.  */
+static int
+examine_argument (ffi_type *type, int in_return, int *int_nregs,int *sse_nregs)
+{
+  enum x86_64_reg_class class[MAX_CLASSES];
+  int offset = 0;
+  int n;
+
+  n = classify_argument (type, class, &offset);
+
+  if (n == 0)
+    return 0;
+
+  *int_nregs = 0;
+  *sse_nregs = 0;
+  for (n--; n>=0; n--)
+    switch (class[n])
+      {
+      case X86_64_INTEGER_CLASS:
+      case X86_64_INTEGERSI_CLASS:
+	(*int_nregs)++;
+	break;
+      case X86_64_SSE_CLASS:
+      case X86_64_SSESF_CLASS:
+      case X86_64_SSEDF_CLASS:
+	(*sse_nregs)++;
+	break;
+      case X86_64_NO_CLASS:
+      case X86_64_SSEUP_CLASS:
+	break;
+      case X86_64_X87_CLASS:
+      case X86_64_X87UP_CLASS:
+	if (!in_return)
+	  return 0;
+	break;
+      default:
+	abort ();
+      }
+  return 1;
+}
+
+/* Functions to load floats and double to an SSE register placeholder.  */
+extern void float2sse (float, __int128_t *);
+extern void double2sse (double, __int128_t *);
+extern void floatfloat2sse (void *, __int128_t *);
+
+/* Functions to put the floats and doubles back.  */
+extern float sse2float (__int128_t *);
+extern double sse2double (__int128_t *);
+extern void sse2floatfloat(__int128_t *, void *);
+
+/*@-exportheader@*/
+void
+ffi_prep_args (stackLayout *stack, extended_cif *ecif)
+/*@=exportheader@*/
+{
+  int gprcount, ssecount, i, g, s;
+  void **p_argv;
+  void *argp = &stack->argspace;
+  ffi_type **p_arg;
+
+  /* First check if the return value should be passed in memory. If so,
+     pass the pointer as the first argument.  */
+  gprcount = ssecount = 0;
+  if (ecif->cif->rtype->type != FFI_TYPE_VOID 
+      && examine_argument (ecif->cif->rtype, 1, &g, &s) == 0)
+    (void *)stack->gpr[gprcount++] = ecif->rvalue;
+
+  for (i=ecif->cif->nargs, p_arg=ecif->cif->arg_types, p_argv = ecif->avalue;
+       i!=0; i--, p_arg++, p_argv++)
+    {
+      int in_register = 0;
+
+      switch ((*p_arg)->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	  if (gprcount < MAX_GPR_REGS)
+	    {
+	      stack->gpr[gprcount] = 0;
+	      stack->gpr[gprcount++] = *(long long *)(*p_argv);
+	      in_register = 1;
+	    }
+	  break;
+
+	case FFI_TYPE_FLOAT:
+	  if (ssecount < MAX_SSE_REGS)
+	    {
+	      float2sse (*(float *)(*p_argv), &stack->sse[ssecount++]);
+	      in_register = 1;
+	    }
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  if (ssecount < MAX_SSE_REGS)
+	    {
+	      double2sse (*(double *)(*p_argv), &stack->sse[ssecount++]);
+	      in_register = 1;
+	    }
+	  break;
+	}
+
+      if (in_register)
+	continue;
+
+      /* Either all places in registers where filled, or this is a
+	 type that potentially goes into a memory slot.  */
+      if (examine_argument (*p_arg, 0, &g, &s) == 0
+	  || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
+	{
+	  /* Pass this argument in memory.  */
+	  argp = (void *)ALIGN(argp, (*p_arg)->alignment);
+	  memcpy (argp, *p_argv, (*p_arg)->size);
+	  argp += (*p_arg)->size;
+	}
+      else
+	{
+	  /* All easy cases are eliminated. Now fire the big guns.  */
+
+	  enum x86_64_reg_class classes[MAX_CLASSES];
+	  int offset = 0, j, num;
+	  void *a;
+
+	  num = classify_argument (*p_arg, classes, &offset);
+	  for (j=0, a=*p_argv; j<num; j++, a+=8)
+	    {
+	      switch (classes[j])
+		{
+		case X86_64_INTEGER_CLASS:
+		case X86_64_INTEGERSI_CLASS:
+		  stack->gpr[gprcount++] = *(long long *)a;
+		  break;
+		case X86_64_SSE_CLASS:
+		  floatfloat2sse (a, &stack->sse[ssecount++]);
+		  break;
+		case X86_64_SSESF_CLASS:
+		  float2sse (*(float *)a, &stack->sse[ssecount++]);
+		  break;
+		case X86_64_SSEDF_CLASS:
+		  double2sse (*(double *)a, &stack->sse[ssecount++]);
+		  break;
+		default:
+		  abort();
+		}
+	    }
+	}
+    }
+}
+
+/* Perform machine dependent cif processing.  */
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  int gprcount, ssecount, i, g, s;
+
+  gprcount = ssecount = 0;
+
+  /* Reset the byte count. We handle this size estimation here.  */
+  cif->bytes = 0;
+
+  /* If the return value should be passed in memory, pass the pointer
+     as the first argument. The actual memory isn't allocated here.  */
+  if (cif->rtype->type != FFI_TYPE_VOID 
+      && examine_argument (cif->rtype, 1, &g, &s) == 0)
+    gprcount = 1;
+
+  /* Go over all arguments and determine the way they should be passed.
+     If it's in a register and there is space for it, let that be so. If
+     not, add it's size to the stack byte count.  */
+  for (i=0; i<cif->nargs; i++)
+    {
+      if (examine_argument (cif->arg_types[i], 0, &g, &s) == 0
+	  || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
+	{
+	  /* This is passed in memory. First align to the basic type.  */
+	  cif->bytes = ALIGN(cif->bytes, cif->arg_types[i]->alignment);
+
+	  /* Stack arguments are *always* at least 8 byte aligned.  */
+	  cif->bytes = ALIGN(cif->bytes, 8);
+
+	  /* Now add the size of this argument.  */
+	  cif->bytes += cif->arg_types[i]->size;
+	}
+      else
+	{
+	  gprcount += g;
+	  ssecount += s;
+	}
+    }
+
+  /* Set the flag for the closures return.  */
+    switch (cif->rtype->type)
+    {
+    case FFI_TYPE_VOID:
+    case FFI_TYPE_STRUCT:
+    case FFI_TYPE_SINT64:
+    case FFI_TYPE_FLOAT:
+    case FFI_TYPE_DOUBLE:
+    case FFI_TYPE_LONGDOUBLE:
+      cif->flags = (unsigned) cif->rtype->type;
+      break;
+
+    case FFI_TYPE_UINT64:
+      cif->flags = FFI_TYPE_SINT64;
+      break;
+
+    default:
+      cif->flags = FFI_TYPE_INT;
+      break;
+    }
+
+  return FFI_OK;
+}
+
+typedef struct
+{
+  long gpr[2];
+  __int128_t sse[2];
+  long double st0;
+} return_value;
+
+void
+ffi_fill_return_value (return_value *rv, extended_cif *ecif)
+{
+  enum x86_64_reg_class classes[MAX_CLASSES];
+  int i = 0, num;
+  long *gpr = rv->gpr;
+  __int128_t *sse = rv->sse;
+  signed char sc;
+  signed short ss;
+
+  /* This is needed because of the way x86-64 handles signed short
+     integers.  */
+  switch (ecif->cif->rtype->type)
+    {
+    case FFI_TYPE_SINT8:
+      sc = *(signed char *)gpr;
+      *(long long *)ecif->rvalue = (long long)sc;
+      return;
+    case FFI_TYPE_SINT16:
+      ss = *(signed short *)gpr;
+      *(long long *)ecif->rvalue = (long long)ss;
+      return;
+    default:
+      /* Just continue.  */
+      ;
+    }
+
+  num = classify_argument (ecif->cif->rtype, classes, &i);
+
+  if (num == 0)
+    /* Return in memory.  */
+    ecif->rvalue = (void *) rv->gpr[0];
+  else if (num == 2 && classes[0] == X86_64_X87_CLASS &&
+	classes[1] == X86_64_X87UP_CLASS)
+    /* This is a long double (this is easiest to handle this way instead
+       of an eightbyte at a time as in the loop below.  */
+    *((long double *)ecif->rvalue) = rv->st0;
+  else
+    {
+      void *a;
+
+      for (i=0, a=ecif->rvalue; i<num; i++, a+=8)
+	{
+	  switch (classes[i])
+	    {
+	    case X86_64_INTEGER_CLASS:
+	    case X86_64_INTEGERSI_CLASS:
+	      *(long long *)a = *gpr;
+	      gpr++;
+	      break;
+	    case X86_64_SSE_CLASS:
+	      sse2floatfloat (sse++, a);
+	      break;
+	    case X86_64_SSESF_CLASS:
+	      *(float *)a = sse2float (sse++);
+	      break;
+	    case X86_64_SSEDF_CLASS:
+	      *(double *)a = sse2double (sse++);
+	      break;
+	    default:
+	      abort();
+	    }
+	}
+    }
+}
+
+/*@-declundef@*/
+/*@-exportheader@*/
+extern void ffi_call_UNIX64(void (*)(stackLayout *, extended_cif *),
+			    void (*) (return_value *, extended_cif *),
+			    /*@out@*/ extended_cif *, 
+			    unsigned, /*@out@*/ unsigned *, void (*fn)());
+/*@=declundef@*/
+/*@=exportheader@*/
+
+void ffi_call(/*@dependent@*/ ffi_cif *cif, 
+	      void (*fn)(), 
+	      /*@out@*/ void *rvalue, 
+	      /*@dependent@*/ void **avalue)
+{
+  extended_cif ecif;
+  int dummy;
+
+  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) && 
+      (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0))
+    {
+      /*@-sysunrecog@*/
+      ecif.rvalue = alloca(cif->rtype->size);
+      /*@=sysunrecog@*/
+    }
+  else
+    ecif.rvalue = rvalue;
+    
+  /* Stack must always be 16byte aligned. Make it so.  */
+  cif->bytes = ALIGN(cif->bytes, 16);
+  
+  switch (cif->abi) 
+    {
+    case FFI_SYSV:
+      /* Calling 32bit code from 64bit is not possible  */
+      FFI_ASSERT(0);
+      break;
+
+    case FFI_UNIX64:
+      /*@-usedef@*/
+      ffi_call_UNIX64 (ffi_prep_args, ffi_fill_return_value, &ecif,
+		       cif->bytes, ecif.rvalue, fn);
+      /*@=usedef@*/
+      break;
+
+    default:
+      FFI_ASSERT(0);
+      break;
+    }
+}
+
+extern void ffi_closure_UNIX64(void);
+
+ffi_status
+ffi_prep_closure (ffi_closure* closure,
+		  ffi_cif* cif,
+		  void (*fun)(ffi_cif*, void*, void**, void*),
+		  void *user_data)
+{
+  volatile unsigned short *tramp;
+
+  /* FFI_ASSERT (cif->abi == FFI_OSF);  */
+
+  tramp = (volatile unsigned short *) &closure->tramp[0];
+  tramp[0] = 0xbb49;		/* mov <code>, %r11	*/
+  tramp[5] = 0xba49;		/* mov <data>, %r10	*/
+  tramp[10] = 0xff49;		/* jmp *%r11	*/
+  tramp[11] = 0x00e3;
+  *(void * volatile *) &tramp[1] = ffi_closure_UNIX64;
+  *(void * volatile *) &tramp[6] = closure;
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
+int
+ffi_closure_UNIX64_inner(ffi_closure *closure, va_list l, void *rp)
+{
+  ffi_cif *cif;
+  void **avalue;
+  ffi_type **arg_types;
+  long i, avn, argn;
+
+  cif = closure->cif;
+  avalue = alloca(cif->nargs * sizeof(void *));
+
+  argn = 0;
+
+  i = 0;
+  avn = cif->nargs;
+  arg_types = cif->arg_types;
+  
+  /* Grab the addresses of the arguments from the stack frame.  */
+  while (i < avn)
+    {
+      switch (arg_types[i]->type)
+	{
+	case FFI_TYPE_SINT8:
+	case FFI_TYPE_UINT8:
+	case FFI_TYPE_SINT16:
+	case FFI_TYPE_UINT16:
+	case FFI_TYPE_SINT32:
+	case FFI_TYPE_UINT32:
+	case FFI_TYPE_SINT64:
+	case FFI_TYPE_UINT64:
+	case FFI_TYPE_POINTER:
+	  {
+	    if (l->gp_offset > 48-8)
+	      {
+		avalue[i] = l->overflow_arg_area;
+		l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+	      }
+	    else
+	      {
+		avalue[i] = (char *)l->reg_save_area + l->gp_offset;
+		l->gp_offset += 8;
+	      }
+	  }
+	  break;
+
+	case FFI_TYPE_STRUCT:
+	  /* FIXME  */
+	  FFI_ASSERT(0);
+	  break;
+
+	case FFI_TYPE_DOUBLE:
+	  {
+	    if (l->fp_offset > 176-16)
+	      {
+		avalue[i] = l->overflow_arg_area;
+		l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+	      }
+	    else
+	      {
+		avalue[i] = (char *)l->reg_save_area + l->fp_offset;
+		l->fp_offset += 16;
+	      }
+	  }
+#if DEBUG_FFI
+	  fprintf (stderr, "double arg %d = %g\n", i, *(double *)avalue[i]);
+#endif
+	  break;
+	  
+	case FFI_TYPE_FLOAT:
+	  {
+	    if (l->fp_offset > 176-16)
+	      {
+		avalue[i] = l->overflow_arg_area;
+		l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
+	      }
+	    else
+	      {
+		avalue[i] = (char *)l->reg_save_area + l->fp_offset;
+		l->fp_offset += 16;
+	      }
+	  }
+#if DEBUG_FFI
+	  fprintf (stderr, "float arg %d = %g\n", i, *(float *)avalue[i]);
+#endif
+	  break;
+	  
+	default:
+	  FFI_ASSERT(0);
+	}
+
+      argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
+      i++;
+    }
+
+  /* Invoke the closure.  */
+  (closure->fun) (cif, rp, avalue, closure->user_data);
+
+  /* FIXME: Structs not supported.  */
+  FFI_ASSERT(cif->rtype->type != FFI_TYPE_STRUCT);
+
+  /* Tell ffi_closure_UNIX64 how to perform return type promotions.  */
+
+  return cif->rtype->type;
+}
+#endif /* ifndef __x86_64__ */
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/x86/sysv.S gcc/libffi/src/x86/sysv.S
--- gcc-3.2.2.orig/libffi/src/x86/sysv.S	Tue Jul 17 02:10:53 2001
+++ gcc/libffi/src/x86/sysv.S	Fri Jul 19 08:08:31 2002
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   sysv.S - Copyright (c) 1996, 1998, 2001  Cygnus Solutions
+   sysv.S - Copyright (c) 1996, 1998, 2001, 2002  Cygnus Solutions
    
    X86 Foreign Function Interface 
 
@@ -23,6 +23,8 @@
    OTHER DEALINGS IN THE SOFTWARE.
    ----------------------------------------------------------------------- */
 
+#ifndef __x86_64__
+
 #define LIBFFI_ASM	
 #include <ffi.h>
 
@@ -163,3 +165,5 @@
 	.align 4
 .LEFDE1:
 	.set	.LLFDE1,.LEFDE1-.LSFDE1
+
+#endif /* ifndef __x86_64__ */
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/x86/unix64.S gcc/libffi/src/x86/unix64.S
--- gcc-3.2.2.orig/libffi/src/x86/unix64.S	Thu Jan  1 09:00:00 1970
+++ gcc/libffi/src/x86/unix64.S	Wed Jan 29 00:54:28 2003
@@ -0,0 +1,302 @@
+/* -----------------------------------------------------------------------
+   unix64.S - Copyright (c) 2002  Bo Thorsen <bo@suse.de>
+
+   x86-64 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.
+   ----------------------------------------------------------------------- */
+
+#ifdef __x86_64__
+#define LIBFFI_ASM	
+#include <ffi.h>
+
+	.section	.rodata
+.LC0:
+	.string	"asm in progress %lld\n"
+.LC1:
+	.string	"asm in progress\n"
+.text
+	.align	2
+.globl ffi_call_UNIX64
+        .type	ffi_call_UNIX64,@function
+
+ffi_call_UNIX64:
+.LFB1:
+        pushq	%rbp
+.LCFI0:
+        movq	%rsp, %rbp
+.LCFI1:
+	/* Save all arguments */
+	subq	$48, %rsp
+.LCFI2:
+	movq	%rdi, -8(%rbp)		/* ffi_prep_args	 */
+	movq	%rsi, -16(%rbp)		/* ffi_fill_return_value */
+	movq	%rdx, -24(%rbp)		/* ecif			 */
+	movq	%rcx, -32(%rbp)		/* cif->bytes		 */
+	movq	%r8, -40(%rbp)		/* ecif.rvalue		 */
+	movq	%r9, -48(%rbp)		/* fn			 */
+
+	/* Make room for all of the new args and the register args */
+	addl	$176, %ecx
+.LCFI3:
+	subq	%rcx, %rsp
+.LCFI4:
+	/* Setup the call to ffi_prep_args.  */
+	movq	%rdi, %rax		/* &ffi_prep_args	*/
+	movq	%rsp, %rdi		/* stackLayout		*/
+	movq	%rdx, %rsi		/* ecif			*/
+	call	*%rax			/* ffi_prep_args(stackLayout, ecif);*/ 
+
+	/* ffi_prep_args have put all the register contents into the  */
+	/* stackLayout struct. Now put the register values in place.  */
+	movq	(%rsp), %rdi
+	movq	8(%rsp), %rsi
+	movq	16(%rsp), %rdx
+	movq	24(%rsp), %rcx
+	movq	32(%rsp), %r8
+	movq	40(%rsp), %r9
+	movaps	48(%rsp), %xmm0
+	movaps	64(%rsp), %xmm1
+	movaps	80(%rsp), %xmm2
+	movaps	96(%rsp), %xmm3
+	movaps	112(%rsp), %xmm4
+	movaps	128(%rsp), %xmm5
+	movaps	144(%rsp), %xmm6
+	movaps	160(%rsp), %xmm7
+
+	/* Remove space for stackLayout so stack arguments are placed
+	   correctly for the call.  */
+.LCFI5:
+	addq	$176, %rsp
+.LCFI6:
+	/* Call the user function.  */
+	call	*-48(%rbp)
+
+	/* Make stack space for the return_value struct.  */
+	subq	$64, %rsp
+
+	/* Fill in all potential return values to this struct.  */
+	movq	%rax, (%rsp)
+	movq	%rdx, 8(%rsp)
+	movaps	%xmm0, 16(%rsp)
+	movaps	%xmm1, 32(%rsp)
+	fstpt	48(%rsp)
+
+	/* Now call ffi_fill_return_value.  */
+	movq	%rsp, %rdi		/* struct return_value	  */
+	movq	-24(%rbp), %rsi		/* ecif			  */
+	movq	-16(%rbp), %rax		/* &ffi_fill_return_value */
+	call	*%rax			/* call it		  */
+
+	/* And the work is done.  */
+        leave
+        ret
+.LFE1:
+.ffi_call_UNIX64_end:
+        .size    ffi_call_UNIX64,.ffi_call_UNIX64_end-ffi_call_UNIX64
+
+.text
+	.align	2
+.globl float2sse
+        .type	float2sse,@function
+float2sse:
+	/* Save the contents of this sse-float in a pointer.  */
+	movaps	%xmm0, (%rdi)
+	ret
+
+	.align	2
+.globl floatfloat2sse
+        .type	floatfloat2sse,@function
+floatfloat2sse:
+	/* Save the contents of these two sse-floats in a pointer.  */
+	movq	(%rdi), %xmm0
+	movaps	%xmm0, (%rsi)
+	ret
+
+	.align	2
+.globl double2sse
+        .type	double2sse,@function
+double2sse:
+	/* Save the contents of this sse-double in a pointer.  */
+	movaps	%xmm0, (%rdi)
+	ret
+
+	.align	2
+.globl sse2float
+        .type	sse2float,@function
+sse2float:
+	/* Save the contents of this sse-float in a pointer.  */
+	movaps	(%rdi), %xmm0
+	ret
+
+	.align	2
+.globl sse2double
+        .type	sse2double,@function
+sse2double:
+	/* Save the contents of this pointer in a sse-double.  */
+	movaps	(%rdi), %xmm0
+	ret
+
+	.align	2
+.globl sse2floatfloat
+        .type	sse2floatfloat,@function
+sse2floatfloat:
+	/* Save the contents of this pointer in two sse-floats.  */
+	movaps	(%rdi), %xmm0
+	movq	%xmm0, (%rsi)
+	ret
+
+	.align	2
+.globl ffi_closure_UNIX64
+        .type	ffi_closure_UNIX64,@function
+
+ffi_closure_UNIX64:
+.LFB2:
+        pushq   %rbp
+.LCFI10:
+        movq    %rsp, %rbp
+.LCFI11:
+        subq    $240, %rsp
+.LCFI12:
+	movq	%rdi, -176(%rbp)
+        movq    %rsi, -168(%rbp)
+        movq    %rdx, -160(%rbp)
+        movq    %rcx, -152(%rbp)
+        movq    %r8, -144(%rbp)
+        movq    %r9, -136(%rbp)
+        /* FIXME: We can avoid all this stashing of XMM registers by
+	   (in ffi_prep_closure) computing the number of
+	   floating-point args and moving it into %rax before calling
+	   this function.  Once this is done, uncomment the next few
+	   lines and only the essential XMM registers will be written
+	   to memory.  This is a significant saving.  */
+/*         movzbl  %al, %eax  */
+/*         movq    %rax, %rdx */
+/*         leaq    0(,%rdx,4), %rax */
+/*         leaq    2f(%rip), %rdx */
+/*         subq    %rax, %rdx */
+        leaq    -1(%rbp), %rax
+/*         jmp     *%rdx */
+        movaps  %xmm7, -15(%rax)
+        movaps  %xmm6, -31(%rax)
+        movaps  %xmm5, -47(%rax)
+        movaps  %xmm4, -63(%rax)
+        movaps  %xmm3, -79(%rax)
+        movaps  %xmm2, -95(%rax)
+        movaps  %xmm1, -111(%rax)
+        movaps  %xmm0, -127(%rax)
+2:
+        movl    %edi, -180(%rbp)
+        movl    $0, -224(%rbp)
+        movl    $48, -220(%rbp)
+        leaq    16(%rbp), %rax
+        movq    %rax, -216(%rbp)
+        leaq    -176(%rbp), %rdx
+        movq    %rdx, -208(%rbp)
+        leaq    -224(%rbp), %rsi
+	movq	%r10, %rdi
+	movq	%rsp, %rdx
+        call    ffi_closure_UNIX64_inner@PLT
+
+	cmpl	$FFI_TYPE_FLOAT, %eax
+	je	1f
+	cmpl	$FFI_TYPE_DOUBLE, %eax
+	je	2f
+	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
+	je	3f
+	cmpl	$FFI_TYPE_STRUCT, %eax
+	je	4f
+	popq	%rax
+        leave
+        ret
+1:
+2:
+3:	
+	movaps	-240(%rbp), %xmm0
+        leave
+        ret
+4:
+	leave
+	ret
+.LFE2:	
+		
+        .section        .eh_frame,"a",@progbits
+.Lframe0:
+        .long   .LECIE1-.LSCIE1
+.LSCIE1:
+        .long   0x0
+        .byte   0x1
+        .string "zR"
+        .uleb128 0x1
+        .sleb128 -8
+        .byte   0x10
+        .uleb128 0x1
+        .byte   0x1b
+        .byte   0xc
+        .uleb128 0x7
+        .uleb128 0x8
+        .byte   0x90
+        .uleb128 0x1
+        .align 8
+.LECIE1:
+.LSFDE1:
+	.long	.LEFDE1-.LASFDE1
+.LASFDE1:
+        .long   .LASFDE1-.Lframe0
+
+        .long   .LFB1-.
+        .long   .LFE1-.LFB1
+        .uleb128 0x0
+        .byte   0x4		# DW_CFA_advance_loc4
+        .long   .LCFI0-.LFB1
+        .byte   0xe		# DW_CFA_def_cfa_offset
+        .uleb128 0x10
+        .byte   0x86		# DW_CFA_offset: r6 at cfa-16
+        .uleb128 0x2
+        .byte   0x4		# DW_CFA_advance_loc4
+        .long   .LCFI1-.LCFI0
+        .byte   0x86		# DW_CFA_offset: r6 at cfa-16
+        .uleb128 0x2
+        .byte   0xd		# DW_CFA_def_cfa_reg: r6
+        .uleb128 0x6
+	.align 8
+.LEFDE1:
+.LSFDE3:
+        .long   .LEFDE3-.LASFDE3        # FDE Length
+.LASFDE3:
+        .long   .LASFDE3-.Lframe0       # FDE CIE offset
+
+        .long   .LFB2-. # FDE initial location
+        .long   .LFE2-.LFB2     # FDE address range
+        .uleb128 0x0    # Augmentation size
+        .byte   0x4     # DW_CFA_advance_loc4
+        .long   .LCFI10-.LFB2
+        .byte   0xe     # DW_CFA_def_cfa_offset
+        .uleb128 0x10
+        .byte   0x86    # DW_CFA_offset, column 0x6
+        .uleb128 0x2
+        .byte   0x4     # DW_CFA_advance_loc4
+        .long   .LCFI11-.LCFI10
+        .byte   0xd     # DW_CFA_def_cfa_register
+        .uleb128 0x6
+        .align 8
+.LEFDE3:
+
+#endif /* __x86_64__  */
diff -ruN --exclude=CVS gcc-3.2.2.orig/libffi/src/x86/win32.S gcc/libffi/src/x86/win32.S
--- gcc-3.2.2.orig/libffi/src/x86/win32.S	Tue Mar 27 11:39:16 2001
+++ gcc/libffi/src/x86/win32.S	Fri Dec  6 10:16:45 2002
@@ -1,5 +1,8 @@
 /* -----------------------------------------------------------------------
-   win32.S - Copyright (c) 1996, 1998, 2001  Cygnus Solutions
+   win32.S - Copyright (c) 1996, 1998, 2001, 2002  Red Hat, Inc.
+	     Copyright (c) 2001  John Beniton
+	     Copyright (c) 2002  Ranjit Mathew
+			
  
    X86 Foreign Function Interface
  
@@ -52,7 +55,10 @@
         # Return stack to previous state and call the function
         addl  $8,%esp
  
-        call  *28(%ebp)
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+	call  *28(%ebp)
  
         # Remove the space we pushed for the args
         movl  16(%ebp),%ecx
@@ -123,3 +129,98 @@
         ret
  
 .ffi_call_SYSV_end:
+
+        # This assumes we are using gas.
+        .balign 16
+.globl _ffi_call_STDCALL
+
+_ffi_call_STDCALL:
+        pushl %ebp
+        movl  %esp,%ebp
+
+        # Make room for all of the new args.
+        movl  16(%ebp),%ecx 
+        subl  %ecx,%esp
+
+        movl  %esp,%eax
+
+        # Place all of the ffi_prep_args in position
+        pushl 12(%ebp)
+        pushl %eax
+        call  *8(%ebp)
+
+        # Return stack to previous state and call the function
+        addl  $8,%esp
+
+        # FIXME: Align the stack to a 128-bit boundary to avoid
+        # potential performance hits.
+
+        call  *28(%ebp)
+
+        # stdcall functions pop arguments off the stack themselves
+
+        # Load %ecx with the return type code
+        movl  20(%ebp),%ecx
+
+        # If the return value pointer is NULL, assume no return value.
+        cmpl  $0,24(%ebp)
+        jne   sc_retint
+
+        # Even if there is no space for the return value, we are
+        # obliged to handle floating-point values.
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   sc_noretval
+        fstp  %st(0)
+
+        jmp   sc_epilogue
+
+sc_retint:
+        cmpl  $FFI_TYPE_INT,%ecx
+        jne   sc_retfloat
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        jmp   sc_epilogue
+
+sc_retfloat:
+        cmpl  $FFI_TYPE_FLOAT,%ecx
+        jne   sc_retdouble
+         # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstps (%ecx)
+        jmp   sc_epilogue
+
+sc_retdouble:
+        cmpl  $FFI_TYPE_DOUBLE,%ecx
+        jne   sc_retlongdouble
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpl (%ecx)
+        jmp   sc_epilogue
+
+sc_retlongdouble:
+        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
+        jne   sc_retint64
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        fstpt (%ecx)
+        jmp   sc_epilogue
+
+sc_retint64:
+        cmpl  $FFI_TYPE_SINT64,%ecx
+        jne   sc_retstruct
+        # Load %ecx with the pointer to storage for the return value
+        movl  24(%ebp),%ecx
+        movl  %eax,0(%ecx)
+        movl  %edx,4(%ecx)
+
+sc_retstruct:
+        # Nothing to do!
+
+sc_noretval:
+sc_epilogue:
+        movl %ebp,%esp
+        popl %ebp
+        ret
+
+.ffi_call_STDCALL_end:
--- gcc-3.2.2.orig/libjava/configure.host	Mon Jun 10 13:15:26 2002
+++ gcc-3.2.2/libjava/configure.host	Sat Feb 15 19:57:25 2003
@@ -115,6 +115,12 @@
 	enable_getenv_properties_default=no
 	enable_main_args_default=no
 	;;
+  sh-* | sh[34]*-*)
+	sysdeps_dir=sh
+	libgcj_flags="${libgcj_flags} -mieee"
+	libgcj_interpreter=yes
+	enable_hash_synchronization_default=yes
+	;;
 esac
 
 # This case statement supports generic port properties and may refine
@@ -126,7 +132,8 @@
   powerpc*-linux* | \
   alpha*-linux* | \
   sparc*-linux* | \
-  ia64-*)
+  ia64-* | \
+  sh-linux* | sh[34]*-linux*)
   	can_unwind_signal=yes
 	;;
   *-*-darwin*)
