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