stor-layout.c (place_union_field): Apply ADJUST_FIELD_ALIGN to type_align when PCC_BITFIELD_TYPE_MATTERS.
* 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
This commit is contained in:
parent
65b91091db
commit
ad9335eb67
14 changed files with 151 additions and 50 deletions
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) \
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
53
gcc/testsuite/gcc.dg/i386-bitfield1.c
Normal file
53
gcc/testsuite/gcc.dg/i386-bitfield1.c
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Reference in a new issue