[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[avr-gcc-list] GCC does useless 16-bit operations
From: |
dan |
Subject: |
[avr-gcc-list] GCC does useless 16-bit operations |
Date: |
Thu, 10 May 2007 23:28:14 -0400 (EDT) |
For the C code:
uint8_t tx_producer_index;
...
{
...
uint8_t temp = (tx_producer_index + 1) % 64;
I get the assembly from gcc 3.4.4:
13a2: e0 91 f7 00 lds r30, 0x00F7
13a6: 8e 2f mov r24, r30
13a8: 99 27 eor r25, r25
13aa: 01 96 adiw r24, 0x01 ; 1
13ac: 9c 01 movw r18, r24
13ae: 80 7c andi r24, 0xC0 ; 192
13b0: 93 70 andi r25, 0x03 ; 3
13b2: 28 1b sub r18, r24
>From gcc 4.1.2, it's even worse:
1658: 80 91 f8 00 lds r24, 0x00F8
165c: e8 2f mov r30, r24
165e: ff 27 eor r31, r31
1660: cf 01 movw r24, r30
1662: 01 96 adiw r24, 0x01 ; 1
1664: 60 e4 ldi r22, 0x40 ; 64
1666: 70 e0 ldi r23, 0x00 ; 0
1668: e9 d2 rcall .+1490 ; 0x1c3c <__divmodhi4>
166a: 28 2f mov r18, r24
The C code:
uint8_t temp = (tx_producer_index + 1U) % 64;
is much much better with 3.4.4:
16de: e0 91 f7 00 lds r30, 0x00F7
16e2: ef 5f subi r30, 0xFF ; 255
16e4: 9e 2f mov r25, r30
16e6: 9f 73 andi r25, 0x3F ; 63
But
uint8_t temp = (tx_producer_index + (uint8_t) 1) % 64;
is the same as without the cast. So two issues:
1) Shouldn't the type of "(uint8_t) 1" be strictly no larger than the type
of 1U?
2) gcc 4.1.2 generates unuseably bad code for int16_t % int8_t when the
int8_t is a positive power-of-2 constant.
3) I'm not totally sure, but I think it shouldn't need 16-bit math in any
of this. And gcc 4.1.2 does use 16-bit math for the addition with the
64 unchanged, but doesn't if the 64 is replaced with 64U, which must
be an error of some sort.
Is there something I should do to figure out what GCC thinks it's doing?
-Daniel
*This .sig left intentionally blank*
- [avr-gcc-list] GCC does useless 16-bit operations,
dan <=