开发者

inline assembly error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'

开发者 https://www.devze.com 2023-03-09 16:29 出处:网络
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 (w

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? There is nothing special in assembly code, but I am using a lot of memory c开发者_如何学Pythononstraints (12 constraints), can this cause this problem?


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 ?

The use of XMM registers is not the issue, the error message indicates that GCC wanted to create code like, say:

movdqa (%rax),%xmm0

i.e. 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.

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) : ...);

i.e. 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.


The Debug configuration uses -O0 by default. 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, e.g. -Os, which is the one used by default in the Release configuration.

0

精彩评论

暂无评论...
验证码 换一张
取 消