mareiou
mareiou

Reputation: 414

Why the compiler changes movq to movd when doing 64bit operations?

I am programming the following:

__asm__ volatile ("movq %%rax, %%mm1\n"
                  "movq %%rcx, %%mm2\n"
                  : : "a" (0xDEADBEEFDEADBEEF), "c" (0xBADFACE5BADFACE5));

In this case, I am moving the value from rax to mm1 which both are 64b registers (moving a qword value from one register to another). But when I compile my code I see:

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 ?? 

I am compiling my code in 64bit mode, I am not sure why it is changing a 64bit operation to a 32bit.

Upvotes: 6

Views: 2391

Answers (2)

o11c
o11c

Reputation: 16086

Despite the linked bug report, I cannot reproduce.

I tested gcc 4.4 though 4.9, with various optimization levels:

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

In all cases, the resulting x.s file contained only movq, not movd.

Upvotes: 0

Alexguitar
Alexguitar

Reputation: 722

From this bugzilla:

This is done on purpose to provide backward compatibility since vmovq isn't in original x86-64 spec and older assemblers don't support it. From i386-opc.tbl in binutils:

These really shouldn't allow for Reg64 (movq is the right mnemonic for copying between Reg64/Mem64 and RegXMM/RegMMX, as is mandated by Intel's spec). AMD's spec, having been in existence for much longer, failed to recognize that and specified movd for 32- and 64-bit operations.

vmovd really shouldn't allow for 64bit operand (vmovq is the right mnemonic for copying between Reg64/Mem64 and RegXMM, as is mandated by Intel AVX spec). To avoid extra template in gcc x86 backend and support assembler for AMD64, we accept 64bit operand on vmovd so that we can use one template for both SSE and AVX instructions.

Upvotes: 4

Related Questions