libffi port for x86-64

Bo Thorsen bo@sonofthor.dk
Wed Jul 17 09:35:00 GMT 2002


Hi,

This is a port of libffi to x86-64. The patch runs the testsuite without 
problems both on x86 and x86-64.

I have added some more struct tests, because the tests that were there didn't 
handle the quirks of the x86-64 ABI for small structs.

I have included the configure (against normal practice). If the patch looks 
fine, but my generated configure doesn't, someone else must regenerate it.

Bo.

2002-07-16  Bo Thorsen  <bo@berlioz.suse.de>

	* src/x86/unix64.S: New file that handles argument setup for
	x86-64.

	* src/x86/sysv.S: Don't use this on x86-64.

	* src/x86/ffi.c: Add x86-64 support.
	(merge_classes): Helper function for argument passing.
	(classify_argument): Likewise.
	(examine_argument): Likewise.
	(ffi_prep_args64): Add x86-64 version of this function.
	(ffi_prep_cif_machdep64): Likewise.
	(ffi_fill_return_value): Add function to handle return values. Used
	by the assemblercode in unix64.S.
	(ffi_prep_cif_machdep): Renamed to ffi_prep_cif_machdep32.
	(ffi_prep_cif_machdep): Use this new function to choose between 32 and
	64 bit versions to avoid two functions with identical names.
	(ffi_call): Add dispatcher for x86-64.

	* src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
	for x86-64.

	* src/ffitest.c (struct6): New test that tests a special case in
	the x86-64 ABI.
	(struct7): Likewise.
	(struct8): Likewise.
	(struct9): Likewise.
	(closure_test_fn): Silence warning about this when it's not used.
	(main): Add the new tests.
	(main): Fix a couple of wrong casts and silence some compiler warnings.

	* include/ffi.h.in: Add x86-64 ABI definition.

	* fficonfig.h.in: Regenerate.
	* Makefile.am: Add x86-64 support.
	* configure.in: Likewise.
	* Makefile.in: Regenerate.
	* configure: Likewise.

2002-06-24  Bo Thorsen  <bo@suse.de>

	* src/types.c: Merge settings for similar architectures.
	Add x86-64 sizes and alignments.

2002-06-23  Bo Thorsen  <bo@suse.de>

	* src/arm/ffi.c (ffi_prep_args): Remove unused vars.
	* src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
	* src/mips/ffi.c (ffi_prep_args): Likewise.
	* src/m68k/ffi.c (ffi_prep_args): Likewise.

Index: libffi/Makefile.am
===================================================================
RCS file: /cvs/gcc/gcc/libffi/Makefile.am,v
retrieving revision 1.19
diff -u -b -B -r1.19 Makefile.am
--- libffi/Makefile.am	29 Apr 2002 04:14:43 -0000	1.19
+++ libffi/Makefile.am	17 Jul 2002 16:26:44 -0000
@@ -7,7 +7,7 @@
 EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
 		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/ffi.c src/x86/sysv.S src/x86/win32.S 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 \
@@ -105,6 +105,7 @@
 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/unix64.S src/x86/ffi.c src/x86/sysv.S
 
 ##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c 
$(TARGET_SRC_@TARGET@)
 ## Work around automake deficiency
@@ -161,6 +162,10 @@
 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
 
 AM_CFLAGS = -fexceptions
Index: libffi/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/Makefile.in,v
retrieving revision 1.24
diff -u -b -B -r1.24 Makefile.in
--- libffi/Makefile.in	29 Apr 2002 04:14:43 -0000	1.24
+++ libffi/Makefile.in	17 Jul 2002 16:26:45 -0000
@@ -88,7 +88,7 @@
 EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
 		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/ffi.c src/x86/sysv.S src/x86/win32.S 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 \
@@ -176,6 +176,7 @@
 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/ffi.c src/x86/sysv.S src/x86/unix.S
 
 libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
 		src/raw_api.c src/java_raw_api.c
@@ -193,6 +194,7 @@
 @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)
 @MIPS_GCC_TRUE@libffi_convenience_la_SOURCES = 
@MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
 @MIPS_SGI_TRUE@libffi_convenience_la_SOURCES = 
@MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
 @X86_TRUE@libffi_convenience_la_SOURCES = 
@X86_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86)
@@ -206,6 +208,7 @@
 @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)
 
 AM_CFLAGS = -fexceptions
 
@@ -295,6 +298,9 @@
 @S390_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @S390_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @S390_TRUE@src/s390/sysv.lo src/s390/ffi.lo
+@X86_64_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
+@X86_64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
+@X86_64_TRUE@src/x86/ffi.lo src/x86/sysv.lo src/x86/unix64.lo
 @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
@@ -314,6 +320,9 @@
 @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_64_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo src/types.lo \
+@X86_64_TRUE@src/raw_api.lo src/java_raw_api.lo src/x86/ffi.lo \
+@X86_64_TRUE@src/x86/sysv.lo src/x86/unix64.lo
 noinst_PROGRAMS =  ffitest$(EXEEXT)
 PROGRAMS =  $(noinst_PROGRAMS)
 
Index: libffi/configure
===================================================================
RCS file: /cvs/gcc/gcc/libffi/configure,v
retrieving revision 1.30
diff -u -b -B -r1.30 configure
--- libffi/configure	8 May 2002 04:36:40 -0000	1.30
+++ libffi/configure	17 Jul 2002 16:26:45 -0000
@@ -53,7 +53,6 @@
 program_transform_name=s,x,x,
 silent=
 site=
-sitefile=
 srcdir=
 target=NONE
 verbose=
@@ -168,7 +167,6 @@
   --help                  print this message
   --no-create             do not create output files
   --quiet, --silent       do not print \`checking...' messages
-  --site-file=FILE        use FILE as the site file
   --version               print the version of autoconf that created 
configure
 Directory and file names:
   --prefix=PREFIX         install architecture-independent files in PREFIX
@@ -339,11 +337,6 @@
   -site=* | --site=* | --sit=*)
     site="$ac_optarg" ;;
 
-  -site-file | --site-file | --site-fil | --site-fi | --site-f)
-    ac_prev=sitefile ;;
-  -site-file=* | --site-file=* | --site-fil=* | --site-fi=* | --site-f=*)
-    sitefile="$ac_optarg" ;;
-
   -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
     ac_prev=srcdir ;;
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
@@ -509,16 +502,12 @@
 srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
 
 # Prefer explicitly selected file to automatically selected ones.
-if test -z "$sitefile"; then
-  if test -z "$CONFIG_SITE"; then
+if test -z "$CONFIG_SITE"; then
     if test "x$prefix" != xNONE; then
       CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
     else
       CONFIG_SITE="$ac_default_prefix/share/config.site 
$ac_default_prefix/etc/config.site"
     fi
-  fi
-else
-  CONFIG_SITE="$sitefile"
 fi
 for ac_site_file in $CONFIG_SITE; do
   if test -r "$ac_site_file"; then
@@ -557,12 +546,12 @@
 fi
 
 echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
-echo "configure:561: checking for Cygwin environment" >&5
+echo "configure:550: checking for Cygwin environment" >&5
 if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 566 "configure"
+#line 555 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -573,7 +562,7 @@
 return __CYGWIN__;
 ; return 0; }
 EOF
-if { (eval echo configure:577: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:566: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_cygwin=yes
 else
@@ -590,19 +579,19 @@
 CYGWIN=
 test "$ac_cv_cygwin" = yes && CYGWIN=yes
 echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
-echo "configure:594: checking for mingw32 environment" >&5
+echo "configure:583: checking for mingw32 environment" >&5
 if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 599 "configure"
+#line 588 "configure"
 #include "confdefs.h"
 
 int main() {
 return __MINGW32__;
 ; return 0; }
 EOF
-if { (eval echo configure:606: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:595: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_mingw32=yes
 else
@@ -679,7 +668,7 @@
 fi
 
 echo $ac_n "checking host system type""... $ac_c" 1>&6
-echo "configure:683: checking host system type" >&5
+echo "configure:672: checking host system type" >&5
 
 host_alias=$host
 case "$host_alias" in
@@ -770,7 +759,7 @@
 fi
 
 echo $ac_n "checking build system type""... $ac_c" 1>&6
-echo "configure:774: checking build system type" >&5
+echo "configure:763: checking build system type" >&5
 
 build_alias=$build
 case "$build_alias" in
@@ -790,7 +779,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:794: checking for $ac_word" >&5
+echo "configure:783: 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
@@ -820,7 +809,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:824: checking for $ac_word" >&5
+echo "configure:813: 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
@@ -871,7 +860,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:875: checking for $ac_word" >&5
+echo "configure:864: 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
@@ -903,7 +892,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... 
$ac_c" 1>&6
-echo "configure:907: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) 
works" >&5
+echo "configure:896: 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.
@@ -914,12 +903,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 918 "configure"
+#line 907 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && 
test -s conftest${ac_exeext}; then
+if { (eval echo configure:912: \"$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
@@ -945,12 +934,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:949: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) 
is a cross-compiler" >&5
+echo "configure:938: 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:954: checking whether we are using GNU C" >&5
+echo "configure:943: 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
@@ -959,7 +948,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:963: 
\"$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:952: 
\"$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
@@ -978,7 +967,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:982: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:971: 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
@@ -1021,7 +1010,7 @@
 if test "$GCC" = yes; then
   # Check if gcc -print-prog-name=ld gives a path.
   echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
-echo "configure:1025: checking for ld used by GCC" >&5
+echo "configure:1014: checking for ld used by GCC" >&5
   case $host in
   *-*-mingw*)
     # gcc leaves a trailing carriage return which upsets mingw
@@ -1051,10 +1040,10 @@
   esac
 elif test "$with_gnu_ld" = yes; then
   echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
-echo "configure:1055: checking for GNU ld" >&5
+echo "configure:1044: checking for GNU ld" >&5
 else
   echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
-echo "configure:1058: checking for non-GNU ld" >&5
+echo "configure:1047: checking for non-GNU ld" >&5
 fi
 if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1089,7 +1078,7 @@
 fi
 test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 
1>&2; exit 1; }
 echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
-echo "configure:1093: checking if the linker ($LD) is GNU ld" >&5
+echo "configure:1082: checking if the linker ($LD) is GNU ld" >&5
 if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1106,7 +1095,7 @@
 
 
 echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
-echo "configure:1110: checking for $LD option to reload object files" >&5
+echo "configure:1099: checking for $LD option to reload object files" >&5
 if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1118,7 +1107,7 @@
 test -n "$reload_flag" && reload_flag=" $reload_flag"
 
 echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
-echo "configure:1122: checking for BSD-compatible nm" >&5
+echo "configure:1111: checking for BSD-compatible nm" >&5
 if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1156,7 +1145,7 @@
 echo "$ac_t""$NM" 1>&6
 
 echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
-echo "configure:1160: checking whether ln -s works" >&5
+echo "configure:1149: checking whether ln -s works" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1177,7 +1166,7 @@
 fi
 
 echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
-echo "configure:1181: checking how to recognise dependant libraries" >&5
+echo "configure:1170: checking how to recognise dependant libraries" >&5
 if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1341,13 +1330,13 @@
 deplibs_check_method=$lt_cv_deplibs_check_method
 
 echo $ac_n "checking for object suffix""... $ac_c" 1>&6
-echo "configure:1345: checking for object suffix" >&5
+echo "configure:1334: 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:1351: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:1340: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   for ac_file in conftest.*; do
     case $ac_file in
     *.c) ;;
@@ -1367,7 +1356,7 @@
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:1371: checking for executable suffix" >&5
+echo "configure:1360: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1377,10 +1366,10 @@
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:1381: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; 
}; then
+  if { (eval echo configure:1370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; 
}; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -1410,7 +1399,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:1414: checking for ${ac_tool_prefix}file" >&5
+echo "configure:1403: 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
@@ -1472,7 +1461,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:1476: checking for file" >&5
+echo "configure:1465: 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
@@ -1543,7 +1532,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:1547: checking for $ac_word" >&5
+echo "configure:1536: 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
@@ -1575,7 +1564,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:1579: checking for $ac_word" >&5
+echo "configure:1568: 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
@@ -1610,7 +1599,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:1614: checking for $ac_word" >&5
+echo "configure:1603: 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
@@ -1642,7 +1631,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:1646: checking for $ac_word" >&5
+echo "configure:1635: 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
@@ -1709,8 +1698,8 @@
 case $host in
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 1713 "configure"' > conftest.$ac_ext
-  if { (eval echo configure:1714: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+  echo '#line 1702 "configure"' > conftest.$ac_ext
+  if { (eval echo configure:1703: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
     case `/usr/bin/file conftest.$ac_objext` in
     *32-bit*)
       LD="${LD-ld} -32"
@@ -1731,7 +1720,7 @@
   SAVE_CFLAGS="$CFLAGS"
   CFLAGS="$CFLAGS -belf"
   echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
-echo "configure:1735: checking whether the C compiler needs -belf" >&5
+echo "configure:1724: 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
@@ -1744,14 +1733,14 @@
 cross_compiling=$ac_cv_prog_cc_cross
 
      cat > conftest.$ac_ext <<EOF
-#line 1748 "configure"
+#line 1737 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext}; then
+if { (eval echo configure:1744: \"$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
@@ -1879,7 +1868,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:1883: checking for a BSD compatible install" >&5
+echo "configure:1872: 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
@@ -1932,7 +1921,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:1936: checking whether build environment is sane" >&5
+echo "configure:1925: checking whether build environment is sane" >&5
 # Just in case
 sleep 1
 echo timestamp > conftestfile
@@ -1989,7 +1978,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:1993: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:1982: 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
@@ -2028,7 +2017,7 @@
 
 missing_dir=`cd $ac_aux_dir && pwd`
 echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
-echo "configure:2032: checking for working aclocal" >&5
+echo "configure:2021: 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.
@@ -2041,7 +2030,7 @@
 fi
 
 echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
-echo "configure:2045: checking for working autoconf" >&5
+echo "configure:2034: 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.
@@ -2054,7 +2043,7 @@
 fi
 
 echo $ac_n "checking for working automake""... $ac_c" 1>&6
-echo "configure:2058: checking for working automake" >&5
+echo "configure:2047: 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.
@@ -2067,7 +2056,7 @@
 fi
 
 echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
-echo "configure:2071: checking for working autoheader" >&5
+echo "configure:2060: 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.
@@ -2080,7 +2069,7 @@
 fi
 
 echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
-echo "configure:2084: checking for working makeinfo" >&5
+echo "configure:2073: 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.
@@ -2097,7 +2086,7 @@
 
 
 echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
-echo "configure:2101: checking for executable suffix" >&5
+echo "configure:2090: checking for executable suffix" >&5
 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2107,10 +2096,10 @@
   rm -f conftest*
   echo 'int main () { return 0; }' > conftest.$ac_ext
   ac_cv_exeext=
-  if { (eval echo configure:2111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; 
}; then
+  if { (eval echo configure:2100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; 
}; then
     for file in conftest.*; do
       case $file in
-      *.c | *.o | *.obj | *.ilk | *.pdb) ;;
+      *.c | *.o | *.obj) ;;
       *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
       esac
     done
@@ -2128,7 +2117,7 @@
 ac_exeext=$EXEEXT
 
 echo $ac_n "checking whether to enable maintainer-specific portions of 
Makefiles""... $ac_c" 1>&6
-echo "configure:2132: checking whether to enable maintainer-specific portions 
of Makefiles" >&5
+echo "configure:2121: 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"
@@ -2154,7 +2143,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:2158: checking for $ac_word" >&5
+echo "configure:2147: 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
@@ -2184,7 +2173,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:2188: checking for $ac_word" >&5
+echo "configure:2177: 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
@@ -2235,7 +2224,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:2239: checking for $ac_word" >&5
+echo "configure:2228: 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
@@ -2267,7 +2256,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... 
$ac_c" 1>&6
-echo "configure:2271: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) 
works" >&5
+echo "configure:2260: 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.
@@ -2278,12 +2267,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 2282 "configure"
+#line 2271 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:2287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext}; then
+if { (eval echo configure:2276: \"$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
@@ -2309,12 +2298,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:2313: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) 
is a cross-compiler" >&5
+echo "configure:2302: 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:2318: checking whether we are using GNU C" >&5
+echo "configure:2307: 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
@@ -2323,7 +2312,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:2327: 
\"$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:2316: 
\"$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
@@ -2342,7 +2331,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:2346: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:2335: 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
@@ -2404,6 +2393,7 @@
 rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
 s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -2528,8 +2518,17 @@
   S390_FALSE=
 fi
 
+
+if test x$TARGET = xX86_64; then
+  X86_64_TRUE=
+  X86_64_FALSE='#'
+else
+  X86_64_TRUE='#'
+  X86_64_FALSE=
+fi
+
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:2533: checking how to run the C preprocessor" >&5
+echo "configure:2532: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -2544,13 +2543,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 2548 "configure"
+#line 2547 "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:2554: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2553: \"$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
   :
@@ -2561,13 +2560,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 2565 "configure"
+#line 2564 "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:2571: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2570: \"$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
   :
@@ -2578,13 +2577,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 2582 "configure"
+#line 2581 "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:2588: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2587: \"$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
   :
@@ -2609,12 +2608,12 @@
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2613: checking for ANSI C header files" >&5
+echo "configure:2612: 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 2618 "configure"
+#line 2617 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2622,7 +2621,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2625: \"$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*
@@ -2639,7 +2638,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 2643 "configure"
+#line 2642 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2657,7 +2656,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 2661 "configure"
+#line 2660 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2678,7 +2677,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2682 "configure"
+#line 2681 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2689,7 +2688,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2715,12 +2714,12 @@
 for ac_func in memcpy
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2719: checking for $ac_func" >&5
+echo "configure:2718: 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 2724 "configure"
+#line 2723 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2743,7 +2742,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2747: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext}; then
+if { (eval echo configure:2746: \"$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
@@ -2770,19 +2769,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:2774: checking for working alloca.h" >&5
+echo "configure:2773: 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 2779 "configure"
+#line 2778 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:2786: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext}; then
+if { (eval echo configure:2785: \"$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
@@ -2803,12 +2802,12 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:2807: checking for alloca" >&5
+echo "configure:2806: 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 2812 "configure"
+#line 2811 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -2836,7 +2835,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:2840: \"$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*
   ac_cv_func_alloca_works=yes
 else
@@ -2868,12 +2867,12 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:2872: checking whether alloca needs Cray hooks" >&5
+echo "configure:2871: 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 2877 "configure"
+#line 2876 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -2898,12 +2897,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:2902: checking for $ac_func" >&5
+echo "configure:2901: 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 2907 "configure"
+#line 2906 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2926,7 +2925,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2930: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext}; then
+if { (eval echo configure:2929: \"$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
@@ -2953,7 +2952,7 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:2957: checking stack direction for C alloca" >&5
+echo "configure:2956: 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
@@ -2961,7 +2960,7 @@
   ac_cv_c_stack_direction=0
 else
   cat > conftest.$ac_ext <<EOF
-#line 2965 "configure"
+#line 2964 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -2980,7 +2979,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:2984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2983: \"$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
@@ -3003,13 +3002,13 @@
 
 
 echo $ac_n "checking size of short""... $ac_c" 1>&6
-echo "configure:3007: checking size of short" >&5
+echo "configure:3006: 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 3013 "configure"
+#line 3012 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3019,7 +3018,7 @@
 switch (0) case 0: case (sizeof (short) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3023: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3022: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_short=$ac_size
 else
@@ -3042,13 +3041,13 @@
 
 
 echo $ac_n "checking size of int""... $ac_c" 1>&6
-echo "configure:3046: checking size of int" >&5
+echo "configure:3045: 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 3052 "configure"
+#line 3051 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3058,7 +3057,7 @@
 switch (0) case 0: case (sizeof (int) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3062: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3061: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_int=$ac_size
 else
@@ -3081,13 +3080,13 @@
 
 
 echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:3085: checking size of long" >&5
+echo "configure:3084: 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 3091 "configure"
+#line 3090 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3097,7 +3096,7 @@
 switch (0) case 0: case (sizeof (long) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3101: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3100: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long=$ac_size
 else
@@ -3120,13 +3119,13 @@
 
 
 echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:3124: checking size of long long" >&5
+echo "configure:3123: 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 3130 "configure"
+#line 3129 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3136,7 +3135,7 @@
 switch (0) case 0: case (sizeof (long long) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3140: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3139: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long_long=$ac_size
 else
@@ -3159,13 +3158,13 @@
 
 
 echo $ac_n "checking size of float""... $ac_c" 1>&6
-echo "configure:3163: checking size of float" >&5
+echo "configure:3162: 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 3169 "configure"
+#line 3168 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3175,7 +3174,7 @@
 switch (0) case 0: case (sizeof (float) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3179: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3178: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_float=$ac_size
 else
@@ -3198,13 +3197,13 @@
 
 
 echo $ac_n "checking size of double""... $ac_c" 1>&6
-echo "configure:3202: checking size of double" >&5
+echo "configure:3201: 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 3208 "configure"
+#line 3207 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3214,7 +3213,7 @@
 switch (0) case 0: case (sizeof (double) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3218: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3217: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_double=$ac_size
 else
@@ -3237,13 +3236,13 @@
 
 
 echo $ac_n "checking size of long double""... $ac_c" 1>&6
-echo "configure:3241: checking size of long double" >&5
+echo "configure:3240: 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 3247 "configure"
+#line 3246 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3253,7 +3252,7 @@
 switch (0) case 0: case (sizeof (long double) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3257: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3256: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_long_double=$ac_size
 else
@@ -3277,13 +3276,13 @@
 
 
 echo $ac_n "checking size of void *""... $ac_c" 1>&6
-echo "configure:3281: checking size of void *" >&5
+echo "configure:3280: 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 3287 "configure"
+#line 3286 "configure"
 #include "confdefs.h"
 #include "confdefs.h"
 #include <sys/types.h>
@@ -3293,7 +3292,7 @@
 switch (0) case 0: case (sizeof (void *) == $ac_size):;
 ; return 0; }
 EOF
-if { (eval echo configure:3297: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3296: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_sizeof_void_p=$ac_size
 else
@@ -3316,14 +3315,14 @@
 
 
 echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:3320: checking whether byte ordering is bigendian" >&5
+echo "configure:3319: 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 3327 "configure"
+#line 3326 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -3334,11 +3333,11 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:3338: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3337: \"$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 3342 "configure"
+#line 3341 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/param.h>
@@ -3349,7 +3348,7 @@
 #endif
 ; return 0; }
 EOF
-if { (eval echo configure:3353: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
+if { (eval echo configure:3352: \"$ac_compile\") 1>&5; (eval $ac_compile) 
2>&5; }; then
   rm -rf conftest*
   ac_cv_c_bigendian=yes
 else
@@ -3369,7 +3368,7 @@
    echo $ac_n "cross-compiling... " 2>&6 
 else
   cat > conftest.$ac_ext <<EOF
-#line 3373 "configure"
+#line 3372 "configure"
 #include "confdefs.h"
 main () {
   /* Are we little or big endian?  From Harbison&Steele.  */
@@ -3382,7 +3381,7 @@
   exit (u.c[sizeof (long) - 1] == 1);
 }
 EOF
-if { (eval echo configure:3386: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3385: \"$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
@@ -3400,7 +3399,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:3404: checking to probe for byte ordering" >&5
+echo "configure:3403: checking to probe for byte ordering" >&5
 
 cat >conftest.c <<EOF
 short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
@@ -3450,7 +3449,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:3454: checking assembler and linker support unaligned pc 
related relocs" >&5
+echo "configure:3453: 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
@@ -3460,14 +3459,14 @@
 	CFLAGS="$CFLAGS -fpic"
 	LDFLAGS="$LDFLAGS -shared"
 	cat > conftest.$ac_ext <<EOF
-#line 3464 "configure"
+#line 3463 "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:3471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } 
&& test -s conftest${ac_exeext}; then
+if { (eval echo configure:3470: \"$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
@@ -3750,6 +3749,8 @@
 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%@CPP@%$CPP%g
 s%@ALLOCA@%$ALLOCA%g
 s%@TARGET@%$TARGET%g
Index: libffi/configure.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/configure.in,v
retrieving revision 1.27
diff -u -b -B -r1.27 configure.in
--- libffi/configure.in	8 May 2002 04:36:40 -0000	1.27
+++ libffi/configure.in	17 Jul 2002 16:26:45 -0000
@@ -68,6 +68,7 @@
 rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
 arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
 s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
+x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
 esac
 
 if test $TARGETDIR = unknown; then
@@ -87,6 +88,7 @@
 AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
 AM_CONDITIONAL(ARM, test x$TARGET = xARM)
 AM_CONDITIONAL(S390, test x$TARGET = xS390)
+AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
 
 AC_HEADER_STDC
 AC_CHECK_FUNCS(memcpy)
Index: libffi/fficonfig.h.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/fficonfig.h.in,v
retrieving revision 1.3
diff -u -b -B -r1.3 fficonfig.h.in
--- libffi/fficonfig.h.in	28 Apr 2002 19:57:42 -0000	1.3
+++ libffi/fficonfig.h.in	17 Jul 2002 16:26:45 -0000
@@ -1,34 +1,4 @@
 /* fficonfig.h.in.  Generated automatically from configure.in by autoheader.  
*/
-
-/* Define if using alloca.c.  */
-#undef C_ALLOCA
-
-/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
-   This function is required for alloca.c support on those systems.  */
-#undef CRAY_STACKSEG_END
-
-/* Define if you have alloca, as a function or macro.  */
-#undef HAVE_ALLOCA
-
-/* Define if you have <alloca.h> and it should be used (not on Ultrix).  */
-#undef HAVE_ALLOCA_H
-
-/* If using the C implementation of alloca, define if you know the
-   direction of stack growth for your system; otherwise it will be
-   automatically deduced at run-time.
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown
- */
-#undef STACK_DIRECTION
-
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
-
-/* Define if your processor stores words with the most significant
-   byte first (like Motorola and SPARC, unlike Intel and VAX).  */
-#undef WORDS_BIGENDIAN
-
 /* Define this if you want extra debugging */
 #undef FFI_DEBUG
 
@@ -42,32 +12,70 @@
 /* Define this is you do not want support for the raw API.  */
 #undef FFI_NO_RAW_API
 
-/* The number of bytes in a double.  */
+/* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */
+#undef BYTEORDER
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those 
systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Define if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Define if you have `alloca', as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if your assembler and linker support unaligned PC relative relocs.
+   */
+#undef HAVE_AS_SPARC_UA_PCREL
+
+/* Define if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Name of package */
+#undef PACKAGE
+
+/* The number of bytes in type double */
 #undef SIZEOF_DOUBLE
 
-/* The number of bytes in a float.  */
+/* The number of bytes in type float */
 #undef SIZEOF_FLOAT
 
-/* The number of bytes in a int.  */
+/* The number of bytes in type int */
 #undef SIZEOF_INT
 
-/* The number of bytes in a long.  */
+/* The number of bytes in type long */
 #undef SIZEOF_LONG
 
-/* The number of bytes in a long double.  */
+/* The number of bytes in type long double */
 #undef SIZEOF_LONG_DOUBLE
 
-/* The number of bytes in a long long.  */
+/* The number of bytes in type long long */
 #undef SIZEOF_LONG_LONG
 
-/* The number of bytes in a short.  */
+/* The number of bytes in type short */
 #undef SIZEOF_SHORT
 
-/* The number of bytes in a void *.  */
+/* The number of bytes in type void * */
 #undef SIZEOF_VOID_P
 
-/* Define if you have the memcpy function.  */
-#undef HAVE_MEMCPY
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at run-time.
+        STACK_DIRECTION > 0 => grows toward higher addresses
+        STACK_DIRECTION < 0 => grows toward lower addresses
+        STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
 
-/* Define if your assembler and linker support unaligned PC relative relocs.  
*/
-#undef HAVE_AS_SPARC_UA_PCREL
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* whether byteorder is bigendian */
+#undef WORDS_BIGENDIAN
Index: libffi/include/Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/include/Makefile.in,v
retrieving revision 1.8
diff -u -b -B -r1.8 Makefile.in
--- libffi/include/Makefile.in	29 Apr 2002 04:14:44 -0000	1.8
+++ libffi/include/Makefile.in	17 Jul 2002 16:26:45 -0000
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -99,14 +99,14 @@
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gtar
+TAR = tar
 GZIP_ENV = --best
 all: all-redirect
 .SUFFIXES:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am 
$(top_srcdir)/configure.in $(ACLOCAL_M4) 
-	cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile
+	cd $(top_srcdir) && $(AUTOMAKE) --cygnus include/Makefile
 
-Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status 
$(BUILT_SOURCES)
+Makefile: $(srcdir)/Makefile.in  $(top_builddir)/config.status
 	cd $(top_builddir) \
 	  && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
 
@@ -140,13 +140,8 @@
 subdir = include
 
 distdir: $(DISTFILES)
-	here=`cd $(top_builddir) && pwd`; \
-	top_distdir=`cd $(top_distdir) && pwd`; \
-	distdir=`cd $(distdir) && pwd`; \
-	cd $(top_srcdir) \
-	  && $(AUTOMAKE) --include-deps --build-dir=$$here 
--srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --foreign 
include/Makefile
 	@for file in $(DISTFILES); do \
-	  d=$(srcdir); \
+	  if test -f $$file; then d=.; else d=$(srcdir); fi; \
 	  if test -d $$d/$$file; then \
 	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
@@ -159,10 +154,12 @@
 info: info-am
 dvi-am:
 dvi: dvi-am
-check-am: all-am
+check-am:
 check: check-am
 installcheck-am:
 installcheck: installcheck-am
+install-info-am: 
+install-info: install-info-am
 install-exec-am:
 install-exec: install-exec-am
 
@@ -211,10 +208,10 @@
 maintainer-clean: maintainer-clean-am
 
 .PHONY: uninstall-hackDATA install-hackDATA tags distdir info-am info \
-dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
-install-exec install-data-am install-data install-am install \
-uninstall-am uninstall all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
+dvi-am dvi check check-am installcheck-am installcheck install-info-am \
+install-info install-exec-am install-exec install-data-am install-data \
+install-am install uninstall-am uninstall all-redirect all-am all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
 maintainer-clean-generic clean mostlyclean distclean maintainer-clean
 
 
Index: libffi/include/ffi.h.in
===================================================================
RCS file: /cvs/gcc/gcc/libffi/include/ffi.h.in,v
retrieving revision 1.15
diff -u -b -B -r1.15 ffi.h.in
--- libffi/include/ffi.h.in	29 Apr 2002 04:14:44 -0000	1.15
+++ libffi/include/ffi.h.in	17 Jul 2002 16:26:45 -0000
@@ -189,10 +189,15 @@
 #endif
 #endif
 
-  /* ---- Intel x86 ---------------- */
-#ifdef X86
+  /* ---- Intel x86 and AMD x86-64 - */
+#if defined(X86) || defined(X86_64)
   FFI_SYSV,
+  FFI_UNIX64,   /* Unix variants all use the same ABI for x86-64  */
+#ifdef X86
   FFI_DEFAULT_ABI = FFI_SYSV,
+#else
+  FFI_DEFAULT_ABI = FFI_UNIX64,
+#endif
 #endif
 
   /* ---- Intel x86 Win32 ---------- */
Index: libffi/src/ffitest.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/ffitest.c,v
retrieving revision 1.6
diff -u -b -B -r1.6 ffitest.c
--- libffi/src/ffitest.c	24 Feb 2002 17:31:45 -0000	1.6
+++ libffi/src/ffitest.c	17 Jul 2002 16:26:45 -0000
@@ -153,6 +153,33 @@
   char c2;
 } test_structure_5;
 
+typedef struct
+{
+  float f;
+  double d;
+} test_structure_6;
+
+typedef struct
+{
+  float f1;
+  float f2;
+  double d;
+} test_structure_7;
+
+typedef struct
+{
+  float f1;
+  float f2;
+  float f3;
+  float f4;
+} test_structure_8;
+
+typedef struct
+{
+  float f;
+  int i;
+} test_structure_9;
+
 static test_structure_1 struct1(test_structure_1 ts)
 {
   /*@-type@*/
@@ -194,15 +221,52 @@
   return ts1;
 }
 
+static test_structure_6 struct6 (test_structure_6 ts)
+{
+  ts.f += 1;
+  ts.d += 1;
+
+  return ts;
+}
+
+static test_structure_7 struct7 (test_structure_7 ts)
+{
+  ts.f1 += 1;
+  ts.f2 += 1;
+  ts.d += 1;
+
+  return ts;
+}
+
+static test_structure_8 struct8 (test_structure_8 ts)
+{
+  ts.f1 += 1;
+  ts.f2 += 1;
+  ts.f3 += 1;
+  ts.f4 += 1;
+
+  return ts;
+}
+
+static test_structure_9 struct9 (test_structure_9 ts)
+{
+  ts.f += 1;
+  ts.i += 1;
+
+  return ts;
+}
+
 /* Take an int and a float argument, together with int userdata, and 	*/
 /* return the sum.							*/
-static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* 
userdata)
+#if FFI_CLOSURES
+static void
+closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
 {
-    *(int*)resp =
-	 *(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata;
+  *(int*)resp = *(int*)args[0] + (int)(*(float*)args[1]) + 
(int)(long)userdata;
 }
 
 typedef int (*closure_test_type)(int, float);
+#endif
 
 int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
 {
@@ -230,11 +294,19 @@
   ffi_type ts3_type;
   ffi_type ts4_type;  
   ffi_type ts5_type;
+  ffi_type ts6_type;
+  ffi_type ts7_type;
+  ffi_type ts8_type;
+  ffi_type ts9_type;
   ffi_type *ts1_type_elements[4];
   ffi_type *ts2_type_elements[3];
   ffi_type *ts3_type_elements[2];
   ffi_type *ts4_type_elements[4];
   ffi_type *ts5_type_elements[3];
+  ffi_type *ts6_type_elements[3];
+  ffi_type *ts7_type_elements[4];
+  ffi_type *ts8_type_elements[5];
+  ffi_type *ts9_type_elements[3];
 
   ts1_type.size = 0;
   ts1_type.alignment = 0;
@@ -256,12 +328,32 @@
   ts5_type.alignment = 0;
   ts5_type.type = FFI_TYPE_STRUCT;
 
+  ts6_type.size = 0;
+  ts6_type.alignment = 0;
+  ts6_type.type = FFI_TYPE_STRUCT;
+
+  ts7_type.size = 0;
+  ts7_type.alignment = 0;
+  ts7_type.type = FFI_TYPE_STRUCT;
+
+  ts8_type.size = 0;
+  ts8_type.alignment = 0;
+  ts8_type.type = FFI_TYPE_STRUCT;
+
+  ts9_type.size = 0;
+  ts9_type.alignment = 0;
+  ts9_type.type = FFI_TYPE_STRUCT;
+
   /*@-immediatetrans@*/
   ts1_type.elements = ts1_type_elements;
   ts2_type.elements = ts2_type_elements;
   ts3_type.elements = ts3_type_elements;
   ts4_type.elements = ts4_type_elements;
   ts5_type.elements = ts5_type_elements;
+  ts6_type.elements = ts6_type_elements;
+  ts7_type.elements = ts7_type_elements;
+  ts8_type.elements = ts8_type_elements;
+  ts9_type.elements = ts9_type_elements;
   /*@=immediatetrans@*/
   
   ts1_type_elements[0] = &ffi_type_uchar;
@@ -285,6 +377,25 @@
   ts5_type_elements[1] = &ffi_type_schar;
   ts5_type_elements[2] = NULL;
 
+  ts6_type_elements[0] = &ffi_type_float;
+  ts6_type_elements[1] = &ffi_type_double;
+  ts6_type_elements[2] = NULL;
+
+  ts7_type_elements[0] = &ffi_type_float;
+  ts7_type_elements[1] = &ffi_type_float;
+  ts7_type_elements[2] = &ffi_type_double;
+  ts7_type_elements[3] = NULL;
+
+  ts8_type_elements[0] = &ffi_type_float;
+  ts8_type_elements[1] = &ffi_type_float;
+  ts8_type_elements[2] = &ffi_type_float;
+  ts8_type_elements[3] = &ffi_type_float;
+  ts8_type_elements[4] = NULL;
+
+  ts9_type_elements[0] = &ffi_type_float;
+  ts9_type_elements[1] = &ffi_type_sint;
+  ts9_type_elements[2] = NULL;
+
   ul = 0;
 
   /* return value tests */
@@ -326,7 +437,7 @@
       {
 	ul++;
 	ffi_call(&cif, FFI_FN(return_sc), &rint, values);
-	CHECK(rint == (int) sc);
+	CHECK(rint == (ffi_arg) sc);
       }
 
     args[0] = &ffi_type_uchar;
@@ -413,7 +524,7 @@
 
     ffi_call(&cif, FFI_FN(floating), &rint, values);
 
-    printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2));
+    printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
 
     CHECK(rint == floating(si1, f, d, ld, si2));
 
@@ -483,7 +594,7 @@
 		       &ffi_type_float, args) == FFI_OK);
 
     /*@-usedef@*/
-    ff =  many(fa[0], fa[1],
+    ff = many (fa[0], fa[1],
 	       fa[2], fa[3],
 	       fa[4], fa[5],
 	       fa[6], fa[7],
@@ -532,7 +643,8 @@
 	    {
 	      ul++;
 	      ffi_call(&cif, FFI_FN(promotion), &rint, values);
-	      CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us);
+	      CHECK((int)rint == (signed char) sc + (signed short) ss +
+		    (unsigned char) uc + (unsigned short) us);
 	    }
     printf("%lu promotion tests run\n", ul);
   }
@@ -579,8 +691,7 @@
     values[0] = &ts2_arg;
     
     /* Initialize the cif */
-    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
-		       &ts2_type, args) == FFI_OK);
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
 
     ts2_arg.d1 = 5.55;
     ts2_arg.d2 = 6.66;
@@ -647,8 +758,7 @@
     values[0] = &ts4_arg;
     
     /* Initialize the cif */
-    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, 
-		       &ts4_type, args) == FFI_OK);
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
 
     ts4_arg.ui1 = 2;
     ts4_arg.ui2 = 3;
@@ -678,8 +788,7 @@
     values[1] = &ts5_arg2;
     
     /* Initialize the cif */
-    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, 
-		       &ts5_type, args) == FFI_OK);
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
 
     ts5_arg1.c1 = 2;
     ts5_arg1.c2 = 6;
@@ -695,6 +804,150 @@
       puts ("Structure test 5 found GCC's structure passing bug.");
 
     free (ts5_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_6 ts6_arg;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_6 *ts6_result = 
+      (test_structure_6 *) malloc (sizeof(test_structure_6));
+
+    args[0] = &ts6_type;
+    values[0] = &ts6_arg;
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
+
+    ts6_arg.f = 5.55f;
+    ts6_arg.d = 6.66;
+
+    printf ("%g\n", ts6_arg.f);
+    printf ("%g\n", ts6_arg.d);
+
+    ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
+
+    printf ("%g\n", ts6_result->f);
+    printf ("%g\n", ts6_result->d);
+
+    CHECK(ts6_result->f == 5.55f + 1);
+    CHECK(ts6_result->d == 6.66 + 1);
+
+    printf("structure test 6 ok!\n");
+
+    free (ts6_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_7 ts7_arg;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_7 *ts7_result = 
+      (test_structure_7 *) malloc (sizeof(test_structure_7));
+
+    args[0] = &ts7_type;
+    values[0] = &ts7_arg;
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
+
+    ts7_arg.f1 = 5.55f;
+    ts7_arg.f2 = 55.5f;
+    ts7_arg.d = 6.66;
+
+    printf ("%g\n", ts7_arg.f1);
+    printf ("%g\n", ts7_arg.f2);
+    printf ("%g\n", ts7_arg.d);
+
+    ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
+
+    printf ("%g\n", ts7_result->f1);
+    printf ("%g\n", ts7_result->f2);
+    printf ("%g\n", ts7_result->d);
+
+    CHECK(ts7_result->f1 == 5.55f + 1);
+    CHECK(ts7_result->f2 == 55.5f + 1);
+    CHECK(ts7_result->d == 6.66 + 1);
+
+    printf("structure test 7 ok!\n");
+
+    free (ts7_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_8 ts8_arg;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_8 *ts8_result = 
+      (test_structure_8 *) malloc (sizeof(test_structure_8));
+
+    args[0] = &ts8_type;
+    values[0] = &ts8_arg;
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
+
+    ts8_arg.f1 = 5.55f;
+    ts8_arg.f2 = 55.5f;
+    ts8_arg.f3 = -5.55f;
+    ts8_arg.f4 = -55.5f;
+
+    printf ("%g\n", ts8_arg.f1);
+    printf ("%g\n", ts8_arg.f2);
+    printf ("%g\n", ts8_arg.f3);
+    printf ("%g\n", ts8_arg.f4);
+
+    ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
+
+    printf ("%g\n", ts8_result->f1);
+    printf ("%g\n", ts8_result->f2);
+    printf ("%g\n", ts8_result->f3);
+    printf ("%g\n", ts8_result->f4);
+
+    CHECK(ts8_result->f1 == 5.55f + 1);
+    CHECK(ts8_result->f2 == 55.5f + 1);
+    CHECK(ts8_result->f3 == -5.55f + 1);
+    CHECK(ts8_result->f4 == -55.5f + 1);
+
+    printf("structure test 8 ok!\n");
+
+    free (ts8_result);
+  }
+
+  /* struct tests */
+  {
+    test_structure_9 ts9_arg;
+
+    /* This is a hack to get a properly aligned result buffer */
+    test_structure_9 *ts9_result = 
+      (test_structure_9 *) malloc (sizeof(test_structure_9));
+
+    args[0] = &ts9_type;
+    values[0] = &ts9_arg;
+
+    /* Initialize the cif */
+    CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
+
+    ts9_arg.f = 5.55f;
+    ts9_arg.i = 5;
+
+    printf ("%g\n", ts9_arg.f);
+    printf ("%d\n", ts9_arg.i);
+
+    ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
+
+    printf ("%g\n", ts9_result->f);
+    printf ("%d\n", ts9_result->i);
+
+    CHECK(ts9_result->f == 5.55f + 1);
+    CHECK(ts9_result->i == 5 + 1);
+
+    printf("structure test 9 ok!\n");
+
+    free (ts9_result);
   }
 
 #else
Index: libffi/src/prep_cif.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/prep_cif.c,v
retrieving revision 1.3
diff -u -b -B -r1.3 prep_cif.c
--- libffi/src/prep_cif.c	2 Mar 2001 22:21:22 -0000	1.3
+++ libffi/src/prep_cif.c	17 Jul 2002 16:26:45 -0000
@@ -103,7 +103,9 @@
   /* 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.
+     TODO: Disable this for s390 too?  */
+#if !defined M68K && !defined __x86_64__
   /* Make space for the return structure pointer */
   if (cif->rtype->type == FFI_TYPE_STRUCT
 #ifdef SPARC
@@ -122,6 +124,8 @@
       if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
 	return FFI_BAD_TYPEDEF;
 
+      /* TODO: Disable this calculation for s390 too?  */
+#ifndef __x86_64__
 #ifdef SPARC
       if (((*ptr)->type == FFI_TYPE_STRUCT
 	   && ((*ptr)->size > 16 || cif->abi != FFI_V9))
@@ -137,6 +141,7 @@
 	  
 	  bytes += STACK_ARG_SIZE((*ptr)->size);
 	}
+#endif
     }
 
   cif->bytes = bytes;
Index: libffi/src/types.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/types.c,v
retrieving revision 1.4
diff -u -b -B -r1.4 types.c
--- libffi/src/types.c	27 Mar 2001 02:39:16 -0000	1.4
+++ libffi/src/types.c	17 Jul 2002 16:26:45 -0000
@@ -42,7 +42,7 @@
 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
 
 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
 
@@ -52,22 +52,7 @@
 
 #endif
 
-#ifdef X86
-
-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
+#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);
@@ -80,12 +65,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,11 +75,6 @@
 FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
 FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
 
-#elif defined M68K
-
-FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
-FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
-
 #elif defined SPARC
 
 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
@@ -103,16 +78,16 @@
 #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
 
Index: libffi/src/arm/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/arm/ffi.c,v
retrieving revision 1.2
diff -u -b -B -r1.2 ffi.c
--- libffi/src/arm/ffi.c	2 Mar 2001 22:21:23 -0000	1.2
+++ libffi/src/arm/ffi.c	17 Jul 2002 16:26:45 -0000
@@ -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;
Index: libffi/src/m68k/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/m68k/ffi.c,v
retrieving revision 1.1.1.1
diff -u -b -B -r1.1.1.1 ffi.c
--- libffi/src/m68k/ffi.c	8 Aug 1999 13:27:19 -0000	1.1.1.1
+++ libffi/src/m68k/ffi.c	17 Jul 2002 16:26:45 -0000
@@ -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;
Index: libffi/src/mips/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/mips/ffi.c,v
retrieving revision 1.2
diff -u -b -B -r1.2 ffi.c
--- libffi/src/mips/ffi.c	2 Mar 2001 22:21:23 -0000	1.2
+++ libffi/src/mips/ffi.c	17 Jul 2002 16:26:45 -0000
@@ -50,7 +50,6 @@
 			  int flags)
 {
   register int i;
-  register int avn;
   register void **p_argv;
   register char *argp;
   register ffi_type **p_arg;
@@ -80,12 +79,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 +97,6 @@
 #define OFFSET sizeof(int)
 #endif      
 
-      if (avn) 
-	{
-	  avn--;
 	  z = (*p_arg)->size;
 	  if (z < sizeof(SLOT_TYPE_UNSIGNED))
 	    {
@@ -179,7 +172,6 @@
 	  p_argv++;
 	  argp += z;
 	  FIX_ARGP;
-	}
     }
   
   return;
Index: libffi/src/sparc/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/sparc/ffi.c,v
retrieving revision 1.3
diff -u -b -B -r1.3 ffi.c
--- libffi/src/sparc/ffi.c	2 Mar 2001 22:21:23 -0000	1.3
+++ libffi/src/sparc/ffi.c	17 Jul 2002 16:26:45 -0000
@@ -34,14 +34,10 @@
 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 +62,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 +112,6 @@
 	    }
 	  p_argv++;
 	  argp += z;
-	}
     }
   
   return;
Index: libffi/src/x86/ffi.c
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/x86/ffi.c,v
retrieving revision 1.6
diff -u -b -B -r1.6 ffi.c
--- libffi/src/x86/ffi.c	28 May 2002 07:11:42 -0000	1.6
+++ libffi/src/x86/ffi.c	17 Jul 2002 16:26:45 -0000
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------
-   ffi.c - Copyright (c) 1996, 1998, 1999  Cygnus Solutions
+   ffi.c - Copyright (c) 1996, 1998, 1999, 2002  Cygnus Solutions
    
    x86 Foreign Function Interface 
 
@@ -31,17 +31,484 @@
 /* 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_args64 (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 (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. For x86-64 this is
+   nothing more than computing the real size estimation for
+   cif->bytes.  */
+ffi_status
+ffi_prep_cif_machdep64 (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 (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;
+	}
+    }
+
+  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();
+	    }
+	}
+    }
+}
+
+#else /* ifdef __x86__64__ */
+
+/* Make the arguments the same as in the 64 bit one.  */
+typedef char stackLayout;
+
 /*@-exportheader@*/
-void ffi_prep_args(char *stack, extended_cif *ecif)
+void
+ffi_prep_args32 (stackLayout *stack, extended_cif *ecif)
 /*@=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)
@@ -107,12 +574,11 @@
       p_argv++;
       argp += z;
     }
-  
-  return;
 }
 
 /* Perform machine dependent cif processing */
-ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
+ffi_status
+ffi_prep_cif_machdep32 (ffi_cif *cif)
 {
   /* Set the return type flag */
   switch (cif->rtype->type)
@@ -138,6 +604,28 @@
   return FFI_OK;
 }
 
+#endif /* ifdef __x86_64__ */
+
+ffi_status
+ffi_prep_cif_machdep (ffi_cif *cif)
+{
+#ifdef __x86_64__
+  return ffi_prep_cif_machdep64 (cif);
+#else
+  return ffi_prep_cif_machdep32 (cif);
+#endif
+}
+
+void
+ffi_prep_args (stackLayout *stack, extended_cif *ecif)
+{
+#ifdef __x86_64__
+  ffi_prep_args64 (stack, ecif);
+#else
+  ffi_prep_args32 (stack, ecif);
+#endif
+}
+
 /*@-declundef@*/
 /*@-exportheader@*/
 extern void ffi_call_SYSV(void (*)(char *, extended_cif *), 
@@ -148,12 +636,24 @@
 /*@=declundef@*/
 /*@=exportheader@*/
 
+#ifdef __x86_64__
+/*@-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@*/
+#endif
+
 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;
@@ -162,7 +662,12 @@
   /* value address then we need to make one		        */
 
   if ((rvalue == NULL) && 
-      (cif->rtype->type == FFI_TYPE_STRUCT))
+#ifndef __x86_64__
+      (cif->rtype->type == FFI_TYPE_STRUCT)
+#else
+      (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0)
+#endif
+      )
     {
       /*@-sysunrecog@*/
       ecif.rvalue = alloca(cif->rtype->size);
@@ -171,21 +676,42 @@
   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:
+#ifdef __x86_64__
+      /* Calling 32bit code from 64bit is not possible  */
+      FFI_ASSERT(0);
+#else
       /*@-usedef@*/
-      ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, 
+      ffi_call_SYSV (ffi_prep_args32, &ecif, cif->bytes, 
 		    cif->flags, ecif.rvalue, fn);
       /*@=usedef@*/
+#endif
       break;
+
+    case FFI_UNIX64:
+#ifndef __x86_64__
+      /* Calling 64bit code from 32bit is not possible  */
+      FFI_ASSERT(0);
+#else
+      /*@-usedef@*/
+      ffi_call_UNIX64 (ffi_prep_args64, ffi_fill_return_value, &ecif,
+		       cif->bytes, ecif.rvalue, fn);
+      /*@=usedef@*/
+#endif
+      break;
+
     default:
       FFI_ASSERT(0);
       break;
     }
 }
 
+#ifndef __x86_64__
 
 /** private members **/
 
@@ -266,12 +792,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 ) {
@@ -443,13 +967,6 @@
  * libffi-1.20, this is not the case.)
  */
 
-extern void 
-ffi_call_SYSV(void (*)(char *, extended_cif *), 
-	      /*@out@*/ extended_cif *, 
-	      unsigned, unsigned, 
-	      /*@out@*/ unsigned *, 
-	      void (*fn)());
-
 void
 ffi_raw_call(/*@dependent@*/ ffi_cif *cif, 
 	     void (*fn)(), 
@@ -475,7 +992,6 @@
   else
     ecif.rvalue = rvalue;
     
-  
   switch (cif->abi) 
     {
     case FFI_SYSV:
@@ -484,10 +1000,18 @@
 		    cif->flags, ecif.rvalue, fn);
       /*@=usedef@*/
       break;
+
+    case FFI_UNIX64:
+      /* Calling 64bit code from 32bit is not possible  */
+      FFI_ASSERT(0);
+      break;
+
     default:
       FFI_ASSERT(0);
       break;
     }
 }
 
-#endif
+#endif /* ifdef !FFI_NO_RAW_API */
+
+#endif /* ifndef __x86_64__ */
Index: libffi/src/x86/sysv.S
===================================================================
RCS file: /cvs/gcc/gcc/libffi/src/x86/sysv.S,v
retrieving revision 1.4
diff -u -b -B -r1.4 sysv.S
--- libffi/src/x86/sysv.S	16 Jul 2001 17:10:53 -0000	1.4
+++ libffi/src/x86/sysv.S	17 Jul 2002 16:26:45 -0000
@@ -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__ */
Index: libffi/src/x86/unix64.S
===================================================================
RCS file: libffi/src/x86/unix64.S
diff -N libffi/src/x86/unix64.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ libffi/src/x86/unix64.S	17 Jul 2002 16:26:45 -0000
@@ -0,0 +1,166 @@
+/* -----------------------------------------------------------------------
+   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
+
+#endif /* __x86_64__  */


-- 

     Bo Thorsen                 |   Praestevejen 4
     Free software developer    |   5290 Marslev
     SuSE Labs                  |   Denmark



More information about the Gcc-patches mailing list