### MONITOR/MWAIT Instruction Pair Usage Example Source: https://www.felixcloutier.com/x86/mwait This code snippet demonstrates a typical sequence for using the MONITOR and MWAIT instructions together. It includes checks to ensure a triggering store doesn't occur between the monitor setup and the MWAIT execution, often placed within a loop for continuous power management. ```assembly EAX = Logical Address(Trigger) ECX = 0 (*Hints *) EDX = 0 (* Hints *) IF ( !trigger_store_happened) { MONITOR EAX, ECX, EDX IF ( !trigger_store_happened ) { MWAIT EAX, ECX } } ``` -------------------------------- ### x86 MOV Instruction Examples Source: https://www.felixcloutier.com/x86/mov Common examples of the MOV instruction demonstrating register-to-register, immediate-to-register, and memory-to-register data movement patterns. ```assembly ; Move immediate value to register MOV EAX, 0x1234 ; Move register to register MOV EBX, EAX ; Move memory content to register MOV EAX, [0x4000] ; Move register to memory MOV [0x4000], EAX ; Move immediate to memory MOV BYTE PTR [0x4000], 0xFF ``` -------------------------------- ### CET State Saving and Setup Logic Source: https://www.felixcloutier.com/x86/eenter This pseudocode outlines the process of saving the current application's CET state and setting up the enclave's CET state. It checks CPUID for CET support (IBT/SS) and conditionally saves the Stack Pointer (SSP) if CET_SS is enabled. ```pseudocode IF ((CPUID.(EAX=7H, ECX=0):EDX[CET_IBT] = 1) OR (CPUID.(EAX=7H, ECX=0):ECX[CET_SS] = 1)) THEN (* Save enclosing application CET state into save registers *) CR_SAVE_IA32_U_CET := IA32_U_CET (* Setup enclave CET state *) IF CPUID.(EAX=07H, ECX=00h):ECX[CET_SS] = 1 THEN CR_SAVE_SSP := SSP SSP := TMP_SSP FI; IA32_U_CET := TMP_IA32_U_CET; FI; Flush_linear_context; Allow_front_end_to_begin_fetch_at_new_RIP; ``` -------------------------------- ### PUSH Instruction Assembly Syntax Source: https://www.felixcloutier.com/x86/push Examples of various PUSH instruction variants including register, memory, immediate, and segment register operations. ```assembly ; Register push PUSH RAX PUSH EAX ; Immediate push PUSH 0x10 ; Memory push PUSH [RBX] ; Segment register push PUSH FS PUSH GS ``` -------------------------------- ### x86 TEST Instruction - Logical Compare Examples Source: https://www.felixcloutier.com/x86/test Demonstrates the usage of the TEST instruction with immediate values and register/memory operands across different operand sizes. The instruction performs a logical AND and updates flags SF, ZF, and PF. ```assembly TEST AL, imm8 ; AND imm8 with AL TEST AX, imm16 ; AND imm16 with AX TEST EAX, imm32 ; AND imm32 with EAX TEST RAX, imm32 ; AND imm32 sign-extended to 64-bits with RAX TEST r/m8, imm8 ; AND imm8 with r/m8 TEST r/m16, imm16 ; AND imm16 with r/m16 TEST r/m32, imm32 ; AND imm32 with r/m32 TEST r/m64, imm32 ; AND imm32 sign-extended to 64-bits with r/m64 TEST r/m8, r8 ; AND r8 with r/m8 TEST r/m16, r16 ; AND r16 with r/m16 TEST r/m32, r32 ; AND r32 with r/m32 TEST r/m64, r64 ; AND r64 with r/m64 ``` -------------------------------- ### Configure PROVISION_KEY Dependencies Source: https://www.felixcloutier.com/x86/egetkey Sets up key dependencies for the PROVISION_KEY operation. It checks for PROVISIONKEY capability, CPUSVN validity, and ISVSVN against current enclave configurations. Initializes TMP_KEYDEPENDENCIES with relevant values, including attribute masks. ```assembly PROVISION_KEY: (* Check ENCLAVE has PROVISIONING capability *) IF (TMP_CURRENTSECS.ATTRIBUTES.PROVISIONKEY = 0) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_ATTRIBUTE; GOTO EXIT; FI; IF (DS:RBX.CPUSVN is beyond current CPU configuration) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_CPUSVN; GOTO EXIT; FI; IF (DS:RBX.ISVSVN > TMP_CURRENTSECS.ISVSVN) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_ISVSVN; GOTO EXIT; FI; (* Determine values key is based on *) TMP_KEYDEPENDENCIES.KEYNAME := PROVISION_KEY; TMP_KEYDEPENDENCIES.ISVFAMILYID := 0; TMP_KEYDEPENDENCIES.ISVEXTPRODID := 0; TMP_KEYDEPENDENCIES.ISVPRODID := TMP_CURRENTSECS.ISVPRODID; TMP_KEYDEPENDENCIES.ISVSVN := DS:RBX.ISVSVN; TMP_KEYDEPENDENCIES.SGXOWNEREPOCH := 0; TMP_KEYDEPENDENCIES.ATTRIBUTES := TMP_ATTRIBUTES; TMP_KEYDEPENDENCIES.ATTRIBUTESMASK := DS:RBX.ATTRIBUTEMASK; TMP_KEYDEPENDENCIES.MRENCLAVE := 0; TMP_KEYDEPENDENCIES.MRSIGNER := TMP_CURRENTSECS.MRSIGNER; TMP_KEYDEPENDENCIES.KEYID := 0; TMP_KEYDEPENDENCIES.SEAL_KEY_FUSES := 0; TMP_KEYDEPENDENCIES.CPUSVN := DS:RBX.CPUSVN; TMP_KEYDEPENDENCIES.PADDING := TMP_CURRENTSECS.PADDING; TMP_KEYDEPENDENCIES.MISCSELECT := TMP_MISCSELECT; TMP_KEYDEPENDENCIES.MISCMASK := ~DS:RBX.MISCMASK; TMP_KEYDEPENDENCIES.KEYPOLICY := 0; TMP_KEYDEPENDENCIES.CONFIGID := 0; IF (CPUID.(EAX=12H, ECX=1):EAX[6] = 1) THEN TMP_KEYDEPENDENCIES.CET_ATTRIBUTES := TMP_CET_ATTRIBUTES; TMP_KEYDEPENDENCIES.CET_ATTRIBUTES _MASK := 0; FI; BREAK; ``` -------------------------------- ### Configure EINITTOKEN_KEY Dependencies Source: https://www.felixcloutier.com/x86/egetkey Sets up key dependencies for the EINITTOKEN_KEY operation. It performs checks for EINITTOKEN capability, CPUSVN validity, and ISVSVN against current enclave configurations. Initializes TMP_KEYDEPENDENCIES with relevant values. ```assembly EINITTOKEN_KEY: (* Check ENCLAVE has EINITTOKEN Key capability *) IF (TMP_CURRENTSECS.ATTRIBUTES.EINITTOKEN_KEY = 0) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_ATTRIBUTE; GOTO EXIT; FI; IF (DS:RBX.CPUSVN is beyond current CPU configuration) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_CPUSVN; GOTO EXIT; FI; IF (DS:RBX.ISVSVN > TMP_CURRENTSECS.ISVSVN) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_ISVSVN; GOTO EXIT; FI; (* Determine values key is based on *) TMP_KEYDEPENDENCIES.KEYNAME := EINITTOKEN_KEY; TMP_KEYDEPENDENCIES.ISVFAMILYID := 0; TMP_KEYDEPENDENCIES.ISVEXTPRODID := 0; TMP_KEYDEPENDENCIES.ISVPRODID := TMP_CURRENTSECS.ISVPRODID TMP_KEYDEPENDENCIES.ISVSVN := DS:RBX.ISVSVN; TMP_KEYDEPENDENCIES.SGXOWNEREPOCH := CR_SGXOWNEREPOCH; TMP_KEYDEPENDENCIES.ATTRIBUTES := TMP_ATTRIBUTES; TMP_KEYDEPENDENCIES.ATTRIBUTESMASK := 0; TMP_KEYDEPENDENCIES.MRENCLAVE := 0; TMP_KEYDEPENDENCIES.MRSIGNER := TMP_CURRENTSECS.MRSIGNER; TMP_KEYDEPENDENCIES.KEYID := DS:RBX.KEYID; TMP_KEYDEPENDENCIES.SEAL_KEY_FUSES := CR_SEAL_FUSES; TMP_KEYDEPENDENCIES.CPUSVN := DS:RBX.CPUSVN; TMP_KEYDEPENDENCIES.PADDING := TMP_CURRENTSECS.PADDING; TMP_KEYDEPENDENCIES.MISCSELECT := TMP_MISCSELECT; TMP_KEYDEPENDENCIES.MISCMASK := 0; TMP_KEYDEPENDENCIES.KEYPOLICY := 0; TMP_KEYDEPENDENCIES.CONFIGID := 0; TMP_KEYDEPENDENCIES.CONFIGSVN := 0; IF (CPUID.(EAX=12H, ECX=1):EAX[6] = 1) THEN TMP_KEYDEPENDENCIES.CET_ATTRIBUTES := TMP_CET_ATTRIBUTES; TMP_KEYDEPENDENCIES.CET_ATTRIBUTES _MASK := 0; FI; BREAK; ``` -------------------------------- ### VRANGEPD Assembly Example Source: https://www.felixcloutier.com/x86/vrangepd An example demonstrating the usage of the VRANGEPD instruction with specific operands and immediate values to check if an input operand is bounded between ±1023, preserving the sign of the input operand. ```assembly VRANGEPD zmm_dst, zmm_src, zmm_1023, 02h; Where: zmm_dst is the destination operand. zmm_src is the input operand to compare against ±1023 (this is SRC1). zmm_1023 is the reference operand, contains the value of 1023 (and this is SRC2). IMM=02(imm8[1:0]='10) selects the Min Absolute value operation with selection of SRC1.sign. In case |zmm_src| < 1023 (i.e., SRC1 is smaller than 1023 in magnitude), then its value will be written into zmm_dst. Otherwise, the value stored in zmm_dst will get the value of 1023 (received on zmm_1023, which is SRC2). However, the sign control (imm8[3:2]='00) instructs to select the sign of SRC1 received from zmm_src. So, even in the case of |zmm_src| ≥ 1023, the selected sign of SRC1 is kept. Thus, if zmm_src < -1023, the result of VRANGEPD will be the minimal value of -1023 while if zmm_src > +1023, the result of VRANGE will be the maximal value of +1023. ``` -------------------------------- ### FXCH Usage Example Source: https://www.felixcloutier.com/x86/fxch An example sequence demonstrating how to use FXCH to perform a square root operation on the third register from the top of the FPU stack. It swaps the target register to the top, executes FSQRT, and swaps it back. ```assembly FXCH ST(3); FSQRT; FXCH ST(3); ``` -------------------------------- ### Configure REPORT_KEY Dependencies Source: https://www.felixcloutier.com/x86/egetkey Sets up the key dependencies for the REPORT_KEY operation. It initializes various fields of TMP_KEYDEPENDENCIES based on current CPU states and specific report key requirements. Includes conditional logic for CET attributes based on CPUID. ```assembly TMP_KEYDEPENDENCIES.CPUSVN := DS:RBX.CPUSVN; TMP_KEYDEPENDENCIES.PADDING := TMP_CURRENTSECS.PADDING; TMP_KEYDEPENDENCIES.MISCSELECT := TMP_MISCSELECT; TMP_KEYDEPENDENCIES.MISCMASK := ~DS:RBX.MISCMASK; TMP_KEYDEPENDENCIES.KEYPOLICY := DS:RBX.KEYPOLICY; TMP_KEYDEPENDENCIES.CONFIGID := TMP_CONFIGID; TMP_KEYDEPENDENCIES.CONFIGSVN := TMP_CONFIGSVN; IF CPUID.(EAX=12H, ECX=1):EAX[6] = 1 THEN TMP_KEYDEPENDENCIES.CET_ATTRIBUTES := TMP_CET_ATTRIBUTES; TMP_KEYDEPENDENCIES.CET_ATTRIBUTES _MASK := DS:RBX.CET_ATTRIBUTES _MASK; FI; BREAK; REPORT_KEY: //Determine values key is based on TMP_KEYDEPENDENCIES.KEYNAME := REPORT_KEY; TMP_KEYDEPENDENCIES.ISVFAMILYID := 0; TMP_KEYDEPENDENCIES.ISVEXTPRODID := 0; TMP_KEYDEPENDENCIES.ISVPRODID := 0; TMP_KEYDEPENDENCIES.ISVSVN := 0; TMP_KEYDEPENDENCIES.SGXOWNEREPOCH := CR_SGXOWNEREPOCH; TMP_KEYDEPENDENCIES.ATTRIBUTES := TMP_CURRENTSECS.ATTRIBUTES; TMP_KEYDEPENDENCIES.ATTRIBUTESMASK := 0; TMP_KEYDEPENDENCIES.MRENCLAVE := TMP_CURRENTSECS.MRENCLAVE; TMP_KEYDEPENDENCIES.MRSIGNER := 0; TMP_KEYDEPENDENCIES.KEYID := DS:RBX.KEYID; TMP_KEYDEPENDENCIES.SEAL_KEY_FUSES := CR_SEAL_FUSES; TMP_KEYDEPENDENCIES.CPUSVN := CR_CPUSVN; TMP_KEYDEPENDENCIES.PADDING := HARDCODED_PKCS1_5_PADDING; TMP_KEYDEPENDENCIES.MISCSELECT := TMP_CURRENTSECS.MISCSELECT; TMP_KEYDEPENDENCIES.MISCMASK := 0; TMP_KEYDEPENDENCIES.KEYPOLICY := 0; TMP_KEYDEPENDENCIES.CONFIGID := TMP_CURRENTSECS.CONFIGID; TMP_KEYDEPENDENCIES.CONFIGSVN := TMP_CURRENTSECS.CONFIGSVN; IF (CPUID.(EAX=12H, ECX=1):EAX[6] = 1) THEN TMP_KEYDEPENDENCIES.CET_ATTRIBUTES := TMP_CURRENTSECS.CET_ATTRIBUTES; TMP_KEYDEPENDENCIES.CET_ATTRIBUTES_MASK := 0; FI; BREAK; ``` -------------------------------- ### VRANGESD Instruction Logic and Example Source: https://www.felixcloutier.com/x86/vrangesd This snippet outlines the operational logic of the VRANGESD instruction, including conditional execution based on writemask and merging/zeroing masking. It also provides a practical example demonstrating its use for bounding an input operand between ±1023. ```assembly IF k1[0] OR *no writemask* THEN DEST[63:0] := RangeDP (SRC1[63:0], SRC2[63:0], CmpOpCtl[1:0], SignSelCtl[1:0]); ELSE IF *merging-masking* ; merging-masking THEN *DEST[63:0] remains unchanged* ELSE ; zeroing-masking DEST[63:0] = 0 FI; FI; DEST[127:64] := SRC1[127:64] DEST[MAXVL-1:128] := 0 VRANGESD xmm_dst, xmm_src, xmm_1023, 02h; ``` -------------------------------- ### Intel C/C++ Compiler Intrinsic for KMOV Source: https://www.felixcloutier.com/x86/kmovw%3Akmovb%3Akmovq%3Akmovd Example of the C/C++ intrinsic equivalent used to interface with the KMOV instruction set in high-level code. ```cpp KMOVW __mmask16 _mm512_kmov(__mmask16 a); ``` -------------------------------- ### Configure PROVISION_SEAL_KEY Dependencies Source: https://www.felixcloutier.com/x86/egetkey Sets up key dependencies for the PROVISION_SEAL_KEY operation. It includes checks for PROVISIONKEY capability, CPUSVN validity, and ISVSVN. Initializes TMP_KEYDEPENDENCIES and TMP_ISVFAMILYID. ```assembly PROVISION_SEAL_KEY: (* Check ENCLAVE has PROVISIONING capability *) IF (TMP_CURRENTSECS.ATTRIBUTES.PROVISIONKEY = 0) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_ATTRIBUTE; GOTO EXIT; FI; IF (DS:RBX.CPUSVN is beyond current CPU configuration) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_CPUSVN; GOTO EXIT; FI; IF (DS:RBX.ISVSVN > TMP_CURRENTSECS.ISVSVN) THEN RFLAGS.ZF := 1; RAX := SGX_INVALID_ISVSVN; GOTO EXIT; FI; (* Include enclave product family ID? *) TMP_ISVFAMILYID := 0; ``` -------------------------------- ### MMX 64-bit Operand Operation Source: https://www.felixcloutier.com/x86/psignb%3Apsignw%3Apsignd Example implementation of the PSIGNB instruction logic for 64-bit MMX registers, iterating through packed bytes. ```pseudo-code VL=64 KL := VL/8 for i in 0...KL-1: srcdest.byte[i] := byte_sign(src.byte[i], srcdest.byte[i]) ``` -------------------------------- ### Initialize Authenticated Code Execution Environment Source: https://www.felixcloutier.com/x86/senter This pseudocode defines the register initialization and signaling sequence required to enter authenticated code mode. It sets up control registers, segment descriptors, and signals the chipset to prepare the environment. ```pseudocode ACMODEFLAG := 1; CR0.[PG.AM.WP] := 0; CR4 := 00004000h; EFLAGS := 00000002h; IA32_EFER := 0; EBP := ACBASE; GDTR.BASE := ACBASE+ACRAM[GDTBasePtr]; GDTR.LIMIT := ACRAM[GDTLimit]; CS.SEL := ACRAM[SegSel]; CS.BASE := 0; CS.LIMIT := FFFFFh; CS.G := 1; CS.D := 1; CS.AR := 9Bh; DS.SEL := ACRAM[SegSel]+8; DS.BASE := 0; DS.LIMIT := FFFFFh; DS.G := 1; DS.D := 1; DS.AR := 93h; SS := DS; ES := DS; DR7 := 00000400h; IA32_DEBUGCTL := 0; SignalTXTMsg(UnlockSMRAM); SignalTXTMsg(OpenPrivate); SignalTXTMsg(OpenLocality3); EIP := ACEntryPoint; END; ``` -------------------------------- ### Double ST(0) Value Source: https://www.felixcloutier.com/x86/fadd%3Afaddp%3Afiadd Example of using the FADD instruction to double the value currently stored in the ST(0) FPU register. ```assembly FADD ST(0), ST(0); ``` -------------------------------- ### AC Module Entry Point and TPM Interaction Source: https://www.felixcloutier.com/x86/senter This pseudocode describes the logic for determining the AC module entry point and the interaction with the Trusted Platform Module (TPM) for signature verification. It includes conditional logic for different TPM interface modes and error handling for TPM communication. ```pseudocode IF ((ACMCONTROL.0 = 1) and (ACMCONTROL.1 = 1) and (snoop hit to modified line detected on ACRAM load)) THEN ACEntryPoint := ACBASE+ACRAM[ErrorEntryPoint]; ELSE ACEntryPoint := ACBASE+ACRAM[EntryPoint]; IF ((ACEntryPoint >= ACSIZE) or (ACEntryPoint < (ACRAM[HeaderLen] * 4 + Scratch_size))) THEN TXT-SHUTDOWN(#BadACMFormat); IF ((ACRAM[SegSel] > (ACRAM[GDTLimit] - 15)) or (ACRAM[SegSel] < 8)) THEN TXT-SHUTDOWN(#BadACMFormat); IF ((ACRAM[SegSel].TI=1) or (ACRAM[SegSel].RPL≠0)) THEN TXT-SHUTDOWN(#BadACMFormat); IF (FTM_INTERFACE_ID.[3:0] = 1 ) (* Alternate FTM Interface has been enabled *) THEN (* TPM_LOC_CTRL_4 is located at 0FED44008H, TMP_DATA_BUFFER_4 is located at 0FED44080H *) WRITE(TPM_LOC_CTRL_4) := 01H; (* Modified HASH.START protocol *) (* Write to firmware storage *) WRITE(TPM_DATA_BUFFER_4) := SIGNATURE_LEN_CONST + 4; FOR I=0 to SIGNATURE_LEN_CONST - 1 DO WRITE(TPM_DATA_BUFFER_4 + 2 + I ) := ACRAM[SCRATCH.I]; WRITE(TPM_DATA_BUFFER_4 + 2 + SIGNATURE_LEN_CONST) := EDX; WRITE(FTM.LOC_CTRL) := 06H; (* Modified protocol combining HASH.DATA and HASH.END *) ELSE IF (FTM_INTERFACE_ID.[3:0] = 0 ) (* Use standard TPM Interface *) ACRAM[SCRATCH.SIGNATURE_LEN_CONST] := EDX; WRITE(TPM.HASH.START) := 0; FOR I=0 to SIGNATURE_LEN_CONST + 3 DO WRITE(TPM.HASH.DATA) := ACRAM[SCRATCH.I]; WRITE(TPM.HASH.END) := 0; ``` -------------------------------- ### Search for Supported AC Module Versions Source: https://www.felixcloutier.com/x86/parameters A pseudo-code routine to iterate through SMX parameters and verify if a specific AC module version is supported by the processor. ```pseudo-code parameter_search_index = 0 do { EBX = parameter_search_index++ EAX = 6 GETSEC if (EAX[4:0] == 1) { if ((version_query & EBX) == ECX) { version_is_supported = 1 break } } } while (EAX[4:0] != 0) ``` -------------------------------- ### KORTEST C/C++ Intrinsic Source: https://www.felixcloutier.com/x86/kortestw%3Akortestb%3Akortestq%3Akortestd Example of the Intel C/C++ compiler intrinsic equivalent for the KORTESTW instruction. This allows developers to access the hardware instruction directly from high-level code. ```C/C++ KORTESTW __mmask16 _mm512_kortest[cz](__mmask16 a, __mmask16 b); ``` -------------------------------- ### Execute CPUID Basic Information Request Source: https://www.felixcloutier.com/x86/cpuid Example of loading the EAX register with 00H to retrieve the maximum return value and the processor vendor identification string. ```Assembly MOV EAX, 00H CPUID ``` -------------------------------- ### POST /instruction/EGETKEY Source: https://www.felixcloutier.com/x86/egetkey Executes the EGETKEY instruction to derive a key based on the provided KEYREQUEST structure. ```APIDOC ## POST /instruction/EGETKEY ### Description Derives a cryptographic key based on the input KEYREQUEST structure provided in the RBX register and stores the result at the address specified in the RCX register. ### Method POST ### Endpoint /instruction/EGETKEY ### Parameters #### Request Body - **RBX** (struct) - Required - Contains the KEYREQUEST structure including KEYPOLICY, ISVSVN, CPUSVN, and ATTRIBUTEMASK. - **RCX** (address) - Required - The memory address where the derived key will be stored. ### Request Example { "RBX": { "KEYPOLICY": "0x0001", "ISVSVN": 0, "CPUSVN": "0x...", "ATTRIBUTEMASK": "0xFF..." }, "RCX": "0x00007FFFFFFF0000" } ### Response #### Success Response (200) - **RAX** (int) - Returns 0 on success. - **ZF** (flag) - Cleared (0) on success. #### Error Handling - **SGX_INVALID_KEYNAME** (RAX=1) - Returned if the requested key name is invalid. - **#GP(0)** - Triggered if executed outside an enclave or if memory operands are invalid/misaligned. #### Response Example { "RAX": 0, "ZF": 0 } ``` -------------------------------- ### VGATHERDPS / VGATHERQPS Operations Source: https://www.felixcloutier.com/x86/vgatherdps%3Avgatherqps Documentation for gather instructions that fetch packed single-precision floating-point values from memory using vector indices. ```APIDOC ## VGATHERDPS / VGATHERQPS ### Description These instructions gather packed single-precision floating-point values from memory locations specified by a base address, a vector of indices, and a scale factor. The operations support both 128-bit and 256-bit vector lengths. ### Method N/A (CPU Instruction) ### Parameters #### Request Body - **BASE_ADDR** (pointer) - Required - The base memory address for the gather operation. - **VINDEX** (vector) - Required - Vector containing indices to be multiplied by scale. - **SCALE** (integer) - Required - Scale factor (1, 2, 4, or 8). - **MASK** (vector) - Required - Mask register determining which elements to load. ### Response #### Success Response (200) - **DEST** (vector) - The resulting vector containing gathered floating-point values. ### Response Example { "result": "DEST[i+31:i] := FETCH_32BITS(BASE_ADDR + (SignExtend(VINDEX)*SCALE + DISP))" } ``` -------------------------------- ### XBEGIN Instruction Source: https://www.felixcloutier.com/x86/xbegin The XBEGIN instruction marks the start of an RTM code region. It transitions the processor into transactional execution and specifies a relative offset for the fallback code path in the event of a transactional abort. ```APIDOC ## XBEGIN (Transactional Begin) ### Description Initiates a Restricted Transactional Memory (RTM) region. If the processor is not already in transactional execution, it transitions to it and records the architectural state. A relative offset is provided to determine the fallback address if the transaction aborts. ### Method N/A (Assembly Instruction) ### Endpoint XBEGIN rel16 | XBEGIN rel32 ### Parameters #### Path Parameters - **rel16/rel32** (offset) - Required - A 16-bit or 32-bit relative offset used to calculate the fallback instruction pointer. ### Request Example ```asm XBEGIN fallback_label ``` ### Response #### Success Response (Transactional Execution) - **RTM_ACTIVE** (boolean) - Set to 1 upon successful transition. - **RTM_NEST_COUNT** (integer) - Incremented to indicate nesting level. #### Abort Response - **EAX** (register) - Updated with abort status code. - **Architectural State** (state) - Restored to the state prior to the outermost XBEGIN. ### Response Example ```json { "status": "RTM_STARTED", "nest_count": 1 } ``` ``` -------------------------------- ### C/C++ Intrinsic Equivalents Source: https://www.felixcloutier.com/x86/vpternlogd%3Avpternlogq List of available compiler intrinsics for VPTERNLOGD and VPTERNLOGQ across different vector sizes. ```APIDOC ## [INTRINSICS] VPTERNLOGQ / VPTERNLOGD ### Description Intel C/C++ Compiler intrinsics for performing ternary logic operations on 32-bit (D) and 64-bit (Q) integers. ### Available Intrinsics - **_mm512_ternarylogic_epi64**(__m512i a, __m512i b, int imm) - **_mm512_mask_ternarylogic_epi64**(__m512i s, __mmask8 m, __m512i a, __m512i b, int imm) - **_mm512_maskz_ternarylogic_epi64**(__mmask8 m, __m512i a, __m512i b, int imm) - **_mm256_ternarylogic_epi64**(__m256i a, __m256i b, int imm) - **_mm_ternarylogic_epi64**(__m128i a, __m128i b, int imm) ### Notes - Intrinsics are available for 128-bit, 256-bit, and 512-bit registers. - Masked versions (mask/maskz) allow for conditional execution based on a mask register. ``` -------------------------------- ### Execute CPUID Extended Function Requests Source: https://www.felixcloutier.com/x86/cpuid Examples of using various EAX values to query specific processor features such as performance monitoring, topology enumeration, and address size data. ```Assembly CPUID.EAX = 05H ; Returns MONITOR/MWAIT leaf. CPUID.EAX = 0AH ; Returns Architectural Performance Monitoring leaf. CPUID.EAX = 0BH ; Returns Extended Topology Enumeration leaf. CPUID.EAX = 1FH ; Returns V2 Extended Topology Enumeration leaf. CPUID.EAX = 80000008H ; Returns linear/physical address size data. ``` -------------------------------- ### x86 Privilege Level Transition and Stack Management Source: https://www.felixcloutier.com/x86/intn%3Ainto%3Aint3%3Aint1 Handles transitions between privilege levels during interrupts or exceptions. It includes logic for 32-bit and 64-bit IDT gates, pushing necessary information onto the stack, and managing the shadow stack if enabled. ```assembly Push(far pointer to return instruction); (* Old CS and IP, 2 words *) Push(ErrorCode); (* If needed, 2 bytes *) ELSE (* 64-bit IDT gate *) Push(far pointer to old stack); (* Old SS and SP, each an 8-byte push *) Push(RFLAGS); (* 8-byte push *) Push(far pointer to return instruction); (* Old CS and RIP, each an 8-byte push *) Push(ErrorCode); (* If needed, 8-bytes *) FI; FI; IF ShadowStackEnabled(CPL) AND CPL = 3 THEN IF IA32_EFER.LMA = 0 THEN IA32_PL3_SSP := SSP; ELSE (* adjust so bits 63:N get the value of bit N–1, where N is the CPU’s maximum linear-address width *) IA32_PL3_SSP := LA_adjust(SSP); FI; FI; CPL := new code-segment DPL; CS(RPL) := CPL; IF ShadowStackEnabled(CPL) oldSSP := SSP SSP := NewSSP IF SSP & 0x07 != 0 THEN #GP(0); FI; (* Token and CS:LIP:oldSSP pushed on shadow stack must be contained in a naturally aligned 32-byte region *) IF (SSP & ~0x1F) != ((SSP – 24) & ~0x1F) #GP(0); FI; IF ((IA32_EFER.LMA and CS.L) = 0 AND SSP[63:32] != 0) THEN #GP(0); FI; expected_token_value = SSP (* busy bit - bit position 0 - must be clear *) new_token_value = SSP | BUSY_BIT (* Set the busy bit *) IF shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value) != expected_token_value THEN #GP(0); FI; IF oldSS.DPL != 3 ShadowStackPush8B(oldCS); (* Padded with 48 high-order bits of 0 *) ShadowStackPush8B(oldCSBASE + oldRIP); (* Padded with 32 high-order bits of 0 for 32 bit LIP*) ShadowStackPush8B(oldSSP); FI; FI; IF EndbranchEnabled (CPL) IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH; IA32_S_CET.SUPPRESS = 0 FI; IF IDT gate is interrupt gate THEN IF := 0 (* Interrupt flag set to 0, interrupts disabled *); FI; TF := 0; VM := 0; RF := 0; NT := 0; END; ``` -------------------------------- ### EINIT Instruction Logic and SECS Initialization Source: https://www.felixcloutier.com/x86/einit Pseudocode representing the EINIT instruction execution flow. It handles the derivation of the EINITTOKEN key, validation of token measurements and attributes, and the final update of the SECS structure. ```Pseudocode HARDCODED_PKCS1_5_PADDING[2815:2656] := 2004000501020403650148866009060D30313000H; TMP_KEYDEPENDENCIES.KEYNAME := EINITTOKEN_KEY; TMP_KEYDEPENDENCIES.ISVPRODID := TMP_TOKEN.ISVPRODIDLE; TMP_KEYDEPENDENCIES.ISVSVN := TMP_TOKEN.ISVSVNLE; TMP_KEYDEPENDENCIES.MRSIGNER := IA32_SGXLEPUBKEYHASH; TMP_EINITTOKENKEY := derivekey(TMP_KEYDEPENDENCIES); IF (TMP_TOKEN.MAC != CMAC(TMP_EINITTOKENKEY, TMP_TOKEN[1535:0] ) ) RFLAGS.ZF := 1; RAX := SGX_INVALID_EINITTOKEN; GOTO EXIT; FI; DS:RCX.MRENCLAVE := TMP_MRENCLAVE; DS:RCX.MRSIGNER := TMP_MRSIGNER; Update DS:RCX to initialized; RFLAGS.ZF := 0; RAX := 0; ``` -------------------------------- ### FSCALE Operation Example Source: https://www.felixcloutier.com/x86/fscale Illustrates the core operation of the FSCALE instruction, showing how ST(0) is modified based on ST(1). This operation is fundamental to understanding the instruction's purpose in scaling floating-point values. ```assembly ST(0) := ST(0) * 2^RoundTowardZero(ST(1)); ``` -------------------------------- ### Populating TMP_REPORT Structure (x86) Source: https://www.felixcloutier.com/x86/ereport This code populates the TMP_REPORT structure with various security-related attributes and data. It includes information from the current SECS, REPORTDATA, and potentially CET attributes if supported. The MAC and KEYID are also initialized. ```x86 Assembly (* REPORT MAC needs to be computed over data which cannot be modified *) TMP_REPORT.CPUSVN := CR_CPUSVN; TMP_REPORT.ISVFAMILYID := TMP_CURRENTSECS.ISVFAMILYID; TMP_REPORT.ISVEXTPRODID := TMP_CURRENTSECS.ISVEXTPRODID; TMP_REPORT.ISVPRODID := TMP_CURRENTSECS.ISVPRODID; TMP_REPORT.ISVSVN := TMP_CURRENTSECS.ISVSVN; TMP_REPORT.ATTRIBUTES := TMP_CURRENTSECS.ATTRIBUTES; TMP_REPORT.REPORTDATA := DS:RCX[511:0]; TMP_REPORT.MRENCLAVE := TMP_CURRENTSECS.MRENCLAVE; TMP_REPORT.MRSIGNER := TMP_CURRENTSECS.MRSIGNER; TMP_REPORT.MRRESERVED := 0; TMP_REPORT.KEYID[255:0] := CR_REPORT_KEYID; TMP_REPORT.MISCSELECT := TMP_CURRENTSECS.MISCSELECT; TMP_REPORT.CONFIGID := TMP_CURRENTSECS.CONFIGID; TMP_REPORT.CONFIGSVN := TMP_CURRENTSECS.CONFIGSVN; IF (CPUID.(EAX=12H, ECX=1):EAX[6] = 1) THEN TMP_REPORT.CET_ATTRIBUTES := TMP_CURRENTSECS.CET_ATTRIBUTES; FI; ``` -------------------------------- ### Unpack High Data Instructions (Assembly) Source: https://www.felixcloutier.com/x86/punpckhbw%3Apunpckhwd%3Apunpckhdq%3Apunpckhqdq Assembly syntax examples for high-order data interleaving across various SIMD architectures. These instructions perform unpacking operations on registers ranging from 64-bit MMX to 512-bit ZMM registers. ```assembly ; Legacy MMX/SSE PUNPCKHBW mm1, mm2/m64 PUNPCKHBW xmm1, xmm2/m128 ; AVX/AVX2 VEX encoded VPUNPCKHBW xmm1, xmm2, xmm3/m128 VPUNPCKHBW ymm1, ymm2, ymm3/m256 ; AVX-512 EVEX encoded with masking VPUNPCKHBW zmm1 {k1}{z}, zmm2, zmm3/m512 VPUNPCKHQDQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst ``` -------------------------------- ### Other Exceptions Source: https://www.felixcloutier.com/x86/vpgatherdd%3Avpgatherdq Reference to other exception conditions applicable to the intrinsics. ```APIDOC ## Other Exceptions ### Description Refers to external documentation for specific exception conditions (Type E12 Class Exception Conditions). ### Method N/A ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### VRANGESS Instruction Details Source: https://www.felixcloutier.com/x86/vrangess This section details the VRANGESS instruction's behavior, including its conditional execution based on writemask and merging/zeroing masking options. It also provides a practical example of its usage for bounding a value within ±150. ```APIDOC ## VRANGESS ### Description Performs a range comparison on single-precision floating-point values. The destination element is updated based on whether the source operands fall within a specified range, with options for masking and sign selection. ### Method Not applicable (this describes an instruction, not an HTTP endpoint). ### Endpoint Not applicable. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```assembly VRANGESS zmm_dst, zmm_src, zmm_150, 02h ``` This example checks if `zmm_src` is bounded between ±150. If `|zmm_src| < 150`, `zmm_src` is written to `zmm_dst`. Otherwise, `150` (from `zmm_150`) is written, with the sign of `zmm_src` preserved. ### Response #### Success Response (200) - **DEST[31:0]** (single-precision float) - The result of the range comparison. - **DEST[127:32]** (single-precision float) - Copied from SRC1[127:32]. - **DEST[MAXVL-1:128]** (single-precision float) - Set to 0. #### Response Example (Assembly instruction, no direct JSON response) ### SIMD Floating-Point Exceptions - Invalid - Denormal ### Other Exceptions See Table 2-47, “Type E3 Class Exception Conditions.” ``` -------------------------------- ### EGETKEY Pseudo-code Key Derivation Source: https://www.felixcloutier.com/x86/egetkey This pseudo-code snippet demonstrates the logic used by the EGETKEY instruction to populate key dependencies based on the KEYPOLICY structure and current enclave state. It handles conditional inclusion of various enclave identifiers and concludes by invoking the derivekey function to produce the final output key. ```Pseudo-code IF (DS:RBX.KEYPOLICY.ISVFAMILYID = 1) THEN TMP_ISVFAMILYID := TMP_CURRENTSECS.ISVFAMILYID; FI; TMP_ISVPRODID := 0; IF (DS:RBX.KEYPOLICY.NOISVPRODID = 0) TMP_ISVPRODID := TMP_CURRENTSECS.ISVPRODID; FI; TMP_CONFIGID := 0; TMP_CONFIGSVN := 0; IF (DS:RBX.KEYPOLICY.CONFIGID = 1) TMP_CONFIGID := TMP_CURRENTSECS.CONFIGID; TMP_CONFIGSVN := DS:RBX.CONFIGSVN; FI; TMP_ISVEXTPRODID := 0; IF (DS:RBX.KEYPOLICY.ISVEXTPRODID = 1) TMP_ISVEXTPRODID := TMP_CURRENTSECS.ISVEXTPRODID; FI; TMP_KEYDEPENDENCIES.KEYNAME := PROVISION_SEAL_KEY; TMP_KEYDEPENDENCIES.ISVFAMILYID := TMP_ISVFAMILYID; TMP_KEYDEPENDENCIES.ISVEXTPRODID := TMP_ISVEXTPRODID; TMP_KEYDEPENDENCIES.ISVPRODID := TMP_ISVPRODID; TMP_KEYDEPENDENCIES.ISVSVN := DS:RBX.ISVSVN; TMP_KEYDEPENDENCIES.SGXOWNEREPOCH := 0; TMP_KEYDEPENDENCIES.ATTRIBUTES := TMP_ATTRIBUTES; TMP_KEYDEPENDENCIES.ATTRIBUTESMASK := DS:RBX.ATTRIBUTEMASK; TMP_KEYDEPENDENCIES.MRENCLAVE := 0; TMP_KEYDEPENDENCIES.MRSIGNER := TMP_CURRENTSECS.MRSIGNER; TMP_KEYDEPENDENCIES.KEYID := 0; TMP_KEYDEPENDENCIES.SEAL_KEY_FUSES := CR_SEAL_FUSES; TMP_KEYDEPENDENCIES.CPUSVN := DS:RBX.CPUSVN; TMP_KEYDEPENDENCIES.PADDING := TMP_CURRENTSECS.PADDING; TMP_KEYDEPENDENCIES.MISCSELECT := TMP_MISCSELECT; TMP_KEYDEPENDENCIES.MISCMASK := ~DS:RBX.MISCMASK; TMP_KEYDEPENDENCIES.KEYPOLICY := DS:RBX.KEYPOLICY; TMP_KEYDEPENDENCIES.CONFIGID := TMP_CONFIGID; TMP_KEYDEPENDENCIES.CONFIGSVN := TMP_CONFIGSVN; IF (CPUID.(EAX=12H, ECX=1):EAX[6] = 1) THEN TMP_KEYDEPENDENCIES.CET_ATTRIBUTES := TMP_CET_ATTRIBUTES; TMP_KEYDEPENDENCIES.CET_ATTRIBUTES _MASK := 0; FI; BREAK; DEFAULT: RFLAGS.ZF := 1; RAX := SGX_INVALID_KEYNAME; GOTO EXIT: ESAC; TMP_OUTPUTKEY := derivekey(TMP_KEYDEPENDENCIES); DS:RCX[15:0] := TMP_OUTPUTKEY; RAX := 0; RFLAGS.ZF := 0; EXIT: RFLAGS.CF := 0; RFLAGS.PF := 0; RFLAGS.AF := 0; RFLAGS.OF := 0; RFLAGS.SF := 0; ``` -------------------------------- ### SHUFPD/VSHUFPD Instruction Assembly Usage Source: https://www.felixcloutier.com/x86/shufpd Examples of assembly syntax for various SHUFPD/VSHUFPD instruction variants, including legacy SSE, VEX, and EVEX encodings with support for writemasks and memory operands. ```Assembly ; Legacy SSE2 SHUFPD xmm1, xmm2, 0x01 ; AVX 128-bit VSHUFPD xmm1, xmm2, xmm3, 0x01 ; AVX 256-bit VSHUFPD ymm1, ymm2, ymm3, 0x0F ; AVX-512 512-bit with writemask VSHUFPD zmm1 {k1}, zmm2, zmm3, 0xFF ``` -------------------------------- ### x86 Assembly: 64-bit Mode Comparisons (Byte, Word, Doubleword, Quadword) Source: https://www.felixcloutier.com/x86/scas%3Ascasb%3Ascasw%3Ascasd This code illustrates comparisons in 64-bit x86 assembly. It supports byte, word, doubleword, and quadword comparisons, adjusting the R|E|DI register according to the Direction Flag (DF) and updating status flags based on the subtraction outcome. The REX.W prefix is used for quadword operations. ```assembly IF (Byte comparison) THEN temp := AL − SRC; SetStatusFlags(temp); THEN IF DF = 0 THEN (R|E)DI := (R|E)DI + 1; ELSE (R|E)DI := (R|E)DI – 1; FI; ELSE IF (Word comparison) THEN temp := AX − SRC; SetStatusFlags(temp); IF DF = 0 THEN (R|E)DI := (R|E)DI + 2; ELSE (R|E)DI := (R|E)DI – 2; FI; FI; ELSE IF (Doubleword comparison) THEN temp := EAX – SRC; SetStatusFlags(temp); IF DF = 0 THEN (R|E)DI := (R|E)DI + 4; ELSE (R|E)DI := (R|E)DI – 4; FI; FI; ELSE IF (Quadword comparison using REX.W ) THEN temp := RAX − SRC; SetStatusFlags(temp); IF DF = 0 THEN (R|E)DI := (R|E)DI + 8; ELSE (R|E)DI := (R|E)DI – 8; FI; FI; FI; ``` -------------------------------- ### Scatter Prefetch Single Precision (PS) with 64-bit Index (C/C++) Source: https://www.felixcloutier.com/x86/vscatterpf0dps%3Avscatterpf0qps%3Avscatterpf0dpd%3Avscatterpf0qpd Provides intrinsic functions for prefetching single-precision floating-point data using 64-bit indices with scatter operations. It includes versions with and without masks, and requires the AVX-512 foundation instruction set. ```c void _mm512_prefetch_i64scatter_ps(void * base, __m512i vdx, int scale, int hint); void _mm512_mask_prefetch_i64scatter_ps(void * base, __mmask8 m, __m512i vdx, int scale, int hint); ``` -------------------------------- ### BEXTR Intrinsic for 64-bit Operands Source: https://www.felixcloutier.com/x86/bextr This C intrinsic function, `_bextr_u64`, provides a way to use the BEXTR instruction for 64-bit unsigned integers. It takes the source value, the starting bit position, and the length of the bit field to extract as arguments. ```c BEXTR unsigned __int64 _bextr_u64(unsigned __int64 src, unsigned __int32 start. unsigned __int32 len); ``` -------------------------------- ### BEXTR Intrinsic for 32-bit Operands Source: https://www.felixcloutier.com/x86/bextr This C intrinsic function, `_bextr_u32`, provides a way to use the BEXTR instruction for 32-bit unsigned integers. It takes the source value, the starting bit position, and the length of the bit field to extract as arguments. ```c BEXTR unsigned __int32 _bextr_u32(unsigned __int32 src, unsigned __int32 start. unsigned __int32 len); ``` -------------------------------- ### SIMD Floating-Point Exceptions Source: https://www.felixcloutier.com/x86/vpgatherdd%3Avpgatherdq Information regarding SIMD floating-point exceptions for the described intrinsics. ```APIDOC ## SIMD Floating-Point Exceptions ### Description This section indicates that there are no specific SIMD floating-point exceptions associated with these intrinsics. ### Method N/A ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### ERESUME Flow: Enclave Initialization and Mode Checks (Assembly) Source: https://www.felixcloutier.com/x86/eresume This snippet focuses on ensuring the enclave is properly initialized and that the processor's operating mode matches the enclave's configuration. It checks if the enclave has been previously EINITted and verifies that the 64-bit mode setting in the processor (TMP_MODE64) aligns with the SECS.ATTRIBUTES.MODE64BIT value. ```Assembly (* SECS must exist and enclave must have previously been EINITted *) IF (the enclave is not already initialized) THEN #GP(0); FI; (* make sure the logical processor's operating mode matches the enclave *) IF ( (TMP_MODE64 ≠ TMP_SECS.ATTRIBUTES.MODE64BIT)) THEN #GP(0); FI; ```