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



Reply via email to