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

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

Re: [avr-gcc-list] Byte values promoted to int when during compare


From: Matthew Arcus
Subject: Re: [avr-gcc-list] Byte values promoted to int when during compare
Date: Sat, 17 Jul 2004 18:27:51 +0100

On Thursday 24 June 2004 5:15 pm, address@hidden wrote:
> >>> unsigned char A,B; ... A & 15 != B ...
> >>
> >>  It seems that A is promoted to int before the binary & operation ?
> >>  But why?
> >
> > Because the C standard says so.
>
> And because the compiler was not clever enough (or was not instructed
> to do so?) to optimize this back to byte-only operations?

I was looking at the code generated for:

unsigned int get16(unsigned char *p)
{
  return (*p << 8) | *(p+1);
}

which (target 8535, -Os) compiles to (comments inserted by myself):

        movw r30,r24 // Copy parameter p (R24, R25) to Z register (R30 & R31)
        ld r24,Z     // Load R24 indirect from Z
        clr r25      // R25 = 0
        mov r19,r24  // R19 = R24
        clr r18      // R18 = 0
        ldd r24,Z+1  // Load R24 indirect from Z+1
        clr r25      // R25 = 0
        or r18,r24   // R18 = R18 | R24, ie. R18 = R24, since R18 = 0
        or r19,r25   // R19 = R19 | R25, ie. R19 = R19, since R25 = 0
        movw r24,r18 // Move result (in R18/19) to return value register 
(R24/25)
        ret

(the code for -O3 is similar).

OK, so the copying to Z is necessary, since we only have a limited
range of index registers that we can use, and we have to do the load
indirects, but we should be able to simplify to something like:

        movw r30,r24 // Copy parameter p (R24, R25) to Z register (R30 & R31)
        ld r24,Z     // Load R24 indirect from Z
        ld r25,Z+1   // Load R24 indirect from Z+1
        ret

The problem, I guess, is that the intermediate values are all 16-bit
(since that's the size of an int on the AVR) and presumably are
represented as 16-bit values in the RTL, where most of the
optimization takes place, but the RTL optimizer doesn't know about the
mapping of RTL registers to pairs of 8-bit registers, so we don't get
the obvious optimizations happening.

Is there any scope for adding some sort of optimization stage after the 
conversion to 8-bit register code that will get rid of some of this stuff 
(my knowledge of GCC internals is limited to a quick eyeballing of the 
relevant parts of the code)?

Matthew.


reply via email to

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