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)