Instruction
PUNPCKHBW
Interleaves the high bytes of two MMX or XMM operands.
PUNPCKHBW interleaves the high bytes of its two operands, a byte of
the destination, a byte of the source, and so on: 8 results in an
XMM register, 4 in an MMX register. It is the legacy SSE and MMX form
of VPUNPCKHBW, whose page covers the interleave
itself and how the VEX and EVEX forms keep each 128-bit lane
separate. On Zen 5, the recorded punpckhbw mm0, mm4 combined bytes
4 to 7 of MM0, 8Eh, 9Bh, A8h and B5h, with those of MM4, AAh, B7h,
C4h and D1h, into 8Eh, AAh, 9Bh, B7h, A8h, C4h, B5h and D1h.
What the legacy form adds
The destination doubles as the first source. The MMX memory operand
is a full 64-bit mm/m64, all eight bytes, even though only the high
four feed the result; the XMM memory operand is 128 bits and must be
aligned to 16 bytes, for the same reason. The 128-bit legacy form
leaves bits 255:128 of the register as they were, unlike the VEX
form, which zeros them (see mixing SSE and
AVX). In our builds at -O2, a straight
call to the intrinsic compiles to the single instruction in GCC 14
and Clang 23 regardless of -march, since both the MMX and the
128-bit SSE2 forms need no newer feature than the baseline.
AMD’s latency spreadsheet for Zen 5 gives PUNPCKHBW a latency of one cycle, four per cycle, for the XMM form with a register source; the MMX form with a memory source instead runs at two per cycle.
Forms
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 bytes 15 to 0: b15, a15, b14, a14, b13, a13, b12, a12, b11, a11, b10, a10, b9, a9, b8, a8.
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
PUNPCKHBW mm, mm/m64src1 = mm1.read() # mm1 as it was
for i in range(8):
j = i // 2 + 4
if i % 2 == 0:
mm1.b[i] = src1.b[j]
else:
mm1.b[i] = src2.b[j]
# x87: TOP = 0, all tags valid, bits 79:64 of mm1's register all onesRun on AMD Zen 5 (EPYC 9645): 2 cases.
PUNPCKHBW xmm, xmm/m128src1 = xmm1.read() # xmm1 as it was
for i in range(16):
j = i // 2 + 8
if i % 2 == 0:
xmm1.b[i] = src1.b[j]
else:
xmm1.b[i] = src2.b[j]
# bits 128 and up of the register are unchangedRun on AMD Zen 5 (EPYC 9645): 2 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
PUNPCKHBW mm, mm/m64 | ||
mm | explicit | read, write |
mm/m64 | explicit | read |
PUNPCKHBW xmm, xmm/m128 | ||
xmm | explicit | read, write |
xmm/m128 | 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.
PUNPCKHBW mm, mm/m64- may abort a TSX transaction
PUNPCKHBW xmm, m128- aligned memory operand
Intrinsics
The C intrinsics of Clang 23.1.2 that compile to PUNPCKHBW, 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 |
|---|---|
_mm_unpackhi_epi8
__m128i _mm_unpackhi_epi8(__m128i __a, __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 MMX instructions
- PADDB
- PADDD
- PADDSB
- PADDSW
- PADDUSB
- PADDUSW
- PADDW
- PAND
- PANDN
- PCMPEQB
- PCMPEQD
- PCMPEQW
- PCMPGTB
- PCMPGTD
- PCMPGTW
- PMADDWD
- PMULHW
- PMULLW
- POR
- PSLLD
- PSLLQ
- PSLLW
- PSRAD
- PSRAW
- PSRLD
- PSRLQ
- PSRLW
- PSUBB
- PSUBD
- PSUBSB
- PSUBSW
- PSUBUSB
- PSUBUSW
- PSUBW
- PUNPCKHDQ
- PUNPCKHWD
- PUNPCKLBW
- PUNPCKLDQ
- PUNPCKLWD
- PXOR
More SSE2 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-502 (PUNPCKHBW/
PUNPCKHWD/ PUNPCKHDQ/ PUNPCKHQDQ) - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- 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.