Instruction
XSAVE
Saves the state components that XCR0 and EDX:EAX select, such as the x87, SSE and AVX registers, to a 64-byte aligned XSAVE area.
- Extensions
- Mnemonics
- XSAVE, XSAVE64
- Forms
- 2 (2 Legacy)
- Data
- Intel XED v2026.08.23
XSAVE saves the state components selected by the requested-feature bitmap, XCR0 AND EDX:EAX, to the XSAVE area at its memory operand, which must be aligned to 64 bytes. The area has three parts:
- Legacy region, bytes 0 to 511: the x87 and SSE state (components 0 and 1) in the layout of FXSAVE.
- XSAVE header, bytes 512 to 575: XSTATE_BV, a bitmap of the components the area holds in a state other than their initial one, and XCOMP_BV, which says whether the area is in the compacted format.
- Extended region, from byte 576: every other component, in the standard format at the offset that CPUID leaf 0DH, sub-leaf n, gives for component n in EBX, with its size in EAX.
XSAVE always writes the standard format and every selected component. For a component in its initial state it may clear the component’s bit in XSTATE_BV, and XRSTOR then puts that component in its initial state instead of reading it from the area. CPUID leaf 0DH, sub-leaf 0, gives in EBX the size of an area for the components currently enabled in XCR0, which is what a buffer must hold.
XSAVE64, the form with REX.W, stores the x87 instruction and data pointers of the legacy region as 64-bit addresses, as FXSAVE64 does. Because the size varies with the processor and with XCR0, Linux sizes the XSAVE area of its signal frames at run time, and a program that uses AMX must first ask for permission to use the tile data (see vector state in the ABIs). The XSAVE extension lists the components.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
XSAVE mem
XSAVE_MEMmxsave | NP 0F AE /4 | XSAVE + OSXSAVE |
XSAVE64 mem
XSAVE64_MEMmxsave | REX.W 0F AE /4 | XSAVE + OSXSAVE |
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
bv = load(a + 512, 64) # XSTATE_BV, which keeps its bits
bv = bv & ~rfbm | xinuse & rfbm # outside RFBM
store(a + 512, 64, bv)
if rfbm & 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 rfbm & 6: # SSE or AVX: MXCSR and its mask
store(a + 24, 32, mxcsr)
store(a + 28, 32, mxcsr_mask)
if rfbm & 2: # SSE: XMM0 to XMM15
for i in range(16):
store(a + 160 + 16 * i, 128, xmm[i])
if rfbm & 4: # AVX: bits 255:128
b = a + xsave_offset(2, 0)
for i in range(16):
v = ymm[i].dq[1]
store(b + 16 * i, 128, v)
if rfbm & 0x20: # AVX-512: k0 to k7
b = a + xsave_offset(5, 0)
for i in range(8):
store(b + 8 * i, 64, opmask[i])
if rfbm & 0x40: # bits 511:256 of zmm0-15
b = a + xsave_offset(6, 0)
for i in range(16):
v = zmm[i].qq[1]
store(b + 32 * i, 256, v)
if rfbm & 0x80: # zmm16 to zmm31
b = a + xsave_offset(7, 0)
for i in range(16):
store(b + 64 * i, 512, zmm[16 + i])
if rfbm & 0x200: # PKRU, in 4 of its 8 bytes (Zen 5)
store(a + xsave_offset(9, 0), 32, pkru)
# MPX's and AMX's components (3, 4, 17, 18) likewiseRun on AMD Zen 5 (EPYC 9645): 5 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
XSAVE mem XSAVE64 mem | ||
mem | explicit | read, 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 |
|---|---|---|
XSAVE | XSAVE + OSXSAVE | Sandy Bridge, Ivy Bridge, Haswell, Broadwell, 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, Knights Landing, Knights Mill, Bulldozer, Piledriver, Zen, Zen+, Zen 2, Zen 3, Zen 4, Zen 5, Zen 6 |
More XSAVE 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 2D, page 6-58 (XSAVE)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- Linux kernel documentation: Using XSTATE features in user space applications
- Intel Advanced Performance Extensions (Intel APX) Architecture Specification, revision 7.0 (July 2025)
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.