stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN to type_align when PCC_BI...
authorJakub Jelinek <jakub@redhat.com>
Wed, 7 Aug 2002 21:05:16 +0000 (23:05 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 7 Aug 2002 21:05:16 +0000 (23:05 +0200)
* stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN
to type_align when PCC_BITFIELD_TYPE_MATTERS.  Only apply
ADJUST_FIELD_ALIGN if not DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
(place_field): Likewise.
* config/i386/i386.c (x86_field_alignment): Don't check
DECL_USER_ALIGN here.
* config/rs6000/rs6000.c (rs6000_field_alignment): New.
* config/rs6000/rs6000-protos.h (rs6000_field_alignment): New
prototype.
* config/rs6000/rs6000.h (ADJUST_FIELD_ALIGN): Define.
* config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Remove.
* config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Remove.
* config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Remove.
* config/rs6000/sysv4.h (ADJUST_FIELD_ALIGN): Remove.
* doc/tm.texi (ADJUST_FIELD_ALIGN): Update description.

* gcc.dg/i386-bitfield1.c: New test.
* g++.dg/abi/bitfield3.C: Update.

Co-Authored-By: Richard Henderson <rth@redhat.com>
From-SVN: r56107

14 files changed:
gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/rs6000/aix.h
gcc/config/rs6000/darwin.h
gcc/config/rs6000/linux64.h
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/sysv4.h
gcc/doc/tm.texi
gcc/stor-layout.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/abi/bitfield3.C
gcc/testsuite/gcc.dg/i386-bitfield1.c [new file with mode: 0644]

index d7659d080ddd4e89932f583d32755476572e0929..3490b504781ac5189c4ca6d89b6c2ca4f6ddb628 100644 (file)
@@ -1,3 +1,22 @@
+2002-08-07  Jakub Jelinek  <jakub@redhat.com>
+           Richard Henderson  <rth@redhat.com>
+
+       * stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN
+       to type_align when PCC_BITFIELD_TYPE_MATTERS.  Only apply
+       ADJUST_FIELD_ALIGN if not DECL_USER_ALIGN resp. TYPE_USER_ALIGN.
+       (place_field): Likewise.
+       * config/i386/i386.c (x86_field_alignment): Don't check
+       DECL_USER_ALIGN here.
+       * config/rs6000/rs6000.c (rs6000_field_alignment): New.
+       * config/rs6000/rs6000-protos.h (rs6000_field_alignment): New
+       prototype.
+       * config/rs6000/rs6000.h (ADJUST_FIELD_ALIGN): Define.
+       * config/rs6000/aix.h (ADJUST_FIELD_ALIGN): Remove.
+       * config/rs6000/darwin.h (ADJUST_FIELD_ALIGN): Remove.
+       * config/rs6000/linux64.h (ADJUST_FIELD_ALIGN): Remove.
+       * config/rs6000/sysv4.h (ADJUST_FIELD_ALIGN): Remove.
+       * doc/tm.texi (ADJUST_FIELD_ALIGN): Update description.
+
 2002-08-07  Neil Booth  <neil@daikokuya.co.uk>
 
        * Makefile.in (c-opts.o, c-common.o, C_AND_OBJC_OBJS): Update.
index ae2fe990db3086f13ddb3b27f0aa1d6fe2887b2e..5ef4e7637c6c274cfa74103bcad06e6f613c8f71 100644 (file)
@@ -13818,10 +13818,12 @@ x86_field_alignment (field, computed)
      int computed;
 {
   enum machine_mode mode;
-  if (TARGET_64BIT || DECL_USER_ALIGN (field) || TARGET_ALIGN_DOUBLE)
+  tree type = TREE_TYPE (field);
+
+  if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
     return computed;
-  mode = TYPE_MODE (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE
-                   ? get_inner_array_type (field) : TREE_TYPE (field));
+  mode = TYPE_MODE (TREE_CODE (type) == ARRAY_TYPE
+                   ? get_inner_array_type (type) : type);
   if (mode == DFmode || mode == DCmode
       || GET_MODE_CLASS (mode) == MODE_INT
       || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
index 5e619e64d05f4860cc610f217e90cb54c07e5961..b639025c9cbd9dabbe752902f4ab279389289362 100644 (file)
@@ -111,13 +111,6 @@ Boston, MA 02111-1307, USA.  */
 #define LIB_SPEC "%{pg:-L/lib/profiled -L/usr/lib/profiled}\
 %{p:-L/lib/profiled -L/usr/lib/profiled} %{!shared:%{g*:-lg}} -lc"
 
-/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
-             ? get_inner_array_type (FIELD) \
-             : TREE_TYPE (FIELD)) == DFmode \
-   ? MIN ((COMPUTED), 32) : (COMPUTED))
-
 /* AIX 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)  \
index 417cfb9697d803c2dde8f12f0a8460d3ba1c3b54..6b6ca11dddbb08ccc4540b561e63f155c79da08f 100644 (file)
@@ -196,13 +196,6 @@ Boston, MA 02111-1307, USA.  */
 /* Fix for emit_group_load (): force large constants to be pushed via regs.  */
 #define ALWAYS_PUSH_CONSTS_USING_REGS_P                1
 
-/* Darwin word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
-             ? get_inner_array_type (FIELD) \
-             : TREE_TYPE (FIELD)) == DFmode \
-   ? MIN ((COMPUTED), 32) : (COMPUTED))
-
 /* 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)  \
index a1f162e05586697aba9c7e2dbc5f1cb3e6ffb64c..1d9b1a1d9f0d6e2a791bc36d6accb501923bb49c 100644 (file)
@@ -72,13 +72,6 @@ Boston, MA 02111-1307, USA.  */
 
 #define USER_LABEL_PREFIX  ""
 
-/* AIX word-aligns FP doubles but doubleword-aligns 64-bit ints.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
-  (TYPE_MODE (TREE_CODE (TREE_TYPE (FIELD)) == ARRAY_TYPE \
-             ? get_inner_array_type (FIELD) \
-             : TREE_TYPE (FIELD)) == DFmode \
-   ? MIN ((COMPUTED), 32) : (COMPUTED))
-
 /* AIX increases natural record alignment to doubleword if the first
    field is an FP double while the FP fields remain word aligned.  */
 #undef ROUND_TYPE_ALIGN
index 42563d30378cb8b43d5bdd4723b564835b97e3ee..3725c7fe9da304533fa74b346693edb2f92178a8 100644 (file)
@@ -151,6 +151,7 @@ extern void setup_incoming_varargs PARAMS ((CUMULATIVE_ARGS *,
                                            int *, int));
 extern struct rtx_def *rs6000_va_arg PARAMS ((tree, tree));
 extern void output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+extern int rs6000_field_alignment PARAMS ((tree, int));
 #ifdef ARGS_SIZE_RTX
 /* expr.h defines ARGS_SIZE_RTX and `enum direction' */
 extern enum direction function_arg_padding PARAMS ((enum machine_mode, tree));
index 3e6a9a9359975dc977acf60ad5d15a67e673dd1c..382f47bc22418fc3503037eca4969cf833240d46 100644 (file)
@@ -13115,3 +13115,24 @@ rs6000_xcoff_encode_section_info (decl, first)
       && ! DECL_WEAK (decl))
     SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
 }
+
+int
+rs6000_field_alignment (field, computed)
+     tree field;
+     int computed;
+{
+  tree type = get_inner_array_type (field);
+
+  if (DEFAULT_ABI == ABI_V4)
+    {
+      if (TARGET_ALTIVEC && TREE_CODE (type) == VECTOR_TYPE)
+       return 128;
+    }
+  else
+    {
+      if (TYPE_MODE (type) == DFmode)
+       return MIN (32, computed);
+    }
+
+  return computed;
+}
index 35e9f098cc68de1c896034c21e62d398c871955d..a502d525d4c07e7b7853253e483939f2f04bedc9 100644 (file)
@@ -631,6 +631,10 @@ extern int rs6000_default_long_calls;
 /* A bitfield declared as `int' forces `int' alignment for the struct.  */
 #define PCC_BITFIELD_TYPE_MATTERS 1
 
+/* Most ABIs word-align FP doubles but doubleword-align 64-bit ints.  */
+#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) \
+  rs6000_field_alignment ((FIELD), (COMPUTED))
+
 /* Make strings word-aligned so strcpy from constants will be faster.
    Make vector constants quadword aligned.  */
 #define CONSTANT_ALIGNMENT(EXP, ALIGN)                           \
index ae589fd948ec63cd07e94474f28b21207928e452..24a5c9c5d7bb291f8113f7686b367262b6319f6e 100644 (file)
@@ -380,12 +380,6 @@ do {                                                                       \
 /* Real stack boundary as mandated by the appropriate ABI.  */
 #define ABI_STACK_BOUNDARY ((TARGET_EABI && !TARGET_ALTIVEC_ABI) ? 64 : 128)
 
-/* An expression for the alignment of a structure field FIELD if the
-   alignment computed in the usual way is COMPUTED.  */
-#define ADJUST_FIELD_ALIGN(FIELD, COMPUTED)                                  \
-       ((TARGET_ALTIVEC && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE)     \
-        ? 128 : COMPUTED)
-
 /* Define this macro as an expression for the alignment of a type
    (given by TYPE as a tree node) if the alignment computed in the
    usual way is COMPUTED and the alignment explicitly specified was
@@ -396,7 +390,6 @@ do {                                                                        \
          : MAX (COMPUTED, SPECIFIED))
 
 #undef  BIGGEST_FIELD_ALIGNMENT
-#undef  ADJUST_FIELD_ALIGN
 
 /* Use ELF style section commands.  */
 
index 12f6ff7399de6b163c28ea37029bb3208237118f..d13b53ee4a4470e104786c74529685775c2f199d 100644 (file)
@@ -1068,9 +1068,11 @@ by the @code{__attribute__ ((aligned (@var{n})))} construct.
 @findex ADJUST_FIELD_ALIGN
 @item ADJUST_FIELD_ALIGN (@var{field}, @var{computed})
 An expression for the alignment of a structure field @var{field} if the
-alignment computed in the usual way is @var{computed}.  GCC uses
-this value instead of the value in @code{BIGGEST_ALIGNMENT} or
-@code{BIGGEST_FIELD_ALIGNMENT}, if defined.
+alignment computed in the usual way (including applying of
+@code{BIGGEST_ALIGNMENT} and @code{BIGGEST_FIELD_ALIGNMENT} to the
+alignment) is @var{computed}.  It overrides alignment only if the
+field alignment has not been set by the
+@code{__attribute__ ((aligned (@var{n})))} construct.
 
 @findex MAX_OFILE_ALIGNMENT
 @item MAX_OFILE_ALIGNMENT
index 753e41d29ade13847d0e4be6f78c90ba28795f87..5a4041e5af0ed94608915c267616c2559d176c66 100644 (file)
@@ -671,7 +671,8 @@ place_union_field (rli, field)
 #endif
 
 #ifdef ADJUST_FIELD_ALIGN
-  desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
+  if (! DECL_USER_ALIGN (field))
+    desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
 #endif
 
   TYPE_USER_ALIGN (rli->t) |= DECL_USER_ALIGN (field);
@@ -685,10 +686,14 @@ place_union_field (rli, field)
      entire union to have `int' alignment.  */
   if (PCC_BITFIELD_TYPE_MATTERS && DECL_BIT_FIELD_TYPE (field))
     {
-      rli->record_align = MAX (rli->record_align,
-                              TYPE_ALIGN (TREE_TYPE (field)));
-      rli->unpadded_align = MAX (rli->unpadded_align,
-                                TYPE_ALIGN (TREE_TYPE (field)));
+      unsigned int type_align = TYPE_ALIGN (TREE_TYPE (field));
+
+#ifdef ADJUST_FIELD_ALIGN
+      if (! TYPE_USER_ALIGN (TREE_TYPE (field)))
+       type_align = ADJUST_FIELD_ALIGN (field, type_align);
+#endif
+      rli->record_align = MAX (rli->record_align, type_align);
+      rli->unpadded_align = MAX (rli->unpadded_align, type_align);
     }
 #endif
 
@@ -785,7 +790,8 @@ place_field (rli, field)
 #endif
 
 #ifdef ADJUST_FIELD_ALIGN
-  desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
+  if (! user_align)
+    desired_align = ADJUST_FIELD_ALIGN (field, desired_align);
 #endif
 
   /* Record must have at least as much alignment as any field.
@@ -829,6 +835,11 @@ place_field (rli, field)
        {
          unsigned int type_align = TYPE_ALIGN (type);
 
+#ifdef ADJUST_FIELD_ALIGN
+         if (! TYPE_USER_ALIGN (type))
+           type_align = ADJUST_FIELD_ALIGN (field, type_align);
+#endif
+
          if (maximum_field_alignment != 0)
            type_align = MIN (type_align, maximum_field_alignment);
          else if (DECL_PACKED (field))
@@ -917,6 +928,11 @@ place_field (rli, field)
       HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
       HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
 
+#ifdef ADJUST_FIELD_ALIGN
+      if (! TYPE_USER_ALIGN (type))
+       type_align = ADJUST_FIELD_ALIGN (field, type_align);
+#endif
+
       /* A bit field may not span more units of alignment of its type
         than its type itself.  Advance to next boundary if necessary.  */
       if ((((offset * BITS_PER_UNIT + bit_offset + field_size +
@@ -946,6 +962,11 @@ place_field (rli, field)
       HOST_WIDE_INT offset = tree_low_cst (rli->offset, 0);
       HOST_WIDE_INT bit_offset = tree_low_cst (rli->bitpos, 0);
 
+#ifdef ADJUST_FIELD_ALIGN
+      if (! TYPE_USER_ALIGN (type))
+       type_align = ADJUST_FIELD_ALIGN (field, type_align);
+#endif
+
       if (maximum_field_alignment != 0)
        type_align = MIN (type_align, maximum_field_alignment);
       /* ??? This test is opposite the test in the containing if
index 63175ca31232ce9e2f32bd7fca66001a43d0dd39..2438925246bdb78171ebb0db688789e1211faa41 100644 (file)
@@ -1,3 +1,9 @@
+2002-08-07  Jakub Jelinek  <jakub@redhat.com>
+           Richard Henderson  <rth@redhat.com>
+
+       * gcc.dg/i386-bitfield1.c: New test.
+       * g++.dg/abi/bitfield3.C: Update.
+
 2002-08-07  Neil Booth  <neil@daikokuya.co.uk>
 
        * objc.dg/const-str-2.m: Update.
index 1e599355f6976de33807888632af2f16ba92d8f7..da7b92fad7f9fa0e9adaaaea843e5e6132ce8271 100644 (file)
@@ -56,25 +56,25 @@ int main (void)
     return 4;
   if (__alignof__ (b.e) != 4)
     return 5;
-  if (&c.i - &c.g != 16)
+  if (&c.i - &c.g != 12)
     return 6;
-  if (sizeof (c) != 24)
+  if (sizeof (c) != 16)
     return 7;
-  if (sizeof (c4) != 4 * 24)
+  if (sizeof (c4) != 4 * 16)
     return 8;
-  if (sizeof (d) != 2 * 8 + 24)
+  if (sizeof (d) != 2 * 4 + 16)
     return 9;
-  if (__alignof__ (d.k) != 8)
+  if (__alignof__ (d.k) != 4)
     return 10;
-  if (&e.o - &e.m != 28)
+  if (&e.o - &e.m != 24)
     return 11;
-  if (sizeof (e) != 32)
+  if (sizeof (e) != 28)
     return 12;
-  if (sizeof (e4) != 4 * 32)
+  if (sizeof (e4) != 4 * 28)
     return 13;
-  if (sizeof (f) != 2 * 8 + 32)
+  if (sizeof (f) != 2 * 4 + 28)
     return 14;
-  if (__alignof__ (f.q) != 8)
+  if (__alignof__ (f.q) != 4)
     return 15;
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/i386-bitfield1.c b/gcc/testsuite/gcc.dg/i386-bitfield1.c
new file mode 100644 (file)
index 0000000..8045a67
--- /dev/null
@@ -0,0 +1,53 @@
+// Test for bitfield alignment in structs on IA-32
+// { dg-do run { target i?86-*-* } }
+// { dg-options "-O2" }
+
+extern void abort (void);
+extern void exit (int);
+
+struct A
+{
+  char a;
+  long long b : 61;
+  char c;
+} a, a4[4];
+
+struct B
+{
+  char d;
+  struct A e;
+  char f;
+} b;
+
+struct C
+{
+  char g;
+  union U
+  {
+    char u1;
+    long long u2;
+    long long u3 : 64;
+  } h;
+  char i;
+} c;
+
+int main (void)
+{
+  if (&a.c - &a.a != 12)
+    abort ();
+  if (sizeof (a) != 16)
+    abort ();
+  if (sizeof (a4) != 4 * 16)
+    abort ();
+  if (sizeof (b) != 2 * 4 + 16)
+    abort ();
+  if (__alignof__ (b.e) != 4)
+    abort ();
+  if (&c.i - &c.g != 12)
+    abort ();
+  if (sizeof (c) != 16)
+    abort ();
+  if (__alignof__ (c.h) != 4)
+    abort ();
+  exit (0);
+}