[Top][All Lists]

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

Re: [avr-gcc-list] compilation results with avr-gcc 4.8.3

From: David Brown
Subject: Re: [avr-gcc-list] compilation results with avr-gcc 4.8.3
Date: Fri, 26 Sep 2014 10:41:25 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0

On 25/09/14 19:50, Christian Schmidt wrote:
> Hi again,
> I did some more testing and found that using
> int main (void) {
>     uint8_t reg;
>     do {
>         reg = PINx(I2C_PORT);  // macro translates to PIND
>   6a:   80 b3           in      r24, 0x10       ; 16
>     } while (((uint8_t) ~reg) & I2C_MASK);
>   6c:   80 95           com     r24
>   6e:   88 71           andi    r24, 0x18       ; 24
>   70:   e1 f7           brne    .-8             ; 0x6a <main>
> produces the intended result. Is it fair to conclude that the ~
> operator, applied to an unsigned char, does produce an int as output
> instead of the input type?
> Could that be considered a bug, or is this in line with the C specification?
> Regards,
> Christian

As Joerg says, the C specifications say that most arithmetic operations
on sizes less than "int" (i.e., signed and unsigned chars) get
"promoted" to int operations.  gcc has to generate code that follows
these rules, and it does it in the safest and easiest way - it promotes
the char to an int, and does the operation.  Then there are passes
(pattern matching, peephole optimisations, etc.) that try to remove the
extra instructions before generating the final code.

This process will generate bigger and slower code in some places, but
also makes it easier to take advantage of other optimisations in more
complex code (and it lets us AVR users get more benefit from work done
by the "big boys" in gcc development).  Many common cases are catered
for, so that extra code is often removed.  But there are plenty of
"missed optimisation" issues in the bug tracker, for cases where the
compiler does not fix up the code.  It is worth checking the bugzilla
lists for your case here - if it is not there from before, then add it.
 Every now and again, some dedicated soul goes on a "binge" and clears
up these issues, as they are sometimes quite straightforward to fix.

In the meantime, it can often help to use extra casts such as you did
here.  There are also other formulations of the same logic but which may
have better optimisation:

int main(void) {
        uint8_t reg;
        do {
                reg = PIND;
        while (!(reg & 0x18));

reply via email to

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