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

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

Re: [avr-gcc-list] char to int promotion in bitwise operators


From: Francisco Silva
Subject: Re: [avr-gcc-list] char to int promotion in bitwise operators
Date: Thu, 20 Aug 2009 23:01:03 -0300

2009/8/20 Andrew Zabolotny <address@hidden>:
> Hello!
>
> I've been looking at the compiled .S file for my library and have
> noticed that the code is substantially larger than could be because
> every my check for bitflags, like in this example:
>
> ------------------
> #define FLAG_A 0x01
> #define FLAG_B 0x02
>
> ...
>
> if (flags & FLAG_A) ...
> if (flags & FLAG_B) ...
> ------------------
>
> gcc will extend both 'flags' and FLAG_A to a 16-bit integer type and
> then do a 16-bit 'and' and compare. I recalled that I've seen something
> about this in avr-libc documentation, and indeed I found the section:
>
> 11.21 Why does the compiler compile an 8-bit operation that uses
>      bitwise operators into a 16-bit operation in assembly?
>
> However, the solution in that section does not help here anyway. If I
> modify those if's to look like:
>
> ------------------
> if (((unsigned char)flags) & ((unsigned char)FLAG_A) ...
> ------------------
>
> gcc will anyway expand both operands to int first :-( Even the
> following cumbersome example will result in everything being expanded
> (and even compared!) as 16-bit integers:
>
> ------------------
> if ((unsigned char)(((unsigned char)a) & ((unsigned char)FLAG)) !=
> (unsigned char)0) ...
> ------------------
>
> Is there a way to force the compiler to use 8-bit integers for bitwise
> operators? The only way I found so far is to use the -mint8 switch, but
> libc docs says that this option is not really supported by libc.
>
> --
> Andrew

Try the following spell:
 ------------------
 #define FLAG_A 0x01
 #define FLAG_B 0x02

 ...
uint8_t t /* temporary dummy variable */
 if ((t = flags & FLAG_A)) ...
 if ((t = flags & FLAG_B)) ...
 ------------------

The double parenteses avoids a ggc warning.
Most of the time this compiles to a sbrs instruction followed by a branch.

DISCLAIMER: don't count on it being consistent across gcc versions or
optimising options.


-- 
Francisco




reply via email to

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