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

            Bug ID: 121198
           Summary: [avr][hreg-constraints] error: 'asm' operand has
                    impossible constraints or there are not enough
                    registers
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: rtl-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: gjl at gcc dot gnu.org
  Target Milestone: ---

The following test case is a very common scenario where a 16-bit register x is
extended to something wider like y.  x occupies two 8-bit registers, y occupies
four:

// x comes in in r24..r25.                                                      
long foo (int x)
{
    long y;
    // y occupies r22..r25.                                                     
    // x occupies r22..r23.                                                     
    __asm volatile ("; %0" : "={r22}" (y) : "{r22}" (x));
    // Return in r22..r25.                                                      
    return y;
}

Compile with:

$ avr-gcc foo.c -S -dp -mmcu=atmega8
foo.c: In function 'foo':
foo.c:7:5: error: 'asm' operand has impossible constraints or there are not
enough registers
    7 |     __asm volatile ("; %0" : "={r22}" (y) : "{r22}" (x));
      |     ^~~~~

IMO the test case above should work, just like

long bar (int x)
{
    register long y __asm("22");
    register int r22 __asm("22") = x;
    __asm volatile ("; %0, %1" : "=r" (y) : "r" (r22));
    return y;
}

Configured with: ../../source/gcc-master/configure --target=avr
--enable-languages=c,c++ --disable-nls --disable-libcc1 -with-gnu-ld
--with-gnu-as --with-long-double=64

Reply via email to