bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug gas/11818] New: MOVD (mov doubleword) into 64-bit register with zer


From: adam at consulting dot net dot nz
Subject: [Bug gas/11818] New: MOVD (mov doubleword) into 64-bit register with zero extension incorrectly changed to load quadword
Date: 14 Jul 2010 00:47:15 -0000

Consider this inline assembly compiled by GCC on x86-64 Linux with the small
code model:

#include <stdint.h>

typedef uint32_t u32x4_t __attribute__ ((vector_size (16)));

void decode_and_jump(u32x4_t instructions) {
  void *ptr;
  asm("movd %[from], %[to]\n" : [to] "=r" (ptr) : [from] "x" (instructions));
  goto *ptr;
}

int main() {}

gcc-4.5 -O3 movd_movq.c && objdump -d -m i386:x86-64 a.out|less

00000000004004a0 <decode_and_jump>:
  4004a0:       66 48 0f 7e c0          movq   %xmm0,%rax
  4004a5:       ff e0                   jmpq   *%rax

I suspect GAS has incorrectly changed the move doubleword instruction to move
quadword because the destination argument is a 64-bit register. There needs to
be a distinction between moving a quadword into a 64-bit register and moving a
doubleword into a 64-bit register with zero extension to 64 bits. This
distinction should be defined by the different mnemonics MOVD and MOVQ.

Supplying a 32-bit variable to the inline assembly is suboptimal because GCC has
no knowledge that the opaque instruction actually zero-extended the 32-bit
register to 64 bits:

void decode_and_jump_alt(u32x4_t instructions) {
  uint32_t addr;
  asm("movd %[from], %[to]\n" : [to] "=r" (addr) : [from] "x" (instructions));
  void *ptr=(void *) addr;
  goto *ptr;
}

00000000004004c0 <decode_and_jump_alt>:
  4004c0:       66 0f 7e c0             movd   %xmm0,%eax
  4004c4:       89 c0                   mov    %eax,%eax
  4004c6:       ff e0                   jmpq   *%rax

In summary, GAS should translate the mnemonic MOVD (X)MM, R64 to MOVD (X)MM,
R32. Only the MOVQ mnemonic should move a quadword!

MOVD zero-extending 32-bit registers to 64 bits is defined behaviour:
<http://software.intel.com/en-us/forums/showthread.php?t=76103&o=d&s=lr>

-- 
           Summary: MOVD (mov doubleword) into 64-bit register with zero
                    extension incorrectly changed to load quadword
           Product: binutils
           Version: unspecified
            Status: NEW
          Severity: normal
          Priority: P2
         Component: gas
        AssignedTo: unassigned at sources dot redhat dot com
        ReportedBy: adam at consulting dot net dot nz
                CC: bug-binutils at gnu dot org


http://sourceware.org/bugzilla/show_bug.cgi?id=11818

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]