[Top][All Lists]
[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.
- [Bug gas/11818] New: MOVD (mov doubleword) into 64-bit register with zero extension incorrectly changed to load quadword,
adam at consulting dot net dot nz <=