Instruction
PALIGNR
Concatenates two MMX or XMM operands and extracts a register's worth of bytes at the byte offset an immediate gives; SSSE3.
- Extensions
- Forms
- 4 (4 Legacy)
- Data
- Intel XED v2026.08.23
PALIGNR places the destination above the source to form one value of twice the register’s width, shifts that right by the number of bytes in the immediate, and keeps the low half. With an offset of 5 on XMM registers, the result is bytes 5 to 15 of the source followed by bytes 0 to 4 of the destination. An offset of 16 gives the destination unchanged, larger ones shift in zeros, and from 32 on (16 in the MMX form) the result is zero.
The order is the usual stumbling block. In _mm_alignr_epi8(a, b, n),
a is the upper half and b the lower one, so the result starts with
byte n of b: the operand that comes second supplies the first bytes.
It is what a byte-granular window over a stream needs:
- Stitching unaligned data. Code that may only load aligned 16-byte blocks can rebuild the 16 bytes at any offset from two neighboring blocks. Intel’s optimization manual recommends this in place of unaligned loads that would split cache lines (Section 6.3) and builds a memory copy for misaligned sources on it, with one aligned load, one PALIGNR and one aligned store per 16 bytes (Section 15.16.3.1).
- Sliding windows. Filters that need
x[i],x[i+1],x[i+2]and so on in separate registers take each one from two loaded blocks with a different offset; the manual’s FIR filter example does this with offsets of 4, 8 and 12. - Rotating bytes. With the same register in both operands, PALIGNR
rotates it. Compiling a byte rotation by 3 written with
__builtin_shufflevector, GCC 14 and Clang 23 at -O2 emitpalignr xmm0, xmm0, 3once SSSE3 is enabled; for the SSE2 baseline they need PSRLDQ, PSLLDQ and POR.
The legacy SSE form needs a memory operand aligned to 16 bytes. The VEX and EVEX forms, VPALIGNR, work within each 128-bit lane: a 256-bit VPALIGNR is two independent 128-bit ones, and Intel’s optimization manual points out that its memory copy therefore needs an extra load per 32 bytes (Section 15.16.3.1). AVX-512’s VALIGND and VALIGNQ shift across the whole register, in units of doublewords or quadwords.
In the optimization guide
What the optimization guide says about PALIGNR, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Jaguar and Puma
- Vectors and floating point: The FPU forms three forwarding domains, floating point (FPA and FPM), vector integer (the VALUs and VIMUL) and store and convert, and a result passed from one to another costs a cycle more.
Silvermont to Goldmont Plus
- Front end: Silvermont decodes SSSE3 and SSE4 instructions that use xmm8 to xmm15 slowly, as they exceed 3 bytes of prefixes and escapes. sources differ
- Loads, stores and caches: Unaligned vector loads are one micro-op, but line splits are slow; Intel suggests aligned loads and palignr.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
PALIGNR mm, m64, imm8
PALIGNR_MMXq_MEMq_IMMb | NP 0F 3A 0F /r ib | SSSE3 + MMX |
PALIGNR mm, mm, imm8
PALIGNR_MMXq_MMXq_IMMb | NP 0F 3A 0F /r ib | SSSE3 + MMX |
PALIGNR xmm, m128, imm8
PALIGNR_XMMdq_MEMdq_IMMb | 66 0F 3A 0F /r ib | SSSE3 |
PALIGNR xmm, xmm, imm8
PALIGNR_XMMdq_XMMdq_IMMb | 66 0F 3A 0F /r ib | SSSE3 |
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.
Example: imm8 = 5.
With imm8 = 5, result bytes 15 to 0: a4, a3, a2, a1, a0, b15, b14, b13, b12, b11, b10, b9, b8, b7, b6, b5.
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
PALIGNR mm, mm/m64, imm8src1 = mm1.read() # mm1 as it was
for i in range(8):
j = i + imm8 # byte j of mm1:src2
if j < 8:
x = src2.b[i + imm8]
elif j < 16:
x = src1.b[i + imm8 - 8]
else:
x = 0
mm1.b[i] = x
# x87: TOP = 0, all tags valid, bits 79:64 of mm1's register all onesRun on AMD Zen 5 (EPYC 9645): 2 cases.
PALIGNR xmm, xmm/m128, imm8src1 = xmm1.read() # xmm1 as it was
for i in range(16):
j = i + imm8 # byte j of xmm1:src2
if j < 16:
x = src2.b[i + imm8]
elif j < 32:
x = src1.b[i + imm8 - 16]
else:
x = 0
xmm1.b[i] = x
# bits 128 and up of the register are unchangedRun on AMD Zen 5 (EPYC 9645): 2 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
PALIGNR mm, mm/m64, imm8 | ||
mm | explicit | read, write |
mm/m64 | explicit | read |
imm8 | explicit | read |
PALIGNR xmm, xmm/m128, imm8 | ||
xmm | explicit | read, write |
xmm/m128 | explicit | read |
imm8 | 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.
PALIGNR mm, mm/m64, imm8- may abort a TSX transaction
PALIGNR xmm, m128, imm8- aligned memory operand
Intrinsics
The C intrinsics of Clang 23.1.2 that compile to PALIGNR, 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_alignr_epi8
__m128i _mm_alignr_epi8(__m128i a, __m128i b, const int n) |
|
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 SSSE3 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-216 (PALIGNR)
- Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)
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.