This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: sh64-elf (SH5) port


On Feb  4, 2002, Mark Mitchell <mark@codesourcery.com> wrote:

> +@deftypefn {Target Hook} bool TARGET_MS_BITFIELD_LAYOUT_P (tree
> @var{record_type})
> +This target hook returns @code{true} if bit-fields in the given
> +@var{record_type} are to be laid out following the rules of a certain
> +proprietary compiler, namely: (i) a bit-field won't share the same

> Just say "Visual C/C++".  No need to be cutesy. :-)

Ok, fixed.

> +storage unit with the previous bit-field if their underlying types have
> +different sizes, and the bit-field will be aligned to the highest
> +alignment of the underlying types of itself and of the previous
> +bit-field; (ii) a zero-sized bit-field will affect the alignment of the
> +whole enclosing structure, even if it is unnamed; except that (iii) a
> +zero-sized bit-field will be disregarded unless it follows another
> +bit-field of non-zero size.  If this hook returns @code{true}, other
> +macros that control bit-field layout are ignored.
> +@end deftypefn

> This a good explanation, but I'd prefer to see it in the code, I think.

I thought of someone writing a port and looking for an option that
would do it.  I'd have hoped to find the description of the behavior
along with the option, not hidden deep somewhere in the compiler code.

> From a user-level documentation point of view, we just need to know what
> the point of the option does.  (Same as for -fpic

It's not a command-line option, it's a target definition hook.  So,
it's not for users, but for porters.

> +/* Default value of targetm.ms_bitfield_layout_p that always returns
> +   true.  */

> This comment is lying.

Heh.  Just checking whether you were paying attention :-)

Thanks, fixed.

> +  if ((* targetm.ms_bitfield_layout_p) (rli->t)
> +      && TREE_CODE (field) == FIELD_DECL
> +      && type != error_mark_node

> Probably, put the detailed information about the rules right before
> this hunk.

How about just adding a pointer to the docs right before this hunk?

> Patch approved with those changes.

Since I seem to have got approval for the code changes, I'm going
ahead and checking this in, but I'll revise the docs and comments as I
receive further feedback.

Thanks a lot for reviewing the patches at such an inconvenient time.
Have a nice trip!

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* target.h (struct gcc_target): Added ms_bitfield_layout_p.
	* target-def.h (TARGET_MS_BITFIELD_LAYOUT_P): New.  Added to...
	(TARGET_INITIALIZER): this.
	* doc/tm.texi (TARGET_MS_BITFIELD_LAYOUT_P): Document.
	(BITFIELD_NBYTES_LIMITED): Markup fix.
	* tree.h (default_ms_bitfield_layout_p): Declare.
	(record_layout_info): Added prev_field.
	* tree.c (default_ms_bitfield_layout_p): New fn.
	* c-decl.c (finish_struct): Disregard EMPTY_FIELD_BOUNDARY and
	PCC_BITFIELD_TYPE_MATTERS for MS bit-field layout.
	* stor-layout.c: Include target.h.
	(start_record_layout): Initialize prev_field.
	(place_field): Handle MS bit-field layout, and disregard
	EMPTY_FIELD_BOUNDARY, BITFIELD_NBYTES_LIMITED and
	PCC_BITFIELD_TYPE_MATTERS in this case.  Update prev_field.
	* Makefile.in (stor-layout.o): Adjust dependencies.

Index: gcc/cp/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* class.c: Include target.h.
	(check_bitfield_decl): Disregard EMPTY_FIELD_BOUNDARY,
	BITFIELDS_NBYTES_LIMITED and PCC_BITFIELD_TYPE_MATTERS for MS
	bit-field layout.
	* Make-lang.in: Adjust deps.

Index: gcc/target.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/target.h,v
retrieving revision 1.18
diff -u -p -r1.18 target.h
--- gcc/target.h 2001/12/17 15:05:22 1.18
+++ gcc/target.h 2002/02/04 14:08:15
@@ -1,5 +1,5 @@
 /* Data structure definitions for a generic GCC target.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -161,6 +161,10 @@ struct gcc_target
   /* Return true if FNDECL (which has at least one machine attribute)
      can be inlined despite its machine attributes, false otherwise.  */
   bool (* function_attribute_inlinable_p) PARAMS ((tree fndecl));
+
+  /* Return true if bitfields in RECORD_TYPE should follow the
+     Microsoft Visual C++ bitfield layout rules.  */
+  bool (* ms_bitfield_layout_p) PARAMS ((tree record_type));
 
   /* Set up target-specific built-in functions.  */
   void (* init_builtins) PARAMS ((void));
Index: gcc/target-def.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/target-def.h,v
retrieving revision 1.16
diff -u -p -r1.16 target-def.h
--- gcc/target-def.h 2001/12/17 15:05:22 1.16
+++ gcc/target-def.h 2002/02/04 14:08:15
@@ -1,5 +1,5 @@
 /* Default initializers for a generic GCC target.
-   Copyright (C) 2001 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
 
 This program is free software; you can redistribute it and/or modify it
 under the terms of the GNU General Public License as published by the
@@ -164,6 +164,7 @@ Foundation, 59 Temple Place - Suite 330,
 #define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES default_set_default_type_attributes
 #define TARGET_INSERT_ATTRIBUTES default_insert_attributes
 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P default_function_attribute_inlinable_p
+#define TARGET_MS_BITFIELD_LAYOUT_P default_ms_bitfield_layout_p
 
 /* In builtins.c.  */
 #define TARGET_INIT_BUILTINS default_init_builtins
@@ -186,6 +187,7 @@ Foundation, 59 Temple Place - Suite 330,
   TARGET_SET_DEFAULT_TYPE_ATTRIBUTES,		\
   TARGET_INSERT_ATTRIBUTES,			\
   TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P,	\
+  TARGET_MS_BITFIELD_LAYOUT_P,			\
   TARGET_INIT_BUILTINS,				\
   TARGET_EXPAND_BUILTIN,			\
   TARGET_SECTION_TYPE_FLAGS,			\
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/egcs/gcc/doc/tm.texi,v
retrieving revision 1.97
diff -u -p -r1.97 tm.texi
--- gcc/doc/tm.texi 2002/02/02 18:56:36 1.97
+++ gcc/doc/tm.texi 2002/02/04 14:29:02
@@ -1199,8 +1199,8 @@ get from @code{PCC_BITFIELD_TYPE_MATTERS
 
 @findex BITFIELD_NBYTES_LIMITED
 @item BITFIELD_NBYTES_LIMITED
-Like PCC_BITFIELD_TYPE_MATTERS except that its effect is limited to
-aligning a bit-field within the structure.
+Like @code{PCC_BITFIELD_TYPE_MATTERS} except that its effect is limited
+to aligning a bit-field within the structure.
 
 @findex MEMBER_TYPE_FORCES_BLK
 @item MEMBER_TYPE_FORCES_BLK (@var{field})
@@ -1328,6 +1328,20 @@ The ordering of the component words of f
 memory is controlled by @code{FLOAT_WORDS_BIG_ENDIAN}.
 
 @end table
+
+@deftypefn {Target Hook} bool TARGET_MS_BITFIELD_LAYOUT_P (tree @var{record_type})
+This target hook returns @code{true} if bit-fields in the given
+@var{record_type} are to be laid out following the rules of Microsoft
+Visual C/C++, namely: (i) a bit-field won't share the same storage
+unit with the previous bit-field if their underlying types have
+different sizes, and the bit-field will be aligned to the highest
+alignment of the underlying types of itself and of the previous
+bit-field; (ii) a zero-sized bit-field will affect the alignment of
+the whole enclosing structure, even if it is unnamed; except that
+(iii) a zero-sized bit-field will be disregarded unless it follows
+another bit-field of non-zero size.  If this hook returns @code{true},
+other macros that control bit-field layout are ignored.
+@end deftypefn
 
 @node Type Layout
 @section Layout of Source Language Data Types
Index: gcc/tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.303
diff -u -p -r1.303 tree.h
--- gcc/tree.h 2002/02/02 00:14:31 1.303
+++ gcc/tree.h 2002/02/04 14:08:21
@@ -2234,6 +2234,7 @@ extern int default_comp_type_attributes 
 extern void default_set_default_type_attributes PARAMS ((tree));
 extern void default_insert_attributes PARAMS ((tree, tree *));
 extern bool default_function_attribute_inlinable_p PARAMS ((tree));
+extern bool default_ms_bitfield_layout_p PARAMS ((tree));
 
 /* Split a list of declspecs and attributes into two.  */
 
@@ -2323,6 +2324,8 @@ typedef struct record_layout_info_s
   /* The alignment of the record so far, allowing for the record to be
      padded only at the end, in bits.  */
   unsigned int unpadded_align;
+  /* The previous field layed out.  */
+  tree prev_field;
   /* The static variables (i.e., class variables, as opposed to
      instance variables) encountered in T.  */
   tree pending_statics;
Index: gcc/tree.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.c,v
retrieving revision 1.236
diff -u -p -r1.236 tree.c
--- gcc/tree.c 2002/02/02 00:14:30 1.236
+++ gcc/tree.c 2002/02/04 14:08:18
@@ -2736,6 +2736,16 @@ default_function_attribute_inlinable_p (
   return false;
 }
 
+/* Default value of targetm.ms_bitfield_layout_p that always returns
+   false.  */
+bool
+default_ms_bitfield_layout_p (record)
+     tree record ATTRIBUTE_UNUSED;
+{
+  /* By default, GCC does not use the MS VC++ bitfield layout rules.  */
+  return false;
+}
+
 /* Return non-zero if IDENT is a valid name for attribute ATTR,
    or zero if not.
 
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-decl.c,v
retrieving revision 1.294
diff -u -p -r1.294 c-decl.c
--- gcc/c-decl.c 2002/02/02 00:14:31 1.294
+++ gcc/c-decl.c 2002/02/04 14:08:12
@@ -5727,7 +5727,8 @@ finish_struct (t, fieldlist, attributes)
 	      DECL_BIT_FIELD (x) = 1;
 	      SET_DECL_C_BIT_FIELD (x);
 
-	      if (width == 0)
+	      if (width == 0
+		  && ! (* targetm.ms_bitfield_layout_p) (t))
 		{
 		  /* field size 0 => force desired amount of alignment.  */
 #ifdef EMPTY_FIELD_BOUNDARY
Index: gcc/stor-layout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/stor-layout.c,v
retrieving revision 1.117
diff -u -p -r1.117 stor-layout.c
--- gcc/stor-layout.c 2002/01/22 14:33:34 1.117
+++ gcc/stor-layout.c 2002/02/04 14:08:15
@@ -30,6 +30,7 @@ Software Foundation, 59 Temple Place - S
 #include "expr.h"
 #include "toplev.h"
 #include "ggc.h"
+#include "target.h"
 
 /* Set to one when set_sizetype has been called.  */
 static int sizetype_set;
@@ -503,6 +504,7 @@ start_record_layout (t)
 
   rli->offset = size_zero_node;
   rli->bitpos = bitsize_zero_node;
+  rli->prev_field = 0;
   rli->pending_statics = 0;
   rli->packed_maybe_necessary = 0;
 
@@ -787,8 +789,26 @@ place_field (rli, field)
   /* Record must have at least as much alignment as any field.
      Otherwise, the alignment of the field within the record is
      meaningless.  */
+  if ((* targetm.ms_bitfield_layout_p) (rli->t)
+      && type != error_mark_node
+      && DECL_BIT_FIELD_TYPE (field)
+      && ! integer_zerop (TYPE_SIZE (type))
+      && integer_zerop (DECL_SIZE (field)))
+    {
+      if (rli->prev_field
+	  && DECL_BIT_FIELD_TYPE (rli->prev_field)
+	  && ! integer_zerop (DECL_SIZE (rli->prev_field)))
+	{
+	  rli->record_align = MAX (rli->record_align, desired_align);
+	  rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
+	}
+      else
+	desired_align = 1;
+    }	
+  else
 #ifdef PCC_BITFIELD_TYPE_MATTERS
   if (PCC_BITFIELD_TYPE_MATTERS && type != error_mark_node
+      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
       && DECL_BIT_FIELD_TYPE (field)
       && ! integer_zerop (TYPE_SIZE (type)))
     {
@@ -878,6 +898,7 @@ place_field (rli, field)
      variable-sized fields, we need not worry about compatibility.  */
 #ifdef PCC_BITFIELD_TYPE_MATTERS
   if (PCC_BITFIELD_TYPE_MATTERS
+      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
       && TREE_CODE (field) == FIELD_DECL
       && type != error_mark_node
       && DECL_BIT_FIELD (field)
@@ -907,6 +928,7 @@ place_field (rli, field)
 
 #ifdef BITFIELD_NBYTES_LIMITED
   if (BITFIELD_NBYTES_LIMITED
+      && ! (* targetm.ms_bitfield_layout_p) (rli->t)
       && TREE_CODE (field) == FIELD_DECL
       && type != error_mark_node
       && DECL_BIT_FIELD_TYPE (field)
@@ -940,6 +962,50 @@ place_field (rli, field)
     }
 #endif
 
+  /* See the docs for TARGET_MS_BITFIELD_LAYOUT_P for details.  */
+  if ((* targetm.ms_bitfield_layout_p) (rli->t)
+      && TREE_CODE (field) == FIELD_DECL
+      && type != error_mark_node
+      && ! DECL_PACKED (field)
+      && rli->prev_field
+      && DECL_SIZE (field)
+      && host_integerp (DECL_SIZE (field), 1)
+      && DECL_SIZE (rli->prev_field)
+      && host_integerp (DECL_SIZE (rli->prev_field), 1)
+      && host_integerp (rli->offset, 1)
+      && host_integerp (TYPE_SIZE (type), 1)
+      && host_integerp (TYPE_SIZE (TREE_TYPE (rli->prev_field)), 1)
+      && ((DECL_BIT_FIELD_TYPE (rli->prev_field)
+	   && ! integer_zerop (DECL_SIZE (rli->prev_field)))
+	  || (DECL_BIT_FIELD_TYPE (field)
+	      && ! integer_zerop (DECL_SIZE (field))))
+      && (! simple_cst_equal (TYPE_SIZE (type),
+			      TYPE_SIZE (TREE_TYPE (rli->prev_field)))
+	  /* If the previous field was a zero-sized bit-field, either
+	     it was ignored, in which case we must ensure the proper
+	     alignment of this field here, or it already forced the
+	     alignment of this field, in which case forcing the
+	     alignment again is harmless.  So, do it in both cases.  */
+	  || (DECL_BIT_FIELD_TYPE (rli->prev_field)
+	      && integer_zerop (DECL_SIZE (rli->prev_field)))))
+    {
+      unsigned int type_align = TYPE_ALIGN (type);
+
+      if (rli->prev_field
+	  && DECL_BIT_FIELD_TYPE (rli->prev_field)
+	  /* If the previous bit-field is zero-sized, we've already
+	     accounted for its alignment needs (or ignored it, if
+	     appropriate) while placing it.  */
+	  && ! integer_zerop (DECL_SIZE (rli->prev_field)))
+	type_align = MAX (type_align,
+			  TYPE_ALIGN (TREE_TYPE (rli->prev_field)));
+
+      if (maximum_field_alignment != 0)
+	type_align = MIN (type_align, maximum_field_alignment);
+
+      rli->bitpos = round_up (rli->bitpos, type_align);
+    }
+
   /* Offset so far becomes the position of this field after normalizing.  */
   normalize_rli (rli);
   DECL_FIELD_OFFSET (field) = rli->offset;
@@ -965,6 +1030,8 @@ place_field (rli, field)
 
   if (known_align != actual_align)
     layout_decl (field, actual_align);
+
+  rli->prev_field = field;
 
   /* Now add size of this field to the size of the record.  If the size is
      not constant, treat the field as being a multiple of bytes and just
Index: gcc/Makefile.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/Makefile.in,v
retrieving revision 1.826
diff -u -p -r1.826 Makefile.in
--- gcc/Makefile.in 2002/02/01 11:48:41 1.826
+++ gcc/Makefile.in 2002/02/04 14:08:07
@@ -1335,7 +1335,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H
 print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(GGC_H) \
    langhooks.h
 stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
-   function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H)
+   function.h $(EXPR_H) $(RTL_H) toplev.h $(GGC_H) $(TM_P_H) $(TARGET_H)
 fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) flags.h \
    toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) $(GGC_H) $(TM_P_H)
 diagnostic.o : diagnostic.c diagnostic.h real.h diagnostic.def \
Index: gcc/cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.434
diff -u -p -r1.434 class.c
--- gcc/cp/class.c 2002/02/04 08:55:42 1.434
+++ gcc/cp/class.c 2002/02/04 14:13:39
@@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "ggc.h"
 #include "lex.h"
+#include "target.h"
 
 #include "obstack.h"
 #define obstack_chunk_alloc xmalloc
@@ -3106,7 +3107,8 @@ check_bitfield_decl (field)
       DECL_SIZE (field) = convert (bitsizetype, w);
       DECL_BIT_FIELD (field) = 1;
 
-      if (integer_zerop (w))
+      if (integer_zerop (w)
+	  && ! (* targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (field)))
 	{
 #ifdef EMPTY_FIELD_BOUNDARY
 	  DECL_ALIGN (field) = MAX (DECL_ALIGN (field), 
Index: gcc/cp/Make-lang.in
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/Make-lang.in,v
retrieving revision 1.106
diff -u -p -r1.106 Make-lang.in
--- gcc/cp/Make-lang.in 2002/02/04 08:55:42 1.106
+++ gcc/cp/Make-lang.in 2002/02/04 14:13:33
@@ -262,7 +262,7 @@ cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H)
    diagnostic.h
 cp/typeck.o: cp/typeck.c $(CXX_TREE_H) flags.h $(RTL_H) $(EXPR_H) toplev.h \
    diagnostic.h
-cp/class.o: cp/class.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H)
+cp/class.o: cp/class.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(TARGET_H)
 cp/call.o: cp/call.c $(CXX_TREE_H) flags.h toplev.h $(RTL_H) $(EXPR_H) \
      $(GGC_H) diagnostic.h
 cp/friend.o: cp/friend.c $(CXX_TREE_H) flags.h $(RTL_H) toplev.h $(EXPR_H)

-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                  aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]