aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/rs6000
diff options
context:
space:
mode:
authorRong Xu <xur@google.com>2014-08-06 17:50:42 -0700
committerRong Xu <xur@google.com>2014-08-06 17:50:42 -0700
commitf1c18afafc2b321465ae6b07ede127095942d7dc (patch)
tree812093eebfa8510367718c12c02f7da03c0e73bf /gcc-4.9/gcc/config/rs6000
parent38a8aecfb882072900434499696b5c32a2274515 (diff)
downloadtoolchain_gcc-f1c18afafc2b321465ae6b07ede127095942d7dc.tar.gz
toolchain_gcc-f1c18afafc2b321465ae6b07ede127095942d7dc.tar.bz2
toolchain_gcc-f1c18afafc2b321465ae6b07ede127095942d7dc.zip
[gcc-4.9] Merge svn r213650 from google/gcc-4_9 branch
Merge svn r213650 from google/gcc-4_9 branch. Tested with arm,x86,mips,arm64,x86_64,mips64 build in liunux/windows. Change-Id: I0c07f67d516074172aa393003eee664d01f2e0f2
Diffstat (limited to 'gcc-4.9/gcc/config/rs6000')
-rw-r--r--gcc-4.9/gcc/config/rs6000/freebsd64.h2
-rw-r--r--gcc-4.9/gcc/config/rs6000/linux64.h2
-rw-r--r--gcc-4.9/gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc-4.9/gcc/config/rs6000/rs6000.c111
-rw-r--r--gcc-4.9/gcc/config/rs6000/sysv4.h18
5 files changed, 124 insertions, 10 deletions
diff --git a/gcc-4.9/gcc/config/rs6000/freebsd64.h b/gcc-4.9/gcc/config/rs6000/freebsd64.h
index 4f678f6f4..1f3ef199e 100644
--- a/gcc-4.9/gcc/config/rs6000/freebsd64.h
+++ b/gcc-4.9/gcc/config/rs6000/freebsd64.h
@@ -367,7 +367,7 @@ extern int dot_symbols;
/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */
#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED)) \
? 128 \
: (TARGET_64BIT \
&& TARGET_ALIGN_NATURAL == 0 \
diff --git a/gcc-4.9/gcc/config/rs6000/linux64.h b/gcc-4.9/gcc/config/rs6000/linux64.h
index 52c233b7d..a198af186 100644
--- a/gcc-4.9/gcc/config/rs6000/linux64.h
+++ b/gcc-4.9/gcc/config/rs6000/linux64.h
@@ -246,7 +246,7 @@ extern int dot_symbols;
/* PowerPC64 Linux word-aligns FP doubles when -malign-power is given. */
#undef ADJUST_FIELD_ALIGN
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED)) \
? 128 \
: (TARGET_64BIT \
&& TARGET_ALIGN_NATURAL == 0 \
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000-protos.h b/gcc-4.9/gcc/config/rs6000/rs6000-protos.h
index 785f6ce1b..067a74aa6 100644
--- a/gcc-4.9/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc-4.9/gcc/config/rs6000/rs6000-protos.h
@@ -155,6 +155,7 @@ extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool, rtx);
#ifdef TREE_CODE
extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align);
+extern bool rs6000_special_adjust_field_align_p (tree, unsigned int);
extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
unsigned int);
extern unsigned int darwin_rs6000_special_round_type_align (tree, unsigned int,
diff --git a/gcc-4.9/gcc/config/rs6000/rs6000.c b/gcc-4.9/gcc/config/rs6000/rs6000.c
index bf67e7298..d7cbc6cde 100644
--- a/gcc-4.9/gcc/config/rs6000/rs6000.c
+++ b/gcc-4.9/gcc/config/rs6000/rs6000.c
@@ -5871,6 +5871,34 @@ rs6000_data_alignment (tree type, unsigned int align, enum data_align how)
return align;
}
+/* Previous GCC releases forced all vector types to have 16-byte alignment. */
+
+bool
+rs6000_special_adjust_field_align_p (tree field, unsigned int computed)
+{
+ if (TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE)
+ {
+ if (computed != 128)
+ {
+ static bool warned;
+ if (!warned && warn_psabi)
+ {
+ warned = true;
+ inform (input_location,
+ "the layout of aggregates containing vectors with"
+ " %d-byte alignment will change in a future GCC release",
+ computed / BITS_PER_UNIT);
+ }
+ }
+ /* GCC 4.8/4.9 Note: To avoid any ABI change on a release branch, we
+ keep the special treatment of vector types, but warn if there will
+ be differences in future GCC releases. */
+ return true;
+ }
+
+ return false;
+}
+
/* AIX increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
@@ -9180,14 +9208,51 @@ rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
|| (type && TREE_CODE (type) == VECTOR_TYPE
&& int_size_in_bytes (type) >= 16))
return 128;
- else if (((TARGET_MACHO && rs6000_darwin64_abi)
- || DEFAULT_ABI == ABI_ELFv2
- || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
- && mode == BLKmode
- && type && TYPE_ALIGN (type) > 64)
+
+ /* Aggregate types that need > 8 byte alignment are quadword-aligned
+ in the parameter area in the ELFv2 ABI, and in the AIX ABI unless
+ -mcompat-align-parm is used. */
+ if (((DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm)
+ || DEFAULT_ABI == ABI_ELFv2)
+ && type && TYPE_ALIGN (type) > 64)
+ {
+ /* "Aggregate" means any AGGREGATE_TYPE except for single-element
+ or homogeneous float/vector aggregates here. We already handled
+ vector aggregates above, but still need to check for float here. */
+ bool aggregate_p = (AGGREGATE_TYPE_P (type)
+ && !SCALAR_FLOAT_MODE_P (elt_mode));
+
+ /* We used to check for BLKmode instead of the above aggregate type
+ check. Warn when this results in any difference to the ABI. */
+ if (aggregate_p != (mode == BLKmode))
+ {
+ static bool warned;
+ if (!warned && warn_psabi)
+ {
+ warned = true;
+ inform (input_location,
+ "the ABI of passing aggregates with %d-byte alignment"
+ " will change in a future GCC release",
+ (int) TYPE_ALIGN (type) / BITS_PER_UNIT);
+ }
+ }
+
+ /* GCC 4.8/4.9 Note: To avoid any ABI change on a release branch, we
+ keep using the BLKmode check, but warn if there will be differences
+ in future GCC releases. */
+ if (mode == BLKmode)
+ return 128;
+ }
+
+ /* Similar for the Darwin64 ABI. Note that for historical reasons we
+ implement the "aggregate type" check as a BLKmode check here; this
+ means certain aggregate types are in fact not aligned. */
+ if (TARGET_MACHO && rs6000_darwin64_abi
+ && mode == BLKmode
+ && type && TYPE_ALIGN (type) > 64)
return 128;
- else
- return PARM_BOUNDARY;
+
+ return PARM_BOUNDARY;
}
/* The offset in words to the start of the parameter save area. */
@@ -10225,6 +10290,7 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
rtx r, off;
int i, k = 0;
unsigned long n_fpreg = (GET_MODE_SIZE (elt_mode) + 7) >> 3;
+ int fpr_words;
/* Do we also need to pass this argument in the parameter
save area? */
@@ -10253,6 +10319,37 @@ rs6000_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off);
}
+ /* If there were not enough FPRs to hold the argument, the rest
+ usually goes into memory. However, if the current position
+ is still within the register parameter area, a portion may
+ actually have to go into GPRs.
+
+ Note that it may happen that the portion of the argument
+ passed in the first "half" of the first GPR was already
+ passed in the last FPR as well.
+
+ For unnamed arguments, we already set up GPRs to cover the
+ whole argument in rs6000_psave_function_arg, so there is
+ nothing further to do at this point.
+
+ GCC 4.8/4.9 Note: This was implemented incorrectly in earlier
+ GCC releases. To avoid any ABI change on the release branch,
+ we retain that original implementation here, but warn if we
+ encounter a case where the ABI will change in the future. */
+ fpr_words = (i * GET_MODE_SIZE (elt_mode)) / (TARGET_32BIT ? 4 : 8);
+ if (i < n_elts && align_words + fpr_words < GP_ARG_NUM_REG
+ && cum->nargs_prototype > 0)
+ {
+ static bool warned;
+ if (!warned && warn_psabi)
+ {
+ warned = true;
+ inform (input_location,
+ "the ABI of passing homogeneous float aggregates"
+ " will change in a future GCC release");
+ }
+ }
+
return rs6000_finish_function_arg (mode, rvec, k);
}
else if (align_words < GP_ARG_NUM_REG)
diff --git a/gcc-4.9/gcc/config/rs6000/sysv4.h b/gcc-4.9/gcc/config/rs6000/sysv4.h
index afbd2892e..7cc543319 100644
--- a/gcc-4.9/gcc/config/rs6000/sysv4.h
+++ b/gcc-4.9/gcc/config/rs6000/sysv4.h
@@ -292,7 +292,7 @@ do { \
/* An expression for the alignment of a structure field FIELD if the
alignment computed in the usual way is COMPUTED. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
+ (rs6000_special_adjust_field_align_p ((FIELD), (COMPUTED)) \
? 128 : COMPUTED)
#undef BIGGEST_FIELD_ALIGNMENT
@@ -962,3 +962,19 @@ ncrtn.o%s"
#define TARGET_USES_SYSV4_OPT 1
#undef DBX_REGISTER_NUMBER
+
+/* Link -lasan early on the command line. For -static-libasan, don't link
+ it for -shared link, the executable should be compiled with -static-libasan
+ in that case, and for executable link link with --{,no-}whole-archive around
+ it to force everything into the executable. And similarly for -ltsan. */
+#if defined(HAVE_LD_STATIC_DYNAMIC)
+#undef LIBASAN_EARLY_SPEC
+#define LIBASAN_EARLY_SPEC "%{!shared:libasan_preinit%O%s} " \
+ "%{static-libasan:%{!shared:" \
+ LD_STATIC_OPTION " --whole-archive -lasan --no-whole-archive " \
+ LD_DYNAMIC_OPTION "}}%{!static-libasan:-lasan}"
+#undef LIBTSAN_EARLY_SPEC
+#define LIBTSAN_EARLY_SPEC "%{static-libtsan:%{!shared:" \
+ LD_STATIC_OPTION " --whole-archive -ltsan --no-whole-archive " \
+ LD_DYNAMIC_OPTION "}}%{!static-libtsan:-ltsan}"
+#endif