This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Patch Darwin 2/2] fix PPC64 ABI
On 24 Jul 2010, at 16:10, David Edelsohn wrote:
On Sat, Jul 24, 2010 at 11:06 AM, IainS
<developer@sandoe-acoustics.co.uk> wrote:
Mike, David,
On 24 Jul 2010, at 10:45, Mike Stump wrote:
Also, as memory serves there is one more fix from last year that
fixes the
abi so that it is self consistent from last year. I think it
fixes a
failing struct abi testcase as I recall.
OK, I found it (the struct hack is needed after all, in fact).
FWIW, The fail of gcc.target/powerpc/ppc64-abi-1.c is misleading -
I think
that is a situation where the test-case needs some tweaking.
The darwin64-abi.c check from 4.2.1 (or LLVM) is the right thing to
use...
... but I have no idea what license it is covered by and,
therefore,
whether we can import it... so for now I'm using it outside the gcc
tree.
====
There will follow a part #3 (I can hack a fix... now I need to find
the
Right Way).
Part 3 will apply on top of parts 1 & 2 .. so those patches stand.
Darwin-specific patches approved by Mike are fine with me
part 1 is r162567
part 2 (as amended with Nathan's suggestion, copied below) is r162568
(changelog for #2 is 162569)
cheers,
Iain
amended part 2/2
/* 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 (TARGET_MACHO
&& 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);
}