Closed llvmbot closed 3 years ago
From the X86InstrInfo.td
// Match 'movd GR64, MMX' as an alias for movq to be compatible with gas,
// which supports this due to an old AMD documentation bug when 64-bit mode was
// created.
def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
(MMX_MOVD64to64rr VR64:$dst, GR64:$src), 0>;
def : InstAlias<"movd\t{$src, $dst|$dst, $src}",
(MMX_MOVD64from64rr GR64:$dst, VR64:$src), 0>;
I'm reopening this and changing the name summary slightly. I don't know if that is correct or if I should just open another bug.
movd %r8, %mm7 should be illegal. (Correct code would use r8d.) However, instead of syntax erroring, movd is instead silently converted to movq %r8, %mm7
BAD: echo "movd %r8, %mm7" | llvm-mc -show-encoding -assemble -triple x86_64-unknown-unknown
.text
movq %r8, %mm7 # encoding: [0x49,0x0f,0x6e,0xf8]
GOOD: echo "movd %r8d, %mm7" | llvm-mc -show-encoding -assemble -triple x86_64-unknown-unknown
.text
movd %r8d, %mm7 # encoding: [0x41,0x0f,0x6e,0xf8]
GOOD: echo "movq %r8, %mm7" | llvm-mc -show-encoding -assemble -triple x86_64-unknown-unknown
.text
movq %r8, %mm7 # encoding: [0x49,0x0f,0x6e,0xf8]
There are TWO sets of MOVQ instructions. This I did not know.
There's "MOVD/MOVQ—Move Doubleword/Move Quadword"
NP REX.W + 0F 6E /r MOVQ mm, r/m64 NP REX.W + 0F 7E /r MOVQ r/m64, mm 66 REX.W 0F 6E /r MOVQ xmm, r/m64 66 REX.W 0F 7E /r MOVQ r/m64, xmm
NP 0F 6E /r MOVD mm, r/m32 NP 0F 7E /r MOVD r/m32, mm 66 0F 6E /r MOVD xmm, r/m32 66 0F 7E /r MOVD r/m32, xmm
and there is also "MOVQ—Move Quadword"
NP 0F 6F /r MOVQ mm, mm/m64 NP 0F 7F /r MOVQ mm/m64, mm F3 0F 7E /r MOVQ xmm1, xmm2/m64
The first does NOT support MOVD mm0, mm1. The second supports MOVQ mm0, mm1.
No bug.
AFAIK, ICC also uses GNU assembler by default.
gcc and icc both reject this if you select "compile to binary" in output on godbolt. For gcc its probably because they don't have an integrated assembler and need the GNU assembler to evaluate the assembly text. That's a separate process. I don't know how icc's internals work.
Extended Description
In x86_64, movd mm0, mm1 gets an invalid operand error. gcc and icc both accept this. The bug happens when there are two mmx register operands for movd. It doesn't happen for movq or with only a single mmx register operand.
https://godbolt.org/z/7GEdrz