From patchwork Sun Jun 5 19:54:41 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 98777 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 2ED0FB6FB4 for ; Mon, 6 Jun 2011 05:55:03 +1000 (EST) Received: (qmail 22273 invoked by alias); 5 Jun 2011 19:55:01 -0000 Received: (qmail 22263 invoked by uid 22791); 5 Jun 2011 19:54:59 -0000 X-SWARE-Spam-Status: No, hits=-3.2 required=5.0 tests=AWL, BAYES_50, NO_DNS_FOR_FROM, RCVD_IN_DNSWL_HI, TW_AV, TW_CX, TW_UX, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mga11.intel.com (HELO mga11.intel.com) (192.55.52.93) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 05 Jun 2011 19:54:42 +0000 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 05 Jun 2011 12:54:41 -0700 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.135]) by fmsmga002.fm.intel.com with ESMTP; 05 Jun 2011 12:54:41 -0700 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id B213C180F4F; Sun, 5 Jun 2011 12:54:41 -0700 (PDT) Date: Sun, 5 Jun 2011 12:54:41 -0700 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: Uros Bizjak Subject: PATCH [1/n]: Add initial -x32 support Message-ID: <20110605195441.GA1225@intel.com> Reply-To: "H.J. Lu" MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hi, I'd like to start submitting a series of patches to enable x32: https://sites.google.com/site/x32abi/ The GCC x32 branch is very stable. There are no unexpected failures in C, C++, Fortran and Objective C testsuites. SPEC CPU 2K/2006 compile and run correctly at -O2 and -O3. More than 90% of changes are in x86 backend. This is the first patch to support x32. By default, x32 is disabled and x32 run-time support isn't required. OK for trunk? Thanks. H.J. --- 2011-06-05 H.J. Lu * config.gcc: Support --enable-x32/--enable-ia32 for x86 Linux targets. * configure.ac: Support --enable-x32/--enable-ia32. * configure: Regenerated. * config/i386/gnu-user64.h (ASM_SPEC): Support x32. (LINK_SPEC): Likewise. (TARGET_THREAD_SSP_OFFSET): Likewise. (TARGET_THREAD_SPLIT_STACK_OFFSET): Likewise. * config/i386/i386.h (TARGET_X32): New. (TARGET_LP64): New. (LONG_TYPE_SIZE): Likewise. (POINTER_SIZE): Likewise. (POINTERS_EXTEND_UNSIGNED): Likewise. * config/i386/i386.opt (mx32): New. * config/i386/linux64.h (GLIBC_DYNAMIC_LINKERX32): New. * config/i386/t-linux64-x32: New. * config/i386/t-linuxx32: Likewise. * config/linux.h (UCLIBC_DYNAMIC_LINKERX32): New. (BIONIC_DYNAMIC_LINKERX32): Likewise. (GNU_USER_DYNAMIC_LINKERX32): Likewise. * doc/invoke.texi: Document -mx32. diff --git a/gcc/config.gcc b/gcc/config.gcc index 624129b..24b4a57 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1232,7 +1232,17 @@ i[34567]86-*-linux* | i[34567]86-*-kfreebsd*-gnu | i[34567]86-*-knetbsd*-gnu | i if test x$enable_targets = xall; then tm_file="${tm_file} i386/x86-64.h i386/gnu-user64.h i386/linux64.h" tm_defines="${tm_defines} TARGET_BI_ARCH=1" - tmake_file="${tmake_file} i386/t-linux64" + case x${enable_x32}${enable_ia32} in + xyesyes) + tmake_file="${tmake_file} i386/t-linuxx32" + ;; + xyesno) + tmake_file="${tmake_file} i386/t-linux64-x32" + ;; + *) + tmake_file="${tmake_file} i386/t-linux64" + ;; + esac need_64bit_hwint=yes need_64bit_isa=yes case X"${with_cpu}" in @@ -1270,7 +1280,18 @@ x86_64-*-linux* | x86_64-*-kfreebsd*-gnu | x86_64-*-knetbsd*-gnu) x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h i386/kfreebsd-gnu.h" ;; x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;; esac - tmake_file="${tmake_file} i386/t-linux64 i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules" + case x${enable_x32}${enable_ia32} in + xyesyes) + tmake_file="${tmake_file} i386/t-linuxx32" + ;; + xyesno) + tmake_file="${tmake_file} i386/t-linux64-x32" + ;; + *) + tmake_file="${tmake_file} i386/t-linux64" + ;; + esac + tmake_file="${tmake_file} i386/t-crtstuff i386/t-crtpc i386/t-crtfm t-dfprules" ;; i[34567]86-pc-msdosdjgpp*) xm_file=i386/xm-djgpp.h diff --git a/gcc/config/i386/gnu-user64.h b/gcc/config/i386/gnu-user64.h index 3ece0fa..b99fb13 100644 --- a/gcc/config/i386/gnu-user64.h +++ b/gcc/config/i386/gnu-user64.h @@ -65,17 +65,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif #undef ASM_SPEC -#define ASM_SPEC "%{" SPEC_32 ":--32} %{" SPEC_64 ":--64} \ +#define ASM_SPEC "%{" SPEC_32 ":%{!mx32:--32}} %{" \ + SPEC_64 ":%{!mx32:--64}} %{mx32:--x32} \ %{!mno-sse2avx:%{mavx:-msse2avx}} %{msse2avx:%{!mavx:-msse2avx}}" #undef LINK_SPEC -#define LINK_SPEC "%{" SPEC_64 ":-m elf_x86_64} %{" SPEC_32 ":-m elf_i386} \ +#define LINK_SPEC "%{" SPEC_64 ":%{!mx32:-m elf_x86_64}} %{" \ + SPEC_32 ":%{!mx32:-m elf_i386}} %{mx32:-m elf32_x86_64} \ %{shared:-shared} \ %{!shared: \ %{!static: \ %{rdynamic:-export-dynamic} \ - %{" SPEC_32 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "} \ - %{" SPEC_64 ":-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}} \ + %{" SPEC_32 ":%{!mx32:-dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \ + %{" SPEC_64 ":%{!mx32:-dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "}} \ + %{mx32:-dynamic-linker " GNU_USER_DYNAMIC_LINKERX32 "}} \ %{static:-static}}" /* Similar to standard GNU userspace, but adding -ffast-math support. */ @@ -109,10 +112,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #ifdef TARGET_LIBC_PROVIDES_SSP /* i386 glibc provides __stack_chk_guard in %gs:0x14, + x32 glibc provides it in %fs:0x18. x86_64 glibc provides it in %fs:0x28. */ -#define TARGET_THREAD_SSP_OFFSET (TARGET_64BIT ? 0x28 : 0x14) +#define TARGET_THREAD_SSP_OFFSET \ + (TARGET_64BIT ? (TARGET_X32 ? 0x18 : 0x28) : 0x14) /* We steal the last transactional memory word. */ #define TARGET_CAN_SPLIT_STACK -#define TARGET_THREAD_SPLIT_STACK_OFFSET (TARGET_64BIT ? 0x70 : 0x30) +#define TARGET_THREAD_SPLIT_STACK_OFFSET \ + (TARGET_64BIT ? (TARGET_X32 ? 0x40 : 0x70) : 0x30) #endif diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 8badcbb..f9270de 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -42,6 +42,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Redefines for option macros. */ #define TARGET_64BIT OPTION_ISA_64BIT +#define TARGET_X32 OPTION_ISA_X32 #define TARGET_MMX OPTION_ISA_MMX #define TARGET_3DNOW OPTION_ISA_3DNOW #define TARGET_3DNOW_A OPTION_ISA_3DNOW_A @@ -72,6 +73,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) /* SSE4.1 defines round instructions */ #define OPTION_MASK_ISA_ROUND OPTION_MASK_ISA_SSE4_1 @@ -638,6 +640,8 @@ enum target_cpu_default #define SHORT_TYPE_SIZE 16 #define INT_TYPE_SIZE 32 +#define LONG_TYPE_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD) +#define POINTER_SIZE (TARGET_X32 ? 32 : BITS_PER_WORD) #define LONG_LONG_TYPE_SIZE 64 #define FLOAT_TYPE_SIZE 32 #define DOUBLE_TYPE_SIZE 64 @@ -1743,6 +1747,13 @@ do { \ between pointers and any other objects of this machine mode. */ #define Pmode (TARGET_64BIT ? DImode : SImode) +/* A C expression whose value is zero if pointers that need to be extended + from being `POINTER_SIZE' bits wide to `Pmode' are sign-extended and + greater then zero if they are zero-extended and less then zero if the + ptr_extend instruction should be used. */ + +#define POINTERS_EXTEND_UNSIGNED 1 + /* A function address in a call instruction is a byte address (for indexing purposes) so give the MEM rtx a byte's mode. */ diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 21e0def..2c8fe8f 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -398,9 +398,13 @@ Target RejectNegative Negative(m64) Report InverseMask(ISA_64BIT) Var(ix86_isa_f Generate 32bit i386 code m64 -Target RejectNegative Negative(m32) Report Mask(ISA_64BIT) Var(ix86_isa_flags) Save +Target RejectNegative Negative(mx32) Report Mask(ISA_64BIT) 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 + mmmx Target Report Mask(ISA_MMX) Var(ix86_isa_flags) Save Support MMX built-in functions diff --git a/gcc/config/i386/linux64.h b/gcc/config/i386/linux64.h index 9bf7eab..78c9c8e 100644 --- a/gcc/config/i386/linux64.h +++ b/gcc/config/i386/linux64.h @@ -26,3 +26,4 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define GLIBC_DYNAMIC_LINKER32 "/lib/ld-linux.so.2" #define GLIBC_DYNAMIC_LINKER64 "/lib64/ld-linux-x86-64.so.2" +#define GLIBC_DYNAMIC_LINKERX32 "/libx32/ld-linux-x32.so.2" diff --git a/gcc/config/i386/t-linux64-x32 b/gcc/config/i386/t-linux64-x32 new file mode 100644 index 0000000..3a4d1de --- /dev/null +++ b/gcc/config/i386/t-linux64-x32 @@ -0,0 +1,34 @@ +# Copyright (C) 2011 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. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# To support x86-64 and x32 libraries, the directory structrue +# should be: +# +# /lib64 has x86-64 libraries. +# /libx32 has x32 libraries. +# +MULTILIB_OPTIONS = m64/mx32 +MULTILIB_DIRNAMES = 64 x32 +MULTILIB_OSDIRNAMES = ../lib64 ../libx32 + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib + +EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \ + crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \ + crtfastmath.o diff --git a/gcc/config/i386/t-linuxx32 b/gcc/config/i386/t-linuxx32 new file mode 100644 index 0000000..92acf91 --- /dev/null +++ b/gcc/config/i386/t-linuxx32 @@ -0,0 +1,42 @@ +# Copyright (C) 2011 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. +# +# You should have received a copy of the GNU General Public License +# along with GCC; see the file COPYING3. If not see +# . + +# On Debian, Ubuntu and other derivative distributions, the 32bit libraries +# are found in /lib32 and /usr/lib32, /lib64 and /usr/lib64 are symlinks to +# /lib and /usr/lib, while other distributions install libraries into /lib64 +# and /usr/lib64. The LSB does not enforce the use of /lib64 and /usr/lib64, +# it doesn't tell anything about the 32bit libraries on those systems. Set +# MULTILIB_OSDIRNAMES according to what is found on the target. + +# To support i386, x86-64 and x32 libraries, the directory structrue +# should be: +# +# /lib has i386 libraries. +# /lib64 has x86-64 libraries. +# /libx32 has x32 libraries. +# +MULTILIB_OPTIONS = m64/m32/mx32 +MULTILIB_DIRNAMES = 64 32 x32 +MULTILIB_OSDIRNAMES = ../lib64 $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib) ../libx32 + +LIBGCC = stmp-multilib +INSTALL_LIBGCC = install-multilib + +EXTRA_MULTILIB_PARTS=crtbegin.o crtend.o crtbeginS.o crtendS.o \ + crtbeginT.o crtprec32.o crtprec64.o crtprec80.o \ + crtfastmath.o diff --git a/gcc/config/linux.h b/gcc/config/linux.h index fc897b1..dbbeea5 100644 --- a/gcc/config/linux.h +++ b/gcc/config/linux.h @@ -77,9 +77,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" #define UCLIBC_DYNAMIC_LINKER32 "/lib/ld-uClibc.so.0" #define UCLIBC_DYNAMIC_LINKER64 "/lib/ld64-uClibc.so.0" +#define UCLIBC_DYNAMIC_LINKERX32 "/lib/ldx32-uClibc.so.0" #define BIONIC_DYNAMIC_LINKER "/system/bin/linker" #define BIONIC_DYNAMIC_LINKER32 "/system/bin/linker" #define BIONIC_DYNAMIC_LINKER64 "/system/bin/linker64" +#define BIONIC_DYNAMIC_LINKERX32 "/system/bin/linkerx32" #define GNU_USER_DYNAMIC_LINKER \ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER, UCLIBC_DYNAMIC_LINKER, \ @@ -90,6 +92,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define GNU_USER_DYNAMIC_LINKER64 \ CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKER64, UCLIBC_DYNAMIC_LINKER64, \ BIONIC_DYNAMIC_LINKER64) +#define GNU_USER_DYNAMIC_LINKERX32 \ + CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \ + BIONIC_DYNAMIC_LINKERX32) /* Determine whether the entire c99 runtime is present in the runtime library. */ diff --git a/gcc/configure.ac b/gcc/configure.ac index 5e41479..a421746 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -611,6 +611,16 @@ AC_ARG_ENABLE(multilib, [], [enable_multilib=yes]) AC_SUBST(enable_multilib) +# With x32 support +AC_ARG_ENABLE(x32, +[ --enable-x32 enable x32 library support for multiple ABIs], +[], [enable_x32=no]) + +# With ia32 support +AC_ARG_ENABLE(ia32, +[ --enable-ia32 enable ia32 library support for multiple ABIs], +[], [enable_ia32=yes]) + # Enable __cxa_atexit for C++. AC_ARG_ENABLE(__cxa_atexit, [AS_HELP_STRING([--enable-__cxa_atexit], [enable __cxa_atexit for C++])], diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index a069042..12080ca 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -609,7 +609,7 @@ Objective-C and Objective-C++ Dialects}. -mpc32 -mpc64 -mpc80 -mstackrealign @gol -momit-leaf-frame-pointer -mno-red-zone -mno-tls-direct-seg-refs @gol -mcmodel=@var{code-model} -mabi=@var{name} @gol --m32 -m64 -mlarge-data-threshold=@var{num} @gol +-m32 -m64 -mx32 -mlarge-data-threshold=@var{num} @gol -msse2avx -mfentry -m8bit-idiv @gol -mavx256-split-unaligned-load -mavx256-split-unaligned-store} @@ -12824,14 +12824,18 @@ on AMD x86-64 processors in 64-bit environments. @table @gcctabopt @item -m32 @itemx -m64 +@itemx -mx32 @opindex m32 @opindex m64 +@opindex mx32 Generate code for a 32-bit or 64-bit environment. -The 32-bit environment sets int, long and pointer to 32 bits and +The -m32 option sets int, long and pointer to 32 bits and generates code that runs on any i386 system. -The 64-bit environment sets int to 32 bits and long and pointer -to 64 bits and generates code for AMD's x86-64 architecture. For -darwin only the -m64 option turns off the @option{-fno-pic} and +The -m64 option sets int to 32 bits and long and pointer +to 64 bits and generates code for AMD's x86-64 architecture. +The -mx32 option sets int, long and pointer to 32 bits and generates +code for AMD's x86-64 architecture. +For darwin only the -m64 option turns off the @option{-fno-pic} and @option{-mdynamic-no-pic} options. @item -mno-red-zone