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

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

[avr-gcc-list] uint8_t assembled as uint16_t in some cases?


From: Robert Baruch
Subject: [avr-gcc-list] uint8_t assembled as uint16_t in some cases?
Date: Tue, 09 Dec 2003 11:22:08 -0500
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/20030624

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,

I have some test code which shows that there's a case where gcc
needlessly converts a uint8_t into a uint16_t. Here's the code:

#include <avr/io.h>
#include <inttypes.h>

volatile uint8_t FLAGS = 0x01;

void main(void)
{
        uint8_t flags;

        /* busy loop */

        while ( ! ((flags=FLAGS) & 0x01) ) ;

        /* do stuff with flags copy */

        if (flags & 0x02)
                FLAGS |= 0x03;
}

The idea being that an interrupt changes the contents of FLAGS, a copy
is kept when the change happens, and we examine the copy. I get this
assembly (with avr-gcc version 3.3.1, using -O2 -mmcu=at90s2313):

void main(void)
{
~  4a:  cf ed           ldi     r28, 0xDF       ; 223
~  4c:  d0 e0           ldi     r29, 0x00       ; 0
~  4e:  de bf           out     0x3e, r29       ; 62
~  50:  cd bf           out     0x3d, r28       ; 61
        uint8_t flags;

        /* busy loop */

        while ( ! ((flags=FLAGS) & 0x01) ) ;
~  52:  80 91 60 00     lds     r24, 0x0060
~  56:  99 27           eor     r25, r25     /* WHY? */
~  58:  80 ff           sbrs    r24, 0
~  5a:  fb cf           rjmp    .-10            ; 0x52

        /* do stuff with flags copy */

        if (flags & 0x02)
~  5c:  81 ff           sbrs    r24, 1
~  5e:  05 c0           rjmp    .+10            ; 0x6a
                FLAGS |= 0x03;
~  60:  80 91 60 00     lds     r24, 0x0060
~  64:  83 60           ori     r24, 0x03       ; 3
~  66:  80 93 60 00     sts     0x0060, r24
}
~  6a:  00 c0           rjmp    .+0             ; 0x6c


So why the extra instruction at 0x56? It seems that although flags was
declared to be uint8_t, the compiler is treating it as a uint16_t. More,
if I change the if-statement from (flags & 0x02) to (flags == 0x02), the
extra instruction goes away. So it seems to have something to do with
the bit-wise operators.

Anyone have any idea? Is it a genuine bug? Is there somewhere in the
source I should be looking for this? Any workaround?

I know, it's only an extra one-cycle instruction, but it adds up when
you're in a loop.

Thanks,

- --Rob



-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQE/1faw3n80I35hhEsRAnGCAJ9jGbqGFxNxSN7ETWl1BwqMg6nAlQCeMyKg
L5xZhz0d9Jmm75COwVhzhME=
=9aYb
-----END PGP SIGNATURE-----



reply via email to

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