This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PowerPC] Fix 25406, rs6000_special_round_type_align
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Edelsohn <dje at watson dot ibm dot com>, pinskia at gcc dot gnu dot org
- Date: Thu, 15 Dec 2005 01:26:16 +1030
- Subject: [PowerPC] Fix 25406, rs6000_special_round_type_align
This is obvious really, but I'm doing more than just fixing the bug so
I'll ask permission to commit. Every place ROUND_TYPE_ALIGN is invoked,
the alignment values are unsigned int, so it makes sense for
rs6000_special_round_type_align to have unsigned int args.
Tested by running make "check-gcc" on powerpc64-linux with site.exp
supplying GCC_UNDER_TEST to use -malign-power, and with TYPE_MODE
in the patch below (and in ADJUST_FIELD_ALIGN) replaced with
MY_TYPE_MODE.
#define MY_TYPE_MODE(X) (!TYPE_P (X) ? abort (), SImode : TYPE_MODE (X))
ie. Effectively turning on rtl checking just here. A full
powerpc64-linux bootstrap takes forever with --enable-checking=all.
* config/rs6000/rs6000.c (rs6000_special_round_type_align): Handle
error_mark_node. Make alignment params unsigned.
* config/rs6000/rs6000-protos.h
(rs6000_special_round_type_align): Update prototype.
(rs6000_machopic_legitimize_pic_address): Remove arg names.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 108499)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -2505,21 +2505,27 @@ invalid_e500_subreg (rtx op, enum machin
field is an FP double while the FP fields remain word aligned. */
unsigned int
-rs6000_special_round_type_align (tree type, int computed, int specified)
+rs6000_special_round_type_align (tree type, unsigned int computed,
+ unsigned int specified)
{
+ unsigned int align = MAX (computed, specified);
tree field = TYPE_FIELDS (type);
/* Skip all non field decls */
while (field != NULL && TREE_CODE (field) != FIELD_DECL)
field = TREE_CHAIN (field);
- if (field == NULL || field == type
- || TYPE_MODE (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
- ? get_inner_array_type (field)
- : TREE_TYPE (field)) != DFmode)
- return MAX (computed, specified);
+ if (field != NULL && field != type)
+ {
+ type = TREE_TYPE (field);
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+
+ if (type != error_mark_node && TYPE_MODE (type) == DFmode)
+ align = MAX (align, 64);
+ }
- return MAX (MAX (computed, specified), 64);
+ return align;
}
/* Return 1 for an operand in small memory on V.4/eabi. */
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h (revision 108499)
+++ gcc/config/rs6000/rs6000-protos.h (working copy)
@@ -105,14 +105,13 @@ extern rtx rs6000_return_addr (int, rtx)
extern void rs6000_output_symbol_ref (FILE*, rtx);
extern HOST_WIDE_INT rs6000_initial_elimination_offset (int, int);
-extern rtx rs6000_machopic_legitimize_pic_address (rtx orig,
- enum machine_mode mode,
- rtx reg);
-
+extern rtx rs6000_machopic_legitimize_pic_address (rtx, enum machine_mode,
+ rtx);
#endif /* RTX_CODE */
#ifdef TREE_CODE
-extern unsigned int rs6000_special_round_type_align (tree, int, int);
+extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
+ unsigned int);
extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
tree, int, int);
extern int function_arg_boundary (enum machine_mode, tree);
--
Alan Modra
IBM OzLabs - Linux Technology Centre