aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/rs6000
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2013-06-18 10:43:27 +0930
committerAlan Modra <amodra@gcc.gnu.org>2013-06-18 10:43:27 +0930
commit69eff9da489b0e8bbf4d1795afc3d5e014a6d025 (patch)
tree0d9e3458992c697ff455a39c7ed4855d830499db /gcc/config/rs6000
parent2058cd6cb36b0601debfd45c5bf5cf79053cdebc (diff)
downloadgcc-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.h1
-rw-r--r--gcc/config/rs6000/rs6000.c42
-rw-r--r--gcc/config/rs6000/rs6000.h38
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. */