http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29560
Georg-Johann Lay <gjl at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |INVALID --- Comment #6 from Georg-Johann Lay <gjl at gcc dot gnu.org> 2011-06-21 18:24:44 UTC --- Closing this PR as invalid. As Andy already explained, for shift offsets >7 and <15 there has to be a defined result because int for avr-gcc is 16 bits, and this is actually *not* a byte shift. With alternative code that tested for these offsets at runtime, jumped around and loaded 0 if appropriate, you were not better of than with the current code -- in the contrary. Note that gcc deflates you function calls to just one instruction in main. So maybe what you really want here is to make these functions static inline so that you do no more see the code in the functions. Presumably you always call this functions with compile time constants. If you really need to quench out the last tick and call with non-constants, you could invent inline assembler with an instruction sequence that is similar to (1 << (R24 & 7)), perhaps together with __builtin_constant_p magic: LDI R24, 1 SBRC R24, 1 LDI R24, 4 SBRC R24, 0 LSL R24 SBRC R24, 2 SWAP R24 Note that with -mint8, int is 8 bits. That is still present as option, but no more supported and perhaps non-functional. -- Just for reference; here is a source without external #include: #define PORTC (*((unsigned char volatile*) 53)) void setpin(unsigned char pin, unsigned char val) { if (val == 1) PORTC |= (1<<pin); else PORTC &= ~(1<<pin); } void setpin1(unsigned char pin, unsigned char val) { const unsigned char one = 1; if (val == 1) PORTC |= (one<<(pin)); else PORTC &= ~(one<<pin); } int main(void) { setpin(3, 1); setpin1(3, 1); return 0; }