diff mbox

PATCH: Add --with-abi= support to x86_64-*-*

Message ID 20120302180050.GA27835@intel.com
State New
Headers show

Commit Message

H.J. Lu March 2, 2012, 6 p.m. UTC
Hi,

This patch adds --with-abi= support to x86_64-*-* to configure GCC with

--with-abi=x32
--with-abi=mx32
--with-multilib-list=mx32

to set the default ABI to x32.  In i386 backend, ISA_64BIT is used to
generate i386 code or x86-64 code.  This patch adds a new bit,
ISA_X86_64 to generate 32bit x86-64 code or 64bit x86-64 code.  Now it
has

OPTION_MASK_ISA_64BIT 		32bit x86-64 code or 64bit x86-64 code
OPTION_MASK_ISA_X86_64		64bit x86-64 code
OPTION_MASK_ISA_X32		32bit x86-64 code

It also extends TARGET_BI_ARCH to support

TARGET_BI_ARCH == 1, by default, OPTION_MASK_ISA_X86_64
TARGET_BI_ARCH == 2, by default, OPTION_MASK_ISA_X32

I also added check --with-multilib-list for x86-64 Linux targets only if
multilib is enabled. 

Tested on Linux/x32.  OK for trunk?

Thanks.


H.J.
---
2012-03-02  H.J. Lu  <hongjiu.lu@intel.com>

	* config.gcc: Use i386/biarchx32.h instead of i386/biarch64.h
	for --with-abi={x32|mx32} or --with-multilib-list=mx32.
	(supported_defaults): Add abi for i[34567]86-*-* and x86_64-*-*.
	Check --with-multilib-list for x86-64 Linux targets only if
	multilib is enabled. 

	* config/i386/biarch64.h (TARGET_64BIT_DEFAULT): Add
	OPTION_MASK_ISA_X86_64.

	* config/i386/biarchx32.h: New.

	* config/i386/gnu-user64.h (SPEC_64): Support TARGET_BI_ARCH == 2.
	(SPEC_X32): Likewise.
	(MULTILIB_DEFAULTS): Likewise.

	* config/i386/i386.c (ix86_option_override_internal): Properly
	set OPTION_MASK_ISA_64BIT and OPTION_MASK_ISA_X32 as well as
	handle -m32, -m64 and -mx32.

	* config/i386/i386.h (TARGET_X86_64): New.
	(TARGET_LP64): Changed to TARGET_X86_64.

	* config/i386/i386.opt (m64): Replace ISA_64BIT with ISA_X86_64.
	(mx86-64): New.

Comments

H.J. Lu March 14, 2012, 4:22 p.m. UTC | #1
On Fri, Mar 2, 2012 at 10:00 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
> Hi,
>
> This patch adds --with-abi= support to x86_64-*-* to configure GCC with
>
> --with-abi=x32
> --with-abi=mx32
> --with-multilib-list=mx32
>
> to set the default ABI to x32.  In i386 backend, ISA_64BIT is used to
> generate i386 code or x86-64 code.  This patch adds a new bit,
> ISA_X86_64 to generate 32bit x86-64 code or 64bit x86-64 code.  Now it
> has
>
> OPTION_MASK_ISA_64BIT           32bit x86-64 code or 64bit x86-64 code
> OPTION_MASK_ISA_X86_64          64bit x86-64 code
> OPTION_MASK_ISA_X32             32bit x86-64 code
>
> It also extends TARGET_BI_ARCH to support
>
> TARGET_BI_ARCH == 1, by default, OPTION_MASK_ISA_X86_64
> TARGET_BI_ARCH == 2, by default, OPTION_MASK_ISA_X32
>
> I also added check --with-multilib-list for x86-64 Linux targets only if
> multilib is enabled.
>
> Tested on Linux/x32.  OK for trunk?
>
> Thanks.
>
>
> H.J.
> ---
> 2012-03-02  H.J. Lu  <hongjiu.lu@intel.com>
>
>        * config.gcc: Use i386/biarchx32.h instead of i386/biarch64.h
>        for --with-abi={x32|mx32} or --with-multilib-list=mx32.
>        (supported_defaults): Add abi for i[34567]86-*-* and x86_64-*-*.
>        Check --with-multilib-list for x86-64 Linux targets only if
>        multilib is enabled.
>
>        * config/i386/biarch64.h (TARGET_64BIT_DEFAULT): Add
>        OPTION_MASK_ISA_X86_64.
>
>        * config/i386/biarchx32.h: New.
>
>        * config/i386/gnu-user64.h (SPEC_64): Support TARGET_BI_ARCH == 2.
>        (SPEC_X32): Likewise.
>        (MULTILIB_DEFAULTS): Likewise.
>
>        * config/i386/i386.c (ix86_option_override_internal): Properly
>        set OPTION_MASK_ISA_64BIT and OPTION_MASK_ISA_X32 as well as
>        handle -m32, -m64 and -mx32.
>
>        * config/i386/i386.h (TARGET_X86_64): New.
>        (TARGET_LP64): Changed to TARGET_X86_64.
>
>        * config/i386/i386.opt (m64): Replace ISA_64BIT with ISA_X86_64.
>        (mx86-64): New.
>
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 99f0b47..5010739 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -486,6 +486,10 @@ fi
>
>  case ${target} in
>  i[34567]86-*-*)
> +       if test "x$with_abi" != x; then
> +               echo "This target does not support --with-abi."
> +               exit 1
> +       fi
>        if test "x$enable_cld" = xyes; then
>                tm_defines="${tm_defines} USE_IX86_CLD=1"
>        fi
> @@ -495,7 +499,24 @@ i[34567]86-*-*)
>        tm_file="vxworks-dummy.h ${tm_file}"
>        ;;
>  x86_64-*-*)
> -       tm_file="i386/biarch64.h ${tm_file}"
> +       case ${with_abi} in
> +       "")
> +               if test "x$with_multilib_list" = xmx32; then
> +                       tm_file="i386/biarchx32.h ${tm_file}"
> +               else
> +                       tm_file="i386/biarch64.h ${tm_file}"
> +               fi
> +               ;;
> +       64 | m64)
> +               tm_file="i386/biarch64.h ${tm_file}"
> +               ;;
> +       x32 | mx32)
> +               tm_file="i386/biarchx32.h ${tm_file}"
> +               ;;
> +       *)
> +               echo "Unknown ABI used in --with-abi=$with_abi"
> +               exit 1
> +       esac
>        if test "x$enable_cld" = xyes; then
>                tm_defines="${tm_defines} USE_IX86_CLD=1"
>        fi
> @@ -1304,22 +1325,24 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
>                ;;
>        esac
>        tmake_file="${tmake_file} i386/t-linux64"
> -       x86_multilibs="${with_multilib_list}"
> -       if test "$x86_multilibs" = "default"; then
> -               x86_multilibs="m64,m32"
> +       if test "x$enable_multilib" = "xyes"; then
> +               x86_multilibs="${with_multilib_list}"
> +               if test "$x86_multilibs" = "default"; then
> +                       x86_multilibs="m64,m32"
> +               fi
> +               x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'`
> +               for x86_multilib in ${x86_multilibs}; do
> +                       case ${x86_multilib} in
> +                       m32 | m64 | mx32)
> +                               TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}"
> +                               ;;
> +                       *)
> +                               echo "--with-multilib-list=${x86_with_multilib} not supported."
> +                               exit 1
> +                       esac
> +               done
> +               TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
>        fi
> -       x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'`
> -       for x86_multilib in ${x86_multilibs}; do
> -               case ${x86_multilib} in
> -               m32 | m64 | mx32)
> -                       TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}"
> -                       ;;
> -               *)
> -                       echo "--with-multilib-list=${x86_with_multilib} not supported."
> -                       exit 1
> -               esac
> -       done
> -       TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
>        ;;
>  i[34567]86-pc-msdosdjgpp*)
>        xm_file=i386/xm-djgpp.h
> @@ -3189,7 +3212,7 @@ case "${target}" in
>                ;;
>
>        i[34567]86-*-* | x86_64-*-*)
> -               supported_defaults="arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
> +               supported_defaults="abi arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
>                for which in arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64; do
>                        eval "val=\$with_$which"
>                        case ${val} in
> diff --git a/gcc/config/i386/biarch64.h b/gcc/config/i386/biarch64.h
> index 629ec98..3dc9889 100644
> --- a/gcc/config/i386/biarch64.h
> +++ b/gcc/config/i386/biarch64.h
> @@ -25,5 +25,5 @@ a copy of the GCC Runtime Library Exception along with this program;
>  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  <http://www.gnu.org/licenses/>.  */
>
> -#define TARGET_64BIT_DEFAULT OPTION_MASK_ISA_64BIT
> +#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ISA_X86_64)
>  #define TARGET_BI_ARCH 1
> diff --git a/gcc/config/i386/biarchx32.h b/gcc/config/i386/biarchx32.h
> new file mode 100644
> index 0000000..963e390
> --- /dev/null
> +++ b/gcc/config/i386/biarchx32.h
> @@ -0,0 +1,28 @@
> +/* Make configure files to produce biarch compiler defaulting to x32 mode.
> +   This file must be included very first, while the OS specific file later
> +   to overwrite otherwise wrong defaults.
> +   Copyright (C) 2012 Free Software Foundation, Inc.
> +
> +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 3, 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.
> +
> +Under Section 7 of GPL version 3, you are granted additional
> +permissions described in the GCC Runtime Library Exception, version
> +3.1, as published by the Free Software Foundation.
> +
> +You should have received a copy of the GNU General Public License and
> +a copy of the GCC Runtime Library Exception along with this program;
> +see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ISA_X32)
> +#define TARGET_BI_ARCH 2
> diff --git a/gcc/config/i386/gnu-user64.h b/gcc/config/i386/gnu-user64.h
> index 954f3b2..6f7b5de 100644
> --- a/gcc/config/i386/gnu-user64.h
> +++ b/gcc/config/i386/gnu-user64.h
> @@ -58,8 +58,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>
>  #if TARGET_64BIT_DEFAULT
>  #define SPEC_32 "m32"
> +#if TARGET_BI_ARCH == 2
> +#define SPEC_64 "m64"
> +#define SPEC_X32 "m32|m64:;"
> +#else
>  #define SPEC_64 "m32|mx32:;"
>  #define SPEC_X32 "mx32"
> +#endif
>  #else
>  #define SPEC_32 "m64|mx32:;"
>  #define SPEC_64 "m64"
> @@ -95,7 +100,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>    %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
>
>  #if TARGET_64BIT_DEFAULT
> +#if TARGET_BI_ARCH == 2
> +#define MULTILIB_DEFAULTS { "mx32" }
> +#else
>  #define MULTILIB_DEFAULTS { "m64" }
> +#endif
>  #else
>  #define MULTILIB_DEFAULTS { "m32" }
>  #endif
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index f93583f..4b6ceab 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -3097,8 +3097,45 @@ ix86_option_override_internal (bool main_args_p)
>   SUBSUBTARGET_OVERRIDE_OPTIONS;
>  #endif
>
> +  /* Turn off both OPTION_MASK_ISA_X86_64 and OPTION_MASK_ISA_X32 if
> +     TARGET_64BIT is false.  */
> +  if (!TARGET_64BIT)
> +    ix86_isa_flags &= ~(OPTION_MASK_ISA_X86_64 | OPTION_MASK_ISA_X32);
> +#ifdef TARGET_BI_ARCH
> +  else
> +    {
> +#if TARGET_BI_ARCH == 1
> +      /* When TARGET_BI_ARCH == 1, by default, OPTION_MASK_ISA_X86_64
> +        is on and OPTION_MASK_ISA_X32 is off.  We turn off
> +        OPTION_MASK_ISA_X86_64 if OPTION_MASK_ISA_X32 is turned on by
> +        -mx32.  */
> +      if (TARGET_X32)
> +       ix86_isa_flags &= ~OPTION_MASK_ISA_X86_64;
> +#else
> +      /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ISA_X32 is
> +        on and OPTION_MASK_ISA_X86_64 is off.  We turn off
> +        OPTION_MASK_ISA_X32 if OPTION_MASK_ISA_X86_64 is turned on by
> +        -m64.  */
> +      if (TARGET_X86_64)
> +       ix86_isa_flags &= ~OPTION_MASK_ISA_X32;
> +#endif
> +    }
> +#endif
> +
>   if (TARGET_X32)
> -    ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
> +    {
> +      /* Always turn on OPTION_MASK_ISA_64BIT and turn off
> +        OPTION_MASK_ISA_X86_64 for TARGET_X32.  */
> +      ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
> +      ix86_isa_flags &= ~OPTION_MASK_ISA_X86_64;
> +    }
> +  else if (TARGET_X86_64)
> +    {
> +      /* Always turn on OPTION_MASK_ISA_64BIT and turn off
> +        OPTION_MASK_ISA_X32 for TARGET_X86_64.  */
> +      ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
> +      ix86_isa_flags &= ~OPTION_MASK_ISA_X32;
> +    }
>
>   /* -fPIC is the default for x86_64.  */
>   if (TARGET_MACHO && TARGET_64BIT)
> diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
> index 7721c46..39ff36a 100644
> --- a/gcc/config/i386/i386.h
> +++ b/gcc/config/i386/i386.h
> @@ -41,6 +41,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>
>  /* Redefines for option macros.  */
>
> +#define TARGET_X86_64  OPTION_ISA_X86_64
>  #define TARGET_64BIT   OPTION_ISA_64BIT
>  #define TARGET_X32     OPTION_ISA_X32
>  #define TARGET_MMX     OPTION_ISA_MMX
> @@ -76,7 +77,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>  #define TARGET_RDRND   OPTION_ISA_RDRND
>  #define TARGET_F16C    OPTION_ISA_F16C
>
> -#define TARGET_LP64    (TARGET_64BIT && !TARGET_X32)
> +#define TARGET_LP64    TARGET_X86_64
>
>  /* SSE4.1 defines round instructions */
>  #define        OPTION_MASK_ISA_ROUND   OPTION_MASK_ISA_SSE4_1
> diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
> index 6c516e7..16e99ed 100644
> --- a/gcc/config/i386/i386.opt
> +++ b/gcc/config/i386/i386.opt
> @@ -411,13 +411,17 @@ Target RejectNegative Negative(m64) Report InverseMask(ISA_64BIT) Var(ix86_isa_f
>  Generate 32bit i386 code
>
>  m64
> -Target RejectNegative Negative(mx32) Report Mask(ISA_64BIT) Var(ix86_isa_flags) Save
> +Target RejectNegative Negative(mx32) Report Mask(ISA_X86_64) Var(ix86_isa_flags) Save
>  Generate 64bit x86-64 code
>
>  mx32
>  Target RejectNegative Negative(m32) Report Mask(ISA_X32) Var(ix86_isa_flags) Save
>  Generate 32bit x86-64 code
>
> +mx86-64
> +Target Undocumented Mask(ISA_64BIT) Var(ix86_isa_flags) Save
> +Generate i386 code or x86-64 code
> +
>  mmmx
>  Target Report Mask(ISA_MMX) Var(ix86_isa_flags) Save
>  Support MMX built-in functions


Hi,

Can any build maintainers review this patch?

Thanks.
Nathanael Nerode March 25, 2012, 9:27 p.m. UTC | #2
On 03/14/2012 12:22 PM, H.J. Lu wrote:
> On Fri, Mar 2, 2012 at 10:00 AM, H.J. Lu <hongjiu.lu@intel.com> wrote:
>> Hi,
>>
>> This patch adds --with-abi= support to x86_64-*-* to configure GCC with
>>
>> --with-abi=x32
>> --with-abi=mx32
>> --with-multilib-list=mx32
>>
>> to set the default ABI to x32.  In i386 backend, ISA_64BIT is used to
>> generate i386 code or x86-64 code.  This patch adds a new bit,
>> ISA_X86_64 to generate 32bit x86-64 code or 64bit x86-64 code.  Now it
>> has
>>
>> OPTION_MASK_ISA_64BIT           32bit x86-64 code or 64bit x86-64 code
>> OPTION_MASK_ISA_X86_64          64bit x86-64 code
>> OPTION_MASK_ISA_X32             32bit x86-64 code
>>
>> It also extends TARGET_BI_ARCH to support
>>
>> TARGET_BI_ARCH == 1, by default, OPTION_MASK_ISA_X86_64
>> TARGET_BI_ARCH == 2, by default, OPTION_MASK_ISA_X32
>>
>> I also added check --with-multilib-list for x86-64 Linux targets only if
>> multilib is enabled.
>>
>> Tested on Linux/x32.  OK for trunk?
>>
<snip>

> Hi,
> 
> Can any build maintainers review this patch?

I don't feel comfortable reviewing this, because I don't fully
comprehend the intricacy of the interactions in this area.  It *looks*
good, but I don't trust my review abilities here.  If this has been
tested *in each of the possible modes* on x86-64, then I would approve
it, but there are an awful lot of combinations, and "Tested on
Linux/x32" does not tell me whether it works correctly on all of them.

Perhaps someone else will be more able to review this by reading through
the logic tree.

> 
> Thanks.
>
diff mbox

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 99f0b47..5010739 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -486,6 +486,10 @@  fi
 
 case ${target} in
 i[34567]86-*-*)
+	if test "x$with_abi" != x; then
+		echo "This target does not support --with-abi."
+		exit 1
+	fi
 	if test "x$enable_cld" = xyes; then
 		tm_defines="${tm_defines} USE_IX86_CLD=1"
 	fi
@@ -495,7 +499,24 @@  i[34567]86-*-*)
 	tm_file="vxworks-dummy.h ${tm_file}"
 	;;
 x86_64-*-*)
-	tm_file="i386/biarch64.h ${tm_file}"
+	case ${with_abi} in
+	"")
+		if test "x$with_multilib_list" = xmx32; then
+			tm_file="i386/biarchx32.h ${tm_file}"
+		else
+			tm_file="i386/biarch64.h ${tm_file}"
+		fi
+		;;
+	64 | m64)
+		tm_file="i386/biarch64.h ${tm_file}"
+		;;
+	x32 | mx32)
+		tm_file="i386/biarchx32.h ${tm_file}"
+		;;
+	*)
+		echo "Unknown ABI used in --with-abi=$with_abi"
+		exit 1
+	esac
 	if test "x$enable_cld" = xyes; then
 		tm_defines="${tm_defines} USE_IX86_CLD=1"
 	fi
@@ -1304,22 +1325,24 @@  x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu)
 		;;
 	esac
 	tmake_file="${tmake_file} i386/t-linux64"
-	x86_multilibs="${with_multilib_list}"
-	if test "$x86_multilibs" = "default"; then
-		x86_multilibs="m64,m32"
+	if test "x$enable_multilib" = "xyes"; then
+		x86_multilibs="${with_multilib_list}"
+		if test "$x86_multilibs" = "default"; then
+			x86_multilibs="m64,m32"
+		fi
+		x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'`
+		for x86_multilib in ${x86_multilibs}; do
+			case ${x86_multilib} in
+			m32 | m64 | mx32)
+				TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}"
+				;;
+			*)
+				echo "--with-multilib-list=${x86_with_multilib} not supported."
+				exit 1
+			esac
+		done
+		TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
 	fi
-	x86_multilibs=`echo $x86_multilibs | sed -e 's/,/ /g'`
-	for x86_multilib in ${x86_multilibs}; do
-		case ${x86_multilib} in
-		m32 | m64 | mx32)
-			TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${x86_multilib}"
-			;;
-		*)
-			echo "--with-multilib-list=${x86_with_multilib} not supported."
-			exit 1
-		esac
-	done
-	TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
 	;;
 i[34567]86-pc-msdosdjgpp*)
 	xm_file=i386/xm-djgpp.h
@@ -3189,7 +3212,7 @@  case "${target}" in
 		;;
 
 	i[34567]86-*-* | x86_64-*-*)
-		supported_defaults="arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
+		supported_defaults="abi arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64"
 		for which in arch arch_32 arch_64 cpu cpu_32 cpu_64 tune tune_32 tune_64; do
 			eval "val=\$with_$which"
 			case ${val} in
diff --git a/gcc/config/i386/biarch64.h b/gcc/config/i386/biarch64.h
index 629ec98..3dc9889 100644
--- a/gcc/config/i386/biarch64.h
+++ b/gcc/config/i386/biarch64.h
@@ -25,5 +25,5 @@  a copy of the GCC Runtime Library Exception along with this program;
 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 <http://www.gnu.org/licenses/>.  */
 
-#define TARGET_64BIT_DEFAULT OPTION_MASK_ISA_64BIT
+#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ISA_X86_64)
 #define TARGET_BI_ARCH 1
diff --git a/gcc/config/i386/biarchx32.h b/gcc/config/i386/biarchx32.h
new file mode 100644
index 0000000..963e390
--- /dev/null
+++ b/gcc/config/i386/biarchx32.h
@@ -0,0 +1,28 @@ 
+/* Make configure files to produce biarch compiler defaulting to x32 mode.
+   This file must be included very first, while the OS specific file later
+   to overwrite otherwise wrong defaults.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+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 3, 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#define TARGET_64BIT_DEFAULT (OPTION_MASK_ISA_64BIT | OPTION_MASK_ISA_X32)
+#define TARGET_BI_ARCH 2
diff --git a/gcc/config/i386/gnu-user64.h b/gcc/config/i386/gnu-user64.h
index 954f3b2..6f7b5de 100644
--- a/gcc/config/i386/gnu-user64.h
+++ b/gcc/config/i386/gnu-user64.h
@@ -58,8 +58,13 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 #if TARGET_64BIT_DEFAULT
 #define SPEC_32 "m32"
+#if TARGET_BI_ARCH == 2
+#define SPEC_64 "m64"
+#define SPEC_X32 "m32|m64:;"
+#else
 #define SPEC_64 "m32|mx32:;"
 #define SPEC_X32 "mx32"
+#endif
 #else
 #define SPEC_32 "m64|mx32:;"
 #define SPEC_64 "m64"
@@ -95,7 +100,11 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
 
 #if TARGET_64BIT_DEFAULT
+#if TARGET_BI_ARCH == 2
+#define MULTILIB_DEFAULTS { "mx32" }
+#else
 #define MULTILIB_DEFAULTS { "m64" }
+#endif
 #else
 #define MULTILIB_DEFAULTS { "m32" }
 #endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index f93583f..4b6ceab 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -3097,8 +3097,45 @@  ix86_option_override_internal (bool main_args_p)
   SUBSUBTARGET_OVERRIDE_OPTIONS;
 #endif
 
+  /* Turn off both OPTION_MASK_ISA_X86_64 and OPTION_MASK_ISA_X32 if
+     TARGET_64BIT is false.  */
+  if (!TARGET_64BIT)
+    ix86_isa_flags &= ~(OPTION_MASK_ISA_X86_64 | OPTION_MASK_ISA_X32);
+#ifdef TARGET_BI_ARCH
+  else
+    {
+#if TARGET_BI_ARCH == 1
+      /* When TARGET_BI_ARCH == 1, by default, OPTION_MASK_ISA_X86_64
+	 is on and OPTION_MASK_ISA_X32 is off.  We turn off
+	 OPTION_MASK_ISA_X86_64 if OPTION_MASK_ISA_X32 is turned on by
+	 -mx32.  */
+      if (TARGET_X32)
+	ix86_isa_flags &= ~OPTION_MASK_ISA_X86_64;
+#else
+      /* When TARGET_BI_ARCH == 2, by default, OPTION_MASK_ISA_X32 is
+	 on and OPTION_MASK_ISA_X86_64 is off.  We turn off
+	 OPTION_MASK_ISA_X32 if OPTION_MASK_ISA_X86_64 is turned on by
+	 -m64.  */
+      if (TARGET_X86_64)
+	ix86_isa_flags &= ~OPTION_MASK_ISA_X32;
+#endif
+    }
+#endif
+
   if (TARGET_X32)
-    ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+    {
+      /* Always turn on OPTION_MASK_ISA_64BIT and turn off
+	 OPTION_MASK_ISA_X86_64 for TARGET_X32.  */
+      ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+      ix86_isa_flags &= ~OPTION_MASK_ISA_X86_64;
+    }
+  else if (TARGET_X86_64)
+    {
+      /* Always turn on OPTION_MASK_ISA_64BIT and turn off
+	 OPTION_MASK_ISA_X32 for TARGET_X86_64.  */
+      ix86_isa_flags |= OPTION_MASK_ISA_64BIT;
+      ix86_isa_flags &= ~OPTION_MASK_ISA_X32;
+    }
 
   /* -fPIC is the default for x86_64.  */
   if (TARGET_MACHO && TARGET_64BIT)
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7721c46..39ff36a 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -41,6 +41,7 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 
 /* Redefines for option macros.  */
 
+#define TARGET_X86_64	OPTION_ISA_X86_64
 #define TARGET_64BIT	OPTION_ISA_64BIT
 #define TARGET_X32	OPTION_ISA_X32
 #define TARGET_MMX	OPTION_ISA_MMX
@@ -76,7 +77,7 @@  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define TARGET_RDRND	OPTION_ISA_RDRND
 #define TARGET_F16C	OPTION_ISA_F16C
 
-#define TARGET_LP64	(TARGET_64BIT && !TARGET_X32)
+#define TARGET_LP64	TARGET_X86_64
 
 /* SSE4.1 defines round instructions */
 #define	OPTION_MASK_ISA_ROUND	OPTION_MASK_ISA_SSE4_1
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 6c516e7..16e99ed 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -411,13 +411,17 @@  Target RejectNegative Negative(m64) Report InverseMask(ISA_64BIT) Var(ix86_isa_f
 Generate 32bit i386 code
 
 m64
-Target RejectNegative Negative(mx32) Report Mask(ISA_64BIT) Var(ix86_isa_flags) Save
+Target RejectNegative Negative(mx32) Report Mask(ISA_X86_64) Var(ix86_isa_flags) Save
 Generate 64bit x86-64 code
 
 mx32
 Target RejectNegative Negative(m32) Report Mask(ISA_X32) Var(ix86_isa_flags) Save
 Generate 32bit x86-64 code
 
+mx86-64
+Target Undocumented Mask(ISA_64BIT) Var(ix86_isa_flags) Save
+Generate i386 code or x86-64 code
+
 mmmx
 Target Report Mask(ISA_MMX) Var(ix86_isa_flags) Save
 Support MMX built-in functions