#! /bin/sh -e
 
# DP: biarch patches for i386/x86_64
 
dir=
if [ $# -eq 3 -a "$2" = '-d' ]; then
    pdir="-d $3"
    dir="$3/"
elif [ $# -ne 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
case "$1" in
    -patch)
        patch $pdir -f --no-backup-if-mismatch -p1 < $0
        cd ${dir}libjava && autoconf
        ;;
    -unpatch)
        patch $pdir -f --no-backup-if-mismatch -R -p1 < $0
        #rm ${dir}gcc/configure
        ;;
    *)
        echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
        exit 1
esac
exit 0


diff -Nurp src.orig/gcc/config/i386/biarch.h src/gcc/config/i386/biarch.h
--- src.orig/gcc/config/i386/biarch.h	1969-12-31 19:00:00.000000000 -0500
+++ src/gcc/config/i386/biarch.h	2004-08-03 22:01:00.000000000 -0400
@@ -0,0 +1,26 @@
+/* Make configure files to produce biarch compiler defaulting to 32bit mode.
+   This file must be included very first, while the OS specific file later
+   to overwrite otherwise wrong defaults. 
+   Copyright (C) 2001, 2004 Free Software Foundation, Inc.
+   Contributed by Bo Thorsen <bo@suse.de>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#define TARGET_64BIT_DEFAULT 0
+#define TARGET_BI_ARCH 1
+#define DRIVER_SELF_SPECS "%{m64:%{!mtune:-mtune=x86-64}}"
diff -Nurp src.orig/gcc/config/i386/linux.h src/gcc/config/i386/linux.h
--- src.orig/gcc/config/i386/linux.h	2004-08-03 22:07:21.000000000 -0400
+++ src/gcc/config/i386/linux.h	2004-08-03 22:01:00.000000000 -0400
@@ -182,6 +182,7 @@ Boston, MA 02111-1307, USA.  */
       }									\
   } while (0)
 
+#ifdef __i386__
 /* Used by crtstuff.c to initialize the base of data-relative relocations.
    These are GOT relative on x86, so return the pic register.  */
 #ifdef __PIC__
@@ -201,6 +202,7 @@ Boston, MA 02111-1307, USA.  */
 	   "addl\t$_GLOBAL_OFFSET_TABLE_+[.-.LPR%=],%0"			\
 	   : "=d"(BASE))
 #endif
+#endif
 
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
diff -Nurp src.orig/gcc/config/i386/linux64.h src/gcc/config/i386/linux64.h
--- src.orig/gcc/config/i386/linux64.h	2004-08-03 22:07:21.000000000 -0400
+++ src/gcc/config/i386/linux64.h	2004-08-03 22:09:04.000000000 -0400
@@ -19,8 +19,11 @@ along with GCC; see the file COPYING.  I
 the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
+#ifndef TARGET_VERSION
 #define TARGET_VERSION fprintf (stderr, " (x86-64 Linux/ELF)");
+#endif
 
+#undef TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS()				\
   do								\
     {								\
@@ -55,6 +58,7 @@ Boston, MA 02111-1307, USA.  */
    done.  */
 
 #undef	LINK_SPEC
+#if TARGET_64BIT_DEFAULT
 #define LINK_SPEC "%{!m32:-m elf_x86_64} %{m32:-m elf_i386} \
   %{shared:-shared} \
   %{!shared: \
@@ -63,8 +67,22 @@ Boston, MA 02111-1307, USA.  */
       %{m32:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
       %{!m32:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
     %{static:-static}}"
+#else
+#define LINK_SPEC "%{m64:-m elf_x86_64} %{!m64:-m elf_i386} \
+  %{shared:-shared} \
+  %{!shared: \
+    %{!static: \
+      %{rdynamic:-export-dynamic} \
+      %{!m64:%{!dynamic-linker:-dynamic-linker /lib/ld-linux.so.2}} \
+      %{m64:%{!dynamic-linker:-dynamic-linker /lib64/ld-linux-x86-64.so.2}}} \
+    %{static:-static}}"
+#endif
 
+#if TARGET_64BIT_DEFAULT
 #define MULTILIB_DEFAULTS { "m64" }
+#else
+#define MULTILIB_DEFAULTS { "m32" }
+#endif
 
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
@@ -79,6 +97,7 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/ucontext.h>
 #endif
 
+#undef MD_FALLBACK_FRAME_STATE_FOR
 #ifdef __x86_64__
 #define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
   do {									\
diff -Nurp src.orig/gcc/config/i386/x86-64.h src/gcc/config/i386/x86-64.h
--- src.orig/gcc/config/i386/x86-64.h	2004-08-03 22:07:21.000000000 -0400
+++ src/gcc/config/i386/x86-64.h	2004-08-03 22:01:00.000000000 -0400
@@ -47,9 +47,15 @@ Boston, MA 02111-1307, USA.  */
 #undef CC1_SPEC
 #define CC1_SPEC "%(cc1_cpu) %{profile:-p}"
 
+#if TARGET_64BIT_DEFAULT
 #undef ASM_SPEC
 #define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} \
  %{Wa,*:%*} %{m32:--32} %{!m32:--64}"
+#else
+#undef ASM_SPEC
+#define ASM_SPEC "%{v:-V} %{Qy:} %{!Qn:-Qy} %{n} %{T} %{Ym,*} %{Yd,*} \
+ %{Wa,*:%*} %{!m64:--32} %{m64:--64}"
+#endif
 
 #define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
   asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
diff -Nurp src.orig/gcc/config.gcc src/gcc/config.gcc
--- src.orig/gcc/config.gcc	2004-08-03 22:07:21.000000000 -0400
+++ src/gcc/config.gcc	2004-08-03 22:07:53.000000000 -0400
@@ -991,8 +991,10 @@ i[34567]86-*-linux*libc1)	# Intel 80386'
 i[34567]86-*-linux*)	# Intel 80386's running GNU/Linux
 			# with ELF format using glibc 2
 			# aka GNU/Linux C library 6
-	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h i386/linux.h"
-	tmake_file="t-slibgcc-elf-ver t-linux i386/t-crtstuff"
+	tm_file="i386/biarch.h ${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h \
+		 svr4.h linux.h i386/linux.h i386/x86-64.h i386/linux64.h"
+	tmake_file="t-slibgcc-elf-ver t-linux i386/t-linux64"
+	need_64bit_hwint=yes
 	;;
 x86_64-*-linux*)
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h \
diff -Nurp src.orig/libffi/Makefile.am src/libffi/Makefile.am
--- src.orig/libffi/Makefile.am	2004-08-03 22:07:21.000000000 -0400
+++ src/libffi/Makefile.am	2004-08-03 22:01:00.000000000 -0400
@@ -90,7 +90,7 @@ noinst_LTLIBRARIES = libffi_convenience.
 
 TARGET_SRC_MIPS_IRIX = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
 TARGET_SRC_MIPS_LINUX = src/mips/ffi.c src/mips/o32.S
-TARGET_SRC_X86 = src/x86/ffi.c src/x86/sysv.S
+TARGET_SRC_X86 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
 TARGET_SRC_X86_WIN32 = src/x86/ffi.c src/x86/win32.S
 TARGET_SRC_SPARC = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
 TARGET_SRC_ALPHA = src/alpha/ffi.c src/alpha/osf.S
diff -Nurp src.orig/libffi/Makefile.in src/libffi/Makefile.in
--- src.orig/libffi/Makefile.in	2004-08-03 22:07:21.000000000 -0400
+++ src/libffi/Makefile.in	2004-08-03 22:01:00.000000000 -0400
@@ -174,7 +174,7 @@ noinst_LTLIBRARIES = libffi_convenience.
 
 TARGET_SRC_MIPS_IRIX = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
 TARGET_SRC_MIPS_LINUX = src/mips/ffi.c src/mips/o32.S
-TARGET_SRC_X86 = src/x86/ffi.c src/x86/sysv.S
+TARGET_SRC_X86 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
 TARGET_SRC_X86_WIN32 = src/x86/ffi.c src/x86/win32.S
 TARGET_SRC_SPARC = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
 TARGET_SRC_ALPHA = src/alpha/ffi.c src/alpha/osf.S
@@ -301,7 +301,7 @@ libffi_convenience_la_LIBADD = 
 @MIPS_IRIX_TRUE@src/mips/n32.lo
 @X86_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @X86_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
-@X86_TRUE@src/x86/ffi.lo src/x86/sysv.lo
+@X86_TRUE@src/x86/ffi64.lo src/x86/unix64.lo src/x86/ffi.lo src/x86/sysv.lo
 @IA64_TRUE@libffi_convenience_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @IA64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @IA64_TRUE@src/ia64/ffi.lo src/ia64/unix.lo
@@ -357,8 +357,8 @@ libffi_la_LIBADD = 
 @MIPS_IRIX_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @MIPS_IRIX_TRUE@src/mips/ffi.lo src/mips/o32.lo src/mips/n32.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
+@X86_TRUE@src/raw_api.lo src/java_raw_api.lo src/x86/ffi64.lo src/x86/unix64.lo \
+@X86_TRUE@src/x86/ffi.lo src/x86/sysv.lo
 @IA64_TRUE@libffi_la_OBJECTS =  src/debug.lo src/prep_cif.lo \
 @IA64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
 @IA64_TRUE@src/ia64/ffi.lo src/ia64/unix.lo
diff -Nurp src.orig/libffi/Makefile.am src/libffi/Makefile.am
--- src.orig/libffi/src/x86/ffitarget.h	2004-08-03 22:07:21.000000000 -0400
+++ src/libffi/src/x86/ffitarget.h	2004-08-03 22:01:00.000000000 -0400
@@ -33,6 +33,11 @@
 #define X86
 #endif
 
+#if defined (X86) && defined (__x86_64__)
+#undef X86
+#define X86_64
+#endif
+
 /* ---- Generic type definitions ----------------------------------------- */
 
 #ifndef LIBFFI_ASM
diff -Nurp src.orig/libjava/configure.in src/libjava/configure.in
--- src.orig/libjava/configure.in	2004-08-03 22:07:21.000000000 -0400
+++ src/libjava/configure.in	2004-08-03 22:01:00.000000000 -0400
@@ -674,16 +674,17 @@ else
        AC_DEFINE(HAVE_DLADDR, 1, [Define if you have dladdr()])
      fi
    ])
-   if test x"$build" = x"$host"; then
-     AC_CHECK_FILES(/proc/self/exe, [
-       AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])])
-   else
-     case $host in
-     *-linux*)
-       AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])
-       ;;
-     esac
-   fi
+   case $host in
+   *-linux*)
+     AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])
+     ;;
+   *)
+     if test x"$build" = x"$host"; then
+       AC_CHECK_FILES(/proc/self/exe, [
+         AC_DEFINE(HAVE_PROC_SELF_EXE, 1, [Define if you have /proc/self/exe])])
+     fi
+     ;;
+   esac
 
    AM_ICONV
    AM_LC_MESSAGES
diff -Nurp src.orig/libjava/include/i386-signal.h src/libjava/include/i386-signal.h
--- src.orig/libjava/include/i386-signal.h	2004-08-03 22:07:21.000000000 -0400
+++ src/libjava/include/i386-signal.h	2004-08-03 22:01:00.000000000 -0400
@@ -11,6 +11,10 @@ details.  */
 
 
 #ifndef JAVA_SIGNAL_H
+#ifdef __x86_64__
+#include "x86_64-signal.h"
+#else
+
 #define JAVA_SIGNAL_H 1
 
 #include <signal.h>
@@ -163,6 +167,6 @@ while (0)  
  * Also, there is at the present time no unwind info in the
  * linuxthreads library's signal handlers and so we can't unwind
  * through them anyway.  */
-
+#endif /* ! __x86_64__ */
 #endif /* JAVA_SIGNAL_H */
   
diff -Nurp src.orig/libjava/sysdep/i386/locks.h src/libjava/sysdep/i386/locks.h
--- src.orig/libjava/sysdep/i386/locks.h	2004-08-03 22:07:21.000000000 -0400
+++ src/libjava/sysdep/i386/locks.h	2004-08-03 22:01:00.000000000 -0400
@@ -24,10 +24,17 @@ compare_and_swap(volatile obj_addr_t *ad
 					      obj_addr_t new_val) 
 {
   char result;
-  __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
-	      : "=m"(*addr), "=q"(result)
+#ifdef __x86_64__
+  __asm__ __volatile__("lock; cmpxchgq %2, %0; setz %1"
+	      : "=m"(*(addr)), "=q"(result)
 	      : "r" (new_val), "a"(old), "m"(*addr)
 	      : "memory");
+#else
+  __asm__ __volatile__("lock; cmpxchgl %2, %0; setz %1"
+		       : "=m"(*(addr)), "=q"(result)
+		       : "r" (new_val), "a"(old), "m"(*addr)
+		       : "memory");
+#endif
   return (bool) result;
 }
 
diff -Nurp src.orig/libtool.m4 src/libtool.m4
--- src.orig/libtool.m4	2004-08-03 22:07:21.000000000 -0400
+++ src/libtool.m4	2004-08-03 22:01:00.000000000 -0400
@@ -189,14 +189,14 @@ ia64-*-hpux*)
   rm -rf conftest*
   ;;
 
-x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
+i[[3456]]86-*-linux*|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case "`/usr/bin/file conftest.o`" in
     *32-bit*)
       case $host in
-        x86_64-*linux*)
+        i[[3456]]86-*-linux*|x86_64-*linux*)
           LD="${LD-ld} -m elf_i386"
           ;;
         ppc64-*linux*|powerpc64-*linux*)
@@ -212,7 +212,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*li
       ;;
     *64-bit*)
       case $host in
-        x86_64-*linux*)
+        i[[3456]]86-*-linux*|x86_64-*linux*)
           LD="${LD-ld} -m elf_x86_64"
           ;;
         ppc*-*linux*|powerpc*-*linux*)
--- src/config-ml.in.orig	2004-08-04 16:21:33.000000000 -0400
+++ src/config-ml.in	2004-08-04 16:26:39.000000000 -0400
@@ -296,6 +296,31 @@
 	  done
 	fi
 	;;
+i[34567]86-*-*)
+	case " $multidirs " in
+	*" 64 "*)
+	  ac_configure_args="${ac_configure_args} --host=x86_64-linux"
+	  # Setting $host this late is a hack.  Some directories can't
+	  # handle it, so disable them for now.
+	  old_multidirs="${multidirs}"
+	  multidirs=""
+	  for x in ${old_multidirs}; do
+	    case "$x" in
+	    *64* ) case ${ml_realsrcdir} in
+			*"libstdc++-v3" ) multidirs="${multidirs} ${x}" ;;
+			*"libf2c" ) multidirs="${multidirs} ${x}" ;;
+			*"libobjc" ) multidirs="${multidirs} ${x}" ;;
+			*"libiberty" ) multidirs="${multidirs} ${x}" ;;
+			*"zlib" ) multidirs="${multidirs} ${x}" ;;
+			*) : ;;
+		     esac 
+		     ;;
+	    *) multidirs="${multidirs} ${x}" ;;
+	  esac
+	  done
+	  ;;
+	esac
+	;;
 m68*-*-*)
 	if [ x$enable_softfloat = xno ]
 	then
@@ -858,9 +883,20 @@
 	fi
     fi
 
+    ml_configure_args=
+    for arg in ${ac_configure_args}
+    do
+      case $arg in
+      *CC=*)  ml_configure_args=${ml_config_env} ;;
+      *CXX=*) ml_configure_args=${ml_config_env} ;;
+      *GCJ=*) ml_configure_args=${ml_config_env} ;;
+      *) ;;
+      esac
+    done
+
     if eval ${ml_config_env} ${ml_config_shell} ${ml_recprog} \
 	--with-multisubdir=${ml_dir} --with-multisrctop=${multisrctop} \
-	${ac_configure_args} ${ml_srcdiroption} ; then
+	${ac_configure_args} ${ml_configure_args} ${ml_srcdiroption} ; then
       true
     else
       exit 1
