diff options
author | Alan Lawrence <alan.lawrence@arm.com> | 2015-07-06 16:58:16 +0000 |
---|---|---|
committer | Alan Lawrence <alalaw01@gcc.gnu.org> | 2015-07-06 16:58:16 +0000 |
commit | 6a47847024dcca2bc071fecd241b5b8bd33c5f7a (patch) | |
tree | 9e43e671bd10a0fffa3b2a35bbef2def72907ff2 /gcc/config | |
parent | a0f4ee6ee5336997f2a3eeaca330d225ae82ace8 (diff) | |
download | gcc-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.c | 19 |
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; } |