This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PowerPC64 alignment of long doubles
On Tue, Sep 16, 2003 at 02:17:29PM +0930, Alan Modra wrote:
> #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
> + rs6000_adjust_field_align (FIELD, COMPUTED)
Ewww. The above unfortunately failed in libobjc, which showed up as
errors in the objc testsuite. This one's been built and tested with
all languages.
* config/rs6000/rs6000.c (rs6000_adjust_field_align): New function.
(rs6000_data_alignment): Likewise.
* config/rs6000/rs6000-protos.h (rs6000_adjust_field_align): Declare.
(rs6000_data_alignment): Declare.
* config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Use
rs6000_adjust_field_align.
(ROUND_TYPE_ALIGN): Don't define.
(DATA_ALIGNMENT): Define.
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.48
diff -u -p -r1.48 linux64.h
--- gcc/config/rs6000/linux64.h 16 Jul 2003 11:52:51 -0000 1.48
+++ gcc/config/rs6000/linux64.h 16 Sep 2003 22:38:46 -0000
@@ -202,35 +202,30 @@
/* We don't need to generate entries in .fixup. */
#undef RELOCATABLE_NEEDS_FIXUP
-/* This now supports a natural alignment mode. */
-/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
-#undef ADJUST_FIELD_ALIGN
+/* PowerPC64 Linux word-aligns FP doubles, unless -malign-natural is given. */
+#undef ADJUST_FIELD_ALIGN
+#ifndef IN_TARGET_LIBS
+#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ rs6000_adjust_field_align (FIELD, COMPUTED)
+#else
+/* Define without a target function for libobjc. */
#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
? 128 \
- : (TARGET_64BIT \
- && TARGET_ALIGN_NATURAL == 0 \
+ : (TARGET_64BIT && !TARGET_ALIGN_NATURAL \
&& TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
? get_inner_array_type (FIELD) \
: TREE_TYPE (FIELD)) == DFmode) \
? MIN ((COMPUTED), 32) \
: (COMPUTED))
+#endif
-/* AIX increases natural record alignment to doubleword if the first
- field is an FP double while the FP fields remain word aligned. */
-#undef ROUND_TYPE_ALIGN
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TARGET_ALTIVEC && TREE_CODE (STRUCT) == VECTOR_TYPE) \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
- : (TARGET_64BIT \
- && (TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TYPE_FIELDS (STRUCT) != 0 \
- && TARGET_ALIGN_NATURAL == 0 \
- && DECL_MODE (TYPE_FIELDS (STRUCT)) == DFmode) \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 64) \
- : MAX ((COMPUTED), (SPECIFIED)))
+/* Align vectors to 128 bits. Make arrays of chars word-aligned.
+ Increase alignment to doubleword if the first field of an aggregate
+ is a double. */
+#undef DATA_ALIGNMENT
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+ rs6000_data_alignment (TYPE, ALIGN)
/* Indicate that jump tables go in the text section. */
#undef JUMP_TABLES_IN_TEXT_SECTION
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.62
diff -u -p -r1.62 rs6000-protos.h
--- gcc/config/rs6000/rs6000-protos.h 12 Sep 2003 19:00:45 -0000 1.62
+++ gcc/config/rs6000/rs6000-protos.h 16 Sep 2003 22:38:46 -0000
@@ -199,6 +199,8 @@ extern int rs6000_register_move_cost (en
extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
extern bool rs6000_tls_referenced_p (rtx);
extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
+extern unsigned int rs6000_adjust_field_align (tree, unsigned int);
+extern unsigned int rs6000_data_alignment (tree, unsigned int);
/* Declare functions in rs6000-c.c */
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.519
diff -u -p -r1.519 rs6000.c
--- gcc/config/rs6000/rs6000.c 15 Sep 2003 20:23:42 -0000 1.519
+++ gcc/config/rs6000/rs6000.c 16 Sep 2003 22:38:52 -0000
@@ -14383,6 +14383,65 @@ rs6000_dwarf_register_span (rtx reg)
: gen_rtvec (2,
gen_rtx_REG (SImode, regno),
gen_rtx_REG (SImode, regno + 1200)));
+}
+
+/* PowerPC64 Linux word-aligns FP doubles and long-doubles, unless
+ -malign-natural is given. */
+unsigned int
+rs6000_adjust_field_align (tree field, unsigned int computed)
+{
+ tree t = TREE_TYPE (field);
+
+ if (TARGET_ALTIVEC && TREE_CODE (t) == VECTOR_TYPE)
+ return 128;
+
+ if (TARGET_64BIT && !TARGET_ALIGN_NATURAL)
+ {
+ if (TREE_CODE (t) == ARRAY_TYPE)
+ t = get_inner_array_type (t);
+ if (FLOAT_TYPE_P (t) && computed > 32)
+ return 32;
+ }
+ return computed;
+}
+
+/* Align vectors to 128 bits. Make arrays of chars word-aligned.
+ For PowerPC64 Linux, increase alignment to doubleword if the first
+ field of an aggregate is a double or long-double. */
+unsigned int
+rs6000_data_alignment (tree type, unsigned int align)
+{
+ if (TREE_CODE (type) == VECTOR_TYPE)
+ return TARGET_SPE_ABI ? 64 : 128;
+
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && TYPE_MODE (TREE_TYPE (type)) == QImode
+ && align < BITS_PER_WORD)
+ return BITS_PER_WORD;
+
+ if (TARGET_64BIT && !TARGET_ALIGN_NATURAL && align < 64)
+ {
+ while (1)
+ {
+ if ((TREE_CODE (type) == RECORD_TYPE
+ || TREE_CODE (type) == UNION_TYPE
+ || TREE_CODE (type) == QUAL_UNION_TYPE)
+ && TYPE_FIELDS (type) != 0
+ && TREE_CODE (TYPE_FIELDS (type)) == FIELD_DECL
+ && TREE_TYPE (TYPE_FIELDS (type)) != type)
+ type = TREE_TYPE (TYPE_FIELDS (type));
+ else if (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ else
+ break;
+ }
+
+ if (FLOAT_TYPE_P (type)
+ && TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)) >= 64)
+ return 64;
+ }
+
+ return align;
}
#include "gt-rs6000.h"
--
Alan Modra
IBM OzLabs - Linux Technology Centre