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:
Jakub Jelinek 2002-08-07 23:05:16 +02:00 committed by Jakub Jelinek
parent 65b91091db
commit ad9335eb67
14 changed files with 151 additions and 50 deletions

View 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.

View 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)

View 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) \

View 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) \

View 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

View 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));

View 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;
}

View 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) \

View 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. */

View 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

View 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

View 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.

View 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;
}

View 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);
}