structure ABI fixes for powerpc-darwin
Geoffrey Keating
gkeating@apple.com
Mon Dec 4 23:17:00 GMT 2006
[I found this mail trapped in my mail system. I don't know if it ever
got sent, so am re-sending it to make sure.]
This patch fixes the many darwin-abi testcases that are XFAILed on
mainline. It also fixes libffi to match the Darwin ABI, and fixes a
few XFAILed testcases there.
It does, however, break more of the objc.dg-struct-layout-encoding-1
testcases; the existing behaviour of that code is preserved, but now
the testcases can see that they're further away from the real ABI than
they used to be.
I'm running a bootstrap and testrun on powerpc-darwin8, and will queue
for 4.3 if that's successful.
--
- Geoffrey Keating <geoffk@apple.com>
===File ~/patches/gcc-rs6000-darwinabi.patch================
Index: gcc/ChangeLog
2006-10-16 Geoffrey Keating <geoffk@apple.com>
PR 23067
* c-decl.c (start_struct): Don't create self-containing
structures.
* config/rs6000/rs6000.c (darwin_rs6000_special_round_type_align):
New.
* config/rs6000/rs6000-protos.h
(darwin_rs6000_special_round_type_align): New.
* config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Rewrite.
(ROUND_TYPE_ALIGN): Use darwin_rs6000_special_round_type_align.
Index: gcc/testsuite/ChangeLog
2006-10-16 Geoffrey Keating <geoffk@apple.com>
PR 23067
* gcc.target/powerpc/darwin-abi-3.c: Remove XFAIL.
* gcc.target/powerpc/darwin-abi-6.c: Remove XFAIL.
* gcc.target/powerpc/darwin-abi-7.c: Remove XFAIL.
* gcc.target/powerpc/darwin-abi-8.c: Remove XFAIL.
* gcc.target/powerpc/darwin-abi-9.c: Remove XFAIL.
* gcc.target/powerpc/darwin-abi-10.c: Remove XFAIL.
* gcc.target/powerpc/darwin-abi-11.c: Remove XFAIL.
Index: libobjc/ChangeLog
2006-10-16 Geoffrey Keating <geoffk@apple.com>
* encoding.c (darwin_rs6000_special_round_type_align): New.
Index: libffi/ChangeLog
2006-10-16 Geoffrey Keating <geoffk@apple.com>
* src/powerpc/ffi_darwin.c (darwin_adjust_aggregate_sizes): New.
(ffi_prep_cif_machdep): Call darwin_adjust_aggregate_sizes for
Darwin.
* testsuite/libffi.call/nested_struct4.c: Remove Darwin XFAIL.
* testsuite/libffi.call/nested_struct6.c: Remove Darwin XFAIL.
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-Wno-long-long" } */
struct A
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-Wno-long-long" } */
struct b
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-Wno-long-long" } */
struct a
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-Wno-long-long" } */
struct f
{
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-Wno-long-long" } */
struct b
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
/* { dg-options "-Wno-long-long" } */
struct b
Index: gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c (revision 118903)
+++ gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c (working copy)
@@ -1,6 +1,5 @@
/* { dg-do compile { target powerpc*-*-darwin* } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-xfail-if "" { powerpc*-*-darwin* } } */
struct c
{
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c (revision 118903)
+++ gcc/c-decl.c (working copy)
@@ -5280,12 +5280,15 @@
error ("nested redefinition of %<union %E%>", name);
else
error ("nested redefinition of %<struct %E%>", name);
+ /* Don't create structures that contain themselves. */
+ ref = NULL_TREE;
}
}
- else
+
+ /* Otherwise create a forward-reference just so the tag is in scope. */
+
+ if (ref == NULL_TREE || TREE_CODE (ref) != code)
{
- /* Otherwise create a forward-reference just so the tag is in scope. */
-
ref = make_node (code);
pushtag (name, ref);
}
Index: gcc/config/rs6000/darwin.h
===================================================================
--- gcc/config/rs6000/darwin.h (revision 118903)
+++ gcc/config/rs6000/darwin.h (working copy)
@@ -367,26 +367,28 @@
/* Fix for emit_group_load (): force large constants to be pushed via regs. */
#define ALWAYS_PUSH_CONSTS_USING_REGS_P 1
-/* This now supports a natural alignment mode */
-/* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints. */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
- (TARGET_ALIGN_NATURAL ? (COMPUTED) : \
- (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
- ? get_inner_array_type (FIELD) \
- : TREE_TYPE (FIELD)) == DFmode \
- ? MIN ((COMPUTED), 32) : (COMPUTED)))
+/* Compute field alignment. This is similar to the version of the
+ macro in the Apple version of GCC, except that version supports
+ 'mac68k' alignment, and that version uses the computed alignment
+ always for the first field of a structure. The first-field
+ behaviour is dealt with by
+ darwin_rs6000_special_round_type_align. */
+#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+ (TARGET_ALIGN_NATURAL ? (COMPUTED) \
+ : (COMPUTED) == 128 ? 128 \
+ : MIN ((COMPUTED), 32))
/* Darwin increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
-#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
- ((TREE_CODE (STRUCT) == RECORD_TYPE \
- || TREE_CODE (STRUCT) == UNION_TYPE \
- || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
- && TARGET_ALIGN_NATURAL == 0 \
- ? rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
- : (TREE_CODE (STRUCT) == VECTOR_TYPE \
- && ALTIVEC_VECTOR_MODE (TYPE_MODE (STRUCT))) \
- ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
+#define ROUND_TYPE_ALIGN(STRUCT, COMPUTED, SPECIFIED) \
+ ((TREE_CODE (STRUCT) == RECORD_TYPE \
+ || TREE_CODE (STRUCT) == UNION_TYPE \
+ || TREE_CODE (STRUCT) == QUAL_UNION_TYPE) \
+ && TARGET_ALIGN_NATURAL == 0 \
+ ? darwin_rs6000_special_round_type_align (STRUCT, COMPUTED, SPECIFIED) \
+ : (TREE_CODE (STRUCT) == VECTOR_TYPE \
+ && ALTIVEC_VECTOR_MODE (TYPE_MODE (STRUCT))) \
+ ? MAX (MAX ((COMPUTED), (SPECIFIED)), 128) \
: MAX ((COMPUTED), (SPECIFIED)))
/* Specify padding for the last element of a block move between
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 118903)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -2591,7 +2591,7 @@
return false;
}
-/* Darwin, AIX increases natural record alignment to doubleword if the first
+/* AIX increases natural record alignment to doubleword if the first
field is an FP double while the FP fields remain word aligned. */
unsigned int
@@ -2618,6 +2618,37 @@
return align;
}
+/* Darwin increases record alignment to the natural alignment of
+ the first field. */
+
+unsigned int
+darwin_rs6000_special_round_type_align (tree type, unsigned int computed,
+ unsigned int specified)
+{
+ unsigned int align = MAX (computed, specified);
+
+ if (TYPE_PACKED (type))
+ return align;
+
+ /* Find the first field, looking down into aggregates. */
+ do {
+ tree field = TYPE_FIELDS (type);
+ /* Skip all non field decls */
+ while (field != NULL && TREE_CODE (field) != FIELD_DECL)
+ field = TREE_CHAIN (field);
+ if (! field)
+ break;
+ type = TREE_TYPE (field);
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ } while (AGGREGATE_TYPE_P (type));
+
+ if (! AGGREGATE_TYPE_P (type) && type != error_mark_node)
+ align = MAX (align, TYPE_ALIGN (type));
+
+ return align;
+}
+
/* Return 1 for an operand in small memory on V.4/eabi. */
int
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
--- gcc/config/rs6000/rs6000-protos.h (revision 118903)
+++ gcc/config/rs6000/rs6000-protos.h (working copy)
@@ -114,6 +114,8 @@
#ifdef TREE_CODE
extern unsigned int rs6000_special_round_type_align (tree, unsigned int,
unsigned int);
+extern unsigned int darwin_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);
Index: libobjc/encoding.c
===================================================================
--- libobjc/encoding.c (revision 118903)
+++ libobjc/encoding.c (working copy)
@@ -120,6 +120,10 @@
: TREE_TYPE (_fields)) == DFmode) \
? MAX (MAX (COMPUTED, SPECIFIED), 64) \
: MAX (COMPUTED, SPECIFIED));})
+/* FIXME: The word 'fixme' is insufficient to explain the wrong-ness
+ of this next macro definition. */
+#define darwin_rs6000_special_round_type_align(S,C,S2) \
+ rs6000_special_round_type_align(S,C,S2)
/*
return the size of an object specified by type
Index: libffi/src/powerpc/ffi_darwin.c
===================================================================
--- libffi/src/powerpc/ffi_darwin.c (revision 118903)
+++ libffi/src/powerpc/ffi_darwin.c (working copy)
@@ -1,11 +1,12 @@
/* -----------------------------------------------------------------------
- ffi.c - Copyright (c) 1998 Geoffrey Keating
+ ffi_darwin.c
- PowerPC Foreign Function Interface
+ Copyright (C) 1998 Geoffrey Keating
+ Copyright (C) 2001 John Hornkvist
+ Copyright (C) 2002, 2006 Free Software Foundation, Inc.
- Darwin ABI support (c) 2001 John Hornkvist
- AIX ABI support (c) 2002 Free Software Foundation, Inc.
-
+ FFI support for Darwin and AIX.
+
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
@@ -225,6 +226,48 @@
//FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
}
+/* Adjust the size of S to be correct for Darwin.
+ On Darwin, the first field of a structure has natural alignment. */
+
+static void
+darwin_adjust_aggregate_sizes (ffi_type *s)
+{
+ int i;
+
+ if (s->type != FFI_TYPE_STRUCT)
+ return;
+
+ s->size = 0;
+ for (i = 0; s->elements[i] != NULL; i++)
+ {
+ ffi_type *p;
+ int align;
+
+ p = s->elements[i];
+ darwin_adjust_aggregate_sizes (p);
+ if (i == 0
+ && (p->type == FFI_TYPE_UINT64
+ || p->type == FFI_TYPE_SINT64
+ || p->type == FFI_TYPE_DOUBLE
+ || p->alignment == 8))
+ align = 8;
+ else if (p->alignment == 16 || p->alignment < 4)
+ align = p->alignment;
+ else
+ align = 4;
+ s->size = ALIGN(s->size, align) + p->size;
+ }
+
+ s->size = ALIGN(s->size, s->alignment);
+
+ if (s->elements[0]->type == FFI_TYPE_UINT64
+ || s->elements[0]->type == FFI_TYPE_SINT64
+ || s->elements[0]->type == FFI_TYPE_DOUBLE
+ || s->elements[0]->alignment == 8)
+ s->alignment = s->alignment > 8 ? s->alignment : 8;
+ /* Do not add additional tail padding. */
+}
+
/* Perform machine dependent cif processing. */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{
@@ -237,8 +280,16 @@
unsigned size_al = 0;
/* All the machine-independent calculation of cif->bytes will be wrong.
+ All the calculation of structure sizes will also be wrong.
Redo the calculation for DARWIN. */
+ if (cif->abi == FFI_DARWIN)
+ {
+ darwin_adjust_aggregate_sizes (cif->rtype);
+ for (i = 0; i < cif->nargs; i++)
+ darwin_adjust_aggregate_sizes (cif->arg_types[i]);
+ }
+
/* Space for the frame pointer, callee's LR, CR, etc, and for
the asm's temp regs. */
Index: libffi/testsuite/libffi.call/nested_struct4.c
===================================================================
--- libffi/testsuite/libffi.call/nested_struct4.c (revision 118903)
+++ libffi/testsuite/libffi.call/nested_struct4.c (working copy)
@@ -6,7 +6,7 @@
PR: PR 25630.
Originator: <andreast@gcc.gnu.org> 20051010 */
-/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* powerpc*-*-darwin* } } */
+/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
#include "ffitest.h"
typedef struct A {
Index: libffi/testsuite/libffi.call/nested_struct6.c
===================================================================
--- libffi/testsuite/libffi.call/nested_struct6.c (revision 118903)
+++ libffi/testsuite/libffi.call/nested_struct6.c (working copy)
@@ -6,7 +6,7 @@
PR: PR 25630.
Originator: <andreast@gcc.gnu.org> 20051010 */
-/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* powerpc*-*-darwin* } } */
+/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
#include "ffitest.h"
typedef struct A {
============================================================
More information about the Gcc-patches
mailing list