diff options
author | Alan Modra <amodra@gmail.com> | 2013-06-18 10:43:27 +0930 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2013-06-18 10:43:27 +0930 |
commit | 69eff9da489b0e8bbf4d1795afc3d5e014a6d025 (patch) | |
tree | 0d9e3458992c697ff455a39c7ed4855d830499db /gcc/config/rs6000 | |
parent | 2058cd6cb36b0601debfd45c5bf5cf79053cdebc (diff) | |
download | gcc-69eff9da489b0e8bbf4d1795afc3d5e014a6d025.zip gcc-69eff9da489b0e8bbf4d1795afc3d5e014a6d025.tar.gz gcc-69eff9da489b0e8bbf4d1795afc3d5e014a6d025.tar.bz2 |
rs6000.h (enum data_align): New.
* config/rs6000/rs6000.h (enum data_align): New.
(LOCAL_ALIGNMENT, DATA_ALIGNMENT): Use rs6000_data_alignment.
(DATA_ABI_ALIGNMENT): Define.
(CONSTANT_ALIGNMENT): Correct comment.
* config/rs6000/rs6000-protos.h (rs6000_data_alignment): Declare.
* config/rs6000/rs6000.c (rs6000_data_alignment): New function.
From-SVN: r200159
Diffstat (limited to 'gcc/config/rs6000')
-rw-r--r-- | gcc/config/rs6000/rs6000-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 42 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 38 |
3 files changed, 59 insertions, 22 deletions
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 02836ec..25bad1b 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -141,6 +141,7 @@ extern int rs6000_loop_align (rtx); #endif /* RTX_CODE */ #ifdef TREE_CODE +extern unsigned int rs6000_data_alignment (tree, unsigned int, enum data_align); 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/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 55273ab..f531730 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5384,6 +5384,48 @@ invalid_e500_subreg (rtx op, enum machine_mode mode) return false; } +/* Return alignment of TYPE. Existing alignment is ALIGN. HOW + selects whether the alignment is abi mandated, optional, or + both abi and optional alignment. */ + +unsigned int +rs6000_data_alignment (tree type, unsigned int align, enum data_align how) +{ + if (how != align_opt) + { + if (TREE_CODE (type) == VECTOR_TYPE) + { + if ((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (type))) + || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (type)))) + { + if (align < 64) + align = 64; + } + else if (align < 128) + align = 128; + } + else if (TARGET_E500_DOUBLE + && TREE_CODE (type) == REAL_TYPE + && TYPE_MODE (type) == DFmode) + { + if (align < 64) + align = 64; + } + } + + if (how != align_abi) + { + if (TREE_CODE (type) == ARRAY_TYPE + && TYPE_MODE (TREE_TYPE (type)) == QImode) + { + if (align < BITS_PER_WORD) + align = BITS_PER_WORD; + } + } + + return align; +} + /* AIX increases natural record alignment to doubleword if the first field is an FP double while the FP fields remain word aligned. */ diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 021e72a..633d789 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -813,12 +813,6 @@ extern unsigned rs6000_pointer_size; /* No data type wants to be aligned rounder than this. */ #define BIGGEST_ALIGNMENT 128 -/* A C expression to compute the alignment for a variables in the - local store. TYPE is the data type, and ALIGN is the alignment - that the object would ordinarily have. */ -#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ - DATA_ALIGNMENT (TYPE, ALIGN) - /* Alignment of field after `int : 0' in a structure. */ #define EMPTY_FIELD_BOUNDARY 32 @@ -828,8 +822,15 @@ extern unsigned rs6000_pointer_size; /* A bit-field declared as `int' forces `int' alignment for the struct. */ #define PCC_BITFIELD_TYPE_MATTERS 1 -/* Make strings word-aligned so strcpy from constants will be faster. - Make vector constants quadword aligned. */ +enum data_align { align_abi, align_opt, align_both }; + +/* A C expression to compute the alignment for a variables in the + local store. TYPE is the data type, and ALIGN is the alignment + that the object would ordinarily have. */ +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ + rs6000_data_alignment (TYPE, ALIGN, align_both) + +/* Make strings word-aligned so strcpy from constants will be faster. */ #define CONSTANT_ALIGNMENT(EXP, ALIGN) \ (TREE_CODE (EXP) == STRING_CST \ && (STRICT_ALIGNMENT || !optimize_size) \ @@ -837,21 +838,14 @@ extern unsigned rs6000_pointer_size; ? BITS_PER_WORD \ : (ALIGN)) -/* Make arrays of chars word-aligned for the same reasons. - Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to +/* Make arrays of chars word-aligned for the same reasons. */ +#define DATA_ALIGNMENT(TYPE, ALIGN) \ + rs6000_data_alignment (TYPE, ALIGN, align_opt) + +/* Align vectors to 128 bits. Align SPE vectors and E500 v2 doubles to 64 bits. */ -#define DATA_ALIGNMENT(TYPE, ALIGN) \ - (TREE_CODE (TYPE) == VECTOR_TYPE \ - ? (((TARGET_SPE && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) \ - || (TARGET_PAIRED_FLOAT && PAIRED_VECTOR_MODE (TYPE_MODE (TYPE)))) \ - ? 64 : 128) \ - : ((TARGET_E500_DOUBLE \ - && TREE_CODE (TYPE) == REAL_TYPE \ - && TYPE_MODE (TYPE) == DFmode) \ - ? 64 \ - : (TREE_CODE (TYPE) == ARRAY_TYPE \ - && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ - && (ALIGN) < BITS_PER_WORD) ? BITS_PER_WORD : (ALIGN))) +#define DATA_ABI_ALIGNMENT(TYPE, ALIGN) \ + rs6000_data_alignment (TYPE, ALIGN, align_abi) /* Nonzero if move instructions will actually fail to work when given unaligned data. */ |