That surely would also be an option. But it would make it more difficult for people to assign their on bitfield naming when relying on standard includes.
I have to add that AVR-GCC supports bitfield access to the I/O registers in exactly this way, also based on the SFR defines. The compiler is optimizing to use bit-set instructions that are only valid in the I/O space.
ok, I see. There seems to be a conflict in maintaining an orthogonal compiler with a non-orthogonal architecture :)
It's already used exactly like that in the HC08 library. See "\SDCC\include\hc08\". struct __hc08_bits { unsigned int bit0:1; unsigned int bit1:1; unsigned int bit2:1; unsigned int bit3:1; unsigned int bit4:1; unsigned int bit5:1; unsigned int bit6:1; unsigned int bit7:1; }; _VOLDATA _UINT8 __at 0x00 PTA; /* Port A Data Register */ #define PTA0 ((struct __hc08_bits *)(&PTA))->bit0 #define PTA1 ((struct __hc08_bits *)(&PTA))->bit1 #define PTA2 ((struct __hc08_bits *)(&PTA))->bit2 #define PTA3 ((struct...
Well, you know, this would be very useful to simplify direct access to individiual I/O pins. I believe the sdcc 8051 library also makes use of this? Instead of "PA & =^BV(1);" ; you could write "PA.p1=0;" or even "PA1=0;"
Ignore __attribute__((__packed__)) instead of throwing error
Of course! I added some additional examples that work, but where inefficient code is generated. The bit transfer could make use of "swapc", while the bittest could use "t0sn". __sfr __at(0x10) pa; #define PA pa // __sfr __at(0x10) PA struct PORT_bits { uint8_t p0:1; uint8_t p1:1; uint8_t p2:1; uint8_t p3:1; uint8_t p4:1; uint8_t p5:1; uint8_t p6:1; uint8_t p7:1; }; // __attribute__((__packed__)); #define BF_PA (*(volatile struct PORT_bits *)&PA) void main(void) { for (;;) { BF_PA.p0=1; // breaks...
The output again, something got mangled up: 260 ; bitfields.c: 55: BF_PA.p0=1; 000040 01 2F 261 mov a, #0x01 a 000042 262 or _pa+0, a 269 ; bitfields.c: 59: BF_PA.p0=0; 00004C FE 2F 270 mov a, #0xfe a 00004E 271 and _pa+0, a