Instruction
MOVHLPS
Copies the high two singles of the source into the low half of the destination XMM register.
- Extensions
- Forms
- 1 (1 Legacy)
- Data
- Intel XED v2026.08.23
MOVHLPS copies the high 64 bits of its second register to the low 64
bits of the first and keeps the first’s high half: movhlps xmm0, xmm1
leaves xmm1[127:64] in bits 63:0 of XMM0. It moves bits, two singles or
one double, without looking at them. Its opcode, 0F 12, is that of
MOVLPS: with a memory operand the byte pair loads the
low half from memory, and with a register in the ModRM byte it is this
instruction. MOVLHPS is the reverse move, with 0F 16
shared with MOVHPS, and VMOVHLPS the
VEX and EVEX form, which takes the high half of one source and the high
half of another and clears the rest of the register.
Being an SSE instruction from the start, it needs no option. Like other
legacy SSE instructions it keeps bits 128 and up (see SSE and
AVX). Zen 5’s recorded movhlps xmm7, xmm11 put the high quadword of XMM11 in the low quadword of XMM7 and
left XMM7’s high quadword and upper bits as they were.
In horizontal sums
_mm_movehl_ps(a, b) gives b’s high pair below and a’s above, and its
common use is folding a vector in half before adding. In our builds at
-O2, GCC 14 compiles a sum of four floats written with _mm_add_ps(v, _mm_movehl_ps(v, v)) to a MOVAPS copy, MOVHLPS and ADDPS. Clang 23
replaces the MOVHLPS with UNPCKHPD, which moves the
same 64 bits, and emits MOVHLPS for the intrinsic on its own. The copy
is there because MOVHLPS overwrites its first operand while v is still
needed for the add; VMOVHLPS, which names a separate destination, needs
none.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
MOVHLPS xmm, xmm
MOVHLPS_XMMq_XMMq | NP 0F 12 /r | SSE |
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.
Result quadwords 1 to 0: a1, b1.
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
xmm1.q[0] = xmm2.q[1] # xmm1.q[1] keeps its value
# bits 128 and up of the register are unchangedRun on AMD Zen 5 (EPYC 9645): 1 case.
Operands
| Operand | Kind | Action |
|---|---|---|
MOVHLPS xmm, xmm | ||
xmm | explicit | read, write |
xmm | 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.
- All forms
SSE_TYPE_7
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.
| ISA set | CPUID | Processors |
|---|---|---|
SSE | SSE | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
More SSE 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. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2B, page 4-72 (MOVHLPS)
- 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
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 text is our own.