This patch adds the configuration changes to the AArch64 GCC to support:

* -milp32 and -mlp64 options in the compiler and the driver
* multilib of ilp32 and/or lp64 libraries
* differentiation of basic types in the compiler backend

The patch enables --with-multilib-list configuration option for specifying the list of library flavors to enable; the default value is "mlp64" and can be overridden by --with-abi to "milp32".

It also enables --with-abi for setting the default model in the compiler. Its default value is "mlp64" unless --with-multilib-list is explicitly specified with "milp32", in which case it defaults to "milp32".

In the backend, two target flags are introduced: TARGET_ILP32 and TARGET_LP64. They are set by -milp32 and -mlp64 respectively, exclusive to each other. The default setting is via the option variable aarch64_pmodel_flags, which defaults to TARGET_DEFAULT_PMODEL, which is further defined in biarchlp64.h or biarchilp32.h depending which header file is included.

                          biarchlp64.h         biarchilp32.h
TARGET_DEFAULT_PMODEL     OPTION_MASK_LP64     OPTION_MASK_ILP32
TARGET_PMODEL             1                    2

TARGET_ILP32 and TARGET_LP64 are implicitly defined as:

#define TARGET_ILP32 ((aarch64_pmodel_flags & OPTION_MASK_ILP32) != 0)
#define TARGET_LP64 ((aarch64_pmodel_flags & OPTION_MASK_LP64) != 0)

Note that the multilib support in the Linux toolchain is suppressed deliberately.

OK for the trunk?

Thanks,
Yufeng


gcc/
        * config.gcc (aarch64*-*-*): Support --with-abi.
        (aarch64*-*-elf): Support --with-multilib-list.
        (aarch64*-*-linux*): Likewise.
        (supported_defaults): Add abi to aarch64*-*-*.
        * configure.ac: Mention AArch64 for --with-multilib-list.
        * configure: Re-generated.
        * config/aarch64/biarchilp32.h: New file.
        * config/aarch64/biarchlp64.h: New file.
        * config/aarch64/aarch64-elf.h (SPEC_LP64): New define.
        (SPEC_ILP32): Ditto.
        (ASM_SPEC): Update to SPEC_LP64 and SPEC_ILP32.
        (MULTILIB_DEFAULTS): New define.
        * config/aarch64/aarch64-elf-raw.h (EMUL_SUFFIX): New define.
        (LINK_SPEC): Change to depend on SPEC_LP64 and SPEC_ILP32 and also
        to use EMUL_SUFFIX.
        * config/aarch64/aarch64.h (LONG_TYPE_SIZE): Change to depend on
        TARGET_ILP32.
        (POINTER_SIZE): New define.
        (POINTERS_EXTEND_UNSIGNED): Ditto.
        * config/aarch64/aarch64.c (initialize_aarch64_programming_model):
        New declaration and definition.
        (aarch64_override_options): Call the new function.
        * config/aarch64/aarch64.opt (aarch64_pmodel_flags): New.
        (milp32, mlp64): New.
        * config/aarch64/t-aarch64 (comma): New define.
        (MULTILIB_OPTIONS): Ditto.
        (MULTILIB_DIRNAMES): Ditto.
        * config/aarch64/t-aarch64-linux (MULTIARCH_DIRNAME): New define.

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 0ad7217..c8af44e 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -497,6 +497,26 @@ then
 fi
 
 case ${target} in
+aarch64*-*-*)
+	case ${with_abi} in
+	"")
+		if test "x$with_multilib_list" = xmilp32; then
+			tm_file="aarch64/biarchilp32.h ${tm_file}"
+		else
+			tm_file="aarch64/biarchlp64.h ${tm_file}"
+		fi
+		;;
+	lp64 | mlp64)
+		tm_file="aarch64/biarchlp64.h ${tm_file}"
+		;;
+	ilp32 | milp32)
+		tm_file="aarch64/biarchilp32.h ${tm_file}"
+		;;
+	*)
+		echo "Unknown ABI used in --with-abi=$with_abi"
+		exit 1
+	esac
+	;;
 i[34567]86-*-*)
 	if test "x$with_abi" != x; then
 		echo "This target does not support --with-abi."
@@ -827,6 +847,32 @@ aarch64*-*-elf)
 		tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
 		;;
 	esac
+	aarch64_multilibs="${with_multilib_list}"
+	if test "$aarch64_multilibs" = "default"; then
+		case ${with_abi} in
+		ilp32 | milp32)
+			aarch64_multilibs="milp32"
+			;;
+		*)
+			# TODO: Change to build both flavours by default when
+			# the ILP32 support is mature enough.
+			# aarch64_multilibs="mlp64,milp32"
+			aarch64_multilibs="mlp64"
+			;;
+		esac
+	fi
+	aarch64_multilibs=`echo $aarch64_multilibs | sed -e 's/,/ /g'`
+	for aarch64_multilib in ${aarch64_multilibs}; do
+		case ${aarch64_multilib} in
+		milp32 | mlp64 )
+			TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${aarch64_multilib}"
+			;;
+		*)
+			echo "--with-multilib-list=${aarch64_multilib} not supported."
+			exit 1
+		esac
+	done
+	TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
 	;;
 aarch64*-*-linux*)
 	tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h"
@@ -837,6 +883,32 @@ aarch64*-*-linux*)
 		tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
 		;;
 	esac
+	aarch64_multilibs="${with_multilib_list}"
+	if test "$aarch64_multilibs" = "default"; then
+		case ${with_abi} in
+		ilp32 | milp32)
+			aarch64_multilibs="milp32"
+			;;
+		*)
+			# TODO: Change to build both flavours by default when
+			# the ILP32 support is mature enough.
+			# aarch64_multilibs="mlp64,milp32"
+			aarch64_multilibs="mlp64"
+			;;
+		esac
+	fi
+	aarch64_multilibs=`echo $aarch64_multilibs | sed -e 's/,/ /g'`
+	for aarch64_multilib in ${aarch64_multilibs}; do
+		case ${aarch64_multilib} in
+		milp32 | mlp64 )
+			TM_MULTILIB_CONFIG="${TM_MULTILIB_CONFIG},${aarch64_multilib}"
+			;;
+		*)
+			echo "--with-multilib-list=${aarch64_multilib} not supported."
+			exit 1
+		esac
+	done
+	TM_MULTILIB_CONFIG=`echo $TM_MULTILIB_CONFIG | sed 's/^,//'`
 	;;
 alpha*-*-linux*)
 	tm_file="elfos.h ${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h glibc-stdint.h"
@@ -3147,7 +3219,7 @@ fi
 supported_defaults=
 case "${target}" in
 	aarch64*-*-*)
-		supported_defaults="cpu arch"
+		supported_defaults="abi cpu arch"
 		for which in cpu arch; do
 
 			eval "val=\$with_$which"
diff --git a/gcc/config/aarch64/aarch64-elf-raw.h b/gcc/config/aarch64/aarch64-elf-raw.h
index 1cd0155..4bef8a6 100644
--- a/gcc/config/aarch64/aarch64-elf-raw.h
+++ b/gcc/config/aarch64/aarch64-elf-raw.h
@@ -25,8 +25,17 @@
 #define STARTFILE_SPEC " crti%O%s crtbegin%O%s crt0%O%s"
 #define ENDFILE_SPEC " crtend%O%s crtn%O%s"
 
+#if TARGET_BIG_ENDIAN_DEFAULT == 1
+#define EMUL_SUFFIX "b"
+#else
+#define EMUL_SUFFIX ""
+#endif
+
 #ifndef LINK_SPEC
-#define LINK_SPEC "%{mbig-endian:-EB} %{mlittle-endian:-EL} -X"
+#define LINK_SPEC "\
+%{mbig-endian:-EB} %{mlittle-endian:-EL} -X \
+%{" SPEC_LP64 ":-m aarch64elf" EMUL_SUFFIX "} \
+%{" SPEC_ILP32 ":-m aarch64elf32" EMUL_SUFFIX "}"
 #endif
 
 #endif /* GCC_AARCH64_ELF_RAW_H */
diff --git a/gcc/config/aarch64/aarch64-elf.h b/gcc/config/aarch64/aarch64-elf.h
index 3f3ae52..ff1a730 100644
--- a/gcc/config/aarch64/aarch64-elf.h
+++ b/gcc/config/aarch64/aarch64-elf.h
@@ -111,12 +111,24 @@
 
 #define GLOBAL_ASM_OP "\t.global\t"
 
+#if TARGET_PMODEL == 2
+/* Default ILP32.  */
+#define SPEC_LP64  "mlp64"
+#define SPEC_ILP32 "mlp64:;"
+#else
+/* Default LP64.  */
+#define SPEC_LP64  "milp32:;"
+#define SPEC_ILP32 "milp32"
+#endif
+
 #ifndef ASM_SPEC
 #define ASM_SPEC "\
 %{mbig-endian:-EB} \
 %{mlittle-endian:-EL} \
 %{mcpu=*:-mcpu=%*} \
-%{march=*:-march=%*}"
+%{march=*:-march=%*} \
+%{" SPEC_ILP32 ":-milp32} \
+%{" SPEC_LP64 ":-mlp64}"
 #endif
 
 #undef TYPE_OPERAND_FMT
@@ -128,4 +140,10 @@
 /* Stabs debug not required.  */
 #undef DBX_DEBUGGING_INFO
 
+#if TARGET_PMODEL == 2
+#define MULTILIB_DEFAULTS { "milp32" }
+#else
+#define MULTILIB_DEFAULTS { "mlp64" }
+#endif
+
 #endif /* GCC_AARCH64_ELF_H */
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 527b00d..9d60225 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -4715,6 +4715,8 @@ aarch64_memory_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
 
 static void initialize_aarch64_code_model (void);
 
+static void initialize_aarch64_programming_model (void);
+
 /* Parse the architecture extension string.  */
 
 static void
@@ -4931,6 +4933,8 @@ aarch64_override_options (void)
 
   initialize_aarch64_code_model ();
 
+  initialize_aarch64_programming_model ();
+
   aarch64_build_bitmask_table ();
 
   /* This target defaults to strict volatile bitfields.  */
@@ -5016,6 +5020,29 @@ initialize_aarch64_code_model (void)
      aarch64_cmodel = aarch64_cmodel_var;
 }
 
+/* A checking mechanism for the implementation of the various programming
+   models.  */
+
+static void
+initialize_aarch64_programming_model (void)
+{
+#if TARGET_PMODEL == 1
+  /* When TARGET_PMODEL == 1, by default, OPTION_MASK_LP64
+     is on and OPTION_MASK_ILP32 is off.  We turn off
+     OPTION_MASK_LP64 if OPTION_MASK_ILP32 is turned on by
+     -milp32.  */
+  if (TARGET_ILP32)
+    aarch64_pmodel_flags &= ~OPTION_MASK_LP64;
+#else
+  /* When TARGET_PMODEL == 2, by default, OPTION_MASK_ILP32 is
+     on and OPTION_MASK_LP64 is off.  We turn off
+     OPTION_MASK_ILP32 if OPTION_MASK_LP64 is turned on by
+     -mlp64.  */
+  if (TARGET_LP64)
+    aarch64_pmodel_flags &= ~OPTION_MASK_ILP32;
+#endif
+}
+
 /* Return true if SYMBOL_REF X binds locally.  */
 
 static bool
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index a08797b..cfdb120 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -95,7 +95,9 @@
 
 #define INT_TYPE_SIZE		32
 
-#define LONG_TYPE_SIZE		64	/* XXX This should be an option */
+#define LONG_TYPE_SIZE		(TARGET_ILP32 ? 32 : 64)
+
+#define POINTER_SIZE		(TARGET_ILP32 ? 32 : 64)
 
 #define LONG_LONG_TYPE_SIZE	64
 
@@ -704,7 +706,18 @@ do {									     \
 
 #define NO_FUNCTION_CSE	1
 
+/* Specify the machine mode that the hardware addresses have.
+   After generation of rtl, the compiler makes no further distinction
+   between pointers and any other objects of this machine mode.  */
 #define Pmode		DImode
+
+/* 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
+
+/* Mode of a function address in a call instruction (for indexing purposes).  */
 #define FUNCTION_MODE	Pmode
 
 #define SELECT_CC_MODE(OP, X, Y)	aarch64_select_cc_mode (OP, X, Y)
diff --git a/gcc/config/aarch64/aarch64.opt b/gcc/config/aarch64/aarch64.opt
index 3518248..cf97c8d 100644
--- a/gcc/config/aarch64/aarch64.opt
+++ b/gcc/config/aarch64/aarch64.opt
@@ -59,6 +59,10 @@ const char *aarch64_cpu_string
 Variable
 const char *aarch64_tune_string
 
+; Bit flags that specify the programming model we are compiling with.
+Variable
+HOST_WIDE_INT aarch64_pmodel_flags = TARGET_DEFAULT_PMODEL
+
 mbig-endian
 Target Report RejectNegative Mask(BIG_END)
 Assume target CPU is configured as big endian
@@ -98,3 +102,11 @@ Target RejectNegative Joined Var(aarch64_cpu_string)
 mtune=
 Target RejectNegative Joined Var(aarch64_tune_string)
 -mtune=CPU	Optimize for CPU
+
+milp32
+Target Report RejectNegative Negative(mlp64) Mask(ILP32) Var(aarch64_pmodel_flags) Save
+Generate code using the ILP32 data model
+
+mlp64
+Target Report RejectNegative Negative(milp32) Mask(LP64) Var(aarch64_pmodel_flags) Save
+Generate code using the LP64 data model
diff --git a/gcc/config/aarch64/biarchilp32.h b/gcc/config/aarch64/biarchilp32.h
new file mode 100644
index 0000000..ad87840
--- /dev/null
+++ b/gcc/config/aarch64/biarchilp32.h
@@ -0,0 +1,29 @@
+/* Make configure files to produce biarch compiler defaulting to ilp32 ABI.
+   This file must be included very first, while the OS specific file later
+   to overwrite otherwise wrong defaults. 
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+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_DEFAULT_PMODEL OPTION_MASK_ILP32
+#define TARGET_PMODEL 2
diff --git a/gcc/config/aarch64/biarchlp64.h b/gcc/config/aarch64/biarchlp64.h
new file mode 100644
index 0000000..87a592b
--- /dev/null
+++ b/gcc/config/aarch64/biarchlp64.h
@@ -0,0 +1,29 @@
+/* Make configure files to produce biarch compiler defaulting to ilp64 ABI.
+   This file must be included very first, while the OS specific file later
+   to overwrite otherwise wrong defaults. 
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   Contributed by ARM Ltd.
+
+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_DEFAULT_PMODEL OPTION_MASK_LP64
+#define TARGET_PMODEL 1
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index 4c265eb..d300b12 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -34,3 +34,7 @@ aarch64-builtins.o: $(srcdir)/config/aarch64/aarch64-builtins.c $(CONFIG_H) \
   $(srcdir)/config/aarch64/aarch64-simd-builtins.def
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/aarch64/aarch64-builtins.c
+
+comma=,
+MULTILIB_OPTIONS    = $(subst $(comma),/,$(TM_MULTILIB_CONFIG))
+MULTILIB_DIRNAMES   = $(patsubst m%, %, $(subst /, ,$(MULTILIB_OPTIONS)))
diff --git a/gcc/config/aarch64/t-aarch64-linux b/gcc/config/aarch64/t-aarch64-linux
index a7a0a88..ca1525e 100644
--- a/gcc/config/aarch64/t-aarch64-linux
+++ b/gcc/config/aarch64/t-aarch64-linux
@@ -23,3 +23,9 @@ LIB1ASMFUNCS = _aarch64_sync_cache_range
 
 AARCH_BE = $(if $(findstring TARGET_BIG_ENDIAN_DEFAULT=1, $(tm_defines)),_be)
 MULTILIB_OSDIRNAMES = .=../lib64$(call if_multiarch,:aarch64$(AARCH_BE)-linux-gnu)
+MULTIARCH_DIRNAME = $(call if_multiarch,aarch64$(AARCH_BE)-linux-gnu)
+
+# Disable the multilib for linux-gnu targets for the time being; focus
+# on the baremetal targets.
+MULTILIB_OPTIONS    =
+MULTILIB_DIRNAMES   =
diff --git a/gcc/configure.ac b/gcc/configure.ac
index eff48d6..6bad7d5 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -839,7 +839,7 @@ esac],
 [enable_languages=c])
 
 AC_ARG_WITH(multilib-list,
-[AS_HELP_STRING([--with-multilib-list], [select multilibs (SH and x86-64 only)])],
+[AS_HELP_STRING([--with-multilib-list], [select multilibs (AArch64, SH and x86-64 only)])],
 :,
 with_multilib_list=default)
 

Reply via email to