Inline assembler translates LSL to wrong code


For some time critical issues I included inline assembler code into an Arduino sketch. Looking into the resulting assembler code I discovered, that the LSL (Logical Shift Left) instruction in the asm statement was translated to an ADD instruction in the assembler listing. The instruction LSR (Logical Shift Right) was translated correctly.

You can reproduce it by the following sketch:

   Inline assembler translates LSL (Logical Shift RLeft) to wrong code.
   sentido, 19.12.09
   Windows XP Professional

int ledPin =  13;

void setup()  {
  pinMode(ledPin, OUTPUT);     

void loop()                     
  // Just do something, otherwise the compiler removes everything while optimizing
  digitalWrite(ledPin, HIGH);   // set the LED on
  // to find location in assembler output easily
  asm volatile("nop");

  // BUG: lsl (Logical Shift Left) produces same output as add,
  //      lsr (Logical Shift Right) is translated correctly
  asm volatile("lsl r3");    // 33 0c   add   r3, r3  ;-> WRONG!!!
  asm volatile("add r3,r3"); // 33 0c   add   r3, r3  ;-> correct
  asm volatile("lsr r3");    // 36 94   lsr   r3      ;-> correct
  // The problem is the same with any other register

In the applet subdirectory execute e.g. "avr-objdump -d LSL_bug.cpp.elf > asm.txt" if you called the sketch LSL_bug and have a look into asm.txt.

Any hints on how to fix it, work around or whom to ask?


Give these a look...

Many thanks, of course it's the same, there is nothing wrong and my trust in the tool chain is back again!