Clang 集成汇编器和 "invalid operand for instruction"

标签 c assembly clang llvm inline-assembly

我们在默认配置中使用 Clang。在默认配置中,使用 Clang 的集成汇编程序(而不是系统汇编程序,如 GAS)。我无法确定以下问题的确切问题(并修复):

$ make
clang++ -DNDEBUG -g2 -O3 -Wall -fPIC -march=native -pipe -c gcm.cpp
...
gcm.cpp:676:3: error: invalid operand for instruction
                AS2(    movd    WORD_REG(di), xmm...
                ^
./cpu.h:221:20: note: expanded from macro 'AS2'
        #define AS2(x, y) GNU_AS2(x, y)
                          ^
./cpu.h:216:27: note: expanded from macro 'GNU_AS2'
        #define GNU_AS2(x, y) "\n\t" #x ", " #y ";"
                             ^
<inline asm>:110:12: note: instantiated into assembly here
        movd rdi, xmm0;
                  ^~~~~
gcm.cpp:685:3: error: invalid operand for instruction
                AS2(    movd    WORD_REG(di), xmm...
                ^
./cpu.h:221:20: note: expanded from macro 'AS2'
        #define AS2(x, y) GNU_AS2(x, y)
                          ^
./cpu.h:216:27: note: expanded from macro 'GNU_AS2'
        #define GNU_AS2(x, y) "\n\t" #x ", " #y ";"
                                 ^
<inline asm>:117:12: note: instantiated into assembly here
        movd rdi, xmm1;
                  ^~~~~

认为以上错误可能与Inline Assembly and Compatibility有关.但据我所知,rdi 是 64 位的,xmm1 是 128 位的,而 movd 指定了操作数的大小,所以兼容性问题不应适用。

上面的代码有什么问题?


您可以在 Crypto++ gcm.cpp Source File 在线检查源文件.如果您安装了 Clang,这个问题应该很容易重现:

git clone https://github.com/weidai11/cryptopp.git cryptopp-asm
cd cryptopp-asm
export CXX=clang++
make GAS210_OR_LATER=1 GAS219_OR_LATER=1 GAS219_OR_LATER=1

或者:

# Try to make just gcm.o
make GAS210_OR_LATER=1 GAS219_OR_LATER=1 GAS219_OR_LATER=1 gcm.o

奇怪的 make 行是由于 LLVM Bug 24200 - With integrated assembler enabled, failed to fetch version string of assembler .

最佳答案

r/m64, xmm 未在英特尔软件开发人员手册中列为 MOVD 指令的有效操作数组合。但是,支持以下两种形式:

MOVD r/m32, xmm
SSE2 Move doubleword from xmm register to r/m32.

MOVQ r/m64, xmm
SSE2 Move quadword from xmm register to r/m64.

这让我怀疑在为 64 位目标构建时 MOVD 指令需要是 MOVQ,或者 rdi 应该是替换为 edi(尽管这可能会影响依赖于 rdi 前 32 位的代码的其他部分)。

关于Clang 集成汇编器和 "invalid operand for instruction",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31558916/

相关文章:

c - 如何创建将 stdin 重定向到子进程的代理进程?

c - 数组元素作为不同数组的索引

assembly - 如何将寄存器中的VALUE移至NASM中的存储变量?

ios - clang 使用 Titanium/外部 iOS 模块构建错误

macos - 禁用汇编器警告 ".section __TEXT,__textcoal_nt,coalesced,pure_instructions"

相机在 OpenGL 中不会移动

c - 如何在c中用参数声明数组大小

c++ - 为什么 vs c++ 2010 编译器会为相似的函数生成不同的汇编代码

assembly - X86 IA32 组件,寄存器名称错误

c++ - 在作为静态成员包含在另一个类中的类的构造函数中使用 cout