[Top][All Lists]
[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-----
- [avr-gcc-list] uint8_t assembled as uint16_t in some cases?,
Robert Baruch <=