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

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

[avr-gcc-list] Gcc bug??


From: Brian Cuthie
Subject: [avr-gcc-list] Gcc bug??
Date: Wed, 10 Mar 2004 10:30:54 -0500

I've got an interrupt handler that contains a switch statement. With -O
optimization, it seems to work fine. Without any optimization (no -O) the
whole machine crashes within seconds.  Looking at the code generated by the
compiler, I'm puzzled over how the unoptimized version could ever work.

Here's the beginning of the optimized version of the interrupt handler (this
is unlinked, so absolute addresses are null):

00000000 <__vector_17>:
uint8_t status;

AVRX_SIGINT(SIG_2WIRE_SERIAL)
{
    IntProlog();                // Switch to kernel stack/context
   0:   0e 94 00 00     call    0x0

        // process twi state changes
        
        status = TWSR & TWSR_STATUS_MASK;
   4:   81 b1           in      r24, 0x01       ; 1
   6:   98 2f           mov     r25, r24
   8:   98 7f           andi    r25, 0xF8       ; 248
   a:   90 93 00 00     sts     0x0000, r25
        
        if (iMode == TWI_S_MODE_LISTEN) {
   e:   80 91 00 00     lds     r24, 0x0000
  12:   85 30           cpi     r24, 0x05       ; 5
  14:   f1 f4           brne    .+60            ; 0x52
        
                // we're listening for a new connection attempt.

                switch (status) {
  16:   89 2f           mov     r24, r25
  18:   99 27           eor     r25, r25
  1a:   80 37           cpi     r24, 0x70       ; 112
  1c:   91 05           cpc     r25, r1
  1e:   69 f0           breq    .+26            ; 0x3a
  20:   81 37           cpi     r24, 0x71       ; 113
  22:   91 05           cpc     r25, r1
  24:   24 f4           brge    .+8             ; 0x2e
  26:   80 36           cpi     r24, 0x60       ; 96
  28:   91 05           cpc     r25, r1
  2a:   29 f0           breq    .+10            ; 0x36
  2c:   ee c0           rjmp    .+476           ; 0x20a
  2e:   88 3a           cpi     r24, 0xA8       ; 168
  30:   91 05           cpc     r25, r1
  32:   29 f0           breq    .+10            ; 0x3e
  34:   ea c0           rjmp    .+468           ; 0x20a
.

Nice code. Clean, and it seems to work.

Now here's the unoptimized version:

00000000 <__vector_17>:
uint8_t status;

AVRX_SIGINT(SIG_2WIRE_SERIAL)
{
    IntProlog();                // Switch to kernel stack/context
   0:   0e 94 00 00     call    0x0

        // process twi state changes
        
        status = TWSR & TWSR_STATUS_MASK;
   4:   98 ef           ldi     r25, 0xF8       ; 248
   6:   80 91 21 00     lds     r24, 0x0021
   a:   89 23           and     r24, r25
   c:   80 93 00 00     sts     0x0000, r24
        
        if (iMode == TWI_S_MODE_LISTEN) {
  10:   80 91 00 00     lds     r24, 0x0000
  14:   85 30           cpi     r24, 0x05       ; 5
  16:   09 f0           breq    .+2             ; 0x1a
  18:   41 c0           rjmp    .+130           ; 0x9c
        
                // we're listening for a new connection attempt.

                switch (status) {
  1a:   80 91 00 00     lds     r24, 0x0000
  1e:   28 2f           mov     r18, r24
  20:   33 27           eor     r19, r19
  22:   29 83           std     Y+1, r18        ; 0x01
  24:   3a 83           std     Y+2, r19        ; 0x02
  26:   89 81           ldd     r24, Y+1        ; 0x01
  28:   9a 81           ldd     r25, Y+2        ; 0x02
  2a:   80 37           cpi     r24, 0x70       ; 112
  2c:   91 05           cpc     r25, r1
  2e:   e1 f0           breq    .+56            ; 0x68
  30:   29 81           ldd     r18, Y+1        ; 0x01
  32:   3a 81           ldd     r19, Y+2        ; 0x02
  34:   21 37           cpi     r18, 0x71       ; 113
  36:   31 05           cpc     r19, r1
  38:   34 f4           brge    .+12            ; 0x46
  3a:   89 81           ldd     r24, Y+1        ; 0x01
  3c:   9a 81           ldd     r25, Y+2        ; 0x02
  3e:   80 36           cpi     r24, 0x60       ; 96
  40:   91 05           cpc     r25, r1
  42:   39 f0           breq    .+14            ; 0x52
  44:   27 c0           rjmp    .+78            ; 0x94
  46:   29 81           ldd     r18, Y+1        ; 0x01
  48:   3a 81           ldd     r19, Y+2        ; 0x02
  4a:   28 3a           cpi     r18, 0xA8       ; 168
  4c:   31 05           cpc     r19, r1
  4e:   b9 f0           breq    .+46            ; 0x7e
  50:   21 c0           rjmp    .+66            ; 0x94
.

Pretty ugly. Worse, it appears to me that the Y register gets used to do an
indirect store without being initialized. Since we don't what the state of Y
was when the interrupt occurs, I suspect this is the cause of my memory
corruption and crashes when running this unoptimized version.

It's worth also pointing out that an app that has run literally for weeks
without error dies within seconds using the unoptimized code.

Any thoughts?

Thanks

-brian
_______________________________________________
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]