return false;
}
-/* AIX increases natural record alignment to doubleword if the first
- field is an FP double while the FP fields remain word aligned. */
+/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints. */
+
+unsigned int
+rs6000_special_adjust_field_align (tree type, unsigned int computed)
+{
+ if (computed <= 32)
+ return computed;
+
+ /* Strip initial arrays. */
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+
+ /* If RECORD or UNION, recursively find the first field. */
+ while (AGGREGATE_TYPE_P (type))
+ {
+ tree field = TYPE_FIELDS (type);
+
+ /* Skip all non field decls */
+ while (field != NULL
+ && (TREE_CODE (field) != FIELD_DECL
+ || DECL_FIELD_ABI_IGNORED (field)))
+ field = DECL_CHAIN (field);
+
+ if (! field)
+ break;
+
+ /* A packed field does not contribute any extra alignment. */
+ if (DECL_PACKED (field))
+ return computed;
+
+ type = TREE_TYPE (field);
+
+ /* Strip arrays. */
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ }
+
+ if (! AGGREGATE_TYPE_P (type) && type != error_mark_node
+ && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode))
+ computed = MIN (computed, 32);
+
+ return computed;
+}
+
+/* AIX increases natural record alignment to doubleword if the innermost first
+ field is an FP double while the FP fields remain word aligned.
+ Only called if TYPE initially is a RECORD or UNION. */
unsigned int
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
- || DECL_FIELD_ABI_IGNORED (field)))
- field = DECL_CHAIN (field);
+ if (TYPE_PACKED (type) || align >= 64)
+ return align;
- if (field != NULL && field != type)
+ /* If RECORD or UNION, recursively find the first field. */
+ do
{
+ tree field = TYPE_FIELDS (type);
+
+ /* Skip all non field decls */
+ while (field != NULL
+ && (TREE_CODE (field) != FIELD_DECL
+ || DECL_FIELD_ABI_IGNORED (field)))
+ field = DECL_CHAIN (field);
+
+ if (! field)
+ break;
+
+ /* A packed field does not contribute any extra alignment. */
+ if (DECL_PACKED (field))
+ return align;
+
type = TREE_TYPE (field);
+
+ /* Strip arrays. */
while (TREE_CODE (type) == ARRAY_TYPE)
type = TREE_TYPE (type);
+ } while (AGGREGATE_TYPE_P (type));
- if (type != error_mark_node
- && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode))
- align = MAX (align, 64);
- }
+ if (! AGGREGATE_TYPE_P (type) && type != error_mark_node
+ && (TYPE_MODE (type) == DFmode || TYPE_MODE (type) == DCmode))
+ align = MAX (align, 64);
return align;
}
case E_OOmode:
case E_XOmode:
if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) != 0)
- error ("%qs is an opaque type, and you can't set it to other values.",
+ error ("%qs is an opaque type, and you cannot set it to other values",
(mode == OOmode) ? "__vector_pair" : "__vector_quad");
break;
else if (TREE_CODE (type) == COMPLEX_TYPE)
error ("use of %<complex%> in AltiVec types is invalid");
else if (DECIMAL_FLOAT_MODE_P (mode))
- error ("use of decimal floating point types in AltiVec types is invalid");
+ error ("use of decimal floating-point types in AltiVec types is invalid");
else if (!TARGET_VSX)
{
if (type == long_unsigned_type_node || type == long_integer_type_node)