Instruction
MOVD
Moves 32 bits between an MMX or XMM register and a general-purpose register or memory, zeroing the rest of a vector register.
MOVD copies 32 bits between a vector register and a general-purpose register or memory. MOVQ does the same for 64 bits.
Into an XMM register, the value lands in bits 31:0 and bits 127:32
become zero. The legacy SSE form leaves bits 128 and up alone, as the
cases recorded on Zen 5 show; VMOVD clears them too. In
the other direction, a 32-bit general-purpose destination is written
like any 32-bit register, with bits 63:32 cleared: on Zen 5,
movd r9d, xmm12 turned R9 from F59C1659221BC591h into
00000000D5C8BBAEh.
In compiled code
GCC 14 and Clang 23 at -O2 emit MOVD wherever a 32-bit value changes sides:
_mm_cvtsi32_si128and_mm_cvtsi128_si32;- reading the bits of a
floatby copying it into auint32_twithmemcpy, and back: the System V ABI passes floats in XMM registers, so this ismovd eax, xmm0ormovd xmm0, edi; _mm_set1_epi32(x): MOVD, then PSHUFD with 0 to copy the doubleword into all four positions. With AVX2 the second step is VPBROADCASTD, and with AVX-512 VPBROADCASTD reads the general-purpose register itself, without MOVD.
For a 4-byte load or store, _mm_loadu_si32 and _mm_storeu_si32, GCC
uses MOVD and Clang MOVSS, which from memory also clears
bits 127:32.
The MMX forms
The encodings without the 66 prefix use MMX registers, which share their
bits with the x87 stack. Like every MMX instruction, they set the x87
TOP to 0 and mark all eight registers valid, and a write to an MMX
register sets bits 79:64 of the x87 register behind it to ones (Intel’s
volume 1, section 9.6.2). After movd mm3, esi on Zen 5, the register
behind MM3 held FFFF00000000C1A0BCE2h, though its bits 79:64 were all
ones before as well. x87 code that follows needs EMMS
first. Neither compiler emits these forms for 64-bit code: both compile
the MMX intrinsics _mm_cvtsi32_si64 and _mm_cvtsi64_si32 to the SSE
form on XMM registers.
The 64-bit form
With REX.W, the same opcodes move 64 bits. Intel’s manual names that
form MOVQ, and so does this site; AMD’s manual lists it under MOVD with
a 64-bit operand. GNU as 2.44 encodes movd xmm0, rax as
movq xmm0, rax.
AMD’s Zen 5 guide lists the legacy MOVD from a general-purpose register into an XMM register as two macro-ops, and VMOVD as one; the moves out of a vector register are one macro-op in both encodings.
In the optimization guide
What the optimization guide says about MOVD, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Bulldozer to Excavator
- Vectors and floating point: Moving a general register to an XMM register with MOVD is a double instruction of 8 cycles, so AMD advises a store and a reload instead, and GCC makes no direct moves to vector registers when tuning for these cores; the way back, MOVD to a general register, is a single instruction. sources differ
Jaguar and Puma
- Vectors and floating point: A move from a general register to an XMM register, as MOVD or an operand of CVTSI2SD or PINSRD, goes through a private scratch location in memory: a store and a load that add 6 cycles. sources differ
Forms
| Instruction | Encoding | Requires |
|---|---|---|
MOVD xmm, m32
MOVD_XMMdq_MEMd | 66 0F 6E /r | SSE2 |
MOVD m32, xmm
MOVD_MEMd_XMMd | 66 0F 7E /r | SSE2 |
MOVD xmm, r32
MOVD_XMMdq_GPR32 | 66 0F 6E /r | SSE2 |
MOVD r32, xmm
MOVD_GPR32_XMMd | 66 0F 7E /r | SSE2 |
MOVD mm, m32
MOVD_MMXq_MEMd | NP 0F 6E /r | MMX |
MOVD mm, r32
MOVD_MMXq_GPR32 | NP 0F 6E /r | MMX |
MOVD m32, mm
MOVD_MEMd_MMXd | NP 0F 7E /r | MMX |
MOVD r32, mm
MOVD_GPR32_MMXd | NP 0F 7E /r | MMX |
Data flow
Where the elements of the sources go, element 0 on the right; results that depend on a control value are drawn for an example. How to read.
MOVD mm, r/m32 MOVD xmm, r/m32Result doublewords 3 to 0: 0, 0, 0, a0.
MOVD r/m32, mm MOVD r/m32, xmmm32 receives doubleword 0 of xmm2: a0.
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
MOVD xmm, r/m32xmm1.write(src2.d[0]) # bits 127:32 zeroed
# bits 128 and up of the register are unchangedRun on AMD Zen 5 (EPYC 9645): 2 cases.
MOVD r/m32, xmmdest.write(xmm2.d[0]) # a register: bits 63:32 cleared
Run on AMD Zen 5 (EPYC 9645): 2 cases.
MOVD mm, r/m32mm1.write(src2.d[0]) # bits 63:32 zeroed
# x87: TOP = 0, all tags valid, bits 79:64 of mm1's register all onesRun on AMD Zen 5 (EPYC 9645): 2 cases.
MOVD r/m32, mmdest.write(mm2.d[0]) # a register: bits 63:32 cleared
# x87: TOP = 0, all tags validRun on AMD Zen 5 (EPYC 9645): 2 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
MOVD xmm, r/m32 | ||
xmm | explicit | write |
r/m32 | explicit | read |
MOVD r/m32, xmm | ||
r/m32 | explicit | write |
xmm | explicit | read |
MOVD mm, r/m32 | ||
mm | explicit | write |
r/m32 | explicit | read |
MOVD r/m32, mm | ||
r/m32 | explicit | write |
mm | explicit | read |
Flags
None: XED records no flag that the forms test or change.
Exceptions
The exception class is XED's name for the set of exception conditions that a form follows. How to read.
Attributes
What else XED records about the forms. How to read.
MOVD mm, r/m32MOVD r/m32, mm- may abort a TSX transaction
Intrinsics
The C intrinsics of Clang 23.1.2 that compile to MOVD, each with the form it compiles to and the Clang options it needs. The forms come from compiling every intrinsic and decoding the result with Intel XED; all intrinsics A–Z explains the method.
| Intrinsic | Compiles to |
|---|---|
_castf32_u32
unsigned int _castf32_u32(float __A) |
|
_mm_cvtsi128_si32
int _mm_cvtsi128_si32(__m128i __a) |
|
_mm_cvtsi32_si128
__m128i _mm_cvtsi32_si128(int __a) |
|
_mm_cvtsi32_si64
__m64 _mm_cvtsi32_si64(int __i) |
|
_mm_cvtsi64_si32
int _mm_cvtsi64_si32(__m64 __m) |
|
_mm_loadu_si32
__m128i _mm_loadu_si32(const void *__a) |
|
_mm_storeu_si32
void _mm_storeu_si32(void *__p, __m128i __b) |
|
CPUID and processors
Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.
More SSE2 instructions
- CVTPS2DQ
- CVTPS2PD
- CVTSD2SI
- CVTSD2SS
- CVTSI2SD
- CVTSS2SD
- CVTTPD2DQ
- CVTTPD2PI
- CVTTPS2DQ
- CVTTSD2SI
- DIVPD
- DIVSD
- LFENCE
- MASKMOVDQU
- MAXPD
- MAXSD
- MFENCE
- MINPD
- MINSD
- MOVAPD
- MOVDQ2Q
- MOVDQA
- MOVDQU
- MOVHPD
- MOVLPD
- MOVMSKPD
- MOVNTDQ
- MOVNTI
- MOVNTPD
- MOVQ
- MOVQ2DQ
- MOVSD
- MOVUPD
- MULPD
- MULSD
- ORPD
- PACKSSDW
- PACKSSWB
- PACKUSWB
- PADDB
More MMX instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - Clang's x86 intrinsic headers, LLVM 23.1.2 (commit
85ac56026243): the intrinsics, their signatures and doc comments, and the Clang of that release, which compiled each of them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2B, page 4-54 (MOVD/
MOVQ) - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 4: 128-Bit and 256-Bit Media Instructions (26568, rev. 3.25, November 2021), Wayback Machine copy of AMD's PDF
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The intrinsics and their signatures come from Clang, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.