Open
Description
The following proof of concept shows the issue:
#include <stdint.h>
uint32_t foo(void)
{
uint32_t result;
__asm__ volatile(
"ldi %A0, 1" "\n\t"
"ldi %B0, 2" "\n\t"
"ldi %C0, 3" "\n\t"
"ldi %D0, 4" "\n\t"
: "=r"(result)
: /* no inputs */
: /* no clobbers */
);
return result;
}
Compiling this with avr-gcc -mmcu=atmega328p -Os -S poc.c
yields:
.file "poc.c"
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__SREG__ = 0x3f
__tmp_reg__ = 0
__zero_reg__ = 1
.text
.global foo
.type foo, @function
foo:
push r28
push r29
rcall .
rcall .
in r28,__SP_L__
in r29,__SP_H__
/* prologue: function */
/* frame size = 4 */
/* stack size = 6 */
.L__stack_usage = 6
/* #APP */
; 6 "poc.c" 1
ldi r24, 1
ldi r25, 2
ldi r26, 3
ldi r27, 4
; 0 "" 2
/* #NOAPP */
movw r22,r24
movw r24,r26
/* epilogue start */
pop __tmp_reg__
pop __tmp_reg__
pop __tmp_reg__
pop __tmp_reg__
pop r29
pop r28
ret
.size foo, .-foo
.ident "GCC: (Alpine Linux) 11.3.0"
However, compilation with clang fails:
$ clang -target avr -mmcu=atmega328p -Os -S poc.c
poc.c:7:9: error: couldn't allocate output register for constraint 'r'
"ldi %A0, 1" "\n\t"
^
1 error generated.