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

时间:2015-08-05 23:32:15

标签: assembly mmx

我正在编写以下内容:

__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位。

2 个答案:

答案 0 :(得分:4)

来自this bugzilla:

  

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

     

这些真的不应该允许Reg64(movq是正确的助记符   按照规定在Reg64 / Mem64和RegXMM / RegMMX之间进行复制   英特尔的规范)。 AMD的规格已经存在了很长时间,   无法识别并为32位和64位指定了movd   操作

     

vmovd真的不应该允许64位操作数(vmovq是正确的   在Reg64 / Mem64和RegXMM之间复制的助记符,如下所示   英特尔AVX规范)。为了避免gcc x86后端的额外模板和   支持AMD64的汇编程序,我们接受vmovd上的64位操作数   我们可以为SSE和AVX指令使用一个模板。

答案 1 :(得分:0)

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

我测试了gcc 4.4虽然4.9,但有各种优化级别:

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

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