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

[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*




reply via email to

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