|
|
NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);
NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);
ELSE
(* current TSS is 16-bit *)
TSSstackAddress := (new code-segment DPL « 2) + 2
IF (TSSstackAddress + 3) > current TSS limit
THEN #TS(error_code(current TSS selector,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);
NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);
FI;
IF NewSS is NULL
THEN #TS(EXT); FI;
IF NewSS index is not within its descriptor-table limits
or NewSS RPL ≠ new code-segment DPL
THEN #TS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
Read new stack-segment descriptor for NewSS in GDT or LDT;
IF new stack-segment DPL ≠ new code-segment DPL
or new stack-segment Type does not indicate writable data segment
THEN #TS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
IF NewSS is not present
THEN #SS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)
ELSE (* IA-32e mode *)
IF IDT-gate IST = 0
THEN TSSstackAddress := (new code-segment DPL « 3) + 4;
ELSE TSSstackAddress := (IDT gate IST « 3) + 28;
FI;
IF (TSSstackAddress + 7) > current TSS limit
THEN #TS(error_code(current TSS selector,0,EXT); FI;
(* idt operand to error_code is 0 because selector is used *)
NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);
NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)
IF IDT-gate IST = 0
THEN
NewSSP := IA32_PLi_SSP (* where i = new code-segment DPL *)
ELSE
NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT-gate IST « 3)
(* Check if shadow stacks are enabled at CPL 0 *)
IF ShadowStackEnabled(CPL 0)
THEN NewSSP := 8 bytes loaded from NewSSPAddress; FI;
FI;
FI;
IF IDT gate is 32-bit
THEN
IF new stack does not have room for 24 bytes (error code pushed)
or 20 bytes (no error code pushed)
THEN #SS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
FI
ELSE
IF IDT gate is 16-bit
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-473
THEN
IF new stack does not have room for 12 bytes (error code pushed)
or 10 bytes (no error code pushed);
THEN #SS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
ELSE (* 64-bit IDT gate*)
IF StackAddress is non-canonical
THEN #SS(EXT); FI; (* Error code contains NULL selector *)
FI;
FI;
IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)
THEN
IF instruction pointer from IDT gate is not within new code-segment limits
THEN #GP(EXT); FI; (* Error code contains NULL selector *)
ESP := NewESP;
SS := NewSS; (* Segment descriptor information also loaded *)
ELSE (* IA-32e mode *)
IF instruction pointer from IDT gate contains a non-canonical address
THEN #GP(EXT); FI; (* Error code contains NULL selector *)
RSP := NewRSP & FFFFFFFFFFFFFFF0H;
SS := NewSS;
FI;
IF IDT gate is 32-bit
THEN
CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)
ELSE
IF IDT gate 16-bit
THEN
CS:IP := Gate(CS:IP);
(* Segment descriptor information also loaded *)
ELSE (* 64-bit IDT gate *)
CS:RIP := Gate(CS:RIP);
(* Segment descriptor information also loaded *)
FI;
FI;
IF IDT gate is 32-bit
THEN
Push(far pointer to old stack);
(* Old SS and ESP, 3 words padded to 4 *)
Push(EFLAGS);
Push(far pointer to return instruction);
(* Old CS and EIP, 3 words padded to 4 *)
Push(ErrorCode); (* If needed, 4 bytes *)
ELSE
IF IDT gate 16-bit
THEN
Push(far pointer to old stack);
(* Old SS and SP, 2 words *)
Push(EFLAGS(15:0]);
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);
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-474
(* 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;
INTERRUPT-FROM-VIRTUAL-8086-MODE:
(* Identify stack-segment selector for privilege level 0 in current TSS *)
IF current TSS is 32-bit
THEN
IF TSS limit < 9
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-475
THEN #TS(error_code(current TSS selector,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
NewSS := 2 bytes loaded from (current TSS base + 8);
NewESP := 4 bytes loaded from (current TSS base + 4);
ELSE (* current TSS is 16-bit *)
IF TSS limit < 5
THEN #TS(error_code(current TSS selector,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
NewSS := 2 bytes loaded from (current TSS base + 4);
NewESP := 2 bytes loaded from (current TSS base + 2);
FI;
IF NewSS is NULL
THEN #TS(EXT); FI; (* Error code contains NULL selector *)
IF NewSS index is not within its descriptor table limits
or NewSS RPL ≠ 0
THEN #TS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
Read new stack-segment descriptor for NewSS in GDT or LDT;
IF new stack-segment DPL ≠ 0 or stack segment does not indicate writable data segment
THEN #TS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
IF new stack segment not present
THEN #SS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
NewSSP := IA32_PL0_SSP (* the new code-segment DPL must be 0 *)
IF IDT gate is 32-bit
THEN
IF new stack does not have room for 40 bytes (error code pushed)
or 36 bytes (no error code pushed)
THEN #SS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
ELSE (* IDT gate is 16-bit)
IF new stack does not have room for 20 bytes (error code pushed)
or 18 bytes (no error code pushed)
THEN #SS(error_code(NewSS,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
FI;
IF instruction pointer from IDT gate is not within new code-segment limits
THEN #GP(EXT); FI; (* Error code contains NULL selector *)
tempEFLAGS := EFLAGS;
VM := 0;
TF := 0;
RF := 0;
NT := 0;
IF service through interrupt gate
THEN IF = 0; FI;
TempSS := SS;
TempESP := ESP;
SS := NewSS;
ESP := NewESP;
(* Following pushes are 16 bits for 16-bit IDT gates and 32 bits for 32-bit IDT gates;
Segment selector pushes in 32-bit mode are padded to two words *)
Push(GS);
Push(FS);
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-476
Push(DS);
Push(ES);
Push(TempSS);
Push(TempESP);
Push(TempEFlags);
Push(CS);
Push(EIP);
GS := 0; (* Segment registers made NULL, invalid for use in protected mode *)
FS := 0;
DS := 0;
ES := 0;
CS := Gate(CS); (* Segment descriptor information also loaded *)
CS(RPL) := 0;
CPL := 0;
IF IDT gate is 32-bit
THEN
EIP := Gate(instruction pointer);
ELSE (* IDT gate is 16-bit *)
EIP := Gate(instruction pointer) AND 0000FFFFH;
FI;
IF ShadowStackEnabled(0)
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;
FI;
IF EndbranchEnabled (CPL)
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;
IA32_S_CET.SUPPRESS = 0
FI;
(* Start execution of new routine in Protected Mode *)
END;
INTRA-PRIVILEGE-LEVEL-INTERRUPT:
NewSSP = SSP;
CHECK_SS_TOKEN = 0
(* PE = 1, DPL = CPL or conforming segment *)
IF IA32_EFER.LMA = 1 (* IA-32e mode *)
IF IDT-descriptor IST ≠ 0
THEN
TSSstackAddress := (IDT-descriptor IST « 3) + 28;
IF (TSSstackAddress + 7) > TSS limit
THEN #TS(error_code(current TSS selector,0,EXT)); FI;
(* idt operand to error_code is 0 because selector is used *)
NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-477
ELSE NewRSP := RSP;
FI;
IF IDT-descriptor IST ≠ 0
IF ShadowStackEnabled(CPL)
THEN
NewSSPAddress = IA32_INTERRUPT_SSP_TABLE_ADDR + (IDT gate IST « 3)
NewSSP := 8 bytes loaded from NewSSPAddress
CHECK_SS_TOKEN = 1
FI;
FI;
FI;
IF 32-bit gate (* implies IA32_EFER.LMA = 0 *)
THEN
IF current stack does not have room for 16 bytes (error code pushed)
or 12 bytes (no error code pushed)
THEN #SS(EXT); FI; (* Error code contains NULL selector *)
ELSE IF 16-bit gate (* implies IA32_EFER.LMA = 0 *)
IF current stack does not have room for 8 bytes (error code pushed)
or 6 bytes (no error code pushed)
THEN #SS(EXT); FI; (* Error code contains NULL selector *)
ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)
IF NewRSP contains a non-canonical address
THEN #SS(EXT); (* Error code contains NULL selector *)
FI;
FI;
IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)
THEN
IF instruction pointer from IDT gate is not within new code-segment limit
THEN #GP(EXT); FI; (* Error code contains NULL selector *)
ELSE
IF instruction pointer from IDT gate contains a non-canonical address
THEN #GP(EXT); FI; (* Error code contains NULL selector *)
RSP := NewRSP & FFFFFFFFFFFFFFF0H;
FI;
IF IDT gate is 32-bit (* implies IA32_EFER.LMA = 0 *)
THEN
Push (EFLAGS);
Push (far pointer to return instruction); (* 3 words padded to 4 *)
CS:EIP := Gate(CS:EIP); (* Segment descriptor information also loaded *)
Push (ErrorCode); (* If any *)
ELSE
IF IDT gate is 16-bit (* implies IA32_EFER.LMA = 0 *)
THEN
Push (FLAGS);
Push (far pointer to return location); (* 2 words *)
CS:IP := Gate(CS:IP);
(* Segment descriptor information also loaded *)
Push (ErrorCode); (* If any *)
ELSE (* IA32_EFER.LMA = 1, 64-bit 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 *)
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-478
Push(ErrorCode); (* If needed, 8 bytes *)
CS:RIP := GATE(CS:RIP);
(* Segment descriptor information also loaded *)
FI;
FI;
CS(RPL) := CPL;
IF ShadowStackEnabled(CPL)
IF CHECK_SS_TOKEN == 1
THEN
IF NewSSP & 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 (NewSSP & ~0x1F) != ((NewSSP - 24) & ~0x1F)
#GP(0); FI;
IF ((IA32_EFER.LMA and CS.L) = 0 AND NewSSP[63:32] != 0)
THEN #GP(0); FI;
expected_token_value = NewSSP (* busy bit - bit position 0 - must be clear *)
new_token_value = NewSSP | BUSY_BIT (* Set the busy bit *)
IF shadow_stack_lock_cmpxchg8b(NewSSP, new_token_value, expected_token_value) != expected_token_value
THEN #GP(0); FI;
FI;
(* Align to next 8 byte boundary *)
tempSSP = SSP;
Shadow_stack_store 4 bytes of 0 to (NewSSP - 4)
SSP = newSSP & 0xFFFFFFFFFFFFFFF8H;
(* push cs:lip:ssp on shadow stack *)
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(tempSSP);
FI;
IF EndbranchEnabled (CPL)
IF CPL = 3
THEN
IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH
IA32_U_CET.SUPPRESS = 0
ELSE
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH
IA32_S_CET.SUPPRESS = 0
FI;
FI;
IF IDT gate is interrupt gate
THEN IF := 0; FI; (* Interrupt flag set to 0; interrupts disabled *)
TF := 0;
NT := 0;
VM := 0;
RF := 0;
END;
Flags Affected
The EFLAGS register is pushed onto the stack. The IF, TF, NT, AC, RF, and VM flags may be cleared, depending on
the mode of operation of the processor when the INT instruction is executed (see the “Operation” section). If the
interrupt uses a task gate, any flags may be set or cleared, controlled by the EFLAGS image in the new task’s TSS.
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-479
Protected Mode Exceptions
#GP(error_code)
If the instruction pointer in the IDT or in the interrupt, trap, or task gate is beyond the code
segment limits.
If the segment selector in the interrupt, trap, or task gate is NULL.
If an interrupt, trap, or task gate, code segment, or TSS segment selector index is outside its
descriptor table limits.
If the vector selects a descriptor outside the IDT limits.
If an IDT descriptor is not an interrupt, trap, or task gate.
If an interrupt is generated by the INT n, INT3, or INTO instruction and the DPL of an interrupt,
trap, or task gate is less than the CPL.
If the segment selector in an interrupt or trap gate does not point to a segment descriptor for
a code segment.
If the segment selector for a TSS has its local/global bit set for local.
If a TSS segment descriptor specifies that the TSS is busy or not available.
If SSP in IA32_PLi_SSP (where i is the new CPL) is not 8 byte aligned.
If the token and the stack frame to be pushed on shadow stack are not contained in a naturally
aligned 32-byte region of the shadow stack.
If “supervisor Shadow Stack” token on new shadow stack is marked busy.
If destination mode is 32-bit or compatibility mode, but SSP address in “supervisor shadow
stack” token is beyond 4GB.
If SSP address in “supervisor shadow stack” token does not match SSP address in
IA32_PLi_SSP (where i is the new CPL).
#SS(error_code)
If pushing the return address, flags, or error code onto the stack exceeds the bounds of the
stack segment and no stack switch occurs.
If the SS register is being loaded and the segment pointed to is marked not present.
If pushing the return address, flags, error code, or stack segment pointer exceeds the bounds
of the new stack segment when a stack switch occurs.
#NP(error_code)
If code segment, interrupt gate, trap gate, task gate, or TSS is not present.
#TS(error_code)
If the RPL of the stack segment selector in the TSS is not equal to the DPL of the code segment
being accessed by the interrupt or trap gate.
If DPL of the stack segment descriptor pointed to by the stack segment selector in the TSS is
not equal to the DPL of the code segment descriptor for the interrupt or trap gate.
If the stack segment selector in the TSS is NULL.
If the stack segment for the TSS is not a writable data segment.
If segment-selector index for stack segment is outside descriptor table limits.
#PF(fault-code)
If a page fault occurs.
#UD
If the LOCK prefix is used.
#AC(EXT)
If alignment checking is enabled, the gate DPL is 3, and a stack push is unaligned.
Real-Address Mode Exceptions
#GP
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the interrupt vector number is outside the IDT limits.
#SS
If stack limit violation on push.
If pushing the return address, flags, or error code onto the stack exceeds the bounds of the
stack segment.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(error_code)
(For INT n, INTO, or BOUND instruction) If the IOPL is less than 3 or the DPL of the interrupt,
trap, or task gate is not equal to 3.
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-480
If the instruction pointer in the IDT or in the interrupt, trap, or task gate is beyond the code
segment limits.
If the segment selector in the interrupt, trap, or task gate is NULL.
If a interrupt gate, trap gate, task gate, code segment, or TSS segment selector index is
outside its descriptor table limits.
If the vector selects a descriptor outside the IDT limits.
If an IDT descriptor is not an interrupt, trap, or task gate.
If an interrupt is generated by INT n, INT3, or INTO and the DPL of an interrupt, trap, or task
gate is less than the CPL.
If the segment selector in an interrupt or trap gate does not point to a segment descriptor for
a code segment.
If the segment selector for a TSS has its local/global bit set for local.
#SS(error_code)
If the SS register is being loaded and the segment pointed to is marked not present.
If pushing the return address, flags, error code, stack segment pointer, or data segments
exceeds the bounds of the stack segment.
#NP(error_code)
If code segment, interrupt gate, trap gate, task gate, or TSS is not present.
#TS(error_code)
If the RPL of the stack segment selector in the TSS is not equal to the DPL of the code segment
being accessed by the interrupt or trap gate.
If DPL of the stack segment descriptor for the TSS’s stack segment is not equal to the DPL of
the code segment descriptor for the interrupt or trap gate.
If the stack segment selector in the TSS is NULL.
If the stack segment for the TSS is not a writable data segment.
If segment-selector index for stack segment is outside descriptor table limits.
#PF(fault-code)
If a page fault occurs.
#OF
If the INTO instruction is executed and the OF flag is set.
#UD
If the LOCK prefix is used.
#AC(EXT)
If alignment checking is enabled, the gate DPL is 3, and a stack push is unaligned.
Compatibility Mode Exceptions
#GP(error_code)
If the instruction pointer in the 64-bit interrupt gate or trap gate is non-canonical.
If the segment selector in the 64-bit interrupt or trap gate is NULL.
If the vector selects a descriptor outside the IDT limits.
If the vector points to a gate which is in non-canonical space.
If the vector points to a descriptor which is not a 64-bit interrupt gate or a 64-bit trap gate.
If the descriptor pointed to by the gate selector is outside the descriptor table limit.
If the descriptor pointed to by the gate selector is in non-canonical space.
If the descriptor pointed to by the gate selector is not a code segment.
If the descriptor pointed to by the gate selector doesn’t have the L-bit set, or has both the L-
bit and D-bit set.
If the descriptor pointed to by the gate selector has DPL > CPL.
#GP(0)
If SSP in IA32_PLi_SSP (where i is the new CPL) is not 8 byte aligned.
If the token and the stack frame to be pushed on shadow stack are not contained in a naturally
aligned 32-byte region of the shadow stack.
If “supervisor shadow stack” token on new shadow stack is marked busy.
If destination mode is 32-bit or compatibility mode, but SSP address in “supervisor shadow
stack” token is beyond 4GB.
If SSP address in “supervisor shadow stack” token does not match SSP address in
IA32_PLi_SSP (where i is the new CPL).
If FRED event delivery would load RIP with a non-canonical address.
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-481
If FRED event delivery would load SSP with an address that is not 8-byte aligned.
If a shadow-stack access performed by FRED event delivery would use an address that is not
canonical relative to the current paging mode or cause a LASS violation.
#SS(error_code)
If an ordinary stack access would use an address that is not canonical relative to the current
paging mode or cause a LASS violation.
#NP(error_code)
If the 64-bit interrupt-gate, 64-bit trap-gate, or code segment is not present.
#TS(error_code)
If an attempt to load RSP from the TSS causes an access to non-canonical space.
If the RSP from the TSS is outside descriptor table limits.
#PF(fault-code)
If a page fault occurs.
#UD
If the LOCK prefix is used.
#AC(EXT)
If alignment checking is enabled, the gate DPL is 3, and a stack push is unaligned.
64-Bit Mode Exceptions
Same exceptions as in compatibility mode.
INT n/INTO/INT3/INT1-Call to Interrupt Procedure
Vol. 2A
3-482
INVD-Invalidate Internal Caches
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 08
INVD
ZO
Valid
Valid
Flush internal caches; initiate flushing of
external caches.
NOTES:
1. See the IA-32 Architecture Compatibility section below.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Invalidates (flushes) the processor’s internal caches and issues a special-function bus cycle that directs external
caches to also flush themselves. Data held in internal caches is not written back to main memory.
After executing this instruction, the processor does not wait for the external caches to complete their flushing oper-
ation before proceeding with instruction execution. It is the responsibility of hardware to respond to the cache flush
signal.
The INVD instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a
program or procedure must be 0 to execute this instruction.
The INVD instruction may be used when the cache is used as temporary memory and the cache contents need to
be invalidated rather than written back to memory. When the cache is used as temporary memory, no external
device should be actively writing data to main memory.
Use this instruction with care. Data cached internally and not written back to main memory will be lost. Note that
any data from an external device to main memory (for example, via a PCIWrite) can be temporarily stored in the
caches; these data can be lost when an INVD instruction is executed. Unless there is a specific requirement or
benefit to flushing caches without writing back modified cache lines (for example, temporary memory, testing, or
fault recovery where cache coherency with main memory is not a concern), software should instead use the
WBINVD instruction.
On processors that support processor reserved memory, the INVD instruction cannot be executed when processor
reserved memory protections are activated. See Section 39.5, “EPC and Management of EPC Pages,” in the Intel®
64 and IA-32 Architectures Software Developer’s Manual, Volume 3D.
On processors that support SEAM, the INVD instruction cannot be executed when the SEAM range is protected. See
Section 35.4, “Memory Protection,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume
3.
Some processors prevent execution of INVD after BIOS execution is complete. They report this by enumerating
CPUID.07H.01H:EAX[30] as 1. On such processors, INVD cannot be executed if bit 0 of SR_BIOS_DONE (MSR
address 151H) is 1.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
IA-32 Architecture Compatibility
The INVD instruction is implementation dependent; it may be implemented differently on different families of Intel
64 or IA-32 processors. This instruction is not supported on IA-32 processors earlier than the Intel486 processor.
Operation
Flush(InternalCaches);
SignalFlush(ExternalCaches);
Continue (* Continue execution *)
INVD-Invalidate Internal Caches
Vol. 2A
3-483
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0.
If the processor reserved memory protections are activated.
If the SEAM range is protected.
If CPUID.07H.01H:EAX[30] = 1 and bit 0 is set in MSR_BIOS_DONE (MSR address 151H).
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP(0)
If CPUID.07H.01H:EAX[30] = 1 and bit 0 is set in MSR_BIOS_DONE (MSR address 151H).
If the processor reserved memory protections are activated.
If the SEAM range is protected.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
The INVD instruction cannot be executed in virtual-8086 mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
INVD-Invalidate Internal Caches
Vol. 2A
3-484
INVLPG-Invalidate TLB Entries
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 01/7
INVLPG m
M
Valid
Valid
Invalidate TLB entries for page containing m.
NOTES:
1. See the IA-32 Architecture Compatibility section below.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (r)
N/A
N/A
N/A
Description
Invalidates any translation lookaside buffer (TLB) entries specified with the source operand. The source operand is
a memory address. The processor determines the page that contains that address and flushes all TLB entries for
that page.1
The INVLPG instruction is a privileged instruction. When the processor is running in protected mode, the CPL must
be 0 to execute this instruction.
The INVLPG instruction normally flushes TLB entries only for the specified page; however, in some cases, it may
flush more entries, even the entire TLB. The instruction invalidates TLB entries associated with the current PCID
and may or may not do so for TLB entries associated with other PCIDs. (If PCIDs are disabled - CR4.PCIDE = 0 -
the current PCID is 000H.) The instruction also invalidates any global TLB entries for the specified page, regardless
of PCID.
For more details on operations that flush the TLB, see “MOV-Move to/from Control Registers” in the Intel® 64 and
IA-32 Architectures Software Developer’s Manual, Volume 2B, and Section 5.10.4.1, “Operations that Invalidate
TLBs and Paging-Structure Caches,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume
3A.
This instruction’s operation is the same in all non-64-bit modes. It also operates the same in 64-bit mode, except
if the memory address is in non-canonical form. In this case, INVLPG is the same as a NOP.
IA-32 Architecture Compatibility
The INVLPG instruction is implementation dependent, and its function may be implemented differently on different
families of Intel 64 or IA-32 processors. This instruction is not supported on IA-32 processors earlier than the
Intel486 processor.
Operation
Invalidate(RelevantTLBEntries);
Continue; (* Continue execution *)
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0.
#UD
Operand is a register.
If the LOCK prefix is used.
1. If the paging structures map the linear address using a page larger than 4 KBytes and there are multiple TLB entries for that page
(see Section 5.10.2.3, “Details of TLB Use,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A), the
instruction invalidates all of them.
INVLPG-Invalidate TLB Entries
Vol. 2A
3-485
Real-Address Mode Exceptions
#UD
Operand is a register.
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
The INVLPG instruction cannot be executed at the virtual-8086 mode.
64-Bit Mode Exceptions
#GP(0)
If the current privilege level is not 0.
#UD
Operand is a register.
If the LOCK prefix is used.
INVLPG-Invalidate TLB Entries
Vol. 2A
3-486
INVPCID-Invalidate Process-Context Identifier
Opcode/Instruction
Op/
64/32-
CPUID
Description
En
bit
Feature
Mode
Flag
66 0F 38 82 /r
RM
N.E./V
INVPCID
Invalidates entries in the TLBs and paging-structure
INVPCID r32, m128
caches based on invalidation type in r32 and descrip-
tor in m128.
66 0F 38 82 /r
RM
V/N.E.
INVPCID
Invalidates entries in the TLBs and paging-structure
INVPCID r64, m128
caches based on invalidation type in r64 and descrip-
tor in m128.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r)
ModRM:r/m (r)
N/A
N/A
Description
Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches based on process-
context identifier (PCID). (See Section 5.10, “Caching Translation Information,” in the Intel 64 and IA-32 Architec-
ture Software Developer’s Manual, Volume 3A.) Invalidation is based on the INVPCID type specified in the register
operand and the INVPCID descriptor specified in the memory operand.
Outside 64-bit mode, the register operand is always 32 bits, regardless of the value of CS.D. In 64-bit mode the
register operand has 64 bits.
There are four INVPCID types currently defined:
• Individual-address invalidation: If the INVPCID type is 0, the logical processor invalidates mappings-except
global translations-for the linear address and PCID specified in the INVPCID descriptor.1 In some cases, the
instruction may invalidate global translations or mappings for other linear addresses (or other PCIDs) as well.
• Single-context invalidation: If the INVPCID type is 1, the logical processor invalidates all mappings-except
global translations-associated with the PCID specified in the INVPCID descriptor. In some cases, the
instruction may invalidate global translations or mappings for other PCIDs as well.
• All-context invalidation, including global translations: If the INVPCID type is 2, the logical processor invalidates
all mappings-including global translations-associated with any PCID.
• All-context invalidation: If the INVPCID type is 3, the logical processor invalidates all mappings-except global
translations-associated with any PCID. In some case, the instruction may invalidate global translations as
well.
The INVPCID descriptor comprises 128 bits and consists of a PCID and a linear address as shown in Figure 3-20.
For INVPCID type 0, the processor uses the full 64 bits of the linear address even outside 64-bit mode; the linear
address is not used for other INVPCID types.
127
6463
1211
0
Linear
Address
Reserved (must be zero)
PCID
Figure 3-20. INVPCID Descriptor
1. If the paging structures map the linear address using a page larger than 4 KBytes and there are multiple TLB entries for that page
(see Section 5.10.2.3, “Details of TLB Use,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A), the
instruction invalidates all of them.
INVPCID-Invalidate Process-Context Identifier
Vol. 2A
3-487
If CR4.PCIDE = 0, a logical processor does not cache information for any PCID other than 000H. In this case,
executions with INVPCID types 0 and 1 are allowed only if the PCID specified in the INVPCID descriptor is 000H;
executions with INVPCID types 2 and 3 invalidate mappings only for PCID 000H. Note that CR4.PCIDE must be 0
outside IA-32e mode (see Section 5.10.1, “Process-Context Identifiers (PCIDs),” of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3A).
Operation
INVPCID_TYPE := value of register operand;
// must be in the range of 0-3
INVPCID_DESC := value of memory operand;
CASE INVPCID_TYPE OF
0:
// individual-address invalidation
PCID := INVPCID_DESC[11:0];
L_ADDR := INVPCID_DESC[127:64];
Invalidate mappings for L_ADDR associated with PCID except global translations;
BREAK;
1:
// single PCID invalidation
PCID := INVPCID_DESC[11:0];
Invalidate all mappings associated with PCID except global translations;
BREAK;
2:
// all PCID invalidation including global translations
Invalidate all mappings for all PCIDs, including global translations;
BREAK;
3:
// all PCID invalidation retaining global translations
Invalidate all mappings for all PCIDs except global translations;
BREAK;
ESAC;
Intel C/C++ Compiler Intrinsic Equivalent
INVPCID void _invpcid(unsigned __int32 type, void * descriptor);
SIMD Floating-Point Exceptions
None.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0.
If the memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS register contains an unusable segment.
If the source operand is located in an execute-only code segment.
If an invalid type is specified in the register operand, i.e., INVPCID_TYPE > 3.
If bits 63:12 of INVPCID_DESC are not all zero.
If INVPCID_TYPE is either 0 or 1 and INVPCID_DESC[11:0] is not zero.
If INVPCID_TYPE is 0 and the linear address in INVPCID_DESC[127:64] is not canonical.
#PF(fault-code)
If a page fault occurs in accessing the memory operand.
#SS(0)
If the memory operand effective address is outside the SS segment limit.
If the SS register contains an unusable segment.
#UD
If if CPUID.07H.00H:EBX.INVPCID[10] = 0.
If the LOCK prefix is used.
INVPCID-Invalidate Process-Context Identifier
Vol. 2A
3-488
Real-Address Mode Exceptions
#GP
If an invalid type is specified in the register operand, i.e., INVPCID_TYPE > 3.
If bits 63:12 of INVPCID_DESC are not all zero.
If INVPCID_TYPE is either 0 or 1 and INVPCID_DESC[11:0] is not zero.
If INVPCID_TYPE is 0 and the linear address in INVPCID_DESC[127:64] is not canonical.
#UD
If CPUID.07H.00H:EBX.INVPCID[10] = 0.
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
The INVPCID instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#GP(0)
If the current privilege level is not 0.
If the memory operand is in the CS, DS, ES, FS, or GS segments and the memory address is
in a non-canonical form.
If an invalid type is specified in the register operand, i.e., INVPCID_TYPE > 3.
If bits 63:12 of INVPCID_DESC are not all zero.
If CR4.PCIDE=0, INVPCID_TYPE is either 0 or 1, and INVPCID_DESC[11:0] is not zero.
If INVPCID_TYPE is 0 and the linear address in INVPCID_DESC[127:64] is not canonical.
#PF(fault-code)
If a page fault occurs in accessing the memory operand.
#SS(0)
If the memory destination operand is in the SS segment and the memory address is in a non-
canonical form.
#UD
If the LOCK prefix is used.
If CPUID.07H.00H:EBX.INVPCID[10] = 0.
INVPCID-Invalidate Process-Context Identifier
Vol. 2A
3-489
IRET/IRETD/IRETQ-Interrupt Return
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
CF
IRET
ZO
Valid
Valid
Interrupt return (16-bit operand size).
CF
IRETD
ZO
Valid
Valid
Interrupt return (32-bit operand size).
REX.W + CF
IRETQ
ZO
Valid
N.E.
Interrupt return (64-bit operand size).
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by
an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform
a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or
when an interrupt or exception causes a task switch to an interrupt or exception handler.) See the section titled
“Task Linking” in Chapter 10 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.
IRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended
for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the
IRET mnemonic interchangeably for both operand sizes.
In Real-Address Mode, the IRET instruction performs a far return to the interrupted program or procedure. During
this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image
from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted
program or procedure.
In Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags
in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting
of these flags, the processor performs the following types of interrupt returns:
• Return from virtual-8086 mode.
• Return to virtual-8086 mode.
• Intra-privilege level return.
• Inter-privilege level return.
• Return from nested task (task switch).
If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure,
without a task switch. The code segment being returned to must be equally or less privileged than the interrupt
handler routine (as indicated by the RPL field of the code segment selector popped from the stack).
As with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code
segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then
resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET
instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is
to virtual-8086 mode, the processor also pops the data segment registers from the stack.
If the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a
CALL instruction, an interrupt, or an exception) back to the calling or interrupted task. The updated state of the
task executing the IRET instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET
instruction is executed.
If the NT flag is set and the processor is in IA-32e mode, the IRET instruction causes a general protection excep-
tion.
If nonmaskable interrupts (NMIs) are blocked (see Section 7.7.2, “NMI Blocking” in the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3A), execution of the IRET instruction unblocks NMIs. This
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-490
unblocking occurs even if the instruction causes a fault. In such a case, NMIs are unmasked before the exception
handler is invoked.
In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.W prefix promotes operation to 64
bits (IRETQ). See the summary chart at the beginning of this section for encoding data and limits.
Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 18, “Control-flow Enforcement Tech-
nology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.
When FRED transitions are enabled, an execution of IRET that would change CPL causes a general-protection
exception, as does an execution of IRET that would enter compatibility mode when CPL is 0.
Instruction ordering. IRET is a serializing instruction. See Section 11.3 of the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 3A.
See “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 28 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.
Operation
IF PE = 0
THEN GOTO REAL-ADDRESS-MODE;
ELSIF (IA32_EFER.LMA = 0)
THEN
IF (EFLAGS.VM = 1)
THEN GOTO RETURN-FROM-VIRTUAL-8086-MODE;
ELSE GOTO PROTECTED-MODE;
FI;
ELSE GOTO IA-32e-MODE;
FI;
REAL-ADDRESS-MODE;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
tempEFLAGS := Pop();
EFLAGS := (tempEFLAGS AND 257FD5H) OR (EFLAGS AND 1A0000H);
ELSE (* OperandSize = 16 *)
EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)
CS := Pop(); (* 16-bit pop *)
EFLAGS[15:0] := Pop();
FI;
END;
RETURN-FROM-VIRTUAL-8086-MODE:
(* Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode *)
IF IOPL = 3 (* Virtual mode: PE = 1, VM = 1, IOPL = 3 *)
THEN IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
EFLAGS := Pop();
(* VM, IOPL,VIP and VIF EFLAG bits not modified by pop *)
IF EIP not within CS limit
THEN #GP(0); FI;
ELSE (* OperandSize = 16 *)
EIP := Pop(); (* 16-bit pop; clear upper 16 bits *)
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-491
CS := Pop(); (* 16-bit pop *)
EFLAGS[15:0] := Pop(); (* IOPL in EFLAGS not modified by pop *)
IF EIP not within CS limit
THEN #GP(0); FI;
FI;
ELSE
#GP(0); (* Trap to virtual-8086 monitor: PE = 1, VM = 1, IOPL < 3 *)
FI;
END;
PROTECTED-MODE:
IF NT = 1
THEN GOTO TASK-RETURN; (* PE = 1, VM = 0, NT = 1 *)
FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
tempEFLAGS := Pop();
ELSE (* OperandSize = 16 *)
EIP := Pop(); (* 16-bit pop; clear upper bits *)
CS := Pop(); (* 16-bit pop *)
tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)
FI;
IF tempEFLAGS(VM) = 1 and CPL = 0
THEN GOTO RETURN-TO-VIRTUAL-8086-MODE;
ELSE GOTO PROTECTED-MODE-RETURN;
FI;
TASK-RETURN: (* PE = 1, VM = 0, NT = 1 *)
SWITCH-TASKS (without nesting) to TSS specified in link field of current TSS;
Mark the task just abandoned as NOT BUSY;
IF EIP is not within CS limit
THEN #GP(0); FI;
END;
RETURN-TO-VIRTUAL-8086-MODE:
(* Interrupted procedure was in virtual-8086 mode: PE = 1, CPL=0, VM = 1 in flag image *)
(* If shadow stack or indirect branch tracking at CPL3 then #GP(0) *)
IF CR4.CET AND (IA32_U_CET.ENDBR_EN OR IA32_U_CET.SHSTK_EN)
THEN #GP(0); FI;
shadowStackEnabled = ShadowStackEnabled(CPL)
IF EIP not within CS limit
THEN #GP(0); FI;
EFLAGS := tempEFLAGS;
ESP := Pop();
SS := Pop(); (* Pop 2 words; throw away high-order word *)
ES := Pop(); (* Pop 2 words; throw away high-order word *)
DS := Pop(); (* Pop 2 words; throw away high-order word *)
FS := Pop(); (* Pop 2 words; throw away high-order word *)
GS := Pop(); (* Pop 2 words; throw away high-order word *)
IF shadowStackEnabled
(* check if 8 byte aligned *)
IF SSP AND 0x7 != 0
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-492
THEN #CP(FAR-RET/IRET); FI;
FI;
CPL := 3;
(* Resume execution in Virtual-8086 mode *)
tempOldSSP = SSP;
(* Now past all faulting points; safe to free the token. The token free is done using the old SSP
* and using a supervisor override as old CPL was a supervisor privilege level *)
IF shadowStackEnabled
expected_token_value = tempOldSSP | BUSY_BIT
(* busy bit - bit position 0 - must be set *)
new_token_value = tempOldSSP
(* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)
FI;
END;
PROTECTED-MODE-RETURN: (* PE = 1 *)
IF CS(RPL) > CPL
THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;
ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;
END;
RETURN-TO-OUTER-PRIVILEGE-LEVEL:
IF OperandSize = 32
THEN
tempESP := Pop();
tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE IF OperandSize = 16
THEN
tempESP := Pop(); (* 16-bit pop; clear upper bits *)
tempSS := Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 64 *)
tempRSP := Pop();
tempSS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)
FI;
IF new mode ≠ 64-Bit Mode
THEN
IF EIP is not within CS limit
THEN #GP(0); FI;
ELSE (* new mode = 64-bit mode *)
IF RIP is non-canonical
THEN #GP(0); FI;
FI;
EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;
IF OperandSize = 32 or OperandSize = 64
THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;
IF CPL ≤ IOPL
THEN EFLAGS(IF) := tempEFLAGS; FI;
IF CPL = 0
THEN
EFLAGS(IOPL) := tempEFLAGS;
IF OperandSize = 32 or OperandSize = 64
THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;
FI;
IF ShadowStackEnabled(CPL)
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-493
(* check if 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
IF CS(RPL) != 3
THEN
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* Do 64 bit compare to detect bits beyond 15 being set *)
tempCS = CS; (* zero padded to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)
IF CSBASE + RIP != tempSsEIP
THEN #CP(FAR-RET/IRET); FI;
(* check if 4 byte aligned *)
IF tempSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
FI;
FI;
tempOldCPL = CPL;
CPL := CS(RPL);
IF OperandSize = 64
THEN
RSP := tempRSP;
SS := tempSS;
ELSE
ESP := tempESP;
SS := tempSS;
FI;
IF new mode != 64-Bit Mode
THEN
IF EIP is not within CS limit
THEN #GP(0); FI;
ELSE (* new mode = 64-bit mode *)
IF RIP is non-canonical
THEN #GP(0); FI;
FI;
tempOldSSP = SSP;
IF ShadowStackEnabled(CPL)
IF CPL = 3
THEN tempSSP := IA32_PL3_SSP; FI;
IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR
((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)
THEN #GP(0); FI;
SSP := tempSSP
FI;
(* Now past all faulting points; safe to free the token. The token free is done using the old SSP
* and using a supervisor override as old CPL was a supervisor privilege level *)
IF ShadowStackEnabled(tempOldCPL)
expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)
new_token_value = tempOldSSP (* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-494
FI;
FOR each SegReg in (ES, FS, GS, and DS)
DO
tempDesc := descriptor cache for SegReg (* hidden part of segment register *)
IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))
THEN (* Segment register invalid *)
SegmentSelector := 0; (*Segment selector becomes null*)
FI;
OD;
END;
RETURN-TO-SAME-PRIVILEGE-LEVEL: (* PE = 1, RPL = CPL *)
IF new mode ≠ 64-Bit Mode
THEN
IF EIP is not within CS limit
THEN #GP(0); FI;
ELSE (* new mode = 64-bit mode *)
IF RIP is non-canonical
THEN #GP(0); FI;
FI;
EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) := tempEFLAGS;
IF OperandSize = 32 or OperandSize = 64
THEN EFLAGS(RF, AC, ID) := tempEFLAGS; FI;
IF CPL ≤ IOPL
THEN EFLAGS(IF) := tempEFLAGS; FI;
IF CPL = 0
THEN
EFLAGS(IOPL) := tempEFLAGS;
IF OperandSize = 32 or OperandSize = 64
THEN EFLAGS(VIF, VIP) := tempEFLAGS; FI;
FI;
IF ShadowStackEnabled(CPL)
IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)
THEN #CP(FAR-RET/IRET); FI;
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
tempCS = CS; (* zero padded to 64 bit *)
IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)
THEN #CP(FAR-RET/IRET); FI;
IF CSBASE + RIP != tempSsLIP (* 64 bit compare; CSBASE+RIP zero padded to 64 bit for 32 bit LIP *)
THEN #CP(FAR-RET/IRET); FI;
IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)
THEN #CP(FAR-RET/IRET); FI;
IF ((IA32_EFER.LMA AND CS.L) = 0 AND tempSSP[63:32] != 0) OR
((IA32_EFER.LMA AND CS.L) = 1 AND tempSSP is not canonical relative to the current paging mode)
THEN #GP(0); FI;
FI;
IF ShadowStackEnabled(CPL)
IF IA32_EFER.LMA = 1
(* In IA-32e-mode the IRET may be switching stacks if the interrupt/exception was delivered
through an IDT with a non-zero IST *)
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-495
(* In IA-32e mode for same CPL IRET there is always a stack switch. The below check verifies if the
stack switch was to self stack and if so, do not try to free the token on this shadow stack. If the
tempSSP was not to same stack then there was a stack switch so do attempt to free the token *)
IF tempSSP != SSP
THEN
expected_token_value = SSP | BUSY_BIT
(* busy bit - bit position 0 - must be set *)
new_token_value = SSP
(* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(SSP, new_token_value, expected_token_value)
FI;
FI;
SSP := tempSSP
FI;
END;
IA-32e-MODE:
IF NT = 1
THEN #GP(0);
ELSE IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop();
tempEFLAGS := Pop();
ELSE IF OperandSize = 16
THEN
EIP := Pop(); (* 16-bit pop; clear upper bits *)
CS := Pop(); (* 16-bit pop *)
tempEFLAGS := Pop(); (* 16-bit pop; clear upper bits *)
FI;
ELSE (* OperandSize = 64 *)
THEN
RIP := Pop();
CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)
tempRFLAGS := Pop();
FI;
IF CS.RPL < CPL or (CR4.FRED = 1 and CS.RPL > CPL)
THEN #GP(CS.selector); FI;
IF CS.RPL > CPL
THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;
ELSE
(* CS.RPL = CPL *)
IF CR4.FRED = 1 and CPL = 0 and CS.L = 0
THEN #GP(CS.selector); FI;
IF instruction began in 64-Bit Mode
THEN
IF OperandSize = 32
THEN
ESP := Pop();
SS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE IF OperandSize = 16
THEN
ESP := Pop(); (* 16-bit pop; clear upper bits *)
SS := Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 64 *)
RSP := Pop();
SS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-496
FI;
FI;
GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;
END;
Flags Affected
All the flags and fields in the EFLAGS register are potentially modified, depending on the mode of operation of the
processor. If performing a return from a nested task to a previous task, the EFLAGS register will be modified
according to the EFLAGS image stored in the previous task’s TSS.
Protected Mode Exceptions
#GP(0)
If the return code or stack segment selector is NULL.
If the return instruction pointer is not within the return code segment limit.
#GP(selector)
If a segment selector index is outside its descriptor table limits.
If the return code segment selector RPL is less than the CPL.
If the DPL of a conforming-code segment is greater than the return code segment selector
RPL.
If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment
selector.
If the stack segment descriptor DPL is not equal to the RPL of the return code segment
selector.
If the stack segment is not a writable data segment.
If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
If the segment descriptor for a code segment does not indicate it is a code segment.
If the segment selector for a TSS has its local/global bit set for local.
If a TSS segment descriptor specifies that the TSS is not busy.
If a TSS segment descriptor specifies that the TSS is not available.
#SS(0)
If the top bytes of stack are not within stack limits.
If the return stack segment is not present.
#NP (selector)
If the return code segment is not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory reference occurs when the CPL is 3 and alignment checking is
enabled.
#UD
If the LOCK prefix is used.
#CP (Far-RET/IRET) If the previous SSP from shadow stack (when returning to CPL <3) or from IA32_PL3_SSP
(returning to CPL 3) is not 4 byte aligned.
If returning to 32-bit or compatibility mode and the previous SSP from shadow stack (when
returning to CPL <3) or from IA32_PL3_SSP (returning to CPL 3) is beyond 4GB.
If return instruction pointer from stack and shadow stack do not match.
Real-Address Mode Exceptions
#GP
If the return instruction pointer is not within the return code segment limit.
#SS
If the top bytes of stack are not within stack limits.
Virtual-8086 Mode Exceptions
#GP(0)
If the return instruction pointer is not within the return code segment limit.
IF IOPL not equal to 3.
#PF(fault-code)
If a page fault occurs.
#SS(0)
If the top bytes of stack are not within stack limits.
#AC(0)
If an unaligned memory reference occurs and alignment checking is enabled.
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-497
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
#GP(0)
If EFLAGS.NT[bit 14] = 1.
Other exceptions same as in Protected Mode.
64-Bit Mode Exceptions
#GP(0)
If EFLAGS.NT[bit 14] = 1.
If the return code segment selector is NULL.
If the stack segment selector is NULL going back to compatibility mode.
If the stack segment selector is NULL going back to CPL3 64-bit mode.
If a NULL stack segment selector RPL is not equal to CPL going back to non-CPL3 64-bit mode.
If the return instruction pointer is not within the return code segment limit.
If the return instruction pointer is non-canonical.
#GP(Selector)
If a segment selector index is outside its descriptor table limits.
If a segment descriptor memory address is non-canonical.
If the segment descriptor for a code segment does not indicate it is a code segment.
If the proposed new code segment descriptor has both the D-bit and L-bit set.
If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment
selector.
If CPL is greater than the RPL of the code segment selector.
If FRED transitions are enabled and CPL is less than the RPL of the code segment selector.
If FRED transitions are enabled and CPL = 0 and IRET would enter compatibility mode.
If the DPL of a conforming-code segment is greater than the return code segment selector
RPL.
If the stack segment is not a writable data segment.
If the stack segment descriptor DPL is not equal to the RPL of the return code segment
selector.
If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
#SS(0)
If an attempt to pop a value off the stack violates the SS limit.
If an attempt to pop a value off the stack causes a non-canonical address to be referenced.
If the return stack segment is not present.
#NP (selector)
If the return code segment is not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory reference occurs when the CPL is 3 and alignment checking is
enabled.
#UD
If the LOCK prefix is used.
#CP (Far-RET/IRET) If the previous SSP from shadow stack (when returning to CPL <3) or from IA32_PL3_SSP
(returning to CPL 3) is not 4 byte aligned.
If returning to 32-bit or compatibility mode and the previous SSP from shadow stack (when
returning to CPL <3) or from IA32_PL3_SSP (returning to CPL 3) is beyond 4GB.
If return instruction pointer from stack and shadow stack do not match.
IRET/IRETD/IRETQ-Interrupt Return
Vol. 2A
3-498
Jcc-Jump if Condition Is Met
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
77 cb
JA rel8
D
Valid
Valid
Jump short if above (CF=0 and ZF=0).
73 cb
JAE rel8
D
Valid
Valid
Jump short if above or equal (CF=0).
72 cb
JB rel8
D
Valid
Valid
Jump short if below (CF=1).
76 cb
JBE rel8
D
Valid
Valid
Jump short if below or equal (CF=1 or ZF=1).
72 cb
JC rel8
D
Valid
Valid
Jump short if carry (CF=1).
E3 cb
JCXZ rel8
D
N.E.
Valid
Jump short if CX register is 0.
E3 cb
JECXZ rel8
D
Valid
Valid
Jump short if ECX register is 0.
E3 cb
JRCXZ rel8
D
Valid
N.E.
Jump short if RCX register is 0.
74 cb
JE rel8
D
Valid
Valid
Jump short if equal (ZF=1).
7F cb
JG rel8
D
Valid
Valid
Jump short if greater (ZF=0 and SF=OF).
7D cb
JGE rel8
D
Valid
Valid
Jump short if greater or equal (SF=OF).
7C cb
JL rel8
D
Valid
Valid
Jump short if less (SF≠ OF).
7E cb
JLE rel8
D
Valid
Valid
Jump short if less or equal (ZF=1 or SF≠ OF).
76 cb
JNA rel8
D
Valid
Valid
Jump short if not above (CF=1 or ZF=1).
72 cb
JNAE rel8
D
Valid
Valid
Jump short if not above or equal (CF=1).
73 cb
JNB rel8
D
Valid
Valid
Jump short if not below (CF=0).
77 cb
JNBE rel8
D
Valid
Valid
Jump short if not below or equal (CF=0 and
ZF=0).
73 cb
JNC rel8
D
Valid
Valid
Jump short if not carry (CF=0).
75 cb
JNE rel8
D
Valid
Valid
Jump short if not equal (ZF=0).
7E cb
JNG rel8
D
Valid
Valid
Jump short if not greater (ZF=1 or SF≠ OF).
7C cb
JNGE rel8
D
Valid
Valid
Jump short if not greater or equal (SF≠ OF).
7D cb
JNL rel8
D
Valid
Valid
Jump short if not less (SF=OF).
7F cb
JNLE rel8
D
Valid
Valid
Jump short if not less or equal (ZF=0 and
SF=OF).
71 cb
JNO rel8
D
Valid
Valid
Jump short if not overflow (OF=0).
7B cb
JNP rel8
D
Valid
Valid
Jump short if not parity (PF=0).
79 cb
JNS rel8
D
Valid
Valid
Jump short if not sign (SF=0).
75 cb
JNZ rel8
D
Valid
Valid
Jump short if not zero (ZF=0).
70 cb
JO rel8
D
Valid
Valid
Jump short if overflow (OF=1).
7A cb
JP rel8
D
Valid
Valid
Jump short if parity (PF=1).
7A cb
JPE rel8
D
Valid
Valid
Jump short if parity even (PF=1).
7B cb
JPO rel8
D
Valid
Valid
Jump short if parity odd (PF=0).
78 cb
JS rel8
D
Valid
Valid
Jump short if sign (SF=1).
74 cb
JZ rel8
D
Valid
Valid
Jump short if zero (ZF = 1).
0F 87 cw
JA rel16
D
N.S.
Valid
Jump near if above (CF=0 and ZF=0). Not
supported in 64-bit mode.
0F 87 cd
JA rel32
D
Valid
Valid
Jump near if above (CF=0 and ZF=0).
0F 83 cw
JAE rel16
D
N.S.
Valid
Jump near if above or equal (CF=0). Not
supported in 64-bit mode.
0F 83 cd
JAE rel32
D
Valid
Valid
Jump near if above or equal (CF=0).
Jcc-Jump if Condition Is Met
Vol. 2A
3-499
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 82 cw
JB rel16
D
N.S.
Valid
Jump near if below (CF=1). Not supported in
64-bit mode.
0F 82 cd
JB rel32
D
Valid
Valid
Jump near if below (CF=1).
0F 86 cw
JBE rel16
D
N.S.
Valid
Jump near if below or equal (CF=1 or ZF=1).
Not supported in 64-bit mode.
0F 86 cd
JBE rel32
D
Valid
Valid
Jump near if below or equal (CF=1 or ZF=1).
0F 82 cw
JC rel16
D
N.S.
Valid
Jump near if carry (CF=1). Not supported in
64-bit mode.
0F 82 cd
JC rel32
D
Valid
Valid
Jump near if carry (CF=1).
0F 84 cw
JE rel16
D
N.S.
Valid
Jump near if equal (ZF=1). Not supported in
64-bit mode.
0F 84 cd
JE rel32
D
Valid
Valid
Jump near if equal (ZF=1).
0F 84 cw
JZ rel16
D
N.S.
Valid
Jump near if 0 (ZF=1). Not supported in 64-bit
mode.
0F 84 cd
JZ rel32
D
Valid
Valid
Jump near if 0 (ZF=1).
0F 8F cw
JG rel16
D
N.S.
Valid
Jump near if greater (ZF=0 and SF=OF). Not
supported in 64-bit mode.
0F 8F cd
JG rel32
D
Valid
Valid
Jump near if greater (ZF=0 and SF=OF).
0F 8D cw
JGE rel16
D
N.S.
Valid
Jump near if greater or equal (SF=OF). Not
supported in 64-bit mode.
0F 8D cd
JGE rel32
D
Valid
Valid
Jump near if greater or equal (SF=OF).
0F 8C cw
JL rel16
D
N.S.
Valid
Jump near if less (SF≠ OF). Not supported in
64-bit mode.
0F 8C cd
JL rel32
D
Valid
Valid
Jump near if less (SF≠ OF).
0F 8E cw
JLE rel16
D
N.S.
Valid
Jump near if less or equal (ZF=1 or SF≠ OF).
Not supported in 64-bit mode.
0F 8E cd
JLE rel32
D
Valid
Valid
Jump near if less or equal (ZF=1 or SF≠ OF).
0F 86 cw
JNA rel16
D
N.S.
Valid
Jump near if not above (CF=1 or ZF=1). Not
supported in 64-bit mode.
0F 86 cd
JNA rel32
D
Valid
Valid
Jump near if not above (CF=1 or ZF=1).
0F 82 cw
JNAE rel16
D
N.S.
Valid
Jump near if not above or equal (CF=1). Not
supported in 64-bit mode.
0F 82 cd
JNAE rel32
D
Valid
Valid
Jump near if not above or equal (CF=1).
0F 83 cw
JNB rel16
D
N.S.
Valid
Jump near if not below (CF=0). Not supported
in 64-bit mode.
0F 83 cd
JNB rel32
D
Valid
Valid
Jump near if not below (CF=0).
0F 87 cw
JNBE rel16
D
N.S.
Valid
Jump near if not below or equal (CF=0 and
ZF=0). Not supported in 64-bit mode.
0F 87 cd
JNBE rel32
D
Valid
Valid
Jump near if not below or equal (CF=0 and
ZF=0).
0F 83 cw
JNC rel16
D
N.S.
Valid
Jump near if not carry (CF=0). Not supported
in 64-bit mode.
0F 83 cd
JNC rel32
D
Valid
Valid
Jump near if not carry (CF=0).
0F 85 cw
JNE rel16
D
N.S.
Valid
Jump near if not equal (ZF=0). Not supported
in 64-bit mode.
Jcc-Jump if Condition Is Met
Vol. 2A
3-500
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 85 cd
JNE rel32
D
Valid
Valid
Jump near if not equal (ZF=0).
0F 8E cw
JNG rel16
D
N.S.
Valid
Jump near if not greater (ZF=1 or SF≠ OF).
Not supported in 64-bit mode.
0F 8E cd
JNG rel32
D
Valid
Valid
Jump near if not greater (ZF=1 or SF≠ OF).
0F 8C cw
JNGE rel16
D
N.S.
Valid
Jump near if not greater or equal (SF≠ OF).
Not supported in 64-bit mode.
0F 8C cd
JNGE rel32
D
Valid
Valid
Jump near if not greater or equal (SF≠ OF).
0F 8D cw
JNL rel16
D
N.S.
Valid
Jump near if not less (SF=OF). Not supported
in 64-bit mode.
0F 8D cd
JNL rel32
D
Valid
Valid
Jump near if not less (SF=OF).
0F 8F cw
JNLE rel16
D
N.S.
Valid
Jump near if not less or equal (ZF=0 and
SF=OF). Not supported in 64-bit mode.
0F 8F cd
JNLE rel32
D
Valid
Valid
Jump near if not less or equal (ZF=0 and
SF=OF).
0F 81 cw
JNO rel16
D
N.S.
Valid
Jump near if not overflow (OF=0). Not
supported in 64-bit mode.
0F 81 cd
JNO rel32
D
Valid
Valid
Jump near if not overflow (OF=0).
0F 8B cw
JNP rel16
D
N.S.
Valid
Jump near if not parity (PF=0). Not supported
in 64-bit mode.
0F 8B cd
JNP rel32
D
Valid
Valid
Jump near if not parity (PF=0).
0F 89 cw
JNS rel16
D
N.S.
Valid
Jump near if not sign (SF=0). Not supported in
64-bit mode.
0F 89 cd
JNS rel32
D
Valid
Valid
Jump near if not sign (SF=0).
0F 85 cw
JNZ rel16
D
N.S.
Valid
Jump near if not zero (ZF=0). Not supported in
64-bit mode.
0F 85 cd
JNZ rel32
D
Valid
Valid
Jump near if not zero (ZF=0).
0F 80 cw
JO rel16
D
N.S.
Valid
Jump near if overflow (OF=1). Not supported
in 64-bit mode.
0F 80 cd
JO rel32
D
Valid
Valid
Jump near if overflow (OF=1).
0F 8A cw
JP rel16
D
N.S.
Valid
Jump near if parity (PF=1). Not supported in
64-bit mode.
0F 8A cd
JP rel32
D
Valid
Valid
Jump near if parity (PF=1).
0F 8A cw
JPE rel16
D
N.S.
Valid
Jump near if parity even (PF=1). Not
supported in 64-bit mode.
0F 8A cd
JPE rel32
D
Valid
Valid
Jump near if parity even (PF=1).
0F 8B cw
JPO rel16
D
N.S.
Valid
Jump near if parity odd (PF=0). Not supported
in 64-bit mode.
0F 8B cd
JPO rel32
D
Valid
Valid
Jump near if parity odd (PF=0).
0F 88 cw
JS rel16
D
N.S.
Valid
Jump near if sign (SF=1). Not supported in 64-
bit mode.
0F 88 cd
JS rel32
D
Valid
Valid
Jump near if sign (SF=1).
0F 84 cw
JZ rel16
D
N.S.
Valid
Jump near if 0 (ZF=1). Not supported in 64-bit
mode.
0F 84 cd
JZ rel32
D
Valid
Valid
Jump near if 0 (ZF=1).
Jcc-Jump if Condition Is Met
Vol. 2A
3-501
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
D
Offset
N/A
N/A
N/A
Description
Checks the state of one or more of the status flags in the EFLAGS register (CF, OF, PF, SF, and ZF) and, if the flags
are in the specified state (condition), performs a jump to the target instruction specified by the destination
operand. A condition code (cc) is associated with each instruction to indicate the condition being tested for. If the
condition is not satisfied, the jump is not performed and execution continues with the instruction following the Jcc
instruction.
The target instruction is specified with a relative offset (a signed offset relative to the current value of the instruc-
tion pointer in the EIP register). A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly
code, but at the machine code level, it is encoded as a signed, 8-bit or 32-bit immediate value, which is added to
the instruction pointer. Instruction coding is most efficient for offsets of -128 to +127. If the operand-size attribute
is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits.
The conditions for each Jcc mnemonic are given in the “Description” column of the table on the preceding page. The
terms “less” and “greater” are used for comparisons of signed integers and the terms “above” and “below” are used
for unsigned integers.
Because a particular state of the status flags can sometimes be interpreted in two ways, two mnemonics are
defined for some opcodes. For example, the JA (jump if above) instruction and the JNBE (jump if not below or
equal) instruction are alternate mnemonics for the opcode 77H.
The Jcc instruction does not support far jumps (jumps to other code segments). When the target for the conditional
jump is in a different segment, use the opposite condition from the condition being tested for the Jcc instruction,
and then access the target with an unconditional far jump (JMP instruction) to the other segment. For example, the
following conditional far jump is illegal:
JZ FARLABEL;
To accomplish this far jump, use the following two instructions:
JNZ BEYOND;
JMP FARLABEL;
BEYOND:
The JRCXZ, JECXZ, and JCXZ instructions differ from other Jcc instructions because they do not check status flags.
Instead, they check RCX, ECX or CX for 0. The register checked is determined by the address-size attribute. These
instructions are useful when used at the beginning of a loop that terminates with a conditional loop instruction
(such as LOOPNE). They can be used to prevent an instruction sequence from entering a loop when RCX, ECX or
CX is 0. This would cause the loop to execute 264, 232 or 64K times (not zero times).
All conditional jumps are converted to code fetches of one or two cache lines, regardless of jump address or cache-
ability.
In 64-bit mode, operand size is fixed at 64 bits. JMP Short is RIP = RIP + 8-bit offset sign extended to 64 bits. JMP
Near is RIP = RIP + 32-bit offset sign extended to 64 bits.
Jcc-Jump if Condition Is Met
Vol. 2A
3-502
Operation
IF condition
THEN
tempEIP := EIP + SignExtend(DEST);
IF OperandSize = 16
THEN tempEIP := tempEIP AND 0000FFFFH;
FI;
IF tempEIP is not within code segment limit
THEN #GP(0);
ELSE EIP := tempEIP
FI;
FI;
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the offset being jumped to is beyond the limits of the CS segment.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If the offset being jumped to is beyond the limits of the CS segment or is outside of the effec-
tive address space from 0 to FFFFH. This condition can occur if a 32-bit address size override
prefix is used.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#GP(0)
If the memory address is in a non-canonical form.
#UD
If the LOCK prefix is used.
Jcc-Jump if Condition Is Met
Vol. 2A
3-503
JMP-Jump
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
EB cb
JMP rel8
D
Valid
Valid
Jump short, RIP = RIP + 8-bit displacement sign
extended to 64-bits.
E9 cw
JMP rel16
D
N.S.
Valid
Jump near, relative, displacement relative to
next instruction. Not supported in 64-bit
mode.
E9 cd
JMP rel32
D
Valid
Valid
Jump near, relative, RIP = RIP + 32-bit
displacement sign extended to 64-bits.
FF /4
JMP r/m16
M
N.S.
Valid
Jump near, absolute indirect, address = zero-
extended r/m16. Not supported in 64-bit
mode.
FF /4
JMP r/m32
M
N.S.
Valid
Jump near, absolute indirect, address given in
r/m32. Not supported in 64-bit mode.
FF /4
JMP r/m64
M
Valid
N.E.
Jump near, absolute indirect, RIP = 64-Bit
offset from register or memory.
EA cd
JMP ptr16:16
S
Inv.
Valid
Jump far, absolute, address given in operand.
EA cp
JMP ptr16:32
S
Inv.
Valid
Jump far, absolute, address given in operand.
FF /5
JMP m16:16
M
Valid
Valid
Jump far, absolute indirect, address given in
m16:16.
FF /5
JMP m16:32
M
Valid
Valid
Jump far, absolute indirect, address given in
m16:32.
REX.W FF /5
JMP m16:64
M
Valid
N.E.
Jump far, absolute indirect, address given in
m16:64.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
S
Segment + Absolute Address
N/A
N/A
N/A
D
Offset
N/A
N/A
N/A
M
ModRM:r/m (r)
N/A
N/A
N/A
Description
Transfers program control to a different point in the instruction stream without recording return information. The
destination (target) operand specifies the address of the instruction being jumped to. This operand can be an
immediate value, a general-purpose register, or a memory location.
This instruction can be used to execute four different types of jumps:
• Near jump-A jump to an instruction within the current code segment (the segment currently pointed to by the
CS register), sometimes referred to as an intrasegment jump.
• Short jump-A near jump where the jump range is limited to -128 to +127 from the current EIP value.
• Far jump-A jump to an instruction located in a different segment than the current code segment but at the
same privilege level, sometimes referred to as an intersegment jump.
• Task switch-A jump to an instruction located in a different task.
A task switch can only be executed in protected mode (see Chapter 10, in the Intel® 64 and IA-32 Architectures
Software Developer’s Manual, Volume 3A, for information on performing task switches with the JMP instruction).
Near and Short Jumps. When executing a near jump, the processor jumps to the address (within the current code
segment) that is specified with the target operand. The target operand specifies either an absolute offset (that is
an offset from the base of the code segment) or a relative offset (a signed displacement relative to the current
JMP-Jump
Vol. 2A
3-504
value of the instruction pointer in the EIP register). A near jump to a relative offset of 8-bits (rel8) is referred to as
a short jump. The CS register is not changed on near and short jumps.
An absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16 or r/m32). The
operand-size attribute determines the size of the target operand (16 or 32 bits). Absolute offsets are loaded
directly into the EIP register. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared,
resulting in a maximum instruction pointer size of 16 bits.
A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code
level, it is encoded as a signed 8-, 16-, or 32-bit immediate value. This value is added to the value in the EIP
register. (Here, the EIP register contains the address of the instruction following the JMP instruction). When using
relative offsets, the opcode (for short vs. near jumps) and the operand-size attribute (for near relative jumps)
determines the size of the target operand (8, 16, or 32 bits).
Far Jumps in Real-Address or Virtual-8086 Mode. When executing a far jump in real-address or virtual-8086 mode,
the processor jumps to the code segment and offset specified with the target operand. Here the target operand
specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory
location (m16:16 or m16:32). With the pointer method, the segment and address of the called procedure is
encoded in the instruction, using a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address imme-
diate. With the indirect method, the target operand specifies a memory location that contains a 4-byte (16-bit
operand size) or 6-byte (32-bit operand size) far address. The far address is loaded directly into the CS and EIP
registers. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.
Far Jumps in Protected Mode. When the processor is operating in protected mode, the JMP instruction can be used
to perform the following three types of far jumps:
• A far jump to a conforming or non-conforming code segment.
• A far jump through a call gate.
• A task switch.
(The JMP instruction cannot be used to perform inter-privilege-level far jumps.)
In protected mode, the processor always uses the segment selector part of the far address to access the corre-
sponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access
rights determine the type of jump to be performed.
If the selected descriptor is for a code segment, a far jump to a code segment at the same privilege level is
performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming,
a general-protection exception is generated.) A far jump to the same privilege level in protected mode is very
similar to one carried out in real-address or virtual-8086 mode. The target operand specifies an absolute far
address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or
m16:32). The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The new
code segment selector and its descriptor are loaded into CS register, and the offset from the instruction is loaded
into the EIP register. Note that a call gate (described in the next paragraph) can also be used to perform far call to
a code segment at the same privilege level. Using this mechanism provides an extra level of indirection and is the
preferred method of making jumps between 16-bit and 32-bit code segments.
When executing a far jump through a call gate, the segment selector specified by the target operand identifies the
call gate. (The offset part of the target operand is ignored.) The processor then jumps to the code segment speci-
fied in the call gate descriptor and begins executing the instruction at the offset specified in the call gate. No stack
switch occurs. Here again, the target operand can specify the far address of the call gate either directly with a
pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32).
Executing a task switch with the JMP instruction is somewhat similar to executing a jump through a call gate. Here
the target operand specifies the segment selector of the task gate for the task being switched to (and the offset
part of the target operand is ignored). The task gate in turn points to the TSS for the task, which contains the
segment selectors for the task’s code and stack segments. The TSS also contains the EIP value for the next instruc-
tion that was to be executed before the task was suspended. This instruction pointer value is loaded into the EIP
register so that the task begins executing again at this next instruction.
The JMP instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of the
task gate. See Chapter 10 in Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for
detailed information on the mechanics of a task switch.
JMP-Jump
Vol. 2A
3-505
When execution of a JMP instruction effects a task switch, the nested task flag (NT) is not set in the EFLAGS
register and the new TSS’s previous task link field is not loaded with the old task’s TSS selector. A return to the
previous task can thus not be carried out by executing the IRET instruction. Switching tasks with the JMP instruc-
tion differs in this regard from the CALL instruction which does set the NT flag and save the previous task link infor-
mation, allowing a return to the calling task with an IRET instruction.
Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 18, “Control-flow Enforcement Tech-
nology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for CET details.
In 64-Bit Mode. The instruction’s operation size is fixed at 64 bits. If a selector points to a gate, then RIP equals the
64-bit displacement taken from gate; else RIP equals the zero-extended offset from the far pointer referenced in
the instruction.
When FRED transitions are enabled, an execution of far JMP that references a call gate causes a general-protection
exception, as does an execution of far JMP that would enter compatibility mode when CPL is 0.
See the summary chart at the beginning of this section for encoding data and limits.
Instruction ordering. Instructions following a far jump may be fetched from memory before earlier instructions
complete execution, but they will not execute (even speculatively) until all instructions prior to the far jump have
completed execution (the later instructions may execute before data stored by the earlier instructions have
become globally visible).
Instructions sequentially following a near indirect JMP instruction (i.e., those not at the target) may be executed
speculatively. If software needs to prevent this (e.g., in order to prevent a speculative execution side channel),
then an INT3 or LFENCE instruction opcode can be placed after the near indirect JMP in order to block speculative
execution.
Operation
IF near jump
IF 64-bit Mode
THEN
IF near relative jump
THEN
tempRIP := RIP + DEST; (* RIP is instruction following JMP instruction*)
ELSE (* Near absolute jump *)
tempRIP := DEST;
FI;
ELSE
IF near relative jump
THEN
tempEIP := EIP + DEST; (* EIP is instruction following JMP instruction*)
ELSE (* Near absolute jump *)
tempEIP := DEST;
FI;
FI;
IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and tempEIP outside code segment limit
THEN #GP(0); FI
IF 64-bit mode and tempRIP is not canonical
THEN #GP(0);
FI;
IF OperandSize = 32
THEN
EIP := tempEIP;
ELSE
IF OperandSize = 16
THEN (* OperandSize = 16 *)
EIP := tempEIP AND 0000FFFFH;
ELSE (* OperandSize = 64)
JMP-Jump
Vol. 2A
3-506
RIP := tempRIP;
FI;
FI;
IF (JMP near indirect, absolute indirect)
IF EndbranchEnabledAndNotSuppressed(CPL)
IF CPL = 3
THEN
IF ( no 3EH prefix OR IA32_U_CET.NO_TRACK_EN == 0 )
THEN
IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH
FI;
ELSE
IF ( no 3EH prefix OR IA32_S_CET.NO_TRACK_EN == 0 )
THEN
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH
FI;
FI;
FI;
FI;
FI;
IF far jump and (PE = 0 or (PE = 1 AND VM = 1)) (* Real-address or virtual-8086 mode *)
THEN
tempEIP := DEST(Offset); (* DEST is ptr16:32 or [m16:32] *)
IF tempEIP is beyond code segment limit
THEN #GP(0); FI;
CS := DEST(segment selector); (* DEST is ptr16:32 or [m16:32] *)
IF OperandSize = 32
THEN
EIP := tempEIP; (* DEST is ptr16:32 or [m16:32] *)
ELSE (* OperandSize = 16 *)
EIP := tempEIP AND 0000FFFFH; (* Clear upper 16 bits *)
FI;
FI;
IF far jump and (PE = 1 and VM = 0)
(* IA-32e mode or protected mode, not virtual-8086 mode *)
THEN
IF effective address in the CS, DS, ES, FS, GS, or SS segment is illegal or segment selector in target operand NULL
THEN #GP(0); FI;
IF segment selector index not within descriptor table limits
THEN #GP(new selector); FI;
Read type and access rights of segment descriptor;
IF (IA32_EFER.LMA = 0)
THEN
IF segment type is not a conforming or nonconforming code segment, call gate, task gate, or TSS
THEN #GP(segment selector); FI;
ELSE
IF segment type is not a conforming or nonconforming code segment or call gate
THEN #GP(segment selector); FI;
FI;
Depending on type and access rights:
GO TO CONFORMING-CODE-SEGMENT;
GO TO NONCONFORMING-CODE-SEGMENT;
GO TO CALL-GATE;
GO TO TASK-GATE;
JMP-Jump
Vol. 2A
3-507
GO TO TASK-STATE-SEGMENT;
ELSE
#GP(segment selector);
FI;
CONFORMING-CODE-SEGMENT:
IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
THEN GP(new code segment selector); FI;
IF DPL > CPL
THEN #GP(segment selector); FI;
IF CR4.FRED = 1 and CPL = 0 and L-bit = 0
THEN GP(new code segment selector); FI;
IF segment not present
THEN #NP(segment selector); FI;
tempEIP := DEST(Offset);
IF OperandSize = 16
THEN tempEIP := tempEIP AND 0000FFFFH;
FI;
IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and
tempEIP outside code segment limit
THEN #GP(0); FI
IF tempEIP is non-canonical
THEN #GP(0); FI;
IF ShadowStackEnabled(CPL)
IF (IA32_EFER.LMA and DEST(segment selector).L) = 0
(* If target is legacy or compatibility mode then the SSP must be in low 4GB *)
IF (SSP & 0xFFFFFFFF00000000 != 0)
THEN #GP(0); FI;
FI;
FI;
CS := DEST[segment selector]; (* Segment descriptor information also loaded *)
CS(RPL) := CPL
EIP := tempEIP;
IF EndbranchEnabled(CPL)
IF CPL = 3
THEN
IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH
IA32_U_CET.SUPPRESS = 0
ELSE
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH
IA32_S_CET.SUPPRESS = 0
FI;
FI;
END;
NONCONFORMING-CODE-SEGMENT:
IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
THEN GP(new code segment selector); FI;
IF (RPL > CPL) OR (DPL ≠ CPL)
THEN #GP(code segment selector); FI;
IF CR4.FRED = 1 and CPL = 0 and L-bit = 0
THEN GP(new code segment selector); FI;
IF segment not present
THEN #NP(segment selector); FI;
tempEIP := DEST(Offset);
IF OperandSize = 16
JMP-Jump
Vol. 2A
3-508
THEN tempEIP := tempEIP AND 0000FFFFH; FI;
IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode)
and tempEIP outside code segment limit
THEN #GP(0); FI
IF tempEIP is non-canonical THEN #GP(0); FI;
IF ShadowStackEnabled(CPL)
IF (IA32_EFER.LMA and DEST(segment selector).L) = 0
(* If target is legacy or compatibility mode then the SSP must be in low 4GB *)
IF (SSP & 0xFFFFFFFF00000000 != 0)
THEN #GP(0); FI;
FI;
FI;
CS := DEST[segment selector]; (* Segment descriptor information also loaded *)
CS(RPL) := CPL;
EIP := tempEIP;
IF EndbranchEnabled(CPL)
IF CPL = 3
THEN
IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH
IA32_U_CET.SUPPRESS = 0
ELSE
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH
IA32_S_CET.SUPPRESS = 0
FI;
FI;
END;
CALL-GATE:
IF call gate DPL < CPL or call gate DPL < call gate segment-selector RPL or CR4.FRED = 1
THEN #GP(call gate selector); FI;
IF call gate not present
THEN #NP(call gate selector); FI;
IF call gate code-segment selector is NULL
THEN #GP(0); FI;
IF call gate code-segment selector index outside descriptor table limits
THEN #GP(code segment selector); FI;
Read code segment descriptor;
IF code-segment segment descriptor does not indicate a code segment
or code-segment segment descriptor is conforming and DPL > CPL
or code-segment segment descriptor is non-conforming and DPL ≠ CPL
THEN #GP(code segment selector); FI;
IF IA32_EFER.LMA = 1 and (code-segment descriptor is not a 64-bit code segment
or code-segment segment descriptor has both L-Bit and D-bit set)
THEN #GP(code segment selector); FI;
IF code segment is not present
THEN #NP(code-segment selector); FI;
tempEIP := DEST(Offset);
IF GateSize = 16
THEN tempEIP := tempEIP AND 0000FFFFH; FI;
IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode) AND tempEIP
outside code segment limit
THEN #GP(0); FI
CS := DEST[SegmentSelector]; (* Segment descriptor information also loaded *)
CS(RPL) := CPL;
JMP-Jump
Vol. 2A
3-509
EIP := tempEIP;
IF EndbranchEnabled(CPL)
IF CPL = 3
THEN
IA32_U_CET.TRACKER = WAIT_FOR_ENDBRANCH;
IA32_U_CET.SUPPRESS = 0
ELSE
IA32_S_CET.TRACKER = WAIT_FOR_ENDBRANCH;
IA32_S_CET.SUPPRESS = 0
FI;
FI;
END;
TASK-GATE:
IF task gate DPL < CPL
or task gate DPL < task gate segment-selector RPL
THEN #GP(task gate selector); FI;
IF task gate not present
THEN #NP(gate selector); FI;
Read the TSS segment selector in the task-gate descriptor;
IF TSS segment selector local/global bit is set to local
or index not within GDT limits
or descriptor is not a TSS segment
or TSS descriptor specifies that the TSS is busy
THEN #GP(TSS selector); FI;
IF TSS not present
THEN #NP(TSS selector); FI;
SWITCH-TASKS to TSS;
IF EIP not within code segment limit
THEN #GP(0); FI;
END;
TASK-STATE-SEGMENT:
IF TSS DPL < CPL
or TSS DPL < TSS segment-selector RPL
or TSS descriptor indicates TSS not available
THEN #GP(TSS selector); FI;
IF TSS is not present
THEN #NP(TSS selector); FI;
SWITCH-TASKS to TSS;
IF EIP not within code segment limit
THEN #GP(0); FI;
END;
Flags Affected
All flags are affected if a task switch occurs; no flags are affected if a task switch does not occur.
Protected Mode Exceptions
#GP(0)
If offset in target operand, call gate, or TSS is beyond the code segment limits.
If the segment selector in the destination operand, call gate, task gate, or TSS is NULL.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
selector.
If target mode is compatibility mode and SSP is not in low 4GB.
JMP-Jump
Vol. 2A
3-510
#GP(selector)
If the segment selector index is outside descriptor table limits.
If the segment descriptor pointed to by the segment selector in the destination operand is not
for a conforming-code segment, nonconforming-code segment, call gate, task gate, or task
state segment.
If the DPL for a nonconforming-code segment is not equal to the CPL
(When not using a call gate.) If the RPL for the segment’s segment selector is greater than the
CPL.
If the DPL for a conforming-code segment is greater than the CPL.
If the DPL from a call-gate, task-gate, or TSS segment descriptor is less than the CPL or than
the RPL of the call-gate, task-gate, or TSS’s segment selector.
If the segment descriptor for selector in a call gate does not indicate it is a code segment.
If the segment descriptor for the segment selector in a task gate does not indicate an available
TSS.
If the segment selector for a TSS has its local/global bit set for local.
If a TSS segment descriptor specifies that the TSS is busy or not available.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#NP (selector)
If the code segment being accessed is not present.
If call gate, task gate, or TSS not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3. (Only occurs when fetching target from memory.)
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS
If a memory operand effective address is outside the SS segment limit.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If the target operand is beyond the code segment limits.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made. (Only occurs
when fetching target from memory.)
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same as 64-bit mode exceptions.
#GP(Selector)
If FRED transitions are enabled and the selector references a call gate.
64-Bit Mode Exceptions
#GP(0)
If a memory address is non-canonical.
If target offset in destination operand is non-canonical.
If target offset in destination operand is beyond the new code segment limit.
If the segment selector in the destination operand is NULL.
If the code segment selector in the 64-bit gate is NULL.
If transitioning to compatibility mode and the SSP is beyond 4GB.
JMP-Jump
Vol. 2A
3-511
#GP(selector)
If the code segment or 64-bit call gate is outside descriptor table limits.
If the code segment or 64-bit call gate overlaps non-canonical space.
If the segment descriptor from a 64-bit call gate is in non-canonical space.
If the segment descriptor pointed to by the segment selector in the destination operand is not
for a conforming-code segment, nonconforming-code segment, 64-bit call gate.
If the segment descriptor pointed to by the segment selector in the destination operand is a
code segment, and has both the D-bit and the L-bit set.
If the DPL for a nonconforming-code segment is not equal to the CPL, or the RPL for the
segment’s segment selector is greater than the CPL.
If the DPL for a conforming-code segment is greater than the CPL.
If the DPL from a 64-bit call-gate is less than the CPL or than the RPL of the 64-bit call-gate.
If the upper type field of a 64-bit call gate is not 0x0.
If the segment selector from a 64-bit call gate is beyond the descriptor table limits.
If the code segment descriptor pointed to by the selector in the 64-bit gate doesn't have the
L-bit set and the D-bit clear.
If the segment descriptor for a segment selector from the 64-bit call gate does not indicate it
is a code segment.
If the code segment is non-conforming and CPL ≠ DPL.
If the code segment is confirming and CPL < DPL.
If FRED transitions are enabled and the selector references a call gate.
If FRED transitions are enabled, CPL is 0, and the instruction would enter compatibility mode.
#NP(selector)
If a code segment or 64-bit call gate is not present.
#UD
(64-bit mode only) If a far jump is direct to an absolute address in memory.
If the LOCK prefix is used.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
JMP-Jump
Vol. 2A
3-512
KADDW/KADDB/KADDQ/KADDD-ADD Two Masks
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.0F.W0 4A /r
RVR
V/V
AVX512DQ
Add 16 bits masks in k2 and k3 and place result in k1.
KADDW k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W0 4A /r
RVR
V/V
AVX512DQ
Add 8 bits masks in k2 and k3 and place result in k1.
KADDB k1, k2, k3
OR AVX10.1
VEX.L1.0F.W1 4A /r
RVR
V/V
AVX512BW
Add 64 bits masks in k2 and k3 and place result in k1.
KADDQ k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W1 4A /r
RVR
V/V
AVX512BW
Add 32 bits masks in k2 and k3 and place result in k1.
KADDD k1, k2, k3
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Adds the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.
Operation
KADDW
DEST[15:0] := SRC1[15:0] + SRC2[15:0]
DEST[MAX_KL-1:16] := 0
KADDB
DEST[7:0] := SRC1[7:0] + SRC2[7:0]
DEST[MAX_KL-1:8] := 0
KADDQ
DEST[63:0] := SRC1[63:0] + SRC2[63:0]
DEST[MAX_KL-1:64] := 0
KADDD
DEST[31:0] := SRC1[31:0] + SRC2[31:0]
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KADDW __mmask16 _kadd_mask16 (__mmask16 a, __mmask16 b);
KADDB __mmask8 _kadd_mask8 (__mmask8 a, __mmask8 b);
KADDQ __mmask64 _kadd_mask64 (__mmask64 a, __mmask64 b);
KADDD __mmask32 _kadd_mask32 (__mmask32 a, __mmask32 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
KADDW/KADDB/KADDQ/KADDD-ADD Two Masks
Vol. 2A
3-513
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KADDW/KADDB/KADDQ/KADDD-ADD Two Masks
Vol. 2A
3-514
KANDNW/KANDNB/KANDNQ/KANDND-Bitwise Logical AND NOT Masks
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.0F.W0 42 /r
RVR
V/V
AVX512F
Bitwise AND NOT 16 bits masks k2 and k3 and place result in k1.
KANDNW k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W0 42 /r
RVR
V/V
AVX512DQ
Bitwise AND NOT 8 bits masks k1 and k2 and place result in k1.
KANDNB k1, k2, k3
OR AVX10.1
VEX.L1.0F.W1 42 /r
RVR
V/V
AVX512BW
Bitwise AND NOT 64 bits masks k2 and k3 and place result in k1.
KANDNQ k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W1 42 /r
RVR
V/V
AVX512BW
Bitwise AND NOT 32 bits masks k2 and k3 and place result in k1.
KANDND k1, k2, k3
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise AND NOT between the vector mask k2 and the vector mask k3, and writes the result into vector
mask k1.
Operation
KANDNW
DEST[15:0] := (BITWISE NOT SRC1[15:0]) BITWISE AND SRC2[15:0]
DEST[MAX_KL-1:16] := 0
KANDNB
DEST[7:0] := (BITWISE NOT SRC1[7:0]) BITWISE AND SRC2[7:0]
DEST[MAX_KL-1:8] := 0
KANDNQ
DEST[63:0] := (BITWISE NOT SRC1[63:0]) BITWISE AND SRC2[63:0]
DEST[MAX_KL-1:64] := 0
KANDND
DEST[31:0] := (BITWISE NOT SRC1[31:0]) BITWISE AND SRC2[31:0]
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KANDNW __mmask16 _mm512_kandn(__mmask16 a, __mmask16 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KANDNW/KANDNB/KANDNQ/KANDND-Bitwise Logical AND NOT Masks
Vol. 2A
3-515
KANDW/KANDB/KANDQ/KANDD-Bitwise Logical AND Masks
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.0F.W0 41 /r
RVR
V/V
AVX512F
Bitwise AND 16 bits masks k2 and k3 and place result in k1.
KANDW k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W0 41 /r
RVR
V/V
AVX512DQ
Bitwise AND 8 bits masks k2 and k3 and place result in k1.
KANDB k1, k2, k3
OR AVX10.1
VEX.L1.0F.W1 41 /r
RVR
V/V
AVX512BW
Bitwise AND 64 bits masks k2 and k3 and place result in k1.
KANDQ k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W1 41 /r
RVR
V/V
AVX512BW
Bitwise AND 32 bits masks k2 and k3 and place result in k1.
KANDD k1, k2, k3
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise AND between the vector mask k2 and the vector mask k3, and writes the result into vector mask
k1.
Operation
KANDW
DEST[15:0] := SRC1[15:0] BITWISE AND SRC2[15:0]
DEST[MAX_KL-1:16] := 0
KANDB
DEST[7:0] := SRC1[7:0] BITWISE AND SRC2[7:0]
DEST[MAX_KL-1:8] := 0
KANDQ
DEST[63:0] := SRC1[63:0] BITWISE AND SRC2[63:0]
DEST[MAX_KL-1:64] := 0
KANDD
DEST[31:0] := SRC1[31:0] BITWISE AND SRC2[31:0]
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KANDW __mmask16 _mm512_kand(__mmask16 a, __mmask16 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KANDW/KANDB/KANDQ/KANDD-Bitwise Logical AND Masks
Vol. 2A
3-516
KMOVW/KMOVB/KMOVQ/KMOVD-Move From and to Mask Registers
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L0.0F.W0 90 /r
RM
V/V
AVX512F
Move 16 bits mask from k2/m16 and store the result in k1.
KMOVW k1, k2/m16
OR AVX10.1
VEX.L0.66.0F.W0 90 /r
RM
V/V
AVX512DQ
Move 8 bits mask from k2/m8 and store the result in k1.
KMOVB k1, k2/m8
OR AVX10.1
VEX.L0.0F.W1 90 /r
RM
V/V
AVX512BW
Move 64 bits mask from k2/m64 and store the result in k1.
KMOVQ k1, k2/m64
OR AVX10.1
VEX.L0.66.0F.W1 90 /r
RM
V/V
AVX512BW
Move 32 bits mask from k2/m32 and store the result in k1.
KMOVD k1, k2/m32
OR AVX10.1
VEX.L0.0F.W0 91 /r
MR
V/V
AVX512F
Move 16 bits mask from k1 and store the result in m16.
KMOVW m16, k1
OR AVX10.1
VEX.L0.66.0F.W0 91 /r
MR
V/V
AVX512DQ
Move 8 bits mask from k1 and store the result in m8.
KMOVB m8, k1
OR AVX10.1
VEX.L0.0F.W1 91 /r
MR
V/V
AVX512BW
Move 64 bits mask from k1 and store the result in m64.
KMOVQ m64, k1
OR AVX10.1
VEX.L0.66.0F.W1 91 /r
MR
V/V
AVX512BW
Move 32 bits mask from k1 and store the result in m32.
KMOVD m32, k1
OR AVX10.1
VEX.L0.0F.W0 92 /r
RR
V/V
AVX512F
Move 16 bits mask from r32 to k1.
KMOVW k1, r32
OR AVX10.1
VEX.L0.66.0F.W0 92 /r
RR
V/V
AVX512DQ
Move 8 bits mask from r32 to k1.
KMOVB k1, r32
OR AVX10.1
VEX.L0.F2.0F.W1 92 /r
RR
V/I
AVX512BW
Move 64 bits mask from r64 to k1.
KMOVQ k1, r64
OR AVX10.1
VEX.L0.F2.0F.W0 92 /r
RR
V/V
AVX512BW
Move 32 bits mask from r32 to k1.
KMOVD k1, r32
OR AVX10.1
VEX.L0.0F.W0 93 /r
RR
V/V
AVX512F
Move 16 bits mask from k1 to r32.
KMOVW r32, k1
OR AVX10.1
VEX.L0.66.0F.W0 93 /r
RR
V/V
AVX512DQ
Move 8 bits mask from k1 to r32.
KMOVB r32, k1
OR AVX10.1
VEX.L0.F2.0F.W1 93 /r
RR
V/I
AVX512BW
Move 64 bits mask from k1 to r64.
KMOVQ r64, k1
OR AVX10.1
VEX.L0.F2.0F.W0 93 /r
RR
V/V
AVX512BW
Move 32 bits mask from k1 to r32.
KMOVD r32, k1
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
RM
ModRM:reg (w)
ModRM:r/m (r)
MR
ModRM:r/m (w, ModRM:[7:6] must not be 11b)
ModRM:reg (r)
RR
ModRM:reg (w)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Copies values from the source operand (second operand) to the destination operand (first operand). The source
and destination operands can be mask registers, memory location or general purpose. The instruction cannot be
used to transfer data between general purpose registers and or memory locations.
KMOVW/KMOVB/KMOVQ/KMOVD-Move From and to Mask Registers
Vol. 2A
3-517
When moving to a mask register, the result is zero extended to MAX_KL size (i.e., 64 bits currently). When moving
to a general-purpose register (GPR), the result is zero-extended to the size of the destination. In 32-bit mode, the
default GPR destination’s size is 32 bits. In 64-bit mode, the default GPR destination’s size is 64 bits. Note that
VEX.W can only be used to modify the size of the GPR operand in 64b mode.
Operation
KMOVW
IF *destination is a memory location*
DEST[15:0] := SRC[15:0]
IF *destination is a mask register or a GPR *
DEST := ZeroExtension(SRC[15:0])
KMOVB
IF *destination is a memory location*
DEST[7:0] := SRC[7:0]
IF *destination is a mask register or a GPR *
DEST := ZeroExtension(SRC[7:0])
KMOVQ
IF *destination is a memory location or a GPR*
DEST[63:0] := SRC[63:0]
IF *destination is a mask register*
DEST := ZeroExtension(SRC[63:0])
KMOVD
IF *destination is a memory location*
DEST[31:0] := SRC[31:0]
IF *destination is a mask register or a GPR *
DEST := ZeroExtension(SRC[31:0])
Intel C/C++ Compiler Intrinsic Equivalent
KMOVW __mmask16 _mm512_kmov(__mmask16 a);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
Instructions with RR operand encoding, see Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask
Instructions w/o Memory Arg).”
Instructions with RM or MR operand encoding, see Table 2-66, “TYPE K21 Exception Definition (VEX-Encoded
OpMask Instructions Addressing Memory).”
KMOVW/KMOVB/KMOVQ/KMOVD-Move From and to Mask Registers
Vol. 2A
3-518
KNOTW/KNOTB/KNOTQ/KNOTD-NOT Mask Register
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L0.0F.W0 44 /r
RR
V/V
AVX512F
Bitwise NOT of 16 bits mask k2.
KNOTW k1, k2
OR AVX10.1
VEX.L0.66.0F.W0 44 /r
RR
V/V
AVX512DQ
Bitwise NOT of 8 bits mask k2.
KNOTB k1, k2
OR AVX10.1
VEX.L0.0F.W1 44 /r
RR
V/V
AVX512BW
Bitwise NOT of 64 bits mask k2.
KNOTQ k1, k2
OR AVX10.1
VEX.L0.66.0F.W1 44 /r
RR
V/V
AVX512BW
Bitwise NOT of 32 bits mask k2.
KNOTD k1, k2
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
RR
ModRM:reg (w)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise NOT of vector mask k2 and writes the result into vector mask k1.
Operation
KNOTW
DEST[15:0] := BITWISE NOT SRC[15:0]
DEST[MAX_KL-1:16] := 0
KNOTB
DEST[7:0] := BITWISE NOT SRC[7:0]
DEST[MAX_KL-1:8] := 0
KNOTQ
DEST[63:0] := BITWISE NOT SRC[63:0]
DEST[MAX_KL-1:64] := 0
KNOTD
DEST[31:0] := BITWISE NOT SRC[31:0]
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KNOTW __mmask16 _mm512_knot(__mmask16 a);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KNOTW/KNOTB/KNOTQ/KNOTD-NOT Mask Register
Vol. 2A
3-519
KORTESTW/KORTESTB/KORTESTQ/KORTESTD-OR Masks and Set Flags
Opcode/
Op/E
64/32 bit
CPUID
Description
Instruction
n
Mode
Feature Flag
Support
VEX.L0.0F.W0 98 /r
RR
V/V
AVX512F
Bitwise OR 16 bits masks k1 and k2 and update ZF and CF accordingly.
KORTESTW k1, k2
OR AVX10.1
VEX.L0.66.0F.W0 98 /r
RR
V/V
AVX512DQ
Bitwise OR 8 bits masks k1 and k2 and update ZF and CF accordingly.
KORTESTB k1, k2
OR AVX10.1
VEX.L0.0F.W1 98 /r
RR
V/V
AVX512BW
Bitwise OR 64 bits masks k1 and k2 and update ZF and CF accordingly.
KORTESTQ k1, k2
OR AVX10.1
VEX.L0.66.0F.W1 98 /r
RR
V/V
AVX512BW
Bitwise OR 32 bits masks k1 and k2 and update ZF and CF accordingly.
KORTESTD k1, k2
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
RR
ModRM:reg (w)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise OR between the vector mask register k2, and the vector mask register k1, and sets CF and ZF
based on the operation result.
ZF flag is set if both sources are 0x0. CF is set if, after the OR operation is done, the operation result is all 1’s.
Operation
KORTESTW
TMP[15:0] := DEST[15:0] BITWISE OR SRC[15:0]
IF(TMP[15:0]=0)
THEN ZF := 1
ELSE ZF := 0
FI;
IF(TMP[15:0]=FFFFh)
THEN CF := 1
ELSE CF := 0
FI;
KORTESTB
TMP[7:0] := DEST[7:0] BITWISE OR SRC[7:0]
IF(TMP[7:0]=0)
THEN ZF := 1
ELSE ZF := 0
FI;
IF(TMP[7:0]==FFh)
THEN CF := 1
ELSE CF := 0
FI;
KORTESTW/KORTESTB/KORTESTQ/KORTESTD-OR Masks and Set Flags
Vol. 2A
3-520
KORTESTQ
TMP[63:0] := DEST[63:0] BITWISE OR SRC[63:0]
IF(TMP[63:0]=0)
THEN ZF := 1
ELSE ZF := 0
FI;
IF(TMP[63:0]==FFFFFFFF_FFFFFFFFh)
THEN CF := 1
ELSE CF := 0
FI;
KORTESTD
TMP[31:0] := DEST[31:0] BITWISE OR SRC[31:0]
IF(TMP[31:0]=0)
THEN ZF := 1
ELSE ZF := 0
FI;
IF(TMP[31:0]=FFFFFFFFh)
THEN CF := 1
ELSE CF := 0
FI;
Intel C/C++ Compiler Intrinsic Equivalent
KORTESTW __mmask16 _mm512_kortest[cz](__mmask16 a, __mmask16 b);
Flags Affected
The ZF flag is set if the result of OR-ing both sources is all 0s.
The CF flag is set if the result of OR-ing both sources is all 1s.
The OF, SF, AF, and PF flags are set to 0.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KORTESTW/KORTESTB/KORTESTQ/KORTESTD-OR Masks and Set Flags
Vol. 2A
3-521
KORW/KORB/KORQ/KORD-Bitwise Logical OR Masks
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.0F.W0 45 /r
RVR
V/V
AVX512F
Bitwise OR 16 bits masks k2 and k3 and place result in k1.
KORW k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W0 45 /r
RVR
V/V
AVX512DQ
Bitwise OR 8 bits masks k2 and k3 and place result in k1.
KORB k1, k2, k3
OR AVX10.1
VEX.L1.0F.W1 45 /r
RVR
V/V
AVX512BW
Bitwise OR 64 bits masks k2 and k3 and place result in k1.
KORQ k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W1 45 /r
RVR
V/V
AVX512BW
Bitwise OR 32 bits masks k2 and k3 and place result in k1.
KORD k1, k2, k3
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise OR between the vector mask k2 and the vector mask k3, and writes the result into vector mask
k1 (three-operand form).
Operation
KORW
DEST[15:0] := SRC1[15:0] BITWISE OR SRC2[15:0]
DEST[MAX_KL-1:16] := 0
KORB
DEST[7:0] := SRC1[7:0] BITWISE OR SRC2[7:0]
DEST[MAX_KL-1:8] := 0
KORQ
DEST[63:0] := SRC1[63:0] BITWISE OR SRC2[63:0]
DEST[MAX_KL-1:64] := 0
KORD
DEST[31:0] := SRC1[31:0] BITWISE OR SRC2[31:0]
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KORW __mmask16 _mm512_kor(__mmask16 a, __mmask16 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KORW/KORB/KORQ/KORD-Bitwise Logical OR Masks
Vol. 2A
3-522
KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD-Shift Left Mask Registers
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L0.66.0F3A.W1 32 /r
RRI
V/V
AVX512F
Shift left 16 bits in k2 by immediate and write result in k1.
KSHIFTLW k1, k2, imm8
OR AVX10.1
VEX.L0.66.0F3A.W0 32 /r
RRI
V/V
AVX512DQ
Shift left 8 bits in k2 by immediate and write result in k1.
KSHIFTLB k1, k2, imm8
OR AVX10.1
VEX.L0.66.0F3A.W1 33 /r
RRI
V/V
AVX512BW
Shift left 64 bits in k2 by immediate and write result in k1.
KSHIFTLQ k1, k2, imm8
OR AVX10.1
VEX.L0.66.0F3A.W0 33 /r
RRI
V/V
AVX512BW
Shift left 32 bits in k2 by immediate and write result in k1.
KSHIFTLD k1, k2, imm8
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RRI
ModRM:reg (w)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
imm8
Description
Shifts 8/16/32/64 bits in the second operand (source operand) left by the count specified in immediate byte and
place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destina-
tion are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for
word shift), 31 (for doubleword shift) or 63 (for quadword shift).
Operation
KSHIFTLW
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=15
THEN DEST[15:0] := SRC1[15:0] << COUNT;
FI;
KSHIFTLB
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=7
THEN DEST[7:0] := SRC1[7:0] << COUNT;
FI;
KSHIFTLQ
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=63
THEN DEST[63:0] := SRC1[63:0] << COUNT;
FI;
KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD-Shift Left Mask Registers
Vol. 2A
3-523
KSHIFTLD
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=31
THEN DEST[31:0] := SRC1[31:0] << COUNT;
FI;
Intel C/C++ Compiler Intrinsic Equivalent
Compiler auto generates KSHIFTLW when needed.
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD-Shift Left Mask Registers
Vol. 2A
3-524
KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD-Shift Right Mask Registers
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L0.66.0F3A.W1 30 /r
RRI
V/V
AVX512F
Shift right 16 bits in k2 by immediate and write result in k1.
KSHIFTRW k1, k2, imm8
OR AVX10.1
VEX.L0.66.0F3A.W0 30 /r
RRI
V/V
AVX512DQ
Shift right 8 bits in k2 by immediate and write result in k1.
KSHIFTRB k1, k2, imm8
OR AVX10.1
VEX.L0.66.0F3A.W1 31 /r
RRI
V/V
AVX512BW
Shift right 64 bits in k2 by immediate and write result in k1.
KSHIFTRQ k1, k2, imm8
OR AVX10.1
VEX.L0.66.0F3A.W0 31 /r
RRI
V/V
AVX512BW
Shift right 32 bits in k2 by immediate and write result in k1.
KSHIFTRD k1, k2, imm8
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RRI
ModRM:reg (w)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
imm8
Description
Shifts 8/16/32/64 bits in the second operand (source operand) right by the count specified in immediate and place
the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are
zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift),
31 (for doubleword shift) or 63 (for quadword shift).
Operation
KSHIFTRW
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=15
THEN DEST[15:0] := SRC1[15:0] >> COUNT;
FI;
KSHIFTRB
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=7
THEN DEST[7:0] := SRC1[7:0] >> COUNT;
FI;
KSHIFTRQ
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=63
THEN DEST[63:0] := SRC1[63:0] >> COUNT;
FI;
KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD-Shift Right Mask Registers
Vol. 2A
3-525
KSHIFTRD
COUNT := imm8[7:0]
DEST[MAX_KL-1:0] := 0
IF COUNT <=31
THEN DEST[31:0] := SRC1[31:0] >> COUNT;
FI;
Intel C/C++ Compiler Intrinsic Equivalent
Compiler auto generates KSHIFTRW when needed.
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD-Shift Right Mask Registers
Vol. 2A
3-526
KTESTW/KTESTB/KTESTQ/KTESTD-Packed Bit Test Masks and Set Flags
Opcode/
Op
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
VEX.L0.0F.W0 99 /r
RR
V/V
AVX512DQ
Set ZF and CF depending on sign bit AND and ANDN of 16 bits mask
KTESTW k1, k2
OR AVX10.1
register sources.
VEX.L0.66.0F.W0 99 /r
RR
V/V
AVX512DQ
Set ZF and CF depending on sign bit AND and ANDN of 8 bits mask reg-
KTESTB k1, k2
OR AVX10.1
ister sources.
VEX.L0.0F.W1 99 /r
RR
V/V
AVX512BW
Set ZF and CF depending on sign bit AND and ANDN of 64 bits mask
KTESTQ k1, k2
OR AVX10.1
register sources.
VEX.L0.66.0F.W1 99 /r
RR
V/V
AVX512BW
Set ZF and CF depending on sign bit AND and ANDN of 32 bits mask
KTESTD k1, k2
OR AVX10.1
register sources.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
RR
ModRM:reg (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise comparison of the bits of the first source operand and corresponding bits in the second source
operand. If the AND operation produces all zeros, the ZF is set else the ZF is clear. If the bitwise AND operation of
the inverted first source operand with the second source operand produces all zeros the CF is set else the CF is
clear. Only the EFLAGS register is updated.
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.
Operation
KTESTW
TEMP[15:0] := SRC2[15:0] AND SRC1[15:0]
IF (TEMP[15:0] = = 0)
THEN ZF :=1;
ELSE ZF := 0;
FI;
TEMP[15:0] := SRC2[15:0] AND NOT SRC1[15:0]
IF (TEMP[15:0] = = 0)
THEN CF :=1;
ELSE CF := 0;
FI;
AF := OF := PF := SF := 0;
KTESTB
TEMP[7:0] := SRC2[7:0] AND SRC1[7:0]
IF (TEMP[7:0] = = 0)
THEN ZF :=1;
ELSE ZF := 0;
FI;
TEMP[7:0] := SRC2[7:0] AND NOT SRC1[7:0]
IF (TEMP[7:0] = = 0)
THEN CF :=1;
ELSE CF := 0;
FI;
AF := OF := PF := SF := 0;
KTESTW/KTESTB/KTESTQ/KTESTD-Packed Bit Test Masks and Set Flags
Vol. 2A
3-527
KTESTQ
TEMP[63:0] := SRC2[63:0] AND SRC1[63:0]
IF (TEMP[63:0] = = 0)
THEN ZF :=1;
ELSE ZF := 0;
FI;
TEMP[63:0] := SRC2[63:0] AND NOT SRC1[63:0]
IF (TEMP[63:0] = = 0)
THEN CF :=1;
ELSE CF := 0;
FI;
AF := OF := PF := SF := 0;
KTESTD
TEMP[31:0] := SRC2[31:0] AND SRC1[31:0]
IF (TEMP[31:0] = = 0)
THEN ZF :=1;
ELSE ZF := 0;
FI;
TEMP[31:0] := SRC2[31:0] AND NOT SRC1[31:0]
IF (TEMP[31:0] = = 0)
THEN CF :=1;
ELSE CF := 0;
FI;
AF := OF := PF := SF := 0;
Intel C/C++ Compiler Intrinsic Equivalent
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KTESTW/KTESTB/KTESTQ/KTESTD-Packed Bit Test Masks and Set Flags
Vol. 2A
3-528
KUNPCKBW/KUNPCKWD/KUNPCKDQ-Unpack for Mask Registers
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.66.0F.W0 4B /r
RVR
V/V
AVX512F
Unpack 8-bit masks in k2 and k3 and write word result in k1.
KUNPCKBW k1, k2, k3
OR AVX10.1
VEX.L1.0F.W0 4B /r
RVR
V/V
AVX512BW
Unpack 16-bit masks in k2 and k3 and write doubleword result
KUNPCKWD k1, k2, k3
OR AVX10.1
in k1.
VEX.L1.0F.W1 4B /r
RVR
V/V
AVX512BW
Unpack 32-bit masks in k2 and k3 and write quadword result in
KUNPCKDQ k1, k2, k3
OR AVX10.1
k1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Unpacks the lower 8/16/32 bits of the second and third operands (source operands) into the low part of the first
operand (destination operand), starting from the low bytes. The result is zero-extended in the destination.
Operation
KUNPCKBW
DEST[7:0] := SRC2[7:0]
DEST[15:8] := SRC1[7:0]
DEST[MAX_KL-1:16] := 0
KUNPCKWD
DEST[15:0] := SRC2[15:0]
DEST[31:16] := SRC1[15:0]
DEST[MAX_KL-1:32] := 0
KUNPCKDQ
DEST[31:0] := SRC2[31:0]
DEST[63:32] := SRC1[31:0]
DEST[MAX_KL-1:64] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KUNPCKBW __mmask16 _mm512_kunpackb(__mmask16 a, __mmask16 b);
KUNPCKDQ __mmask64 _mm512_kunpackd(__mmask64 a, __mmask64 b);
KUNPCKWD __mmask32 _mm512_kunpackw(__mmask32 a, __mmask32 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KUNPCKBW/KUNPCKWD/KUNPCKDQ-Unpack for Mask Registers
Vol. 2A
3-529
KXNORW/KXNORB/KXNORQ/KXNORD-Bitwise Logical XNOR Masks
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.0F.W0 46 /r
RVR
V/V
AVX512F
Bitwise XNOR 16-bit masks k2 and k3 and place result in k1.
KXNORW k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W0 46 /r
RVR
V/V
AVX512DQ
Bitwise XNOR 8-bit masks k2 and k3 and place result in k1.
KXNORB k1, k2, k3
OR AVX10.1
VEX.L1.0F.W1 46 /r
RVR
V/V
AVX512BW
Bitwise XNOR 64-bit masks k2 and k3 and place result in k1.
KXNORQ k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W1 46 /r
RVR
V/V
AVX512BW
Bitwise XNOR 32-bit masks k2 and k3 and place result in k1.
KXNORD k1, k2, k3
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise XNOR between the vector mask k2 and the vector mask k3, and writes the result into vector
mask k1 (three-operand form).
Operation
KXNORW
DEST[15:0] := NOT (SRC1[15:0] BITWISE XOR SRC2[15:0])
DEST[MAX_KL-1:16] := 0
KXNORB
DEST[7:0] := NOT (SRC1[7:0] BITWISE XOR SRC2[7:0])
DEST[MAX_KL-1:8] := 0
KXNORQ
DEST[63:0] := NOT (SRC1[63:0] BITWISE XOR SRC2[63:0])
DEST[MAX_KL-1:64] := 0
KXNORD
DEST[31:0] := NOT (SRC1[31:0] BITWISE XOR SRC2[31:0])
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KXNORW __mmask16 _mm512_kxnor(__mmask16 a, __mmask16 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KXNORW/KXNORB/KXNORQ/KXNORD-Bitwise Logical XNOR Masks
Vol. 2A
3-530
KXORW/KXORB/KXORQ/KXORD-Bitwise Logical XOR Masks
Opcode/
Op/En
64/32 bit
CPUID
Description
Instruction
Mode
Feature Flag
Support
VEX.L1.0F.W0 47 /r
RVR
V/V
AVX512F
Bitwise XOR 16-bit masks k2 and k3 and place result in k1.
KXORW k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W0 47 /r
RVR
V/V
AVX512DQ
Bitwise XOR 8-bit masks k2 and k3 and place result in k1.
KXORB k1, k2, k3
OR AVX10.1
VEX.L1.0F.W1 47 /r
RVR
V/V
AVX512BW
Bitwise XOR 64-bit masks k2 and k3 and place result in k1.
KXORQ k1, k2, k3
OR AVX10.1
VEX.L1.66.0F.W1 47 /r
RVR
V/V
AVX512BW
Bitwise XOR 32-bit masks k2 and k3 and place result in k1.
KXORD k1, k2, k3
OR AVX10.1
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
RVR
ModRM:reg (w)
VEX.1vvv (r)
ModRM:r/m (r, ModRM:[7:6] must be 11b)
Description
Performs a bitwise XOR between the vector mask k2 and the vector mask k3, and writes the result into vector mask
k1 (three-operand form).
Operation
KXORW
DEST[15:0] := SRC1[15:0] BITWISE XOR SRC2[15:0]
DEST[MAX_KL-1:16] := 0
KXORB
DEST[7:0] := SRC1[7:0] BITWISE XOR SRC2[7:0]
DEST[MAX_KL-1:8] := 0
KXORQ
DEST[63:0] := SRC1[63:0] BITWISE XOR SRC2[63:0]
DEST[MAX_KL-1:64] := 0
KXORD
DEST[31:0] := SRC1[31:0] BITWISE XOR SRC2[31:0]
DEST[MAX_KL-1:32] := 0
Intel C/C++ Compiler Intrinsic Equivalent
KXORW __mmask16 _mm512_kxor(__mmask16 a, __mmask16 b);
Flags Affected
None.
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-65, “TYPE K20 Exception Definition (VEX-Encoded OpMask Instructions w/o Memory Arg).”
KXORW/KXORB/KXORQ/KXORD-Bitwise Logical XOR Masks
Vol. 2A
3-531
LAHF-Load Status Flags Into AH Register
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
9F
LAHF
ZO
Valid1
Valid
Load: AH := EFLAGS(SF:ZF:0:AF:0:PF:1:CF).
NOTES:
1. Invalid if CPUID.80000001H:ECX.LAHF_SAHF_64 is enumerated as 0.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
This instruction executes as described above in compatibility mode and legacy mode. It is valid in 64-bit mode only
if CPUID.80000001H:ECX.LAHF_SAHF_64[0] = 1.
Operation
IF 64-Bit Mode
THEN
IF CPUID.80000001H:ECX.LAHF_SAHF_64[0] = 1;
THEN AH := RFLAGS(SF:ZF:0:AF:0:PF:1:CF);
ELSE #UD;
FI;
ELSE
AH := EFLAGS(SF:ZF:0:AF:0:PF:1:CF);
FI;
Flags Affected
None. The state of the flags in the EFLAGS register is not affected.
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#UD
If CPUID.80000001H:ECX.LAHF_SAHF_64[0] = 0.
If the LOCK prefix is used.
LAHF-Load Status Flags Into AH Register
Vol. 2A
3-532
LAR-Load Access Rights
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 02 /r
LAR r16, r16/m16
RM
Valid
Valid
Load access rights from specified descriptor.
0F 02 /r
LAR r32, r32/m161
RM
Valid
Valid
Load access rights from specified descriptor.
REX.W + 0F 02/r
LAR r32, r64/m161
RM
Valid
N.E.
Load access rights from specified descriptor.
NOTES:
1. Regardless of operand size, only bits 15:0 of a register source operand are used. Other bits are ignored.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
Loads the access rights from the segment descriptor specified by the second operand (source operand) into the
first operand (destination operand) and sets the ZF flag in the EFLAGS register. The source operand (which can be
a register or a memory location) contains the segment selector for the segment descriptor being accessed. If the
source operand is a memory address, only 16 bits of data are accessed. The destination operand is a general-
purpose register.
The processor performs access checks as part of the loading process. Once loaded in the destination register, soft-
ware can perform additional checks on the access rights information.
The access rights for a segment descriptor include fields located in the second doubleword (bytes 4-7) of the
segment descriptor. The following fields are loaded by the LAR instruction:
• Bits 7:0 are returned as 0
• Bits 11:8 return the segment type.
• Bit 12 returns the S flag.
• Bits 14:13 return the DPL.
• Bit 15 returns the P flag.
• The following fields are returned only if the operand size is greater than 16 bits:
- Bits 19:16 are undefined.
- Bit 20 returns the software-available bit in the descriptor.
- Bit 21 returns the L flag.
- Bit 22 returns the D/B flag.
- Bit 23 returns the G flag.
- Bits 31:24 are returned as 0.
When the operand size is 16 bits, only the low 16 bits identified above are returned; the upper bits of the destina-
tion are unmodified. When the operand size is 32 bits, the 32-bit value identified above is loaded into the destina-
tion operand; the upper bits of the destination are cleared. When the operand is 64 bits, the 32-bit value is zero-
extended to 64 bits and loaded into the destination operand. (The behavior with 32-bit and 64-bit operand sizes is
identical.)
This instruction performs the following checks before it loads the access rights in the destination register:
• Checks that the segment selector is not NULL.
• Checks that the segment selector points to a descriptor that is within the limits of the GDT or LDT being
accessed
LAR-Load Access Rights
Vol. 2A
3-533
• Checks that the descriptor type is valid for this instruction. All code and data segment descriptors are valid for
(can be accessed with) the LAR instruction. The valid system segment and gate descriptor types are given in
Table 3-55.
• If the segment is not a conforming code segment, it checks that the specified segment descriptor is visible at
the CPL (that is, if the CPL and the RPL of the segment selector are less than or equal to the DPL of the segment
selector).
If the segment descriptor cannot be accessed or is an invalid type for the instruction, the ZF flag is cleared and no
access rights are loaded in the destination operand.
The LAR instruction can only be executed in protected mode and IA-32e mode.
Table 3-55. Segment and Gate Types
Type
Protected Mode
IA-32e Mode
Name
Valid
Name
Valid
0
Reserved
No
Reserved
No
1
Available 16-bit TSS
Yes
Reserved
No
2
LDT
Yes
LDT
Yes
3
Busy 16-bit TSS
Yes
Reserved
No
4
16-bit call gate
Yes
Reserved
No
5
16-bit/32-bit task gate
Yes
Reserved
No
6
16-bit interrupt gate
No
Reserved
No
7
16-bit trap gate
No
Reserved
No
8
Reserved
No
Reserved
No
9
Available 32-bit TSS
Yes
Available 64-bit TSS
Yes
A
Reserved
No
Reserved
No
B
Busy 32-bit TSS
Yes
Busy 64-bit TSS
Yes
C
32-bit call gate
Yes
64-bit call gate
Yes
D
Reserved
No
Reserved
No
E
32-bit interrupt gate
No
64-bit interrupt gate
No
F
32-bit trap gate
No
64-bit trap gate
No
Operation
IF Offset(SRC) > descriptor table limit
THEN
ZF := 0;
ELSE
SegmentDescriptor := descriptor referenced by SRC;
IF SegmentDescriptor(Type) ≠ conforming code segment
and (CPL > DPL) or (RPL > DPL)
or SegmentDescriptor(Type) is not valid for instruction
THEN
ZF := 0;
ELSE
DEST := access rights from SegmentDescriptor as given in Description section;
ZF := 1;
FI;
FI;
LAR-Load Access Rights
Vol. 2A
3-534
Flags Affected
The ZF flag is set to 1 if the access rights are loaded successfully; otherwise, it is cleared to 0.
LAR-Load Access Rights
Vol. 2A
3-535
Protected Mode Exceptions
#GP(0)
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
selector.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and the memory operand effective address is unaligned while
the current privilege level is 3.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#UD
The LAR instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The LAR instruction cannot be executed in virtual-8086 mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If the memory operand effective address referencing the SS segment is in a non-canonical
form.
#GP(0)
If the memory operand effective address is in a non-canonical form.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and the memory operand effective address is unaligned while
the current privilege level is 3.
#UD
If the LOCK prefix is used.
LAR-Load Access Rights
Vol. 2A
3-536
LDDQU-Load Unaligned Integer 128 Bits
Opcode/
Op/
64/32-bit
CPUID
Description
Instruction
En
Mode
Feature
Flag
F2 0F F0 /r
RM
V/V
SSE3
Load unaligned data from mem and return
double quadword in xmm1.
LDDQU xmm1, mem
VEX.128.F2.0F.WIG F0 /r
RM
V/V
AVX
Load unaligned packed integer values from
mem to xmm1.
VLDDQU xmm1, m128
VEX.256.F2.0F.WIG F0 /r
RM
V/V
AVX
Load unaligned packed integer values from
mem to ymm1.
VLDDQU ymm1, m256
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
The instruction is functionally similar to (V)MOVDQU ymm/xmm, m256/m128 for loading from memory. That is:
32/16 bytes of data starting at an address specified by the source memory operand (second operand) are fetched
from memory and placed in a destination register (first operand). The source operand need not be aligned on a
32/16-byte boundary. Up to 64/32 bytes may be loaded from memory; this is implementation dependent.
This instruction may improve performance relative to (V)MOVDQU if the source operand crosses a cache line
boundary. In situations that require the data loaded by (V)LDDQU be modified and stored to the same location, use
(V)MOVDQU or (V)MOVDQA instead of (V)LDDQU. To move a double quadword to or from memory locations that
are known to be aligned on 16-byte boundaries, use the (V)MOVDQA instruction.
Implementation Notes
• If the source is aligned to a 32/16-byte boundary, based on the implementation, the 32/16 bytes may be
loaded more than once. For that reason, the usage of (V)LDDQU should be avoided when using uncached or
write-combining (WC) memory regions. For uncached or WC memory regions, keep using (V)MOVDQU.
• This instruction is a replacement for (V)MOVDQU (load) in situations where cache line splits significantly affect
performance. It should not be used in situations where store-load forwarding is performance critical. If
performance of store-load forwarding is critical to the application, use (V)MOVDQA store-load pairs when data
is 256/128-bit aligned or (V)MOVDQU store-load pairs when data is 256/128-bit unaligned.
• If the memory address is not aligned on 32/16-byte boundary, some implementations may load up to 64/32
bytes and return 32/16 bytes in the destination. Some processor implementations may issue multiple loads to
access the appropriate 32/16 bytes. Developers of multi-threaded or multi-processor software should be aware
that on these processors the loads will be performed in a non-atomic way.
• If alignment checking is enabled (CR0.AM = 1, RFLAGS.AC = 1, and CPL = 3), an alignment-check exception
(#AC) may or may not be generated (depending on processor implementation) when the memory address is
not aligned on an 8-byte boundary.
In 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.
Operation
LDDQU (128-bit Legacy SSE Version)
DEST[127:0] := SRC[127:0]
DEST[MAXVL-1:128] (Unmodified)
LDDQU-Load Unaligned Integer 128 Bits
Vol. 2A
3-537
VLDDQU (VEX.128 Encoded Version)
DEST[127:0] := SRC[127:0]
DEST[MAXVL-1:128] := 0
VLDDQU (VEX.256 Encoded Version)
DEST[255:0] := SRC[255:0]
DEST[MAXVL-1:256] := 0
Intel C/C++ Compiler Intrinsic Equivalent
LDDQU __m128i _mm_lddqu_si128 (__m128i * p);
VLDDQU __m256i _mm256_lddqu_si256 (__m256i * p);
Numeric Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions.”
Note treatment of #AC varies.
LDDQU-Load Unaligned Integer 128 Bits
Vol. 2A
3-538
LDMXCSR-Load MXCSR Register
Opcode/
Op/
64/32-bit
CPUID
Description
Instruction
En
Mode
Feature
Flag
NP 0F AE /2
M
V/V
SSE
Load MXCSR register from m32.
LDMXCSR m32
VEX.LZ.0F.WIG AE /2
M
V/V
AVX
Load MXCSR register from m32.
VLDMXCSR m32
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (r)
N/A
N/A
N/A
Description
Loads the source operand into the MXCSR control/status register. The source operand is a 32-bit memory location.
See “MXCSR Control and Status Register” in Chapter 10, of the Intel® 64 and IA-32 Architectures Software Devel-
oper’s Manual, Volume 1, for a description of the MXCSR register and its contents.
The LDMXCSR instruction is typically used in conjunction with the (V)STMXCSR instruction, which stores the
contents of the MXCSR register in memory.
The default MXCSR value at reset is 1F80H.
If a (V)LDMXCSR instruction clears a SIMD floating-point exception mask bit and sets the corresponding exception
flag bit, a SIMD floating-point exception will not be immediately generated. The exception will be generated only
upon the execution of the next instruction that meets both conditions below:
• the instruction must operate on an XMM or YMM register operand,
• the instruction causes that particular SIMD floating-point exception to be reported.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
If VLDMXCSR is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause
an #UD exception.
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.
Operation
MXCSR := m32;
C/C++ Compiler Intrinsic Equivalent
_mm_setcsr(unsigned int i)
Numeric Exceptions
None.
Other Exceptions
See Table 2-22, “Type 5 Class Exception Conditions,” additionally:
#GP
For an attempt to set reserved bits in MXCSR.
#UD
If VEX.vvvv ≠ 1111B.
LDMXCSR-Load MXCSR Register
Vol. 2A
3-539
LDS/LES/LFS/LGS/LSS-Load Far Pointer
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
C5 /r
LDS r16,m16:16
RM
Invalid
Valid
Load DS:r16 with far pointer from memory.
C5 /r
LDS r32,m16:32
RM
Invalid
Valid
Load DS:r32 with far pointer from memory.
0F B2 /r
LSS r16,m16:16
RM
Valid
Valid
Load SS:r16 with far pointer from memory.
0F B2 /r
LSS r32,m16:32
RM
Valid
Valid
Load SS:r32 with far pointer from memory.
REX.W + 0F B2 /r
LSS r64,m16:64
RM
Valid
N.E.
Load SS:r64 with far pointer from memory.
C4 /r
LES r16,m16:16
RM
Invalid
Valid
Load ES:r16 with far pointer from memory.
C4 /r
LES r32,m16:32
RM
Invalid
Valid
Load ES:r32 with far pointer from memory.
0F B4 /r
LFS r16,m16:16
RM
Valid
Valid
Load FS:r16 with far pointer from memory.
0F B4 /r
LFS r32,m16:32
RM
Valid
Valid
Load FS:r32 with far pointer from memory.
REX.W + 0F B4 /r
LFS r64,m16:64
RM
Valid
N.E.
Load FS:r64 with far pointer from memory.
0F B5 /r
LGS r16,m16:16
RM
Valid
Valid
Load GS:r16 with far pointer from memory.
0F B5 /r
LGS r32,m16:32
RM
Valid
Valid
Load GS:r32 with far pointer from memory.
REX.W + 0F B5 /r
LGS r64,m16:64
RM
Valid
N.E.
Load GS:r64 with far pointer from memory.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
Loads a far pointer (segment selector and offset) from the second operand (source operand) into a segment
register and the first operand (destination operand). The source operand specifies a 48-bit or a 32-bit pointer in
memory depending on the current setting of the operand-size attribute (32 bits or 16 bits, respectively). The
instruction opcode and the destination operand specify a segment register/general-purpose register pair. The 16-
bit segment selector from the source operand is loaded into the segment register specified with the opcode (DS,
SS, ES, FS, or GS). The 32-bit or 16-bit offset is loaded into the register specified with the destination operand.
If one of these instructions is executed in protected mode, additional information from the segment descriptor
pointed to by the segment selector in the source operand is loaded in the hidden part of the selected segment
register.
Also in protected mode, a NULL selector (values 0000 through 0003) can be loaded into DS, ES, FS, or GS registers
without causing a protection exception. (Any subsequent reference to a segment whose corresponding segment
register is loaded with a NULL selector, causes a general-protection exception (#GP) and no memory reference to
the segment occurs.)
In 64-bit mode, the instruction’s default operation size is 32 bits. Using a REX prefix in the form of REX.W promotes
operation to specify a source operand referencing an 80-bit pointer (16-bit selector, 64-bit offset) in memory. Using
a REX prefix in the form of REX.R permits access to additional registers (R8-R15). See the summary chart at the
beginning of this section for encoding data and limits.
Operation
64-BIT_MODE
IF SS is loaded
THEN
IF SegmentSelector = NULL and ( (RPL = 3) or
(RPL ≠ 3 and RPL ≠ CPL) )
THEN #GP(0);
ELSE IF descriptor is in non-canonical space
LDS/LES/LFS/LGS/LSS-Load Far Pointer
Vol. 2A
3-540
|