我正在编写以下内容:
__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位。
答案 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
。