From 58182de35798c4aaeaf0b01a8fe09d01542e70eb Mon Sep 17 00:00:00 2001 From: Geoffrey Keating Date: Wed, 1 Nov 2006 05:28:41 +0000 Subject: [PATCH] In gcc/: PR 23067 In gcc/: 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. In gcc/testsuite/: 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. In libobjc/: * encoding.c (darwin_rs6000_special_round_type_align): New. In libffi/: * 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. From-SVN: r118365 --- gcc/ChangeLog | 12 ++++ gcc/config/rs6000/darwin.h | 36 +++++------ gcc/config/rs6000/rs6000-protos.h | 2 + gcc/config/rs6000/rs6000.c | 33 +++++++++- gcc/testsuite/ChangeLog | 13 +++- .../gcc.target/powerpc/darwin-abi-10.c | 1 - .../gcc.target/powerpc/darwin-abi-11.c | 1 - .../gcc.target/powerpc/darwin-abi-3.c | 1 - .../gcc.target/powerpc/darwin-abi-6.c | 1 - .../gcc.target/powerpc/darwin-abi-7.c | 1 - .../gcc.target/powerpc/darwin-abi-8.c | 1 - .../gcc.target/powerpc/darwin-abi-9.c | 1 - libffi/ChangeLog | 8 +++ libffi/src/powerpc/ffi_darwin.c | 61 +++++++++++++++++-- libffi/testsuite/libffi.call/nested_struct4.c | 2 +- libffi/testsuite/libffi.call/nested_struct6.c | 2 +- libobjc/ChangeLog | 4 ++ libobjc/encoding.c | 4 ++ 18 files changed, 151 insertions(+), 33 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9c6a836a38f..5ad5fb9a887 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2006-10-31 Geoffrey Keating + + 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. + 2006-10-31 Geoffrey Keating * toplev.c (compile_file): Call final_write_globals diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h index 374f0014e13..b8cbdcc2dd1 100644 --- a/gcc/config/rs6000/darwin.h +++ b/gcc/config/rs6000/darwin.h @@ -374,26 +374,28 @@ do { \ /* 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 diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 0cb5a50b773..3331c1137b7 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -114,6 +114,8 @@ extern rtx rs6000_machopic_legitimize_pic_address (rtx, enum machine_mode, #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); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5d4b889e6d7..e82b6d59581 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -2591,7 +2591,7 @@ invalid_e500_subreg (rtx op, enum machine_mode mode) 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 @@ rs6000_special_round_type_align (tree type, unsigned int computed, 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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 95f4301c7ed..64115a9c2e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2006-10-31 Geoffrey Keating + + 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. + 2006-10-31 Eric Christopher Falk Hueffner @@ -6,7 +17,7 @@ * gcc.dg/builtin-bswap-3.c: New. * gcc.dg/builtin-bswap-4.c: New. * gcc.dg/builtin-bswap-5.c: New. - * gcc.dg/i386/builtin-bswap-1.c: New. + * gcc.target/i386/builtin-bswap-1.c: New. 2006-10-31 Geoffrey Keating diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c index 0247c476d67..68540b8a162 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-10.c @@ -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 diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c index bc5f50140ff..5d01572a8ba 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-11.c @@ -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 diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c index 008ea46d524..021abc8fe4d 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-3.c @@ -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 { diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c index 4d80187468e..1892e15bcee 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-6.c @@ -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 diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c index d9ecee97b83..8af61ddacb3 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-7.c @@ -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 diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c index b8e0c4d1f3e..eac0d12d188 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-8.c @@ -1,6 +1,5 @@ /* { dg-do compile { target powerpc*-*-darwin* } } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-xfail-if "" { powerpc*-*-darwin* } } */ struct c { diff --git a/gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c b/gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c index 7f215df9bed..fa5bd017fec 100644 --- a/gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c +++ b/gcc/testsuite/gcc.target/powerpc/darwin-abi-9.c @@ -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 diff --git a/libffi/ChangeLog b/libffi/ChangeLog index 1ab09027872..a5bdcd27e54 100644 --- a/libffi/ChangeLog +++ b/libffi/ChangeLog @@ -1,3 +1,11 @@ +2006-10-16 Geoffrey Keating + + * 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. + 2006-10-10 Paolo Bonzini Sandro Tolaini diff --git a/libffi/src/powerpc/ffi_darwin.c b/libffi/src/powerpc/ffi_darwin.c index 1d4fb34232a..6bc0474e3db 100644 --- a/libffi/src/powerpc/ffi_darwin.c +++ b/libffi/src/powerpc/ffi_darwin.c @@ -1,11 +1,12 @@ /* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating + ffi_darwin.c - PowerPC Foreign Function Interface - - Darwin ABI support (c) 2001 John Hornkvist - AIX ABI support (c) 2002 Free Software Foundation, Inc. + Copyright (C) 1998 Geoffrey Keating + Copyright (C) 2001 John Hornkvist + Copyright (C) 2002, 2006 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 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack) //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 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) 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. */ diff --git a/libffi/testsuite/libffi.call/nested_struct4.c b/libffi/testsuite/libffi.call/nested_struct4.c index d7abf69c126..f67b6a95874 100644 --- a/libffi/testsuite/libffi.call/nested_struct4.c +++ b/libffi/testsuite/libffi.call/nested_struct4.c @@ -6,7 +6,7 @@ PR: PR 25630. Originator: 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 { diff --git a/libffi/testsuite/libffi.call/nested_struct6.c b/libffi/testsuite/libffi.call/nested_struct6.c index 116254708ad..8bf737b36f8 100644 --- a/libffi/testsuite/libffi.call/nested_struct6.c +++ b/libffi/testsuite/libffi.call/nested_struct6.c @@ -6,7 +6,7 @@ PR: PR 25630. Originator: 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 { diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index 511191f7b5b..dbc79f8eb84 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,7 @@ +2006-10-31 Geoffrey Keating + + * encoding.c (darwin_rs6000_special_round_type_align): New. + 2006-10-14 Geoffrey Keating * Makefile.in: Use multi_basedir instead of toplevel_srcdir. diff --git a/libobjc/encoding.c b/libobjc/encoding.c index 21a785814dc..e65634103aa 100644 --- a/libobjc/encoding.c +++ b/libobjc/encoding.c @@ -120,6 +120,10 @@ static int __attribute__ ((__unused__)) not_target_flags = 0; : 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