为什么编译器在执行64位操作时将movq更改为movd?

mar*_*iou 6 assembly mmx

我正在编程以下内容:

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

在这种情况下,我将值从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 ?? 
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*tar 4

来自这个bugzilla:

这样做的目的是为了提供向后兼容性,因为 vmovq 不在原始 x86-64 规范中,并且较旧的汇编程序不支持它。来自 binutils 中的 i386-opc.tbl:

这些确实不应该允许 Reg64(movq 是在 Reg64/Mem64 和 RegXMM/RegMMX 之间复制的正确助记符,正如英特尔规范所规定的那样)。AMD 的规范已经存在了很长时间,但未能认识到这一点,并为 32 位和 64 位操作指定了 movd。

vmovd 确实不应该允许 64 位操作数(vmovq 是在 Reg64/Mem64 和 RegXMM 之间复制的正确助记符,正如 Intel AVX 规范所规定的那样)。为了避免 gcc x86 后端中的额外模板并支持 AMD64 的汇编器,我们在 vmovd 上接受 64 位操作数,以便我们可以对 SSE 和 AVX 指令使用同一个模板。