Skip to content

allocating 32 bit number as registers in AVR inline assembly fails #55159

Open
@maribu

Description

@maribu

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions