https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117659

            Bug ID: 117659
           Summary: [avr] Wrong code for u24 << 16
           Product: gcc
           Version: 15.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

The 24-bit shift << 16 produces wrong code when the input and output registers
are different:

typedef __uint24 T;

__attribute__((noipa))
T shift_16_r24 (T x)
{
  register T r24 __asm("24") = x << 16;
  __asm ("nop ; %0" : "+r" (r24));
  return r24;
}

int main (void)
{
  if (shift_16_r24 (1) != 0x10000)
    __builtin_abort ();

  return 0;
}

$ avr-gcc -mmcu=atmega128 -O1 -S -dp
shift_16_r24:
        mov r26,r24      ;  27  [c=12 l=3]  *ashlpsi3/2
        clr r25
        clr r24
/* #APP */
        nop ; r24       
/* #NOAPP */
        ...

The obvious reason is that ashlpsi3 allows the offset=16 alternative as a
3-operand operantion, but avr_out_ashlpsi3 is printing it as if it was a
2-operand insn.

Reply via email to