Instruction
FXSAVE
Saves the x87, MMX and SSE registers and MXCSR to a 16-byte aligned 512-byte area; FXSAVE64 stores the x87 pointers as 64-bit values.
- Extensions
- Mnemonics
- FXSAVE, FXSAVE64
- Forms
- 2 (2 Legacy)
- Data
- Intel XED v2026.08.23
FXSAVE stores the x87, MMX and SSE state in 512 bytes of memory that must be aligned to 16 bytes; Zen 5 raised #GP for an address aligned only to 8. FXRSTOR loads it back. It came with the Pentium II, ready for the XMM registers that SSE then added, and it is still the first 512 bytes of every XSAVE area, whose page describes that layout as the legacy region; XSAVE added everything since, from the upper halves of the YMM registers on.
Not FNSAVE
FXSAVE differs from the x87’s own FNSAVE in what it leaves behind and how it writes the x87 part:
- It changes no register: FNSAVE ends by initializing the FPU, FXSAVE leaves the stack, the control word and the status as they were.
- It does not check for a pending x87 exception: with one pending, Zen 5 wrote the area and the #MF came at the next waiting instruction.
- The tag word is abridged to one bit per register, set when the register is not empty, and each of ST(0) to ST(7) takes a 16-byte slot instead of 10 bytes.
- In 64-bit mode it saves XMM0 to XMM15 and MXCSR, together with MXCSR_MASK, the MXCSR bits the processor supports: Zen 5 reported 0002FFFFH, bit 6 (DAZ) and AMD’s bit 17 (MM, the misaligned exception mask) included. Zen 5 left bytes 416 to 511 alone, and Intel’s manual leaves bytes 464 to 511 to software.
The pointers, and the two manuals
FXSAVE64 (REX.W) stores the last x87 instruction and data pointers as 64-bit offsets, FXSAVE as 32-bit offsets with their selectors. AMD’s manual saves the pointers and the opcode only while an unmasked exception is pending (ES set), and Zen 5 wrote zeros in their place otherwise. Intel’s manual stores them every time, with the selectors as 0 on processors that report FCS and FDS as deprecated. AMD also has a fast mode, EFER.FFXSR, in which FXSAVE at CPL 0 in 64-bit mode leaves out the XMM registers, to speed up a kernel’s own saves.
From C, _fxsave(p) and _fxsave64(p) need -mfxsr; GCC 14 and Clang
23 at -O2 emit one fxsave or fxsave64 with the pointer as its
memory operand. AMD’s Zen 5 guide lists FXSAVE and FXRSTOR as
microcoded.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
FXSAVE m512byte
FXSAVE_MEMmfpxenv | NP 0F AE /0 | FXSAVE |
FXSAVE64 m512byte
FXSAVE64_MEMmfpxenv | REX.W 0F AE /0 | FXSAVE + LM |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
FXSAVE m512bytea = mem.address
if a % 16:
fault(GP, 0)
t = 0
for j in range(8):
if ftw >> 2 * j & 3 != 3: # Rj not empty
t |= 1 << j
pend = fsw >> 7 & 1 # ES: an exception pending
store(a, 16, fcw)
store(a + 2, 16, fsw)
store(a + 4, 16, t) # byte 5: 0
# the pointers, 32-bit offsets and the selectors, as zeros where
# no exception is pending (Zen 5; Intel's store them always)
store(a + 6, 16, fop if pend else 0)
store(a + 8, 32, fip if pend else 0)
store(a + 12, 32, fcs if pend else 0)
store(a + 16, 32, fdp if pend else 0)
store(a + 20, 32, fds if pend else 0)
store(a + 24, 32, mxcsr)
store(a + 28, 32, mxcsr_mask)
for i in range(8): # 80 bits, 48 of zeros
store(a + 32 + 16 * i, 128, st[i])
for i in range(16):
store(a + 160 + 16 * i, 128, xmm[i])Run on AMD Zen 5 (EPYC 9645): 3 cases.
FXSAVE64 m512bytea = mem.address
if a % 16:
fault(GP, 0)
t = 0
for j in range(8):
if ftw >> 2 * j & 3 != 3: # Rj not empty
t |= 1 << j
pend = fsw >> 7 & 1 # ES: an exception pending
store(a, 16, fcw)
store(a + 2, 16, fsw)
store(a + 4, 16, t) # byte 5: 0
# the pointers, 64-bit offsets, as zeros where no exception is
# pending (Zen 5; Intel's store them always)
store(a + 6, 16, fop if pend else 0)
store(a + 8, 64, fip if pend else 0)
store(a + 16, 64, fdp if pend else 0)
store(a + 24, 32, mxcsr)
store(a + 28, 32, mxcsr_mask)
for i in range(8): # 80 bits, 48 of zeros
store(a + 32 + 16 * i, 128, st[i])
for i in range(16):
store(a + 160 + 16 * i, 128, xmm[i])Run on AMD Zen 5 (EPYC 9645): 2 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
FXSAVE m512byte FXSAVE64 m512byte | ||
m512byte | explicit | write |
x87 control word | 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
Intrinsics
The C intrinsics of Clang 23.1.2 that compile to FXSAVE, 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 |
|---|---|
_fxsave
void _fxsave(void *__p) |
|
_fxsave64
void _fxsave64(void *__p) |
|
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 FXSR 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 2A, page 3-412 (FXSAVE)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.42, March 2024), Wayback Machine copy of AMD's PDF
- AMD64 Architecture Programmer's Manual, Volume 5: 64-Bit Media and x87 Floating-Point Instructions (26569, rev. 3.16, 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 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.