https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65436
Bug ID: 65436 Summary: Max number of extended asm +input operands currently limited to 15 Product: gcc Version: unknown Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: adam at consulting dot net.nz <https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html> states: "The total number of input + output + goto operands is limited to 30." It appears a "+" input operand is internally counted as a dual input plus output operand which limits the total number of such registers to 15: 30_operands.c: #include <stdint.h> typedef uint8_t u8x16_t __attribute__ ((vector_size (16))); int main(void) { register uint64_t rdi asm ("rdi"); register uint64_t rsi asm ("rsi"); register uint64_t r10 asm ("r10"); register uint64_t r11 asm ("r11"); register uint64_t rbx asm ("rbx"); register uint64_t rbp asm ("rbp"); register uint64_t r12 asm ("r12"); register uint64_t r14 asm ("r14"); register uint64_t r15 asm ("r15"); register uint64_t r13 asm ("r13"); register u8x16_t xmm2 asm ("xmm2"); register u8x16_t xmm3 asm ("xmm3"); register u8x16_t xmm4 asm ("xmm4"); register u8x16_t xmm5 asm ("xmm5"); register u8x16_t xmm6 asm ("xmm6"); register u8x16_t xmm7 asm ("xmm7"); //15 operands is OK asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), "+r" (r12), "+r" (r14), "+r" (r15), "+r" (r13), "+x" (xmm2), "+x" (xmm3), "+x" (xmm4), "+x" (xmm5), "+x" (xmm6)); //16 operands asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), "+r" (r12), "+r" (r14), "+r" (r15), "+r" (r13), "+x" (xmm2), "+x" (xmm3), "+x" (xmm4), "+x" (xmm5), "+x" (xmm6), "+x" (xmm7)); register u8x16_t xmm8 asm ("xmm8"); register u8x16_t xmm9 asm ("xmm9"); register u8x16_t xmm10 asm ("xmm10"); register u8x16_t xmm11 asm ("xmm11"); register u8x16_t xmm12 asm ("xmm12"); register u8x16_t xmm13 asm ("xmm13"); register u8x16_t xmm14 asm ("xmm14"); register u8x16_t xmm15 asm ("xmm15"); //24 operands asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), "+r" (r12), "+r" (r14), "+r" (r15), "+r" (r13), "+x" (xmm2), "+x" (xmm3), "+x" (xmm4), "+x" (xmm5), "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9), "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13), "+x" (xmm14), "+x" (xmm15)); register u8x16_t xmm0 asm ("xmm0"); register u8x16_t xmm1 asm ("xmm1"); register uint64_t rax asm ("rax"); register uint64_t rcx asm ("rcx"); register uint64_t rdx asm ("rdx"); register uint64_t r8 asm ("r8"); register uint64_t r9 asm ("r9"); //31 operands asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), "+r" (r12), "+r" (r14), "+r" (r15), "+r" (r13), "+x" (xmm2), "+x" (xmm3), "+x" (xmm4), "+x" (xmm5), "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9), "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13), "+x" (xmm14), "+x" (xmm15), "+x" (xmm0), "+x" (xmm1), "+r" (rax), "+r" (rcx), "+r" (rdx), "+r" (r8), "+r" (r9)); register uint64_t mmx0 asm ("mm0"); register uint64_t mmx1 asm ("mm1"); register uint64_t mmx2 asm ("mm2"); register uint64_t mmx3 asm ("mm3"); register uint64_t mmx4 asm ("mm4"); register uint64_t mmx5 asm ("mm5"); register uint64_t mmx6 asm ("mm6"); register uint64_t mmx7 asm ("mm7"); //39 operands asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), "+r" (r12), "+r" (r14), "+r" (r15), "+r" (r13), "+x" (xmm2), "+x" (xmm3), "+x" (xmm4), "+x" (xmm5), "+x" (xmm6), "+x" (xmm7), "+x" (xmm8), "+x" (xmm9), "+x" (xmm10), "+x" (xmm11), "+x" (xmm12), "+x" (xmm13), "+x" (xmm14), "+x" (xmm15), "+x" (xmm0), "+x" (xmm1), "+r" (rax), "+r" (rcx), "+r" (rdx), "+r" (r8), "+r" (r9), "+y" (mmx0), "+y" (mmx1), "+y" (mmx2), "+y" (mmx3), "+y" (mmx4), "+y" (mmx5), "+y" (mmx6), "+y" (mmx7)); return 0; } $ gcc-snapshot.sh -O3 30_operands.c 30_operands.c: In function 'main': 30_operands.c:29:3: error: more than 30 operands in 'asm' asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), ^ 30_operands.c:43:3: error: more than 30 operands in 'asm' asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), ^ 30_operands.c:57:3: error: more than 30 operands in 'asm' asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), ^ 30_operands.c:74:3: error: more than 30 operands in 'asm' asm volatile ("" : "+r" (rdi), "+r" (rsi), "+r" (r10), "+r" (r11), "+r" (rbx), "+r" (rbp), ^ CLANG compiles the program: $ clang-3.6 -Wall -O3 30_operands.c $ Due to the double counting of +input operands it would be sensible for the operand limit to be at least twice the number of architecture registers. For x64 the minimum should be 2*(16 GPR + 16 XMM + 8 MMX) = 80 operands. This minimum does not include provision for goto operands.