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

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

Re: [avr-gcc-list] GCC 3.0.2 unsigned int bug?


From: Bruce D. Lightner
Subject: Re: [avr-gcc-list] GCC 3.0.2 unsigned int bug?
Date: Mon, 17 Dec 2001 13:29:07 -0800

Chris,

> I'm new here... just playing around with avr-gcc 3.0.2 on
> Linux.
> 
> I'm having trouble understanding this:
> 
> void delay(void)
> {
>         unsigned int d;
> 
>         d = 0x1000;
>         while (d) d--;
> }
> 
> generates this code (using avr-objdump --disassemble):
> 
> 0000004a <delay>:
>   4a:   80 e0           ldi     r24, 0x00       ; 0
>   4c:   90 e1           ldi     r25, 0x10       ; 16
>   4e:   80 50           subi    r24, 0x00       ; 0
>   50:   94 40           sbci    r25, 0x04       ; 4
>   52:   e9 f7           brne    .-6             ; 0x4e
>   54:   08 95           ret
> 
> I can clearly see that the MSB goes in r25 and the LSB in r24
> but then why does it subtract 0x04 from the MSB each iteration?
> 
> Suspecting maybe a disassembler problem, the '94 40' opcode
> indeed would subtract 0x40 from the MSB wouldn't it?
> 
> Am I missing something obvious here or is this a bug?

Apparently, this is a "feature", not a bug.  You no doubt have the "avr-gcc"
optimizer turned on (e.g., "-Os) and thereby gave it free license to do
anthing it wants to your loop code.  The newest releases of "avr-gcc" does
just that.  I would expect the optimizer to remove the loop completely, but
instead it decrements the loop count by a seemingly arbitrary large number
on each iteration.

You can probably fix the problem by either declaring "d" volatile, but you
won't believe big the code gets that "avr-gcc" generates in that case! 
Also, you can make "d" global by moving it outside the delay() routine,
which gives you tight code, but costs a couple of bytes of RAM.

I just "got bit" by this one myself when re-compiling some old AVR C-code
under the new "improved" version of "avr-gcc".  This comes up so often in
this discussion list that I'm tempted to hunt this one down and fix it!

Here's what I ended up doing...

   static void dummy(void) { }

   void delay(void)
   {
       unsigned short count = 25000;

       while(--count) dummy();
   }

This gives one a little better AVR code (and the correct behavior even with
the "optimizer" turned on).  But I can't promise that sometime in the future
that "gcc" might force one to move "dummy()" to a separately compiled
module!

Best regards,

Bruce

-- 
 Bruce D. Lightner
 La Jolla, California
 Email: address@hidden
 URL: http://www.lightner.net/lightner/bruce/



reply via email to

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