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.