Reputation: 102426
We are using Clang in a default configuration. In the default configuration, Clang's Integrated Assembler is used (and not the system assembler, like GAS). I'm having trouble determining the exact problem (and fix) for:
$ 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;
^~~~~
I think the errors above may be related to Inline Assembly and Compatibility. But as far as I know, rdi
is 64-bits, xmm1
is 128-bits, and the movd
specifies the operand size, so the compatibility issue should not apply.
What is the problem with the code above?
You can examine the source file online at Crypto++ gcm.cpp Source File. The issue should be easy to duplicate if you have Clang installed:
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
Or:
# Try to make just gcm.o
make GAS210_OR_LATER=1 GAS219_OR_LATER=1 GAS219_OR_LATER=1 gcm.o
The odd looking make
line is due to LLVM Bug 24200 - With integrated assembler enabled, failed to fetch version string of assembler.
Upvotes: 1
Views: 9345
Reputation: 58507
r/m64, xmm
is not listed as a valid operand combination for the MOVD
instruction in Intel's Software Developers' Manual. However, the following two forms are supported:
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.
Which makes me suspect that the MOVD
instruction needs to be a MOVQ
when building for 64-bit targets, or that rdi
is supposed to be replaced by edi
(although that might affect other parts of the code that rely on the top 32 bits of rdi
).
Upvotes: 3