This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Patch Darwin 2/2] fix PPC64 ABI
- From: IainS <developer at sandoe-acoustics dot co dot uk>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: mrs at gcc dot gnu dot org, David Edelsohn <dje dot gcc at gmail dot com>
- Date: Sat, 24 Jul 2010 09:36:14 +0100
- Subject: [Patch Darwin 2/2] fix PPC64 ABI
Hi,
We need to deal with the fact that the darwin ppc64 ABI is defined by an
earlier version of gcc, with the property that it always applied
alignment
adjustments to the va-args (even for zero-sized types). The cheapest
way
to deal with this is to replicate the effect of the part of
std_gimplify_va_arg_expr ()
that carries out the align adjust, for the case of relevance.
I've made it such that there is no impact at all for non-darwin.
The impact for darwin is restricted to the single m64 ABI case.
OK for trunk and 4.5 when it re-opens?
Iain
gcc/
PR target/29090
* config/rs6000/rs6000.c (rs6000_gimplify_va_arg): Special-case the
Darwin64 ABI, for zero-sized objects.
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 162457)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -8931,6 +8995,51 @@ rs6000_gimplify_va_arg (tree valist, tree type,
gi
return build_va_arg_indirect_ref (t);
}
+#if TARGET_MACHO
+ /* We need to deal with the fact that the darwin ppc64 ABI is
defined by an
+ earlier version of gcc, with the property that it always applied
alignment
+ adjustments to the va-args (even for zero-sized types). The
cheapest way
+ to deal with this is to replicate the effect of the part of
+ std_gimplify_va_arg_expr that carries out the align adjust, for
the case
+ of relevance.
+ We don't need to check for pass-by-reference because of the test
above.
+ We can return a simplifed answer, since we know there's no
offset to add. */
+
+ if (rs6000_darwin64_abi
+ && integer_zerop (TYPE_SIZE (type)))
+ {
+ unsigned HOST_WIDE_INT align, boundary;
+ tree valist_tmp = get_initialized_tmp_var (valist, pre_p, NULL);
+ align = PARM_BOUNDARY / BITS_PER_UNIT;
+ boundary = FUNCTION_ARG_BOUNDARY (TYPE_MODE (type), type);
+ if (boundary > MAX_SUPPORTED_STACK_ALIGNMENT)
+ boundary = MAX_SUPPORTED_STACK_ALIGNMENT;
+ boundary /= BITS_PER_UNIT;
+ if (boundary > align)
+ {
+ tree t ;
+ /* This updates arg ptr by the amount that would be necessary
+ to align the zero-sized (but not zero-alignment) item. */
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+ fold_build2 (POINTER_PLUS_EXPR,
+ TREE_TYPE (valist),
+ valist_tmp, size_int (boundary - 1)));
+ gimplify_and_add (t, pre_p);
+
+ t = fold_convert (sizetype, valist_tmp);
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
+ fold_convert (TREE_TYPE (valist),
+ fold_build2 (BIT_AND_EXPR, sizetype, t,
+ size_int (-boundary))));
+ t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist, t);
+ gimplify_and_add (t, pre_p);
+ }
+ /* Since it is zero-sized there's no increment for the item
itself. */
+ valist_tmp = fold_convert (build_pointer_type (type),
valist_tmp);
+ return build_va_arg_indirect_ref (valist_tmp);
+ }
+#endif
+
if (DEFAULT_ABI != ABI_V4)
{
if (targetm.calls.split_complex_arg && TREE_CODE (type) ==
COMPLEX_TYPE)