Instruction
XSAVEC
Saves selected state components in the compacted format of the XSAVE area, leaving out those in their initial state.
- Extensions
- Mnemonics
- XSAVEC, XSAVEC64
- Forms
- 2 (2 Legacy)
- Data
- Intel XED v2026.08.23
This instruction saves the components that the requested-feature bitmap, XCR0 AND EDX:EAX, selects, as XSAVE does, but packs them: the area’s extended region holds only the components that RFBM names, one after the other, instead of each at the fixed offset that CPUID gives for the standard format. It also skips a component in its initial state, as XSAVEOPT may, but never one that merely has not changed: the area it writes is complete whichever buffer was last restored, which makes it the instruction for a program saving its own state.
The compacted format
- XCOMP_BV, bytes 520 to 527, gets bit 63 set and RFBM in bits 62:0, which tells XRSTOR that the area is compacted and where each component lies.
- Offsets follow from XCOMP_BV: the first component from 2 up starts at byte 576, and each next one right after the one before it, or at the next multiple of 64 where CPUID leaf 0DH, sub-leaf i, reports ECX bit 1. A component left out takes no room.
- XSTATE_BV gets RFBM AND XINUSE: the components saved. Intel’s Volume 1 adds that SSE is saved, with its XSTATE_BV bit set, whenever RFBM asks for it and MXCSR is not 1F80H.
- The rest of the header is not written.
Zen 5 did exactly this in its two recorded cases. Asked for the x87, SSE and PKRU with PKRU at 0 and not in use, it wrote XSTATE_BV = 3 and XCOMP_BV = 8000000000000203H and left the 8 bytes for PKRU at byte 576, and header bytes 528 to 575, as they were. The 64-bit form with the x87, SSE, AVX, the opmask registers and PKRU put them in 904 bytes, PKRU at byte 896, where the standard format puts it at 2432 (CPUID leaf 0DH, sub-leaf 9, EBX = 980H).
Using it
CPUID leaf 0DH, sub-leaf 1, reports it in EAX bit 1. The size of a
compacted area depends on the mask, so code sums the sizes of what it
requests, alignment included. _xsavec(p, mask) and _xsavec64 need
-mxsavec in GCC 14 and Clang 23, and at -O2 split the mask into EDX:EAX
before the one instruction. XSAVES is the version for
CPL 0. AMD’s Zen 5 guide lists it as microcoded.
Forms
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
a = mem.address
if a % 64:
fault(GP, 0)
rfbm = (edx << 32 | eax) & xcr0 # the components to save
s = rfbm & xinuse # the ones in use, which it saves
if rfbm & 2 and mxcsr != 0x1F80: # SSE too where MXCSR is not its
s |= 2 # initial 1F80H
c = 1 << 63 | rfbm # XCOMP_BV: compacted, RFBM's
store(a + 512, 64, s) # XSTATE_BV
store(a + 520, 64, c)
if s & 1: # x87 state
t = 0
for j in range(8):
if ftw >> 2 * j & 3 != 3: # Rj not empty
t |= 1 << j
k = fsw >> 7 & 1 # ES: Zen 5 stores the pointers
store(a, 16, fcw) # as zeros without it
store(a + 2, 16, fsw)
store(a + 4, 16, t)
store(a + 6, 16, fop * k)
if OSIZE == 64: # REX.W: 64-bit offsets
store(a + 8, 64, fip * k)
store(a + 16, 64, fdp * k)
else:
store(a + 8, 32, fip * k)
store(a + 12, 32, fcs * k)
store(a + 16, 32, fdp * k)
store(a + 20, 32, fds * k)
for i in range(8):
store(a + 32 + 16 * i, 128, st[i])
if s & 2: # SSE: MXCSR and its mask, XMM0
store(a + 24, 32, mxcsr) # to XMM15
store(a + 28, 32, mxcsr_mask)
for i in range(16):
store(a + 160 + 16 * i, 128, xmm[i])
if s & 4: # AVX: bits 255:128
b = a + xsave_offset(2, c)
for i in range(16):
v = ymm[i].dq[1]
store(b + 16 * i, 128, v)
if s & 0x20: # AVX-512: k0 to k7
b = a + xsave_offset(5, c)
for i in range(8):
store(b + 8 * i, 64, opmask[i])
if s & 0x40: # bits 511:256 of zmm0-15
b = a + xsave_offset(6, c)
for i in range(16):
v = zmm[i].qq[1]
store(b + 32 * i, 256, v)
if s & 0x80: # zmm16 to zmm31
b = a + xsave_offset(7, c)
for i in range(16):
store(b + 64 * i, 512, zmm[16 + i])
if s & 0x200: # PKRU, in 4 of its 8 bytes (Zen 5)
store(a + xsave_offset(9, c), 32, pkru)
# MPX's and AMX's components (3, 4, 17, 18) likewiseRun on AMD Zen 5 (EPYC 9645): 2 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
XSAVEC mem XSAVEC64 mem | ||
mem | explicit | write |
EDX | implicit | read |
EAX | implicit | read |
XCR0 | implicit | read |
Flags
None: XED records no flag that the forms test or change.
Attributes
What else XED records about the forms. How to read.
- All forms
- aligned memory operand; may abort a TSX transaction
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 |
|---|---|---|
XSAVEC | XSAVEC | Skylake, Comet Lake, Cannon Lake, Ice Lake (client), Tiger Lake, Alder Lake, Arrow Lake, Panther Lake, Nova Lake, Skylake-SP, Cascade Lake, Cooper Lake, Ice Lake (server), Sapphire Rapids, Emerald Rapids, Granite Rapids, Diamond Rapids, Goldmont, Goldmont Plus, Tremont, Snow Ridge, Lakefield, Sierra Forest, Clearwater Forest, Zen, Zen+, Zen 2, Zen 3, Zen 4, Zen 5, Zen 6 |
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 2D, page 6-61 (XSAVEC)
- 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 text is our own.