avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [avr-gcc-list] bug with bitfields in (volatile) registers?


From: Ben Mann
Subject: RE: [avr-gcc-list] bug with bitfields in (volatile) registers?
Date: Fri, 7 Jan 2005 15:29:17 +0800

Hi Ned,

I did a couple of little experiments. It looks like the problem is in the
treatment of the bitfield.

For example, changing the struct to 
{ unsigned char uartState; }
works fine.

int main(void)
{
   0:   c0 e0           ldi     r28, 0x00       ; 0
   2:   d0 e0           ldi     r29, 0x00       ; 0
   4:   de bf           out     0x3e, r29       ; 62
   6:   cd bf           out     0x3d, r28       ; 61

 for (;;)
 {
  while (state.uartState == 10)
   8:   8a e0           ldi     r24, 0x0A       ; 10
   a:   38 16           cp      r3, r24
   c:   e9 f3           breq    .-6             ; 0x8
   ;

  c = 'A';
   e:   01 e4           ldi     r16, 0x41       ; 65
  while (state2 == 10)
  10:   1a 30           cpi     r17, 0x0A       ; 10
  12:   f1 f3           breq    .-4             ; 0x10
   ;
  while (state3 == 10)
  14:   8a e0           ldi     r24, 0x0A       ; 10
  16:   98 16           cp      r9, r24
  18:   e9 f3           breq    .-6             ; 0x14
  1a:   f6 cf           rjmp    .-20            ; 0x8

A big clue was when I (stupidly) tried:

volatile register state_t state __asm__("r3");

...it gives an error about not having the address of the variable -
something only required by the bitfield.

Maybe this will help, I'm sure however that someone will have some more to
say about it.

Ben Mann


-----Original Message-----
From: address@hidden [mailto:address@hidden
On Behalf Of Ned Konz
Sent: Friday, 7 January 2005 2:44 PM
To: address@hidden
Subject: [avr-gcc-list] bug with bitfields in (volatile) registers?


I was just bit by this surprise with registers suddenly being treated as if 
they were not volatile (in avr-gcc 3.4.3). I'm using a chip with no RAM, so
I 
would like the registers to work properly.

// avr-gcc -Os -mmcu=avr2 -mcall-prologues -mint8 -mtiny-stack -save-temps 
-Wall -g -Wa,-almshd=registerbug.lst -Wl,--oformat=ihex -o registerbug.hex 
registerbug.c
// avr-objdump -h -S registerbug.o  > registerbug.lss

typedef struct
{
    unsigned char uartState:4;
    unsigned char unused:4;
} state_t;

register unsigned char c __asm__("r16");
register state_t state __asm__("r3");  // actually volatile... register
unsigned char state2 __asm__("r17"); register unsigned char state3
__asm__("r9");

int main(void)
{
   0: c0 e0        ldi r28, 0x00 ; 0
   2: d0 e0        ldi r29, 0x00 ; 0
   4: de bf        out 0x3e, r29 ; 62
   6: cd bf        out 0x3d, r28 ; 61

// look what's happening here: r3 is getting copied to r24...
   8: 83 2d        mov r24, r3
   a: 8f 70        andi r24, 0x0F ; 15
 for (;;)
 {
// and then the comparison is being done on r24.
// however, meanwhile an interrupt handler is changing r3, and we // get
stuck in this loop forever:
  while (state.uartState == 10)
   c: 8a 30        cpi r24, 0x0A ; 10
   e: f1 f3        breq .-4       ; 0xc
// that should be a branch back to 0x8 instead of 0xc!
   ;

  c = 'A';
  10: 01 e4        ldi r16, 0x41 ; 65

// here everything is fine because we can do a cpi:
  while (state2 == 10)
  12: 1a 30        cpi r17, 0x0A ; 10
  14: f1 f3        breq .-4       ; 0x12
   ;

// and here everything is fine because the generated code
// branches to the right place:
  while (state3 == 10)
  16: 9a e0        ldi r25, 0x0A ; 10
  18: 99 16        cp r9, r25
  1a: c1 f7        brne .-16      ; 0xc
  1c: 9a e0        ldi r25, 0x0A ; 10
  1e: 99 16        cp r9, r25
  20: d1 f3        breq .-12      ; 0x16
  22: f4 cf        rjmp .-24      ; 0xc
   ;
       }
}


Are registers supposed to be treated as if they were volatile?

Is this a bug?

Thanks,
-- 
Ned Konz
http://bike-nomad.com


_______________________________________________
avr-gcc-list mailing list
address@hidden http://www.avr1.org/mailman/listinfo/avr-gcc-list




reply via email to

[Prev in Thread] Current Thread [Next in Thread]