This is the mail archive of the gcc@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: bitfields: types vs modes?


On Wed, 2009-03-11 at 01:05 -0400, DJ Delorie wrote:
> > Can you provide example code?  I'm confused enough to believe
> > that you *should* get this effect with PCC_BITFIELD_TYPE_MATTERS
> > (modulo current bugs).
> 
> Imagine a device with four 8-bit registers followed by a 32-bit
> register with an 8-bit field:
> 
> byte	status (read-only, clears after reading)
> byte	control (read/write)
> byte	tx buf (write only)
> byte	rx buf (read only)
> long	uart configuration
> 		divisor:8
> 		bits:3
> 		stop:1
> 		start:1
> 		reserved:3
> 		clock source:8
> 		pin_selection:8
> 
> so, you'd do this:
> 
> typedef struct {
>   char status:8;
>   char control:8;
>   char tx:8;
>   char rx:8;
>   long divisor:8;
>   long bits:3;
>   long stop:1;
>   long start:1;
>   long reserved:3;
>   long clock_source:8;
>   long pin_selection:8;
> } UartDev;
> 
> extern volatile UartDev uart1;
> 
> If you use SImode to access any of the first four registers, you may
> end up clearing a status bit you haven't read yet.  If you use QImode
> to write the divisor, you may end up clearing the other bits if gcc
> doesn't drive the right values onto the bus.
> 
> With our current code, the mode for access for the above would either
> always be QI or always be SI; there's no way to have QI for the first
> four and SI for the rest.
> 
> The culprit is get_best_mode(), which doesn't know the C type of the
> field.  PCC_BITFIELD_TYPE_MATTERS seems to only control layout, not
> access.  Even if it did solve the type-v-mode problem, turning it on
> would break ABI compatibility.

I don't know how the Ada front-end achieve this and wether it's portable
but the following seem to work:

procedure Aa is

   type U8 is mod 2**8;
   for U8'Size use 8;
   pragma Atomic (U8);

   type U8B is mod 2**8;
   type U3B is mod 2**3;
   type U1B is mod 2;

   type R1 is record
      B1 : U8B;
      B2 : U3B;
      B3 : U1B;
      B4 : U1B;
      B5 : U3B;
      B6, B7 : U8B;
   end record;
   pragma Pack (R1);
   pragma Atomic (R1);

   type R is record
      B1, B2, B3, B4 : U8;
      B5 : R1;
   end record;
   pragma Pack (R);
   pragma Volatile (R);

   X : R;
   X1 : R1;
begin
   X.B1 := 0;
   X.B2 := 0;
   X.B3 := 0;
   X.B4 := 0;
   X1 := X.B5;
end AA;


gcc -S -O2 aa.adb
_ada_aa:
.LFB1:
	movb	$0, -12(%rsp)
	movb	$0, -11(%rsp)
	movb	$0, -10(%rsp)
	movb	$0, -9(%rsp)
	movl	$0, -24(%rsp)
	ret




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