6

我正在编程以下内容:

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

4

2 回答 2

4

这个bugzilla:

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

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

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

于 2015-08-05T23:40:31.307 回答
0

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

我测试了 gcc 4.4 到 4.9,具有各种优化级别:

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

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

于 2015-08-05T23:45:18.260 回答