为什么在进行 64 位操作时,编译器将 move 更改为 move?

Why the compiler changes movq to movd when doing 64bit operations?

我正在编写以下程序:

__asm__ volatile ("movq %%rax, %%mm1\n"
                  "movq %%rcx, %%mm2\n"
                  : : "a" (0xDEADBEEFDEADBEEF), "c" (0xBADFACE5BADFACE5));

在这种情况下,我将值从 rax 移动到 mm1,它们都是 64b 寄存器(将 qword 值从一个寄存器移动到另一个寄存器)。但是当我编译我的代码时,我看到:

mov  rax, 0xDEADBEEFDEADBEEF
mov  rcx, 0xBADFACE5BADFACE5
movd mm1, rax     <-------------- Why it is doing a dword operation ??
movd mm2, rcx     <-------------- Why it is doing a dword operation ?? 

我正在 64 位模式下编译我的代码,我不确定为什么它会将 64 位操作更改为 32 位操作。

来自 thisbugzilla:

This is done on purpose to provide backward compatibility since vmovq isn't in original x86-64 spec and older assemblers don't support it. From i386-opc.tbl in binutils:

These really shouldn't allow for Reg64 (movq is the right mnemonic for copying between Reg64/Mem64 and RegXMM/RegMMX, as is mandated by Intel's spec). AMD's spec, having been in existence for much longer, failed to recognize that and specified movd for 32- and 64-bit operations.

vmovd really shouldn't allow for 64bit operand (vmovq is the right mnemonic for copying between Reg64/Mem64 and RegXMM, as is mandated by Intel AVX spec). To avoid extra template in gcc x86 backend and support assembler for AMD64, we accept 64bit operand on vmovd so that we can use one template for both SSE and AVX instructions.

尽管有链接的错误报告,但我无法重现。

我测试了 gcc 4.4 到 4.9,具有不同的优化级别:

x86_64-linux-gnu-gcc-$VERSION $OPTIMIZATION -S -o x.s x.c

在所有情况下,生成的 x.s 文件仅包含 movq,而不包含 movd