aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorAlan Lawrence <alan.lawrence@arm.com>2015-07-06 16:58:16 +0000
committerAlan Lawrence <alalaw01@gcc.gnu.org>2015-07-06 16:58:16 +0000
commit6a47847024dcca2bc071fecd241b5b8bd33c5f7a (patch)
tree9e43e671bd10a0fffa3b2a35bbef2def72907ff2 /gcc/config
parenta0f4ee6ee5336997f2a3eeaca330d225ae82ace8 (diff)
downloadgcc-6a47847024dcca2bc071fecd241b5b8bd33c5f7a.zip
gcc-6a47847024dcca2bc071fecd241b5b8bd33c5f7a.tar.gz
gcc-6a47847024dcca2bc071fecd241b5b8bd33c5f7a.tar.bz2
[ARM] PR/65956 AAPCS update for alignment attribute
gcc/: PR target/65956 * config/arm/arm.c (arm_needs_doubleword_align): Drop any outer alignment attribute, exploring one level down for records and arrays. gcc/testsuite/: * gcc.target/arm/aapcs/align1.c: New. * gcc.target/arm/aapcs/align_rec1.c: New. * gcc.target/arm/aapcs/align2.c: New. * gcc.target/arm/aapcs/align_rec2.c: New. * gcc.target/arm/aapcs/align3.c: New. * gcc.target/arm/aapcs/align_rec3.c: New. * gcc.target/arm/aapcs/align4.c: New. * gcc.target/arm/aapcs/align_rec4.c: New. * gcc.target/arm/aapcs/align_vararg1.c: New. * gcc.target/arm/aapcs/align_vararg2.c: New. From-SVN: r225465
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/arm/arm.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c2dce95..9d697af 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6161,8 +6161,23 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype,
static bool
arm_needs_doubleword_align (machine_mode mode, const_tree type)
{
- return (GET_MODE_ALIGNMENT (mode) > PARM_BOUNDARY
- || (type && TYPE_ALIGN (type) > PARM_BOUNDARY));
+ if (!type)
+ return PARM_BOUNDARY < GET_MODE_ALIGNMENT (mode);
+
+ /* Scalar and vector types: Use natural alignment, i.e. of base type. */
+ if (!AGGREGATE_TYPE_P (type))
+ return TYPE_ALIGN (TYPE_MAIN_VARIANT (type)) > PARM_BOUNDARY;
+
+ /* Array types: Use member alignment of element type. */
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ return TYPE_ALIGN (TREE_TYPE (type)) > PARM_BOUNDARY;
+
+ /* Record/aggregate types: Use greatest member alignment of any member. */
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
+ if (DECL_ALIGN (field) > PARM_BOUNDARY)
+ return true;
+
+ return false;
}