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

            Bug ID: 127165
           Summary: asm() limited to 30 arguments
           Product: gcc
           Version: 16.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: andrew.cooper3 at citrix dot com
  Target Milestone: ---

The following logic is necessary to make a PSCI v1.2 compliant SMC call on
Aarch64 using inline assembly:

-----
struct psci_args {
    unsigned long
    x0,  x1,  x2,  x3,  x4,  x5,  x6,  x7,  x8, 
    x9,  x10, x11, x12, x13, x14, x15, x16, x17;
};

void psci_1_2(struct psci_args *regs)
{
    register unsigned long r0  asm("x0")  = regs->x0;
    register unsigned long r1  asm("x1")  = regs->x1;
    register unsigned long r2  asm("x2")  = regs->x2;
    register unsigned long r3  asm("x3")  = regs->x3;
    register unsigned long r4  asm("x4")  = regs->x4;
    register unsigned long r5  asm("x5")  = regs->x5;
    register unsigned long r6  asm("x6")  = regs->x6;
    register unsigned long r7  asm("x7")  = regs->x7;
    register unsigned long r8  asm("x8")  = regs->x8;
    register unsigned long r9  asm("x9")  = regs->x9;
    register unsigned long r10 asm("x10") = regs->x10;
    register unsigned long r11 asm("x11") = regs->x11;
    register unsigned long r12 asm("x12") = regs->x12;
    register unsigned long r13 asm("x13") = regs->x13;
    register unsigned long r14 asm("x14") = regs->x14;
    register unsigned long r15 asm("x15") = regs->x15;
    register unsigned long r16 asm("x16") = regs->x16;
    register unsigned long r17 asm("x17") = regs->x17;

    asm volatile (
        "smc #0"
        : "+r" (r0),  "+r" (r1),  "+r" (r2),  "+r" (r3),
          "+r" (r4),  "+r" (r5),  "+r" (r6),  "+r" (r7),
          "+r" (r8),  "+r" (r9),  "+r" (r10), "+r" (r11),
          "+r" (r12), "+r" (r13), "+r" (r14), "+r" (r15),
          "+r" (r16), "+r" (r17)
        :
        : "memory" );

    regs->x0  = r0;
    regs->x1  = r1;
    regs->x2  = r2;
    regs->x3  = r3;
    regs->x4  = r4;
    regs->x5  = r5;
    regs->x6  = r6;
    regs->x7  = r7;
    regs->x8  = r8;
    regs->x9  = r9;
    regs->x10 = r10;
    regs->x11 = r11;
    regs->x12 = r12;
    regs->x13 = r13;
    regs->x14 = r14;
    regs->x15 = r15;
    regs->x16 = r16;
    regs->x17 = r17;
}
-----
yet trying to compile it fails with:

<source>: In function 'psci_1_2':
<source>:28:5: error: more than 30 operands in 'asm'
   28 |     asm volatile (
      |     ^~~
Compiler returned: 1

Full Godbolt example: https://godbolt.org/z/Wj33abKvE

Clang can compile this just fine, and the limit of 30 arguments for an asm()
seems arbitrary, and isn't sufficient for architectures with 32 registers.

Is there anything stopping the limit being higher?

Reply via email to