[Bug c/65436] New: Max number of extended asm +input operands currently limited to 15
adam at consulting dot net.nz
gcc-bugzilla@gcc.gnu.org
Mon Mar 16 12:46:00 GMT 2015
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.
More information about the Gcc-bugs
mailing list