ia32-64/x86/xsave.html
2025-07-08 02:23:29 -03:00

173 lines
9.8 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:x86="http://www.felixcloutier.com/x86"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="style.css"></link><title>XSAVE
— Save Processor Extended States</title></head><body><header><nav><ul><li><a href='index.html'>Index</a></li><li>December 2023</li></ul></nav></header><h1>XSAVE
— Save Processor Extended States</h1>
<table>
<tr>
<th>Opcode / Instruction</th>
<th>Op/En</th>
<th>64/32 bit Mode Support</th>
<th>CPUID Feature Flag</th>
<th>Description</th></tr>
<tr>
<td>NP 0F AE /4 XSAVE mem</td>
<td>M</td>
<td>V/V</td>
<td>XSAVE</td>
<td>Save state components specified by EDX:EAX to mem.</td></tr>
<tr>
<td>NP REX.W + 0F AE /4 XSAVE64 mem</td>
<td>M</td>
<td>V/N.E.</td>
<td>XSAVE</td>
<td>Save state components specified by EDX:EAX to mem.</td></tr></table>
<h2 id="instruction-operand-encoding">Instruction Operand Encoding<a class="anchor" href="#instruction-operand-encoding">
</a></h2>
<table>
<tr>
<th>Op/En</th>
<th>Operand 1</th>
<th>Operand 2</th>
<th>Operand 3</th>
<th>Operand 4</th></tr>
<tr>
<td>M</td>
<td>ModRM:r/m (r, w)</td>
<td>N/A</td>
<td>N/A</td>
<td>N/A</td></tr></table>
<h2 id="description">Description<a class="anchor" href="#description">
</a></h2>
<p>Performs a full or partial save of processor state components to the XSAVE area located at the memory address specified by the destination operand. The implicit EDX:EAX register pair specifies a 64-bit instruction mask. The specific state components saved correspond to the bits set in the requested-feature bitmap (RFBM), which is the logical-AND of EDX:EAX and XCR0.</p>
<p>The format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of Intel<sup>®</sup> 64 and IA-32 Architectures Software Developers Manual, Volume 1. Like FXRSTOR and FXSAVE, the memory format used for x87 state depends on a REX.W prefix; see Section 13.5.1, “x87 State” of Intel<sup>®</sup> 64 and IA-32 Architectures Software Developers Manual, Volume 1.</p>
<p>Section 13.7, “Operation of XSAVE,” of Intel<sup>®</sup> 64 and IA-32 Architectures Software Developers Manual, Volume 1 provides a detailed description of the operation of the XSAVE instruction. The following items provide a high-level outline:</p>
<ul>
<li>XSAVE saves state component <em>i </em>if and only if RFBM[<em>i</em>] = 1.<sup>1</sup></li>
<li>XSAVE does not modify bytes 511:464 of the legacy region of the XSAVE area (see Section 13.4.1, “Legacy Region of an XSAVE Area” of Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1).</li>
<li>XSAVE reads the XSTATE_BV field of the XSAVE header (see Section 13.4.2, “XSAVE Header” of Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1) and writes a modified value back to memory as follows. If RFBM[<em>i</em>] = 1, XSAVE writes XSTATE_BV[<em>i</em>] with the value of XINUSE[<em>i</em>]. (XINUSE is a bitmap by which the processor tracks the status of various state components. See Section 13.6, “Processor Tracking of XSAVEManaged State” of Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1.) If RFBM[<em>i</em>] = 0, XSAVE writes XSTATE_BV[<em>i</em>] with the value that it read from memory (it does not modify the bit). XSAVE does not write to any part of the XSAVE header other than the XSTATE_BV field.</li>
<li>XSAVE always uses the standard format of the extended region of the XSAVE area (see Section 13.4.3, “Extended Region of an XSAVE Area” of Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1).</li></ul>
<blockquote>
<p>1. An exception is made for MXCSR and MXCSR_MASK, which belong to state component 1 — SSE. XSAVE saves these values to memory if either RFBM[1] or RFBM[2] is 1.</p></blockquote>
<p>Use of a destination operand not aligned to 64-byte boundary (in either 64-bit or 32-bit modes) results in a general-protection (#GP) exception. In 64-bit mode, the upper 32 bits of RDX and RAX are ignored.</p>
<h2 id="operation">Operation<a class="anchor" href="#operation">
</a></h2>
<pre>RFBM := XCR0 AND EDX:EAX; /* bitwise logical AND */
OLD_BV := XSTATE_BV field from XSAVE header;
IF RFBM[0] = 1
THEN store x87 state into legacy region of XSAVE area;
FI;
IF RFBM[1] = 1
THEN store XMM registers into legacy region of XSAVE area; // this step does not save MXCSR or MXCSR_MASK
FI;
IF RFBM[1] = 1 OR RFBM[2] = 1
THEN store MXCSR and MXCSR_MASK into legacy region of XSAVE area;
FI;
FOR i := 2 TO 62
IF RFBM[i] = 1
THEN save XSAVE state component i at offset n from base of XSAVE area (n enumerated by CPUID(EAX=0DH,ECX=i):EBX);
FI;
ENDFOR;
XSTATE_BV field in XSAVE header := (OLD_BV AND NOT RFBM) OR (XINUSE AND RFBM);
</pre>
<h2 id="flags-affected">Flags Affected<a class="anchor" href="#flags-affected">
</a></h2>
<p>None.</p>
<h2 id="intel-c-c++-compiler-intrinsic-equivalent">Intel C/C++ Compiler Intrinsic Equivalent<a class="anchor" href="#intel-c-c++-compiler-intrinsic-equivalent">
</a></h2>
<pre>XSAVE void _xsave( void * , unsigned __int64);
</pre>
<pre>XSAVE void _xsave64( void * , unsigned __int64);
</pre>
<h2 class="exceptions" id="protected-mode-exceptions">Protected Mode Exceptions<a class="anchor" href="#protected-mode-exceptions">
</a></h2>
<table>
<tr>
<td rowspan="2">#GP(0)</td>
<td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.</td></tr>
<tr>
<td>If a memory operand is not aligned on a 64-byte boundary, regardless of segment.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td>#PF(fault-code)</td>
<td>If a page fault occurs.</td></tr>
<tr>
<td>#NM</td>
<td>If CR0.TS[bit 3] = 1.</td></tr>
<tr>
<td rowspan="3">#UD</td>
<td>If CPUID.01H:ECX.XSAVE[bit 26] = 0.</td></tr>
<tr>
<td>If CR4.OSXSAVE[bit 18] = 0.</td></tr>
<tr>
<td>If the LOCK prefix is used.</td></tr>
<tr>
<td>#AC</td>
<td>If this exception is disabled a general protection exception (#GP) is signaled if the memory operand is not aligned on a 64-byte boundary, as described above. If the alignment check exception (#AC) is enabled (and the CPL is 3), signaling of #AC is not guaranteed and may vary with implementation, as follows. In all implementations where #AC is not signaled, a general protection exception is signaled in its place. In addition, the width of the alignment check may also vary with implementation. For instance, for a given implementation, an alignment check exception might be signaled for a 2-byte misalignment, whereas a general protection exception might be signaled for all other misalignments (4-, 8-, or 16-byte misalignments).</td></tr></table>
<h2 class="exceptions" id="real-address-mode-exceptions">Real-Address Mode Exceptions<a class="anchor" href="#real-address-mode-exceptions">
</a></h2>
<table>
<tr>
<td rowspan="2">#GP</td>
<td>If a memory operand is not aligned on a 64-byte boundary, regardless of segment.</td></tr>
<tr>
<td>If any part of the operand lies outside the effective address space from 0 to FFFFH.</td></tr>
<tr>
<td>#NM</td>
<td>If CR0.TS[bit 3] = 1.</td></tr>
<tr>
<td rowspan="3">#UD</td>
<td>If CPUID.01H:ECX.XSAVE[bit 26] = 0.</td></tr>
<tr>
<td>If CR4.OSXSAVE[bit 18] = 0.</td></tr>
<tr>
<td>If the LOCK prefix is used.</td></tr></table>
<h2 class="exceptions" id="virtual-8086-mode-exceptions">Virtual-8086 Mode Exceptions<a class="anchor" href="#virtual-8086-mode-exceptions">
</a></h2>
<p>Same exceptions as in protected mode.</p>
<h2 class="exceptions" id="compatibility-mode-exceptions">Compatibility Mode Exceptions<a class="anchor" href="#compatibility-mode-exceptions">
</a></h2>
<p>Same exceptions as in protected mode.</p>
<h2 class="exceptions" id="64-bit-mode-exceptions">64-Bit Mode Exceptions<a class="anchor" href="#64-bit-mode-exceptions">
</a></h2>
<table>
<tr>
<td rowspan="2">#GP(0)</td>
<td>If the memory address is in a non-canonical form.</td></tr>
<tr>
<td>If a memory operand is not aligned on a 64-byte boundary, regardless of segment.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory address referencing the SS segment is in a non-canonical form.</td></tr>
<tr>
<td>#PF(fault-code)</td>
<td>If a page fault occurs.</td></tr>
<tr>
<td>#NM</td>
<td>If CR0.TS[bit 3] = 1.</td></tr>
<tr>
<td rowspan="3">#UD</td>
<td>If CPUID.01H:ECX.XSAVE[bit 26] = 0.</td></tr>
<tr>
<td>If CR4.OSXSAVE[bit 18] = 0.</td></tr>
<tr>
<td>If the LOCK prefix is used.</td></tr>
<tr>
<td>#AC</td>
<td>If this exception is disabled a general protection exception (#GP) is signaled if the memory operand is not aligned on a 64-byte boundary, as described above. If the alignment check exception (#AC) is enabled (and the CPL is 3), signaling of #AC is not guaranteed and may vary with implementation, as follows. In all implementations where #AC is not signaled, a general protection exception is signaled in its place. In addition, the width of the alignment check may also vary with implementation. For instance, for a given implementation, an alignment check exception might be signaled for a 2-byte misalignment, whereas a general protection exception might be signaled for all other misalignments (4-, 8-, or 16-byte misalignments).</td></tr></table><footer><p>
This UNOFFICIAL, mechanically-separated, non-verified reference is provided for convenience, but it may be
inc<span style="opacity: 0.2">omp</span>lete or b<sub>r</sub>oke<sub>n</sub> in various obvious or non-obvious
ways. Refer to <a href="https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4">Intel® 64 and IA-32 Architectures Software Developers Manual</a> for anything serious.
</p></footer></body></html>