[英]inline assembly error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'
I have an inline AT&T style assembly block, which works with XMM registers and there are no problems in Release configuration of my XCode project, however I've stumbled upon this strange error (which is supposedly a GCC bug) in Debug configuration... Can I fix it somehow?我有一个内联AT&T样式的汇编块,它适用于XMM寄存器,并且在我的XCode项目的发布配置中没有问题,但是我在调试配置中偶然发现了这个奇怪的错误(据说是GCC错误)...我可以以某种方式修复它吗? There is nothing special in assembly code, but I am using a lot of memory constraints ( 12 constraints ), can this cause this problem?
汇编代码没什么特别的,但是我用了很多memory约束( 12个约束),会不会导致这个问题?
The Debug configuration uses -O0
by default. Debug 配置默认使用
-O0
。 Since this flag disables optimisations, the compiler is probably not being able to allocate registers given the constraints specified by your inline assembly code, resulting in register starvation.由于此标志禁用优化,编译器可能无法根据您的内联汇编代码指定的约束分配寄存器,从而导致寄存器不足。
One solution is to specify a different optimisation level, eg -Os
, which is the one used by default in the Release configuration.一种解决方案是指定不同的优化级别,例如
-Os
,这是发布配置中默认使用的优化级别。
Not a complete answer, sorry, but the comments section is too short for this...不是一个完整的答案,对不起,但评论部分太短了......
Can you post a sample asm("...":::)
line that demonstrates the problem?您可以发布一个示例
asm("...":::)
行来演示该问题吗?
The use of XMM registers is not the issue, the error message indicates that GCC wanted to create code like, say:使用 XMM 寄存器不是问题,错误消息表明 GCC 想要创建代码,例如:
movdqa (%rax),%xmm0
ie memory loads/stores through pointers held in general registers, and you specified more memory locations than available general-purpose regs (it's probably 12 in debug mode because because RBP
, RSP
are used for frame/stackpointer and likely RBX
for the global offset table and RAX
reserved for returns) without realizing register re-use potential.即 memory 通过保存在通用寄存器中的指针加载/存储,并且您指定的 memory 位置比可用的通用 regs 更多(在调试模式下可能为 12,因为因为
RBP
, RSP
用于帧/堆栈指针,并且可能用于全局偏移量的表RBX
和RAX
保留用于返回)而没有意识到寄存器重用的潜力。
You might be able to eek things out by doing something like:您可以通过执行以下操作来解决问题:
void *all_mem_args_tbl[16] = { memarg1, memarg2, ... };
void *trashme;
asm ("movq (%0), %1\n\t"
"movdqa (%1), %xmm0\n\t"
"movq 8(%0), %1\n\t"
"movdqa (%1), %xmm1\n\t"
...
: "r"all_mem_args_tbl : "r"(trashme) : ...);
ie put all the mem locations into a table that you pass as operand, and then manage the actual general-purpose register use on your own.即把所有的内存位置放到一个你作为操作数传递的表中,然后你自己管理实际的通用寄存器使用。 It might be two pointer accesses through the indirection table, but whether that makes a difference is hard to say without knowing your complete assembler code piece.
它可能是通过间接表访问两个指针,但是如果不知道完整的汇编代码段,很难说这是否会有所不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.