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]

[pre-patch] Re: changing struct bitfield allocation ?


I wrote on gcc@ :
> GCC currently allocates bits for bitfields starting at the lowest
> addressed byte of the bytes allocated to the type (i.e. the LSB for
> little endian, MSB for big endian, but I need them to be allocated
> from the MSB always, at least if the structure has a certain attribute
> set.

Ok, nothing we already had supported this, so I patched it.  It calls
for a new target hook.  A patch preview is attached, as is pre-docs
for the target hook (I.e. I'll pretty it up once the general idea is
approved ;)  How does this look?


  /* Return true if bitfields in RECORD_TYPE should be allocated
     within their base type's bytes starting at the opposite end.  */
  bool (* reverse_bitfield_layout_p) (tree record_type);

  bool TARGET_REVERSE_BITFIELD_LAYOUT_P (tree record_type);

  This predicate indicates if bitfields within record_type should be
  allocated from the "other end" of their base types.  In other words,
  the first int-typed bitfield in a struct would be at the LSB of
  its int on MSB systems, and at the MSB of its int on LSB systems.
  Consider this example:

	union {
	  struct {
	    int a:8;
	    int b:8;
	    int c:8;
	    int d:8;
	  } f;
	  int i;
	  char c[4];
	} foo;

  GCC would normally lay out the bitfields (f.a, etc) such that f.a
  and c[0] shared the same byte in memory.  This would correspond to
  the LSB of foo.i on an LSB system, and the MSB of foo.i on an MSB
  system.

  If this predicate returns true, the layout is altered such that f.a
  and c[3] share the same byte in memory.  Note that, by if this
  predicate is sensitive to the endianness of the target, the
  structures will be laid out with f.a always in the MSB or always in
  the LSB.

  Note that this predicate requires that the
  TARGET_MS_BITFIELD_LAYOUT_P predicate return true, and that the
  record_type is not packed, to ensure that differing base types do
  not overlap within the bitfield allocation.


Index: stor-layout.c
===================================================================
RCS file: /cvs/uberbaum/gcc/stor-layout.c,v
retrieving revision 1.161
diff -p -2 -r1.161 stor-layout.c
*** stor-layout.c	13 Jul 2003 17:12:28 -0000	1.161
--- stor-layout.c	25 Jul 2003 23:22:40 -0000
*************** finalize_type_size (tree type)
*** 1436,1439 ****
--- 1436,1462 ----
  }
  
+ static void
+ reverse_bitfield_layout (record_layout_info rli)
+ {
+   tree field, oldtype;
+   if (! lookup_attribute ("renesas", TYPE_ATTRIBUTES (rli->t)))
+     return;
+   for (field = TYPE_FIELDS (rli->t); field; field = TREE_CHAIN (field))
+     {
+       tree type = TREE_TYPE (field);
+       if (TREE_CODE (field) != FIELD_DECL)
+ 	continue;
+       if (TREE_CODE (field) == ERROR_MARK || TREE_CODE (type) == ERROR_MARK)
+ 	return;
+       oldtype = TREE_TYPE (DECL_FIELD_BIT_OFFSET (field));
+       DECL_FIELD_BIT_OFFSET (field)
+ 	= size_binop (MINUS_EXPR,
+ 		      size_binop (MINUS_EXPR, TYPE_SIZE (type),
+ 				  DECL_SIZE (field)),
+ 		      DECL_FIELD_BIT_OFFSET (field));
+       TREE_TYPE (DECL_FIELD_BIT_OFFSET (field)) = oldtype;
+     }
+ }
+ 
  /* Do all of the work required to layout the type indicated by RLI,
     once the fields have been laid out.  This function will call `free'
*************** void
*** 1445,1448 ****
--- 1468,1476 ----
  finish_record_layout (record_layout_info rli, int free_p)
  {
+   if ((* targetm.ms_bitfield_layout_p) (rli->t)
+       && (* targetm.reverse_bitfield_layout_p) (rli->t)
+       && ! TYPE_PACKED (rli->t))
+       reverse_bitfield_layout (rli);
+ 
    /* Compute the final size.  */
    finalize_record_size (rli);


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