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

このバグジラから:

vmovq は元の x86-64 仕様になく、古いアセンブラはそれをサポートしていないため、これは後方互換性を提供するために意図的に行われます。binutils の i386-opc.tbl から:

これらは実際には Reg64 を許可すべきではありません (Intel の仕様で義務付けられているように、movq は Reg64/Mem64 と RegXMM/RegMMX の間でコピーするための正しいニーモニックです)。AMD の仕様は、ずっと前から存在していましたが、それを認識できず、32 ビットおよび 64 ビット操作用に movd を指定していました。

vmovd は実際には 64 ビット オペランドを許可すべきではありません (vmovq は、Intel AVX 仕様で義務付けられているように、Reg64/Mem64 と RegXMM の間でコピーするための正しいニーモニックです)。gcc x86 バックエンドで余分なテンプレートを回避し、AMD64 のアセンブラーをサポートするために、vmovd で 64 ビット オペランドを受け入れ、SSE と AVX 命令の両方に 1 つのテンプレートを使用できるようにします。

于 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 に答える