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

199 lines
10 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>XSAVES
— Save Processor Extended States Supervisor</title></head><body><header><nav><ul><li><a href='index.html'>Index</a></li><li>December 2023</li></ul></nav></header><h1>XSAVES
— Save Processor Extended States Supervisor</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 C7 /5 XSAVES mem</td>
<td>M</td>
<td>V/V</td>
<td>XSS</td>
<td>Save state components specified by EDX:EAX to mem with compaction, optimizing if possible.</td></tr>
<tr>
<td>NP REX.W + 0F C7 /5 XSAVES64 mem</td>
<td>M</td>
<td>V/N.E.</td>
<td>XSS</td>
<td>Save state components specified by EDX:EAX to mem with compaction, optimizing if possible.</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 (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), the logicalAND of EDX:EAX and the logical-OR of XCR0 with the IA32_XSS MSR. XSAVES may be executed only if CPL = 0.</p>
<p>The format of the XSAVE area is detailed in Section 13.4, “XSAVE Area,” of the 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 the Intel<sup>®</sup> 64 and IA-32 Architectures Software Developers Manual, Volume 1.</p>
<p>Section 13.11, “Operation of XSAVES,” of the Intel<sup>®</sup> 64 and IA-32 Architectures Software Developers Manual, Volume 1 provides a detailed description of the operation of the XSAVES instruction. The following items provide a high-level outline:</p>
<ul>
<li>Execution of XSAVES is similar to that of XSAVEC. XSAVES differs from XSAVEC in that it can save state components corresponding to bits set in the IA32_XSS MSR and that it may use the modified optimization.</li>
<li>XSAVES saves state component <em>i </em>only if RFBM[<em>i</em>] = 1 and XINUSE[<em>i</em>] = 1.<sup>1 </sup>(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 the Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1.) Even if both bits are 1, XSAVES may optimize and not save state component <em>i </em>if (1) state component <em>i </em>has not been modified since the last execution of XRSTOR or XRSTORS; and (2) this execution of XSAVES correspond to that last execution of XRSTOR or XRSTORS as determined by XRSTOR_INFO (see the Operation section below).</li>
<li>XSAVES 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 the Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1).</li>
<li>XSAVES writes the logical AND of RFBM and XINUSE to the XSTATE_BV field of the XSAVE header.<sup>2 </sup>(See Section 13.4.2, “XSAVE Header,” of the Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1.) XSAVES sets bit 63 of the XCOMP_BV field and sets bits 62:0 of that field to RFBM[62:0]. XSAVES does not write to any parts of the XSAVE header other than the XSTATE_BV and XCOMP_BV fields.</li>
<li>XSAVES always uses the compacted format of the extended region of the XSAVE area (see Section 13.4.3, “Extended Region of an XSAVE Area,” of the Intel<sup>® </sup>64 and IA-32 Architectures Software Developers Manual, Volume 1).</li></ul>
<blockquote>
<p>1. There is an exception for state component 1 (SSE). MXCSR is part of SSE state, but XINUSE[1] may be 0 even if MXCSR does not have its initial value of 1F80H. In this case, the init optimization does not apply and XSAVEC will save SSE state as long as RFBM[1] = 1 and the modified optimization is not being applied.</p>
<p>2. There is an exception for state component 1 (SSE). MXCSR is part of SSE state, but XINUSE[1] may be 0 even if MXCSR does not have its initial value of 1F80H. In this case, XSAVES sets XSTATE_BV[1] to 1 as long as RFBM[1] = 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>
<p>See Section 13.6, “Processor Tracking of XSAVE-Managed State,” of Intel<sup>®</sup> 64 and IA-32 Architectures Software Developers Manual, Volume 1 for discussion of the bitmap XMODIFIED and of the quantity XRSTOR_INFO.</p>
<h2 id="operation">Operation<a class="anchor" href="#operation">
</a></h2>
<pre>RFBM := (XCR0 OR IA32_XSS) AND EDX:EAX;
/* bitwise logical OR and AND */
IF in VMX non-root operation
THEN VMXNR := 1;
ELSE VMXNR := 0;
FI;
LAXA := linear address of XSAVE area;
COMPMASK := RFBM OR 80000000_00000000H;
TO_BE_SAVED := RFBM AND XINUSE;
IF XRSTOR_INFO = CPL,VMXNR,LAXA,COMPMASK
THEN TO_BE_SAVED := TO_BE_SAVED AND XMODIFIED;
FI;
IF MXCSR ≠ 1F80H AND RFBM[1]
THEN TO_BE_SAVED[1] = 1;
FI;
IF TO_BE_SAVED[0] = 1
THEN store x87 state into legacy region of XSAVE area;
FI;
IF TO_BE_SAVED[1] = 1
THEN store SSE state into legacy region of XSAVE area; // this step saves the XMM registers, MXCSR, and MXCSR_MASK
FI;
NEXT_FEATURE_OFFSET = 576;
// Legacy area and XSAVE header consume 576 bytes
FOR i := 2 TO 62
IF RFBM[i] = 1
THEN
IF TO_BE_SAVED[i]
THEN
save XSAVE state component i at offset NEXT_FEATURE_OFFSET from base of XSAVE area;
IF i = 8 // state component 8 is for PT state
THEN IA32_RTIT_CTL.TraceEn[bit 0] := 0;
FI;
FI;
NEXT_FEATURE_OFFSET = NEXT_FEATURE_OFFSET + n (n enumerated by CPUID(EAX=0DH,ECX=i):EAX);
FI;
ENDFOR;
NEW_HEADER := RFBM AND XINUSE;
IF MXCSR ≠ 1F80H AND RFBM[1]
THEN NEW_HEADER[1] = 1;
FI;
XSTATE_BV field in XSAVE header := NEW_HEADER;
XCOMP_BV field in XSAVE header := COMPMASK;
</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>XSAVES void _xsaves( void * , unsigned __int64);
</pre>
<pre>XSAVES64 void _xsaves64( 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="3">#GP(0)</td>
<td>IfCPL&gt;0.</td></tr>
<tr>
<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 or CPUID.(EAX=0DH,ECX=1):EAX.XSS[bit 3] = 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="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 or CPUID.(EAX=0DH,ECX=1):EAX.XSS[bit 3] = 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="3">#GP(0)</td>
<td>IfCPL&gt;0.</td></tr>
<tr>
<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 or CPUID.(EAX=0DH,ECX=1):EAX.XSS[bit 3] = 0.</td></tr>
<tr>
<td>If CR4.OSXSAVE[bit 18] = 0.</td></tr>
<tr>
<td>If the LOCK prefix is used.</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>