Intel 64 and IA-32 Architectures. Software Developer’s Manual (Collection, 2023) - page 67

 

  Index      Manuals     Intel 64 and IA-32 Architectures. Software Developer’s Manual (Collection, 2023)

 

Search            copyright infringement  

 

   

 

   

 

Content      ..     65      66      67      68     ..

 

 

 

Intel 64 and IA-32 Architectures. Software Developer’s Manual (Collection, 2023) - page 67

 

 

INSTRUCTION SET REFERENCE, A-L
On inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The
segment selector for the new stack segment is specified in the TSS for the currently running task. The branch to
the new code segment occurs after the stack switch. (Note that when using a call gate to perform a far call to a
segment at the same privilege level, no stack switch occurs.) On the new stack, the processor pushes the segment
selector and stack pointer for the calling procedure’s stack, an optional set of parameters from the calling proce-
dures stack, and the segment selector and instruction pointer for the calling procedure’s code segment. (A value in
the call gate descriptor determines how many parameters to copy to the new stack.) Finally, the processor
branches to the address of the procedure being called within the new code segment.
Executing a task switch with the CALL instruction is similar to executing a call through a call gate. The target
operand specifies the segment selector of the task gate for the new task activated by the switch (the offset in the
target operand is ignored). The task gate in turn points to the TSS for the new task, which contains the segment
selectors for the task’s code and stack segments. Note that the TSS also contains the EIP value for the next instruc-
tion that was to be executed before the calling task was suspended. This instruction pointer value is loaded into the
EIP register to re-start the calling task.
The CALL instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of
the task gate. See Chapter 8, “Task Management,” in the Intel® 64 and IA-32 Architectures Software Developer’s
Manual, Volume 3A, for information on the mechanics of a task switch.
When you execute at task switch with a CALL instruction, the nested task flag (NT) is set in the EFLAGS register
and the new TSS’s previous task link field is loaded with the old task’s TSS selector. Code is expected to suspend
this nested task by executing an IRET instruction which, because the NT flag is set, automatically uses the previous
task link to return to the calling task. (See “Task Linking” in Chapter 8 of the Intel® 64 and IA-32 Architectures
Software Developer’s Manual, Volume 3A, for information on nested tasks.) Switching tasks with the CALL instruc-
tion differs in this regard from JMP instruction. JMP does not set the NT flag and therefore does not expect an IRET
instruction to suspend the task.
Mixing 16-Bit and 32-Bit Calls. When making far calls between 16-bit and 32-bit code segments, use a call gate. If
the far call is from a 32-bit code segment to a 16-bit code segment, the call should be made from the first 64
KBytes of the 32-bit code segment. This is because the operand-size attribute of the instruction is set to 16, so only
a 16-bit return address offset can be saved. Also, the call should be made using a 16-bit call gate so that 16-bit
values can be pushed on the stack. See Chapter 22, “Mixing 16-Bit and 32-Bit Code,” in the Intel® 64 and IA-32
Architectures Software Developer’s Manual, Volume 3B, for more information.
Far Calls in Compatibility Mode. When the processor is operating in compatibility mode, the CALL instruction can be
used to perform the following types of far calls:
Far call to the same privilege level, remaining in compatibility mode
Far call to the same privilege level, transitioning to 64-bit mode
Far call to a different privilege level (inter-privilege level call), transitioning to 64-bit mode
Note that a CALL instruction can not be used to cause a task switch in compatibility mode since task switches are
not supported in IA-32e mode.
In compatibility 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) and access rights determine
the type of call operation to be performed.
If the selected descriptor is for a code segment, a far call 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 call to the same privilege level in compatibility mode is very
similar to one carried out in protected 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. The differ-
ence is that 64-bit mode may be entered. This specified by the L bit in the new code segment descriptor.
Note that a 64-bit call gate (described in the next paragraph) can also be used to perform a far call to a code
segment at the same privilege level. However, using this mechanism requires that the target code segment
descriptor have the L bit set, causing an entry to 64-bit mode.
When executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed
through a 64-bit call gate. The segment selector specified by the target operand identifies the call gate. The target
CALL—Call Procedure
Vol. 2A
3-141
INSTRUCTION SET REFERENCE, A-L
operand can specify the call gate segment selector either directly with a pointer (ptr16:16 or ptr16:32) or indirectly
with a memory location (m16:16 or m16:32). The processor obtains the segment selector for the new code
segment and the new instruction pointer (offset) from the 16-byte call gate descriptor. (The offset from the target
operand is ignored when a call gate is used.)
On inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The
segment selector for the new stack segment is set to NULL. The new stack pointer is specified in the TSS for the
currently running task. The branch to the new code segment occurs after the stack switch. (Note that when using
a call gate to perform a far call to a segment at the same privilege level, an implicit stack switch occurs as a result
of entering 64-bit mode. The SS selector is unchanged, but stack segment accesses use a segment base of 0x0, the
limit is ignored, and the default stack size is 64-bits. The full value of RSP is used for the offset, of which the upper
32-bits are undefined.) On the new stack, the processor pushes the segment selector and stack pointer for the
calling procedure’s stack and the segment selector and instruction pointer for the calling procedure’s code
segment. (Parameter copy is not supported in IA-32e mode.) Finally, the processor branches to the address of the
procedure being called within the new code segment.
Near/(Far) Calls in 64-bit Mode. When the processor is operating in 64-bit mode, the CALL instruction can be used to
perform the following types of far calls:
Far call to the same privilege level, transitioning to compatibility mode
Far call to the same privilege level, remaining in 64-bit mode
Far call to a different privilege level (inter-privilege level call), remaining in 64-bit mode
Note that in this mode the CALL instruction can not be used to cause a task switch in 64-bit mode since task
switches are not supported in IA-32e mode.
In 64-bit mode, the processor always uses the segment selector part of the far address to access the corresponding
descriptor in the GDT or LDT. The descriptor type (code segment, call gate) and access rights determine the type of
call operation to be performed.
If the selected descriptor is for a code segment, a far call 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 call to the same privilege level in 64-bit mode is very similar to
one carried out in compatibility mode. The target operand specifies an absolute far address indirectly with a
memory location (m16:16, m16:32 or m16:64). The form of CALL with a direct specification of absolute far address
is not defined in 64-bit mode. The operand-size attribute determines the size of the offset (16, 32, or 64 bits) in the
far address. The new code segment selector and its descriptor are loaded into the CS register; the offset from the
instruction is loaded into the EIP register. The new code segment may specify entry either into compatibility or 64-
bit mode, based on the L bit value.
A 64-bit call gate (described in the next paragraph) can also be used to perform a far call to a code segment at the
same privilege level. However, using this mechanism requires that the target code segment descriptor have the L
bit set.
When executing an inter-privilege-level far call, the code segment for the procedure being called must be accessed
through a 64-bit call gate. The segment selector specified by the target operand identifies the call gate. The target
operand can only specify the call gate segment selector indirectly with a memory location (m16:16, m16:32 or
m16:64). The processor obtains the segment selector for the new code segment and the new instruction pointer
(offset) from the 16-byte call gate descriptor. (The offset from the target operand is ignored when a call gate is
used.)
On inter-privilege-level calls, the processor switches to the stack for the privilege level of the called procedure. The
segment selector for the new stack segment is set to NULL. The new stack pointer is specified in the TSS for the
currently running task. The branch to the new code segment occurs after the stack switch.
Note that when using a call gate to perform a far call to a segment at the same privilege level, an implicit stack
switch occurs as a result of entering 64-bit mode. The SS selector is unchanged, but stack segment accesses use a
segment base of 0x0, the limit is ignored, and the default stack size is 64-bits. (The full value of RSP is used for the
offset.) On the new stack, the processor pushes the segment selector and stack pointer for the calling procedure’s
stack and the segment selector and instruction pointer for the calling procedure’s code segment. (Parameter copy
is not supported in IA-32e mode.) Finally, the processor branches to the address of the procedure being called
within the new code segment.
3-142
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-Flow Enforcement
Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 for CET
details.
Instruction ordering. Instructions following a far call may be fetched from memory before earlier instructions
complete execution, but they will not execute (even speculatively) until all instructions prior to the far call 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 CALL 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 LFENCE instruction opcode can be placed after the near indirect CALL in order to block speculative execu-
tion.
Operation
IF near call
THEN IF near relative call
THEN
IF OperandSize = 64
THEN
tempDEST := SignExtend(DEST); (* DEST is rel32 *)
tempRIP := RIP + tempDEST;
IF stack not large enough for a 8-byte return address
THEN #SS(0); FI;
Push(RIP);
IF ShadowStackEnabled(CPL) AND DEST != 0
ShadowStackPush8B(RIP);
FI;
RIP := tempRIP;
FI;
IF OperandSize = 32
THEN
tempEIP := EIP + DEST; (* DEST is rel32 *)
IF tempEIP is not within code segment limit THEN #GP(0); FI;
IF stack not large enough for a 4-byte return address
THEN #SS(0); FI;
Push(EIP);
IF ShadowStackEnabled(CPL) AND DEST != 0
ShadowStackPush4B(EIP);
FI;
EIP := tempEIP;
FI;
IF OperandSize = 16
THEN
tempEIP := (EIP + DEST) AND 0000FFFFH; (* DEST is rel16 *)
IF tempEIP is not within code segment limit THEN #GP(0); FI;
IF stack not large enough for a 2-byte return address
THEN #SS(0); FI;
Push(IP);
IF ShadowStackEnabled(CPL) AND DEST != 0
(* IP is zero extended and pushed as a 32 bit value on shadow stack *)
ShadowStackPush4B(IP);
FI;
EIP := tempEIP;
FI;
CALL—Call Procedure
Vol. 2A
3-143
INSTRUCTION SET REFERENCE, A-L
ELSE (* Near absolute call *)
IF OperandSize = 64
THEN
tempRIP := DEST; (* DEST is r/m64 *)
IF stack not large enough for a 8-byte return address
THEN #SS(0); FI;
Push(RIP);
IF ShadowStackEnabled(CPL)
ShadowStackPush8B(RIP);
FI;
RIP := tempRIP;
FI;
IF OperandSize = 32
THEN
tempEIP := DEST; (* DEST is r/m32 *)
IF tempEIP is not within code segment limit THEN #GP(0); FI;
IF stack not large enough for a 4-byte return address
THEN #SS(0); FI;
Push(EIP);
IF ShadowStackEnabled(CPL)
ShadowStackPush4B(EIP);
FI;
EIP := tempEIP;
FI;
IF OperandSize = 16
THEN
tempEIP := DEST AND 0000FFFFH; (* DEST is r/m16 *)
IF tempEIP is not within code segment limit THEN #GP(0); FI;
IF stack not large enough for a 2-byte return address
THEN #SS(0); FI;
Push(IP);
IF ShadowStackEnabled(CPL)
(* IP is zero extended and pushed as a 32 bit value on shadow stack *)
ShadowStackPush4B(IP);
FI;
EIP := tempEIP;
FI;
FI;rel/abs
IF (Call 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;
3-144
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
FI; near
IF far call and (PE = 0 or (PE = 1 and VM = 1)) (* Real-address or virtual-8086 mode *)
THEN
IF OperandSize = 32
THEN
IF stack not large enough for a 6-byte return address
THEN #SS(0); FI;
IF DEST[31:16] is not zero THEN #GP(0); FI;
Push(CS); (* Padded with 16 high-order bits *)
Push(EIP);
CS := DEST[47:32]; (* DEST is ptr16:32 or [m16:32] *)
EIP := DEST[31:0]; (* DEST is ptr16:32 or [m16:32] *)
ELSE (* OperandSize = 16 *)
IF stack not large enough for a 4-byte return address
THEN #SS(0); FI;
Push(CS);
Push(IP);
CS := DEST[31:16]; (* DEST is ptr16:16 or [m16:16] *)
EIP := DEST[15:0]; (* DEST is ptr16:16 or [m16:16]; clear upper 16 bits *)
FI;
FI;
IF far call and (PE = 1 and VM = 0) (* Protected mode or IA-32e Mode, not virtual-8086 mode*)
THEN
IF segment selector in target operand NULL
THEN #GP(0); FI;
IF segment selector index not within descriptor table limits
THEN #GP(new code segment selector); FI;
Read type and access rights of selected 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
64-bit 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;
GO TO TASK-STATE-SEGMENT;
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(new code segment selector); FI;
IF segment not present
CALL—Call Procedure
Vol. 2A
3-145
INSTRUCTION SET REFERENCE, A-L
THEN #NP(new code segment selector); FI;
IF stack not large enough for return address
THEN #SS(0); FI;
tempEIP := DEST(Offset);
IF target mode = Compatibility mode
THEN tempEIP := tempEIP AND 00000000_FFFFFFFFH; FI;
IF OperandSize = 16
THEN
tempEIP := tempEIP AND 0000FFFFH; FI; (* Clear upper 16 bits *)
IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and (tempEIP outside new code segment limit)
THEN #GP(0); FI;
IF tempEIP is non-canonical
THEN #GP(0); FI;
IF ShadowStackEnabled(CPL)
IF OperandSize = 32
THEN
tempPushLIP = CSBASE + EIP;
ELSE
IF OperandSize = 16
THEN
tempPushLIP = CSBASE + IP;
ELSE (* OperandSize = 64 *)
tempPushLIP = RIP;
FI;
FI;
tempPushCS = CS;
FI;
IF OperandSize = 32
THEN
Push(CS); (* Padded with 16 high-order bits *)
Push(EIP);
CS := DEST(CodeSegmentSelector);
(* Segment descriptor information also loaded *)
CS(RPL) := CPL;
EIP := tempEIP;
ELSE
IF OperandSize = 16
THEN
Push(CS);
Push(IP);
CS := DEST(CodeSegmentSelector);
(* Segment descriptor information also loaded *)
CS(RPL) := CPL;
EIP := tempEIP;
ELSE (* OperandSize = 64 *)
Push(CS); (* Padded with 48 high-order bits *)
Push(RIP);
CS := DEST(CodeSegmentSelector);
(* Segment descriptor information also loaded *)
CS(RPL) := CPL;
RIP := tempEIP;
FI;
FI;
IF ShadowStackEnabled(CPL)
3-146
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
IF (IA32_EFER.LMA and DEST(CodeSegmentSelector).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;
(* align to 8 byte boundary if not already aligned *)
tempSSP = SSP;
Shadow_stack_store 4 bytes of 0 to (SSP - 4)
SSP = SSP & 0xFFFFFFFFFFFFFFF8H
ShadowStackPush8B(tempPushCS); (* Padded with 48 high-order bits of 0 *)
ShadowStackPush8B(tempPushLIP); (* 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;
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 (DPLCPL)
THEN #GP(new code segment selector); FI;
IF segment not present
THEN #NP(new code segment selector); FI;
IF stack not large enough for return address
THEN #SS(0); FI;
tempEIP := DEST(Offset);
IF target mode = Compatibility mode
THEN tempEIP := tempEIP AND 00000000_FFFFFFFFH; FI;
IF OperandSize = 16
THEN tempEIP := tempEIP AND 0000FFFFH; FI; (* Clear upper 16 bits *)
IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and (tempEIP outside new code segment limit)
THEN #GP(0); FI;
IF tempEIP is non-canonical
THEN #GP(0); FI;
IF ShadowStackEnabled(CPL)
IF IA32_EFER.LMA & CS.L
tempPushLIP = RIP
ELSE
tempPushLIP = CSBASE + EIP;
FI;
tempPushCS = CS;
FI;
IF OperandSize = 32
THEN
Push(CS); (* Padded with 16 high-order bits *)
CALL—Call Procedure
Vol. 2A
3-147
INSTRUCTION SET REFERENCE, A-L
Push(EIP);
CS := DEST(CodeSegmentSelector);
(* Segment descriptor information also loaded *)
CS(RPL) := CPL;
EIP := tempEIP;
ELSE
IF OperandSize = 16
THEN
Push(CS);
Push(IP);
CS := DEST(CodeSegmentSelector);
(* Segment descriptor information also loaded *)
CS(RPL) := CPL;
EIP := tempEIP;
ELSE (* OperandSize = 64 *)
Push(CS); (* Padded with 48 high-order bits *)
Push(RIP);
CS := DEST(CodeSegmentSelector);
(* Segment descriptor information also loaded *)
CS(RPL) := CPL;
RIP := tempEIP;
FI;
FI;
IF ShadowStackEnabled(CPL)
IF (IA32_EFER.LMA and DEST(CodeSegmentSelector).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;
(* align to 8 byte boundary if not already aligned *)
tempSSP = SSP;
Shadow_stack_store 4 bytes of 0 to (SSP - 4)
SSP = SSP & 0xFFFFFFFFFFFFFFF8H
ShadowStackPush8B(tempPushCS); (* Padded with 48 high-order 0 bits *)
ShadowStackPush8B(tempPushLIP); (* Padded 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;
END;
CALL-GATE:
IF call gate (DPL < CPL) or (RPL > DPL)
THEN #GP(call-gate selector); FI;
IF call gate not present
THEN #NP(call-gate selector); FI;
3-148
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
IF call-gate code-segment selector is NULL
THEN #GP(0); FI;
IF call-gate code-segment selector index is outside descriptor table limits
THEN #GP(call-gate code-segment selector); FI;
Read call-gate code-segment descriptor;
IF call-gate code-segment descriptor does not indicate a code segment
or call-gate code-segment descriptor DPL > CPL
THEN #GP(call-gate code-segment selector); FI;
IF IA32_EFER.LMA = 1 AND (call-gate code-segment descriptor is
not a 64-bit code segment or call-gate code-segment descriptor has both L-bit and D-bit set)
THEN #GP(call-gate code-segment selector); FI;
IF call-gate code segment not present
THEN #NP(call-gate code-segment selector); FI;
IF call-gate code segment is non-conforming and DPL < CPL
THEN go to MORE-PRIVILEGE;
ELSE go to SAME-PRIVILEGE;
FI;
END;
MORE-PRIVILEGE:
IF current TSS is 32-bit
THEN
TSSstackAddress := (new code-segment DPL ∗ 8) + 4;
IF (TSSstackAddress + 5) > current TSS limit
THEN #TS(current TSS selector); FI;
NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 4);
NewESP := 4 bytes loaded from (TSS base + TSSstackAddress);
ELSE
IF current TSS is 16-bit
THEN
TSSstackAddress := (new code-segment DPL ∗ 4) + 2
IF (TSSstackAddress + 3) > current TSS limit
THEN #TS(current TSS selector); FI;
NewSS := 2 bytes loaded from (TSS base + TSSstackAddress + 2);
NewESP := 2 bytes loaded from (TSS base + TSSstackAddress);
ELSE (* current TSS is 64-bit *)
TSSstackAddress := (new code-segment DPL ∗ 8) + 4;
IF (TSSstackAddress + 7) > current TSS limit
THEN #TS(current TSS selector); FI;
NewSS := new code-segment DPL; (* NULL selector with RPL = new CPL *)
NewRSP := 8 bytes loaded from (current TSS base + TSSstackAddress);
FI;
FI;
IF IA32_EFER.LMA = 0 and NewSS is NULL
THEN #TS(NewSS); FI;
Read new stack-segment descriptor;
IF IA32_EFER.LMA = 0 and (NewSS RPL new code-segment DPL
or new stack-segment DPL new code-segment DPL or new stack segment is not a
writable data segment)
THEN #TS(NewSS); FI
IF IA32_EFER.LMA = 0 and new stack segment not present
THEN #SS(NewSS); FI;
IF CallGateSize = 32
THEN
CALL—Call Procedure
Vol. 2A
3-149
INSTRUCTION SET REFERENCE, A-L
IF new stack does not have room for parameters plus 16 bytes
THEN #SS(NewSS); FI;
IF CallGate(InstructionPointer) not within new code-segment limit
THEN #GP(0); FI;
SS := newSS; (* Segment descriptor information also loaded *)
ESP := newESP;
CS:EIP := CallGate(CS:InstructionPointer);
(* Segment descriptor information also loaded *)
Push(oldSS:oldESP); (* From calling procedure *)
temp := parameter count from call gate, masked to 5 bits;
Push(parameters from calling procedure’s stack, temp)
Push(oldCS:oldEIP); (* Return address to calling procedure *)
ELSE
IF CallGateSize = 16
THEN
IF new stack does not have room for parameters plus 8 bytes
THEN #SS(NewSS); FI;
IF (CallGate(InstructionPointer) AND FFFFH) not in new code-segment limit
THEN #GP(0); FI;
SS := newSS; (* Segment descriptor information also loaded *)
ESP := newESP;
CS:IP := CallGate(CS:InstructionPointer);
(* Segment descriptor information also loaded *)
Push(oldSS:oldESP); (* From calling procedure *)
temp := parameter count from call gate, masked to 5 bits;
Push(parameters from calling procedure’s stack, temp)
Push(oldCS:oldEIP); (* Return address to calling procedure *)
ELSE (* CallGateSize = 64 *)
IF pushing 32 bytes on the stack would use a non-canonical address
THEN #SS(NewSS); FI;
IF (CallGate(InstructionPointer) is non-canonical)
THEN #GP(0); FI;
SS := NewSS; (* NewSS is NULL)
RSP := NewESP;
CS:IP := CallGate(CS:InstructionPointer);
(* Segment descriptor information also loaded *)
Push(oldSS:oldESP); (* From calling procedure *)
Push(oldCS:oldEIP); (* Return address to calling procedure *)
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 := CodeSegment(DPL)
CS(RPL) := CPL
IF ShadowStackEnabled(CPL)
oldSSP := SSP
SSP := IA32_PLi_SSP; (* where i is the CPL *)
IF SSP & 0x07 != 0 (* if SSP not aligned to 8 bytes then #GP *)
3-150
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
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;
END;
SAME-PRIVILEGE:
IF CallGateSize = 32
THEN
IF stack does not have room for 8 bytes
THEN #SS(0); FI;
IF CallGate(InstructionPointer) not within code segment limit
THEN #GP(0); FI;
CS:EIP := CallGate(CS:EIP) (* Segment descriptor information also loaded *)
Push(oldCS:oldEIP); (* Return address to calling procedure *)
ELSE
If CallGateSize = 16
THEN
IF stack does not have room for 4 bytes
THEN #SS(0); FI;
IF CallGate(InstructionPointer) not within code segment limit
THEN #GP(0); FI;
CS:IP := CallGate(CS:instruction pointer);
(* Segment descriptor information also loaded *)
Push(oldCS:oldIP); (* Return address to calling procedure *)
ELSE (* CallGateSize = 64)
IF pushing 16 bytes on the stack touches non-canonical addresses
THEN #SS(0); FI;
IF RIP non-canonical
THEN #GP(0); FI;
CS:IP := CallGate(CS:instruction pointer);
(* Segment descriptor information also loaded *)
Push(oldCS:oldIP); (* Return address to calling procedure *)
FI;
FI;
CS(RPL) := CPL
IF ShadowStackEnabled(CPL)
(* Align to next 8 byte boundary *)
CALL—Call Procedure
Vol. 2A
3-151
INSTRUCTION SET REFERENCE, A-L
tempSSP = SSP;
Shadow_stack_store 4 bytes of 0 to (SSP - 4)
SSP = SSP & 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;
END;
TASK-GATE:
IF task gate DPL < CPL or RPL
THEN #GP(task gate selector); FI;
IF task gate not present
THEN #NP(task 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
THEN #GP(TSS selector); FI;
Access TSS descriptor in GDT;
IF descriptor is not a TSS segment
THEN #GP(TSS selector); FI;
IF TSS descriptor specifies that the TSS is busy
THEN #GP(TSS selector); FI;
IF TSS not present
THEN #NP(TSS selector); FI;
SWITCH-TASKS (with nesting) to TSS;
IF EIP not within code segment limit
THEN #GP(0); FI;
END;
TASK-STATE-SEGMENT:
IF TSS DPL < CPL or 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 (with nesting) to TSS;
IF EIP not within code segment limit
THEN #GP(0); FI;
END;
3-152
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
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 the 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 gate 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.
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).
#GP(selector)
If a code segment or gate or TSS 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 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 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 a segment selector from a call gate does not indicate it is a code
segment.
If the segment selector from a call gate is beyond the descriptor table limits.
If the DPL for a code-segment obtained from a call gate is greater than the CPL.
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 pushing the return address, parameters, or stack segment pointer onto the stack exceeds
the bounds of the stack segment, when no stack switch occurs.
If a memory operand effective address is outside the SS segment limit.
#SS(selector)
If pushing the return address, parameters, or stack segment pointer onto the stack exceeds
the bounds of the stack segment, when a stack switch occurs.
If the SS register is being loaded as part of a stack switch and the segment pointed to is
marked not present.
If stack segment does not have room for the return address, parameters, or stack segment
pointer, when stack switch occurs.
#NP(selector)
If a code segment, data segment, call gate, task gate, or TSS is not present.
CALL—Call Procedure
Vol. 2A
3-153
INSTRUCTION SET REFERENCE, A-L
#TS(selector)
If the new stack segment selector and ESP are beyond the end of the TSS.
If the new stack segment selector is NULL.
If the RPL of the new stack segment selector in the TSS is not equal to the DPL of the code
segment being accessed.
If DPL of the stack segment descriptor for the new stack segment is not equal to the DPL of the
code segment descriptor.
If the new stack segment 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.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#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 the target offset is beyond the code segment limit.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the target offset is beyond the code segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
#GP(selector)
If a memory address accessed by the selector is in non-canonical space.
#GP(0)
If the target offset in the destination operand is non-canonical.
64-Bit Mode Exceptions
#GP(0)
If a memory address is non-canonical.
If target offset in destination operand is non-canonical.
If the segment selector in the destination operand is NULL.
If the code segment selector in the 64-bit gate is NULL.
If target mode is compatibility mode and SSP is not in low 4GB.
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 mode or compatibility mode, but SSP address in “super-visor
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).
3-154
Vol. 2A
CALL—Call Procedure
INSTRUCTION SET REFERENCE, A-L
#GP(selector)
If code segment or 64-bit call gate is outside descriptor table limits.
If code segment or 64-bit call gate overlaps 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, or 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 DPL for a code-segment obtained from a 64-bit call gate is greater than the CPL.
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.
#SS(0)
If pushing the return offset or CS selector onto the stack exceeds the bounds of the stack
segment when no stack switch occurs.
If a memory operand effective address is outside the SS segment limit.
If the stack address is in a non-canonical form.
#SS(selector)
If pushing the old values of SS selector, stack pointer, EFLAGS, CS selector, offset, or error
code onto the stack violates the canonical boundary when a stack switch occurs.
#NP(selector)
If a code segment or 64-bit call gate is not present.
#TS(selector)
If the load of the new RSP exceeds the limit of the TSS.
#UD
(64-bit mode only) If a far call 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.
CALL—Call Procedure
Vol. 2A
3-155
INSTRUCTION SET REFERENCE, A-L
CBW/CWDE/CDQE—Convert Byte to Word/Convert Word to Doubleword/Convert Doubleword to
Quadword
Opcode
Instruction
Op/
64-bit
Compat/
Description
En
Mode
Leg Mode
98
CBW
ZO
Valid
Valid
AX := sign-extend of AL.
98
CWDE
ZO
Valid
Valid
EAX := sign-extend of AX.
REX.W + 98
CDQE
ZO
Valid
N.E.
RAX := sign-extend of EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Double the size of the source operand by means of sign extension. The CBW (convert byte to word) instruction
copies the sign (bit 7) in the source operand into every bit in the AH register. The CWDE (convert word to double-
word) instruction copies the sign (bit 15) of the word in the AX register into the high 16 bits of the EAX register.
CBW and CWDE reference the same opcode. The CBW instruction is intended for use when the operand-size attri-
bute is 16; CWDE is intended for use when the operand-size attribute is 32. Some assemblers may force the
operand size. Others may treat these two mnemonics as synonyms (CBW/CWDE) and use the setting of the
operand-size attribute to determine the size of values to be converted.
In 64-bit mode, the default operation size is the size of the destination register. Use of the REX.W prefix promotes
this instruction (CDQE when promoted) to operate on 64-bit operands. In which case, CDQE copies the sign (bit 31)
of the doubleword in the EAX register into the high 32 bits of RAX.
Operation
IF OperandSize = 16 (* Instruction = CBW *)
THEN
AX := SignExtend(AL);
ELSE IF (OperandSize = 32, Instruction = CWDE)
EAX := SignExtend(AX); FI;
ELSE (* 64-Bit Mode, OperandSize = 64, Instruction = CDQE*)
RAX := SignExtend(EAX);
FI;
Flags Affected
None.
Exceptions (All Operating Modes)
#UD
If the LOCK prefix is used.
3-156
Vol. 2A
CBW/CWDE/CDQE—Convert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
INSTRUCTION SET REFERENCE, A-L
CLAC—Clear AC Flag in EFLAGS Register
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F 01 CA
ZO
V/V
SMAP
Clear the AC flag in the EFLAGS register.
CLAC
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Clears the AC flag bit in EFLAGS register. This disables any alignment checking of user-mode data accesses. If the
SMAP bit is set in the CR4 register, this disallows explicit supervisor-mode data accesses to user-mode pages.
This instruction's operation is the same in non-64-bit modes and 64-bit mode. Attempts to execute CLAC when
CPL > 0 cause #UD.
Operation
EFLAGS.AC := 0;
Flags Affected
AC cleared. Other flags are unaffected.
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If the CPL > 0.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
Virtual-8086 Mode Exceptions
#UD
The CLAC instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
If the LOCK prefix is used.
If the CPL > 0.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If the CPL > 0.
If CPUID.(EAX=07H, ECX=0H):EBX.SMAP[bit 20] = 0.
CLAC—Clear AC Flag in EFLAGS Register
Vol. 2A
3-157
INSTRUCTION SET REFERENCE, A-L
CLC—Clear Carry Flag
Opcode
Instruction
Op/
64-bit
Compat/
Description
En
Mode
Leg Mode
F8
CLC
ZO
Valid
Valid
Clear CF flag.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Clears the CF flag in the EFLAGS register. Operation is the same in all modes.
Operation
CF := 0;
Flags Affected
The CF flag is set to 0. The OF, ZF, SF, AF, and PF flags are unaffected.
Exceptions (All Operating Modes)
#UD
If the LOCK prefix is used.
3-158
Vol. 2A
CLC—Clear Carry Flag
INSTRUCTION SET REFERENCE, A-L
CLD—Clear Direction Flag
Opcode
Instruction
Op/
64-bit
Compat/
Description
En
Mode
Leg Mode
FC
CLD
ZO
Valid
Valid
Clear DF flag.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Clears the DF flag in the EFLAGS register. When the DF flag is set to 0, string operations increment the index regis-
ters (ESI and/or EDI). Operation is the same in all modes.
Operation
DF := 0;
Flags Affected
The DF flag is set to 0. The CF, OF, ZF, SF, AF, and PF flags are unaffected.
Exceptions (All Operating Modes)
#UD
If the LOCK prefix is used.
CLD—Clear Direction Flag
Vol. 2A
3-159
INSTRUCTION SET REFERENCE, A-L
CLDEMOTE—Cache Line Demote
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
NP 0F 1C /0
A
V/V
CLDEMOTE
Hint to hardware to move the cache line containing m8 to a
CLDEMOTE m8
more distant level of the cache without writing back to mem-
ory.
Instruction Operand Encoding1
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
A
ModRM:r/m (w)
N/A
N/A
N/A
Description
Hints to hardware that the cache line that contains the linear address specified with the memory operand should be
moved (“demoted”) from the cache(s) closest to the processor core to a level more distant from the processor core.
This may accelerate subsequent accesses to the line by other cores in the same coherence domain, especially if the
line was written by the core that demotes the line. Moving the line in such a manner is a performance optimization,
i.e., it is a hint which does not modify architectural state. Hardware may choose which level in the cache hierarchy
to retain the line (e.g., L3 in typical server designs). The source operand is a byte memory location.
The availability of the CLDEMOTE instruction is indicated by the presence of the CPUID feature flag CLDEMOTE (bit
25 of the ECX register in sub-leaf 07H, see “CPUID—CPU Identification”). On processors which do not support the
CLDEMOTE instruction (including legacy hardware) the instruction will be treated as a NOP.
A CLDEMOTE instruction is ordered with respect to stores to the same cache line, but unordered with respect to
other instructions including memory fences, CLDEMOTE, CLWB or CLFLUSHOPT instructions to a different cache
line. Since CLDEMOTE will retire in order with respect to stores to the same cache line, software should ensure that
after issuing CLDEMOTE the line is not accessed again immediately by the same core to avoid cache data move-
ment penalties.
The effective memory type of the page containing the affected line determines the effect; cacheable types are likely
to generate a data movement operation, while uncacheable types may cause the instruction to be ignored.
Speculative fetching can occur at any time and is not tied to instruction execution. The CLDEMOTE instruction is not
ordered with respect to PREFETCHh instructions or any of the speculative fetching mechanisms. That is, data can
be speculatively loaded into a cache line just before, during, or after the execution of a CLDEMOTE instruction that
references the cache line.
Unlike CLFLUSH, CLFLUSHOPT, and CLWB instructions, CLDEMOTE is not guaranteed to write back modified data to
memory.
The CLDEMOTE instruction may be ignored by hardware in certain cases and is not a guarantee.
The CLDEMOTE instruction can be used at all privilege levels. In certain processor implementations the CLDEMOTE
instruction may set the A bit but not the D bit in the page tables.
If the line is not found in the cache, the instruction will be treated as a NOP.
In some implementations, the CLDEMOTE instruction may always cause a transactional abort with Transactional
Synchronization Extensions (TSX). However, programmers must not rely on CLDEMOTE instruction to force a trans-
actional abort.
1. The Mod field of the ModR/M byte cannot have value 11B.
3-160
Vol. 2A
CLDEMOTE—Cache Line Demote
INSTRUCTION SET REFERENCE, A-L
Operation
Cache_Line_Demote(m8);
Flags Affected
None.
C/C++ Compiler Intrinsic Equivalent
CLDEMOTE void _cldemote(const void*);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#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
#UD
If the LOCK prefix is used.
CLDEMOTE—Cache Line Demote
Vol. 2A
3-161
INSTRUCTION SET REFERENCE, A-L
CLFLUSH—Flush Cache Line
Opcode /
Op/
64-bit
Compat/
Description
Instruction
En
Mode
Leg Mode
NP 0F AE /7
M
Valid
Valid
Flushes cache line containing m8.
CLFLUSH m8
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Invalidates from every level of the cache hierarchy in the cache coherence domain the cache line that contains the
linear address specified with the memory operand. If that cache line contains modified data at any level of the
cache hierarchy, that data is written back to memory. The source operand is a byte memory location.
The availability of CLFLUSH is indicated by the presence of the CPUID feature flag CLFSH
(CPUID.01H:EDX[bit 19]). The aligned cache line size affected is also indicated with the CPUID instruction (bits 8
through 15 of the EBX register when the initial value in the EAX register is 1).
The memory attribute of the page containing the affected line has no effect on the behavior of this instruction. It
should be noted that processors are free to speculatively fetch and cache data from system memory regions
assigned a memory-type allowing for speculative reads (such as, the WB, WC, and WT memory types). PREFETCHh
instructions can be used to provide the processor with hints for this speculative behavior. Because this speculative
fetching can occur at any time and is not tied to instruction execution, the CLFLUSH instruction is not ordered with
respect to PREFETCHh instructions or any of the speculative fetching mechanisms (that is, data can be specula-
tively loaded into a cache line just before, during, or after the execution of a CLFLUSH instruction that references
the cache line).
Executions of the CLFLUSH instruction are ordered with respect to each other and with respect to writes, locked
read-modify-write instructions, and fence instructions.1 They are not ordered with respect to executions of
CLFLUSHOPT and CLWB. Software can use the SFENCE instruction to order an execution of CLFLUSH relative to one
of those operations.
The CLFLUSH instruction can be used at all privilege levels and is subject to all permission checking and faults asso-
ciated with a byte load (and in addition, a CLFLUSH instruction is allowed to flush a linear address in an execute-
only segment). Like a load, the CLFLUSH instruction sets the A bit but not the D bit in the page tables.
In some implementations, the CLFLUSH instruction may always cause transactional abort with Transactional
Synchronization Extensions (TSX). The CLFLUSH instruction is not expected to be commonly used inside typical
transactional regions. However, programmers must not rely on CLFLUSH instruction to force a transactional abort,
since whether they cause transactional abort is implementation dependent.
The CLFLUSH instruction was introduced with the SSE2 extensions; however, because it has its own CPUID feature
flag, it can be implemented in IA-32 processors that do not include the SSE2 extensions. Also, detecting the pres-
ence of the SSE2 extensions with the CPUID instruction does not guarantee that the CLFLUSH instruction is imple-
mented in the processor.
CLFLUSH operation is the same in non-64-bit modes and 64-bit mode.
Operation
Flush_Cache_Line(SRC);
Intel C/C++ Compiler Intrinsic Equivalents
CLFLUSH: void _mm_clflush(void const *p)
1. Earlier versions of this manual specified that executions of the CLFLUSH instruction were ordered only by the MFENCE instruction.
All processors implementing the CLFLUSH instruction also order it relative to the other operations enumerated above.
3-162
Vol. 2A
CLFLUSH—Flush Cache Line
INSTRUCTION SET REFERENCE, A-L
Protected Mode Exceptions
#GP(0)
For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
#SS(0)
For an illegal address in the SS segment.
#PF(fault-code)
For a page fault.
#UD
If CPUID.01H:EDX.CLFSH[bit 19] = 0.
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If any part of the operand lies outside the effective address space from 0 to FFFFH.
#UD
If CPUID.01H:EDX.CLFSH[bit 19] = 0.
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.
#PF(fault-code)
For a page fault.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the memory address is in a non-canonical form.
#PF(fault-code)
For a page fault.
#UD
If CPUID.01H:EDX.CLFSH[bit 19] = 0.
If the LOCK prefix is used.
CLFLUSH—Flush Cache Line
Vol. 2A
3-163
INSTRUCTION SET REFERENCE, A-L
CLFLUSHOPT—Flush Cache Line Optimized
Opcode /
Op/
64-bit
Compat/
Description
Instruction
En
Mode
Leg Mode
NFx 66 0F AE /7
M
Valid
Valid
Flushes cache line containing m8.
CLFLUSHOPT m8
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Invalidates from every level of the cache hierarchy in the cache coherence domain the cache line that contains the
linear address specified with the memory operand. If that cache line contains modified data at any level of the
cache hierarchy, that data is written back to memory. The source operand is a byte memory location.
The availability of CLFLUSHOPT is indicated by the presence of the CPUID feature flag CLFLUSHOPT
(CPUID.(EAX=7,ECX=0):EBX[bit 23]). The aligned cache line size affected is also indicated with the CPUID instruc-
tion (bits 8 through 15 of the EBX register when the initial value in the EAX register is 1).
The memory attribute of the page containing the affected line has no effect on the behavior of this instruction. It
should be noted that processors are free to speculatively fetch and cache data from system memory regions
assigned a memory-type allowing for speculative reads (such as, the WB, WC, and WT memory types). PREFETCHh
instructions can be used to provide the processor with hints for this speculative behavior. Because this speculative
fetching can occur at any time and is not tied to instruction execution, the CLFLUSH instruction is not ordered with
respect to PREFETCHh instructions or any of the speculative fetching mechanisms (that is, data can be specula-
tively loaded into a cache line just before, during, or after the execution of a CLFLUSH instruction that references
the cache line).
Executions of the CLFLUSHOPT instruction are ordered with respect to fence instructions and to locked read-
modify-write instructions; they are also ordered with respect to older writes to the cache line being invalidated.
They are not ordered with respect to other executions of CLFLUSHOPT, to executions of CLFLUSH and CLWB, or to
younger writes to the cache line being invalidated. Software can use the SFENCE instruction to order an execution
of CLFLUSHOPT relative to one of those operations.
The CLFLUSHOPT instruction can be used at all privilege levels and is subject to all permission checking and faults
associated with a byte load (and in addition, a CLFLUSHOPT instruction is allowed to flush a linear address in an
execute-only segment). Like a load, the CLFLUSHOPT instruction sets the A bit but not the D bit in the page tables.
In some implementations, the CLFLUSHOPT instruction may always cause transactional abort with Transactional
Synchronization Extensions (TSX). The CLFLUSHOPT instruction is not expected to be commonly used inside typical
transactional regions. However, programmers must not rely on CLFLUSHOPT instruction to force a transactional
abort, since whether they cause transactional abort is implementation dependent.
CLFLUSHOPT operation is the same in non-64-bit modes and 64-bit mode.
Operation
Flush_Cache_Line_Optimized(SRC);
Intel C/C++ Compiler Intrinsic Equivalents
CLFLUSHOPT
void _mm_clflushopt(void const *p)
3-164
Vol. 2A
CLFLUSHOPT—Flush Cache Line Optimized
INSTRUCTION SET REFERENCE, A-L
Protected Mode Exceptions
#GP(0)
For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
#SS(0)
For an illegal address in the SS segment.
#PF(fault-code)
For a page fault.
#UD
If CPUID.(EAX=7,ECX=0):EBX.CLFLUSHOPT[bit 23] = 0.
If the LOCK prefix is used.
If an instruction prefix F2H or F3H is used.
Real-Address Mode Exceptions
#GP
If any part of the operand lies outside the effective address space from 0 to FFFFH.
#UD
If CPUID.(EAX=7,ECX=0):EBX.CLFLUSHOPT[bit 23] = 0.
If the LOCK prefix is used.
If an instruction prefix F2H or F3H is used.
Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.
#PF(fault-code)
For a page fault.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the memory address is in a non-canonical form.
#PF(fault-code)
For a page fault.
#UD
If CPUID.(EAX=7,ECX=0):EBX.CLFLUSHOPT[bit 23] = 0.
If the LOCK prefix is used.
If an instruction prefix F2H or F3H is used.
CLFLUSHOPT—Flush Cache Line Optimized
Vol. 2A
3-165
INSTRUCTION SET REFERENCE, A-L
CLI—Clear Interrupt Flag
Opcode
Instruction
Op/
64-bit
Compat/
Description
En
Mode
Leg Mode
FA
CLI
ZO
Valid
Valid
Clear interrupt flag; interrupts disabled when
interrupt flag cleared.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
In most cases, CLI clears the IF flag in the EFLAGS register and no other flags are affected. Clearing the IF flag
causes the processor to ignore maskable external interrupts. The IF flag and the CLI and STI instruction have no
effect on the generation of exceptions and NMI interrupts.
Operation is different in two modes defined as follows:
PVI mode (protected-mode virtual interrupts): CR0.PE = 1, EFLAGS.VM = 0, CPL = 3, and CR4.PVI = 1;
VME mode (virtual-8086 mode extensions): CR0.PE = 1, EFLAGS.VM = 1, and CR4.VME = 1.
If IOPL < 3 and either VME mode or PVI mode is active, CLI clears the VIF flag in the EFLAGS register, leaving IF
unaffected.
Table 3-7 indicates the action of the CLI instruction depending on the processor operating mode, IOPL, and CPL.
Table 3-7. Decision Table for CLI Results
Mode
IOPL
CLI Result
Real-address
X1
IF = 0
≥ CPL
IF = 0
Protected, not PVI2
< CPL
#GP fault
3
IF = 0
Protected, PVI3
0-2
VIF = 0
3
IF = 0
Virtual-8086, not VME3
0-2
#GP fault
3
IF = 0
Virtual-8086, VME3
0-2
VIF = 0
NOTES:
1. X = This setting has no effect on instruction operation.
2. For this table, “protected mode” applies whenever CR0.PE = 1 and EFLAGS.VM = 0; it includes compatibility mode and 64-bit mode.
3. PVI mode and virtual-8086 mode each imply CPL = 3.
3-166
Vol. 2A
CLI—Clear Interrupt Flag
INSTRUCTION SET REFERENCE, A-L
Operation
IF CR0.PE = 0
THEN IF := 0; (* Reset Interrupt Flag *)
ELSE
IF IOPL ≥ CPL (* CPL = 3 if EFLAGS.VM = 1 *)
THEN IF := 0; (* Reset Interrupt Flag *)
ELSE
IF VME mode OR PVI mode
THEN VIF := 0; (* Reset Virtual Interrupt Flag *)
ELSE #GP(0);
FI;
FI;
FI;
Flags Affected
Either the IF flag or the VIF flag is cleared to 0. Other flags are unaffected.
Protected Mode Exceptions
#GP(0)
If CPL is greater than IOPL and PVI mode is not active.
If CPL is greater than IOPL and less than 3.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If IOPL is less than 3 and VME mode is not active.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
CLI—Clear Interrupt Flag
Vol. 2A
3-167
INSTRUCTION SET REFERENCE, A-L
CLRSSBSY—Clear Busy Flag in a Supervisor Shadow Stack Token
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
F3 0F AE /6
M
V/V
CET_SS
Clear busy flag in supervisor shadow stack token
CLRSSBSY m64
reference by m64.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
M
N/A
ModRM:r/m (r, w)
N/A
N/A
N/A
Description
Clear busy flag in supervisor shadow stack token reference by m64. Subsequent to marking the shadow stack as
not busy the SSP is loaded with value 0.
Operation
IF (CR4.CET = 0)
THEN #UD; FI;
IF (IA32_S_CET.SH_STK_EN = 0)
THEN #UD; FI;
IF CPL > 0
THEN GP(0); FI;
SSP_LA = Linear_Address(mem operand)
IF SSP_LA not aligned to 8 bytes
THEN #GP(0); FI;
expected_token_value = SSP_LA | BUSY_BIT (* busy bit - bit position 0 - must be set *)
new_token_value = SSP_LA
(* Clear the busy bit *)
IF shadow_stack_lock_cmpxchg8b(SSP_LA, new_token_value, expected_token_value) != expected_token_value
invalid_token := 1; FI
(* Set the CF if invalid token was detected *)
RFLAGS.CF = (invalid_token == 1) ? 1 : 0;
RFLAGS.ZF,PF,AF,OF,SF := 0;
SSP := 0
Flags Affected
CF is set if an invalid token was detected, else it is cleared. ZF, PF, AF, OF, and SF are cleared.
3-168
Vol. 2A
CLRSSBSY—Clear Busy Flag in a Supervisor Shadow Stack Token
INSTRUCTION SET REFERENCE, A-L
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CR4.CET = 0.
IF IA32_S_CET.SH_STK_EN = 0.
#GP(0)
If memory operand linear address not aligned to 8 bytes.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If destination is located in a non-writeable segment.
If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
selector.
If CPL is not 0.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
Real-Address Mode Exceptions
#UD
The CLRSSBSY instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The CLRSSBSY instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
Same exceptions as in protected mode.
#GP(0)
Same exceptions as in protected mode.
#PF(fault-code)
If a page fault occurs.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CR4.CET = 0.
IF IA32_S_CET.SH_STK_EN = 0.
#GP(0)
If memory operand linear address not aligned to 8 bytes.
If CPL is not 0.
If the memory address is in a non-canonical form.
If token is invalid.
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#PF(fault-code)
If a page fault occurs.
CLRSSBSY—Clear Busy Flag in a Supervisor Shadow Stack Token
Vol. 2A
3-169
INSTRUCTION SET REFERENCE, A-L
CLTS—Clear Task-Switched Flag in CR0
Opcode
Instruction
Op/
64-bit
Compat/
Description
En
Mode
Leg Mode
0F 06
CLTS
ZO
Valid
Valid
Clears TS flag in CR0.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Clears the task-switched (TS) flag in the CR0 register. This instruction is intended for use in operating-system
procedures. It is a privileged instruction that can only be executed at a CPL of 0. It is allowed to be executed in real-
address mode to allow initialization for protected mode.
The processor sets the TS flag every time a task switch occurs. The flag is used to synchronize the saving of FPU
context in multitasking applications. See the description of the TS flag in the section titled “Control Registers” in
Chapter 2 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A, for more information
about this flag.
CLTS operation is the same in non-64-bit modes and 64-bit mode.
See Chapter 26, “VMX Non-Root Operation,” of the Intel® 64 and IA-32 Architectures Software Developer’s
Manual, Volume 3C, for more information about the behavior of this instruction in VMX non-root operation.
Operation
CR0.TS[bit 3] := 0;
Flags Affected
The TS flag in CR0 register is cleared.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
CLTS is not recognized in virtual-8086 mode.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#GP(0)
If the CPL is greater than 0.
#UD
If the LOCK prefix is used.
3-170
Vol. 2A
CLTS—Clear Task-Switched Flag in CR0
INSTRUCTION SET REFERENCE, A-L
CLUI—Clear User Interrupt Flag
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
F3 0F 01 EE
ZO
V/I
UINTR
Clear user interrupt flag; user interrupts blocked
CLUI
when user interrupt flag cleared.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
N/A
Description
CLUI clears the user interrupt flag (UIF). Its effect takes place immediately: a user interrupt cannot be delivered
on the instruction boundary following CLUI.
An execution of CLUI inside a transactional region causes a transactional abort; the abort loads EAX as it would
have had it been caused due to an execution of CLI.
Operation
UIF := 0;
Flags Affected
None.
Protected Mode Exceptions
#UD
The CLUI instruction is not recognized in protected mode.
Real-Address Mode Exceptions
#UD
The CLUI instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The CLUI instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
The CLUI instruction is not recognized in compatibility mode.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If executed inside an enclave.
If CR4.UINTR = 0.
If CPUID.07H.0H:EDX.UINTR[bit 5] = 0.
CLUI—Clear User Interrupt Flag
Vol. 2A
3-171
INSTRUCTION SET REFERENCE, A-L
CLWB—Cache Line Write Back
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
66 0F AE /6
M
V/V
CLWB
Writes back modified cache line containing m8, and may
CLWB m8
retain the line in cache hierarchy in non-modified state.
Instruction Operand Encoding1
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Writes back to memory the cache line (if modified) that contains the linear address specified with the memory
operand from any level of the cache hierarchy in the cache coherence domain. The line may be retained in the
cache hierarchy in non-modified state. Retaining the line in the cache hierarchy is a performance optimization
(treated as a hint by hardware) to reduce the possibility of cache miss on a subsequent access. Hardware may
choose to retain the line at any of the levels in the cache hierarchy, and in some cases, may invalidate the line from
the cache hierarchy. The source operand is a byte memory location.
The availability of CLWB instruction is indicated by the presence of the CPUID feature flag CLWB (bit 24 of the EBX
register, see “CPUID — CPU Identification” in this chapter). The aligned cache line size affected is also indicated
with the CPUID instruction (bits 8 through 15 of the EBX register when the initial value in the EAX register is 1).
The memory attribute of the page containing the affected line has no effect on the behavior of this instruction. It
should be noted that processors are free to speculatively fetch and cache data from system memory regions that
are assigned a memory-type allowing for speculative reads (such as, the WB, WC, and WT memory types).
PREFETCHh instructions can be used to provide the processor with hints for this speculative behavior. Because this
speculative fetching can occur at any time and is not tied to instruction execution, the CLWB instruction is not
ordered with respect to PREFETCHh instructions or any of the speculative fetching mechanisms (that is, data can
be speculatively loaded into a cache line just before, during, or after the execution of a CLWB instruction that refer-
ences the cache line).
Executions of the CLWB instruction are ordered with respect to fence instructions and to locked read-modify-write
instructions; they are also ordered with respect to older writes to the cache line being written back. They are not
ordered with respect to other executions of CLWB, to executions of CLFLUSH and CLFLUSHOPT, or to younger
writes to the cache line being written back. Software can use the SFENCE instruction to order an execution of CLWB
relative to one of those operations.
For usages that require only writing back modified data from cache lines to memory (do not require the line to be
invalidated), and expect to subsequently access the data, software is recommended to use CLWB (with appropriate
fencing) instead of CLFLUSH or CLFLUSHOPT for improved performance.
The CLWB instruction can be used at all privilege levels and is subject to all permission checking and faults associ-
ated with a byte load. Like a load, the CLWB instruction sets the accessed flag but not the dirty flag in the page
tables.
In some implementations, the CLWB instruction may always cause transactional abort with Transactional Synchro-
nization Extensions (TSX). CLWB instruction is not expected to be commonly used inside typical transactional
regions. However, programmers must not rely on CLWB instruction to force a transactional abort, since whether
they cause transactional abort is implementation dependent.
Operation
Cache_Line_Write_Back(m8);
1. The Mod field of the ModR/M byte cannot have value 11B.
3-172
Vol. 2A
CLWB—Cache Line Write Back
INSTRUCTION SET REFERENCE, A-L
Flags Affected
None.
C/C++ Compiler Intrinsic Equivalent
CLWB void _mm_clwb(void const *p);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.CLWB[bit 24] = 0.
#GP(0)
For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
#SS(0)
For an illegal address in the SS segment.
#PF(fault-code)
For a page fault.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.CLWB[bit 24] = 0.
#GP
If any part of the operand lies outside the effective address space from 0 to FFFFH.
Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.
#PF(fault-code)
For a page fault.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.CLWB[bit 24] = 0.
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the memory address is in a non-canonical form.
#PF(fault-code)
For a page fault.
CLWB—Cache Line Write Back
Vol. 2A
3-173
INSTRUCTION SET REFERENCE, A-L
CMC—Complement Carry Flag
Opcode
Instruction
Op/
64-bit
Compat/
Description
En
Mode
Leg Mode
F5
CMC
ZO
Valid
Valid
Complement CF flag.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Complements the CF flag in the EFLAGS register. CMC operation is the same in non-64-bit modes and 64-bit mode.
Operation
EFLAGS.CF[bit 0] := NOT EFLAGS.CF[bit 0];
Flags Affected
The CF flag contains the complement of its original value. The OF, ZF, SF, AF, and PF flags are unaffected.
Exceptions (All Operating Modes)
#UD
If the LOCK prefix is used.
3-174
Vol. 2A
CMC—Complement Carry Flag
INSTRUCTION SET REFERENCE, A-L
CMOVcc—Conditional Move
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 47 /r
CMOVA r16, r/m16
RM
Valid
Valid
Move if above (CF=0 and ZF=0).
0F 47 /r
CMOVA r32, r/m32
RM
Valid
Valid
Move if above (CF=0 and ZF=0).
REX.W + 0F 47 /r
CMOVA r64, r/m64
RM
Valid
N.E.
Move if above (CF=0 and ZF=0).
0F 43 /r
CMOVAE r16, r/m16
RM
Valid
Valid
Move if above or equal (CF=0).
0F 43 /r
CMOVAE r32, r/m32
RM
Valid
Valid
Move if above or equal (CF=0).
REX.W + 0F 43 /r
CMOVAE r64, r/m64
RM
Valid
N.E.
Move if above or equal (CF=0).
0F 42 /r
CMOVB r16, r/m16
RM
Valid
Valid
Move if below (CF=1).
0F 42 /r
CMOVB r32, r/m32
RM
Valid
Valid
Move if below (CF=1).
REX.W + 0F 42 /r
CMOVB r64, r/m64
RM
Valid
N.E.
Move if below (CF=1).
0F 46 /r
CMOVBE r16, r/m16
RM
Valid
Valid
Move if below or equal (CF=1 or ZF=1).
0F 46 /r
CMOVBE r32, r/m32
RM
Valid
Valid
Move if below or equal (CF=1 or ZF=1).
REX.W + 0F 46 /r
CMOVBE r64, r/m64
RM
Valid
N.E.
Move if below or equal (CF=1 or ZF=1).
0F 42 /r
CMOVC r16, r/m16
RM
Valid
Valid
Move if carry (CF=1).
0F 42 /r
CMOVC r32, r/m32
RM
Valid
Valid
Move if carry (CF=1).
REX.W + 0F 42 /r
CMOVC r64, r/m64
RM
Valid
N.E.
Move if carry (CF=1).
0F 44 /r
CMOVE r16, r/m16
RM
Valid
Valid
Move if equal (ZF=1).
0F 44 /r
CMOVE r32, r/m32
RM
Valid
Valid
Move if equal (ZF=1).
REX.W + 0F 44 /r
CMOVE r64, r/m64
RM
Valid
N.E.
Move if equal (ZF=1).
0F 4F /r
CMOVG r16, r/m16
RM
Valid
Valid
Move if greater (ZF=0 and SF=OF).
0F 4F /r
CMOVG r32, r/m32
RM
Valid
Valid
Move if greater (ZF=0 and SF=OF).
REX.W + 0F 4F /r
CMOVG r64, r/m64
RM
V/N.E.
N/A
Move if greater (ZF=0 and SF=OF).
0F 4D /r
CMOVGE r16, r/m16
RM
Valid
Valid
Move if greater or equal (SF=OF).
0F 4D /r
CMOVGE r32, r/m32
RM
Valid
Valid
Move if greater or equal (SF=OF).
REX.W + 0F 4D /r
CMOVGE r64, r/m64
RM
Valid
N.E.
Move if greater or equal (SF=OF).
0F 4C /r
CMOVL r16, r/m16
RM
Valid
Valid
Move if less (SF OF).
0F 4C /r
CMOVL r32, r/m32
RM
Valid
Valid
Move if less (SF OF).
REX.W + 0F 4C /r
CMOVL r64, r/m64
RM
Valid
N.E.
Move if less (SF OF).
0F 4E /r
CMOVLE r16, r/m16
RM
Valid
Valid
Move if less or equal (ZF=1 or SF OF).
0F 4E /r
CMOVLE r32, r/m32
RM
Valid
Valid
Move if less or equal (ZF=1 or SF OF).
REX.W + 0F 4E /r
CMOVLE r64, r/m64
RM
Valid
N.E.
Move if less or equal (ZF=1 or SF OF).
0F 46 /r
CMOVNA r16, r/m16
RM
Valid
Valid
Move if not above (CF=1 or ZF=1).
0F 46 /r
CMOVNA r32, r/m32
RM
Valid
Valid
Move if not above (CF=1 or ZF=1).
REX.W + 0F 46 /r
CMOVNA r64, r/m64
RM
Valid
N.E.
Move if not above (CF=1 or ZF=1).
0F 42 /r
CMOVNAE r16, r/m16
RM
Valid
Valid
Move if not above or equal (CF=1).
0F 42 /r
CMOVNAE r32, r/m32
RM
Valid
Valid
Move if not above or equal (CF=1).
REX.W + 0F 42 /r
CMOVNAE r64, r/m64
RM
Valid
N.E.
Move if not above or equal (CF=1).
0F 43 /r
CMOVNB r16, r/m16
RM
Valid
Valid
Move if not below (CF=0).
0F 43 /r
CMOVNB r32, r/m32
RM
Valid
Valid
Move if not below (CF=0).
REX.W + 0F 43 /r
CMOVNB r64, r/m64
RM
Valid
N.E.
Move if not below (CF=0).
0F 47 /r
CMOVNBE r16, r/m16
RM
Valid
Valid
Move if not below or equal (CF=0 and ZF=0).
CMOVcc—Conditional Move
Vol. 2A
3-175
INSTRUCTION SET REFERENCE, A-L
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 47 /r
CMOVNBE r32, r/m32
RM
Valid
Valid
Move if not below or equal (CF=0 and ZF=0).
REX.W + 0F 47 /r
CMOVNBE r64, r/m64
RM
Valid
N.E.
Move if not below or equal (CF=0 and ZF=0).
0F 43 /r
CMOVNC r16, r/m16
RM
Valid
Valid
Move if not carry (CF=0).
0F 43 /r
CMOVNC r32, r/m32
RM
Valid
Valid
Move if not carry (CF=0).
REX.W + 0F 43 /r
CMOVNC r64, r/m64
RM
Valid
N.E.
Move if not carry (CF=0).
0F 45 /r
CMOVNE r16, r/m16
RM
Valid
Valid
Move if not equal (ZF=0).
0F 45 /r
CMOVNE r32, r/m32
RM
Valid
Valid
Move if not equal (ZF=0).
REX.W + 0F 45 /r
CMOVNE r64, r/m64
RM
Valid
N.E.
Move if not equal (ZF=0).
0F 4E /r
CMOVNG r16, r/m16
RM
Valid
Valid
Move if not greater (ZF=1 or SF OF).
0F 4E /r
CMOVNG r32, r/m32
RM
Valid
Valid
Move if not greater (ZF=1 or SF OF).
REX.W + 0F 4E /r
CMOVNG r64, r/m64
RM
Valid
N.E.
Move if not greater (ZF=1 or SF OF).
0F 4C /r
CMOVNGE r16, r/m16
RM
Valid
Valid
Move if not greater or equal (SF OF).
0F 4C /r
CMOVNGE r32, r/m32
RM
Valid
Valid
Move if not greater or equal (SF OF).
REX.W + 0F 4C /r
CMOVNGE r64, r/m64
RM
Valid
N.E.
Move if not greater or equal (SF OF).
0F 4D /r
CMOVNL r16, r/m16
RM
Valid
Valid
Move if not less (SF=OF).
0F 4D /r
CMOVNL r32, r/m32
RM
Valid
Valid
Move if not less (SF=OF).
REX.W + 0F 4D /r
CMOVNL r64, r/m64
RM
Valid
N.E.
Move if not less (SF=OF).
0F 4F /r
CMOVNLE r16, r/m16
RM
Valid
Valid
Move if not less or equal (ZF=0 and SF=OF).
0F 4F /r
CMOVNLE r32, r/m32
RM
Valid
Valid
Move if not less or equal (ZF=0 and SF=OF).
REX.W + 0F 4F /r
CMOVNLE r64, r/m64
RM
Valid
N.E.
Move if not less or equal (ZF=0 and SF=OF).
0F 41 /r
CMOVNO r16, r/m16
RM
Valid
Valid
Move if not overflow (OF=0).
0F 41 /r
CMOVNO r32, r/m32
RM
Valid
Valid
Move if not overflow (OF=0).
REX.W + 0F 41 /r
CMOVNO r64, r/m64
RM
Valid
N.E.
Move if not overflow (OF=0).
0F 4B /r
CMOVNP r16, r/m16
RM
Valid
Valid
Move if not parity (PF=0).
0F 4B /r
CMOVNP r32, r/m32
RM
Valid
Valid
Move if not parity (PF=0).
REX.W + 0F 4B /r
CMOVNP r64, r/m64
RM
Valid
N.E.
Move if not parity (PF=0).
0F 49 /r
CMOVNS r16, r/m16
RM
Valid
Valid
Move if not sign (SF=0).
0F 49 /r
CMOVNS r32, r/m32
RM
Valid
Valid
Move if not sign (SF=0).
REX.W + 0F 49 /r
CMOVNS r64, r/m64
RM
Valid
N.E.
Move if not sign (SF=0).
0F 45 /r
CMOVNZ r16, r/m16
RM
Valid
Valid
Move if not zero (ZF=0).
0F 45 /r
CMOVNZ r32, r/m32
RM
Valid
Valid
Move if not zero (ZF=0).
REX.W + 0F 45 /r
CMOVNZ r64, r/m64
RM
Valid
N.E.
Move if not zero (ZF=0).
0F 40 /r
CMOVO r16, r/m16
RM
Valid
Valid
Move if overflow (OF=1).
0F 40 /r
CMOVO r32, r/m32
RM
Valid
Valid
Move if overflow (OF=1).
REX.W + 0F 40 /r
CMOVO r64, r/m64
RM
Valid
N.E.
Move if overflow (OF=1).
0F 4A /r
CMOVP r16, r/m16
RM
Valid
Valid
Move if parity (PF=1).
0F 4A /r
CMOVP r32, r/m32
RM
Valid
Valid
Move if parity (PF=1).
REX.W + 0F 4A /r
CMOVP r64, r/m64
RM
Valid
N.E.
Move if parity (PF=1).
0F 4A /r
CMOVPE r16, r/m16
RM
Valid
Valid
Move if parity even (PF=1).
0F 4A /r
CMOVPE r32, r/m32
RM
Valid
Valid
Move if parity even (PF=1).
REX.W + 0F 4A /r
CMOVPE r64, r/m64
RM
Valid
N.E.
Move if parity even (PF=1).
3-176
Vol. 2A
CMOVcc—Conditional Move
INSTRUCTION SET REFERENCE, A-L
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 4B /r
CMOVPO r16, r/m16
RM
Valid
Valid
Move if parity odd (PF=0).
0F 4B /r
CMOVPO r32, r/m32
RM
Valid
Valid
Move if parity odd (PF=0).
REX.W + 0F 4B /r
CMOVPO r64, r/m64
RM
Valid
N.E.
Move if parity odd (PF=0).
0F 48 /r
CMOVS r16, r/m16
RM
Valid
Valid
Move if sign (SF=1).
0F 48 /r
CMOVS r32, r/m32
RM
Valid
Valid
Move if sign (SF=1).
REX.W + 0F 48 /r
CMOVS r64, r/m64
RM
Valid
N.E.
Move if sign (SF=1).
0F 44 /r
CMOVZ r16, r/m16
RM
Valid
Valid
Move if zero (ZF=1).
0F 44 /r
CMOVZ r32, r/m32
RM
Valid
Valid
Move if zero (ZF=1).
REX.W + 0F 44 /r
CMOVZ r64, r/m64
RM
Valid
N.E.
Move if zero (ZF=1).
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
Description
Each of the CMOVcc instructions performs a move operation if the status flags in the EFLAGS register (CF, OF, PF,
SF, and ZF) are in a specified state (or condition). A condition code (cc) is associated with each instruction to indi-
cate the condition being tested for. If the condition is not satisfied, a move is not performed and execution
continues with the instruction following the CMOVcc instruction.
Specifically, CMOVcc loads data from its source operand into a temporary register unconditionally (regardless of
the condition code and the status flags in the EFLAGS register). If the condition code associated with the instruction
(cc) is satisfied, the data in the temporary register is then copied into the instruction's destination operand.
These instructions can move 16-bit, 32-bit or 64-bit values from memory to a general-purpose register or from one
general-purpose register to another. Conditional moves of 8-bit register operands are not supported.
The condition for each CMOVcc mnemonic is given in the description column of the above table. 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 CMOVA (conditional move if above) instruction and the CMOVNBE
(conditional move if not below or equal) instruction are alternate mnemonics for the opcode 0F 47H.
The CMOVcc instructions were introduced in P6 family processors; however, these instructions may not be
supported by all IA-32 processors. Software can determine if the CMOVcc instructions are supported by checking
the processor’s feature information with the CPUID instruction (see “CPUID—CPU Identification” in this chapter).
In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to addi-
tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the
beginning of this section for encoding data and limits.
Operation
temp := SRC
IF condition TRUE
THEN DEST := temp;
ELSE IF (OperandSize = 32 and IA-32e mode active)
THEN DEST[63:32] := 0;
FI;
CMOVcc—Conditional Move
Vol. 2A
3-177
INSTRUCTION SET REFERENCE, A-L
Flags Affected
None.
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 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 an unaligned memory reference is made while the
current privilege level is 3.
#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.
#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 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.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the memory address is in a non-canonical form.
#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.
#UD
If the LOCK prefix is used.
3-178
Vol. 2A
CMOVcc—Conditional Move
INSTRUCTION SET REFERENCE, A-L
CMP—Compare Two Operands
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
3C ib
CMP AL, imm8
I
Valid
Valid
Compare imm8 with AL.
3D iw
CMP AX, imm16
I
Valid
Valid
Compare imm16 with AX.
3D id
CMP EAX, imm32
I
Valid
Valid
Compare imm32 with EAX.
REX.W + 3D id
CMP RAX, imm32
I
Valid
N.E.
Compare imm32 sign-extended to 64-bits
with RAX.
80 /7 ib
CMP r/m8, imm8
MI
Valid
Valid
Compare imm8 with r/m8.
REX + 80 /7 ib
CMP r/m8*, imm8
MI
Valid
N.E.
Compare imm8 with r/m8.
81 /7 iw
CMP r/m16, imm16
MI
Valid
Valid
Compare imm16 with r/m16.
81 /7 id
CMP r/m32, imm32
MI
Valid
Valid
Compare imm32 with r/m32.
REX.W + 81 /7 id
CMP r/m64, imm32
MI
Valid
N.E.
Compare imm32 sign-extended to 64-bits
with r/m64.
83 /7 ib
CMP r/m16, imm8
MI
Valid
Valid
Compare imm8 with r/m16.
83 /7 ib
CMP r/m32, imm8
MI
Valid
Valid
Compare imm8 with r/m32.
REX.W + 83 /7 ib
CMP r/m64, imm8
MI
Valid
N.E.
Compare imm8 with r/m64.
38 /r
CMP r/m8, r8
MR
Valid
Valid
Compare r8 with r/m8.
REX + 38 /r
CMP r/m8*, r8*
MR
Valid
N.E.
Compare r8 with r/m8.
39 /r
CMP r/m16, r16
MR
Valid
Valid
Compare r16 with r/m16.
39 /r
CMP r/m32, r32
MR
Valid
Valid
Compare r32 with r/m32.
REX.W + 39 /r
CMP r/m64,r64
MR
Valid
N.E.
Compare r64 with r/m64.
3A /r
CMP r8, r/m8
RM
Valid
Valid
Compare r/m8 with r8.
REX + 3A /r
CMP r8*, r/m8*
RM
Valid
N.E.
Compare r/m8 with r8.
3B /r
CMP r16, r/m16
RM
Valid
Valid
Compare r/m16 with r16.
3B /r
CMP r32, r/m32
RM
Valid
Valid
Compare r/m32 with r32.
REX.W + 3B /r
CMP r64, r/m64
RM
Valid
N.E.
Compare r/m64 with r64.
NOTES:
* In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
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
MR
ModRM:r/m (r)
ModRM:reg (r)
N/A
N/A
MI
ModRM:r/m (r)
imm8/16/32
N/A
N/A
I
AL/AX/EAX/RAX (r)
imm8/16/32
N/A
N/A
Description
Compares the first source operand with the second source operand and sets the status flags in the EFLAGS register
according to the results. The comparison is performed by subtracting the second operand from the first operand
and then setting the status flags in the same manner as the SUB instruction. When an immediate value is used as
an operand, it is sign-extended to the length of the first operand.
The condition codes used by the Jcc, CMOVcc, and SETcc instructions are based on the results of a CMP instruction.
Appendix B, “EFLAGS Condition Codes,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual,
Volume 1, shows the relationship of the status flags and the condition codes.
CMP—Compare Two Operands
Vol. 2A
3-179
INSTRUCTION SET REFERENCE, A-L
In 64-bit mode, the instruction’s default operation size is 32 bits. Use of the REX.R prefix permits access to addi-
tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. See the summary chart at the
beginning of this section for encoding data and limits.
Operation
temp := SRC1 − SignExtend(SRC2);
ModifyStatusFlags; (* Modify status flags in the same manner as the SUB instruction*)
Flags Affected
The CF, OF, SF, ZF, AF, and PF flags are set according to the result.
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 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 an unaligned memory reference is made while the
current privilege level is 3.
#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.
#SS
If a memory operand effective address is outside the SS segment limit.
Virtual-8086 Mode Exceptions
#GP(0)
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.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the memory address is in a non-canonical form.
#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.
#UD
If the LOCK prefix is used.
3-180
Vol. 2A
CMP—Compare Two Operands
INSTRUCTION SET REFERENCE, A-L
CMPPD—Compare Packed Double Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
66 0F C2 /r ib
A
V/V
SSE2
Compare packed double precision floating-point values
CMPPD xmm1, xmm2/m128, imm8
in xmm2/m128 and xmm1 using bits 2:0 of imm8 as a
comparison predicate.
VEX.128.66.0F.WIG C2 /r ib
B
V/V
AVX
Compare packed double precision floating-point values
VCMPPD xmm1, xmm2, xmm3/m128,
in xmm3/m128 and xmm2 using bits 4:0 of imm8 as a
imm8
comparison predicate.
VEX.256.66.0F.WIG C2 /r ib
B
V/V
AVX
Compare packed double precision floating-point values
VCMPPD ymm1, ymm2, ymm3/m256,
in ymm3/m256 and ymm2 using bits 4:0 of imm8 as a
imm8
comparison predicate.
EVEX.128.66.0F.W1 C2 /r ib
C
V/V
AVX512VL
Compare packed double precision floating-point values
VCMPPD k1 {k2}, xmm2,
AVX512F
in xmm3/m128/m64bcst and xmm2 using bits 4:0 of
xmm3/m128/m64bcst, imm8
imm8 as a comparison predicate with writemask k2
and leave the result in mask register k1.
EVEX.256.66.0F.W1 C2 /r ib
C
V/V
AVX512VL
Compare packed double precision floating-point values
VCMPPD k1 {k2}, ymm2,
AVX512F
in ymm3/m256/m64bcst and ymm2 using bits 4:0 of
ymm3/m256/m64bcst, imm8
imm8 as a comparison predicate with writemask k2
and leave the result in mask register k1.
EVEX.512.66.0F.W1 C2 /r ib
C
V/V
AVX512F
Compare packed double precision floating-point values
VCMPPD k1 {k2}, zmm2,
in zmm3/m512/m64bcst and zmm2 using bits 4:0 of
zmm3/m512/m64bcst{sae}, imm8
imm8 as a comparison predicate with writemask k2
and leave the result in mask register k1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
imm8
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Performs a SIMD compare of the packed double precision floating-point values in the second source operand and
the first source operand and returns the result of the comparison to the destination operand. The comparison pred-
icate operand (immediate byte) specifies the type of comparison performed on each pair of packed values in the
two source operands.
EVEX encoded versions: The first source operand (second operand) is a ZMM/YMM/XMM register. The second
source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector
broadcasted from a 64-bit memory location. The destination operand (first operand) is an opmask register.
Comparison results are written to the destination operand under the writemask k2. Each comparison result is a
single mask bit of 1 (comparison true) or 0 (comparison false).
VEX.256 encoded version: The first source operand (second operand) is a YMM register. The second source
operand (third operand) can be a YMM register or a 256-bit memory location. The destination operand (first
operand) is a YMM register. Four comparisons are performed with results written to the destination operand. The
result of each comparison is a quadword mask of all 1s (comparison true) or all 0s (comparison false).
128-bit Legacy SSE version: The first source and destination operand (first operand) is an XMM register. The
second source operand (second operand) can be an XMM register or 128-bit memory location. Bits (MAXVL-1:128)
of the corresponding ZMM destination register remain unchanged. Two comparisons are performed with results
written to bits 127:0 of the destination operand. The result of each comparison is a quadword mask of all 1s
(comparison true) or all 0s (comparison false).
CMPPD—Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-181
INSTRUCTION SET REFERENCE, A-L
VEX.128 encoded version: The first source operand (second operand) is an XMM register. The second source
operand (third operand) can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destina-
tion ZMM register are zeroed. Two comparisons are performed with results written to bits 127:0 of the destination
operand.
The comparison predicate operand is an 8-bit immediate:
For instructions encoded using the VEX or EVEX prefix, bits 4:0 define the type of comparison to be performed
(see Table 3-1). Bits 5 through 7 of the immediate are reserved.
For instruction encodings that do not use VEX prefix, bits 2:0 define the type of comparison to be made (see the
first 8 rows of Table 3-1). Bits 3 through 7 of the immediate are reserved.
Table 3-1. Comparison Predicate for CMPPD and CMPPS Instructions
Predicate
imm8
Description
Result: A Is 1st Operand, B Is 2nd Operand
Signals
Value
#IA on
A >B
A < B
A = B
Unordered1
QNAN
EQ_OQ (EQ)
0H
Equal (ordered, non-signaling)
False
False
True
False
No
LT_OS (LT)
1H
Less-than (ordered, signaling)
False
True
False
False
Yes
LE_OS (LE)
2H
Less-than-or-equal (ordered, signaling)
False
True
True
False
Yes
UNORD_Q (UNORD)
3H
Unordered (non-signaling)
False
False
False
True
No
NEQ_UQ (NEQ)
4H
Not-equal (unordered, non-signaling)
True
True
False
True
No
NLT_US (NLT)
5H
Not-less-than (unordered, signaling)
True
False
True
True
Yes
NLE_US (NLE)
6H
Not-less-than-or-equal (unordered, signaling)
True
False
False
True
Yes
ORD_Q (ORD)
7H
Ordered (non-signaling)
True
True
True
False
No
EQ_UQ
8H
Equal (unordered, non-signaling)
False
False
True
True
No
NGE_US (NGE)
9H
Not-greater-than-or-equal (unordered,
False
True
False
True
Yes
signaling)
NGT_US (NGT)
AH
Not-greater-than (unordered, signaling)
False
True
True
True
Yes
FALSE_OQ(FALSE)
BH
False (ordered, non-signaling)
False
False
False
False
No
NEQ_OQ
CH
Not-equal (ordered, non-signaling)
True
True
False
False
No
GE_OS (GE)
DH
Greater-than-or-equal (ordered, signaling)
True
False
True
False
Yes
GT_OS (GT)
EH
Greater-than (ordered, signaling)
True
False
False
False
Yes
TRUE_UQ(TRUE)
FH
True (unordered, non-signaling)
True
True
True
True
No
EQ_OS
10H
Equal (ordered, signaling)
False
False
True
False
Yes
LT_OQ
11H
Less-than (ordered, nonsignaling)
False
True
False
False
No
LE_OQ
12H
Less-than-or-equal (ordered, nonsignaling)
False
True
True
False
No
UNORD_S
13H
Unordered (signaling)
False
False
False
True
Yes
NEQ_US
14H
Not-equal (unordered, signaling)
True
True
False
True
Yes
NLT_UQ
15H
Not-less-than (unordered, nonsignaling)
True
False
True
True
No
NLE_UQ
16H
Not-less-than-or-equal (unordered, nonsig-
True
False
False
True
No
naling)
ORD_S
17H
Ordered (signaling)
True
True
True
False
Yes
EQ_US
18H
Equal (unordered, signaling)
False
False
True
True
Yes
NGE_UQ
19H
Not-greater-than-or-equal (unordered, non-
False
True
False
True
No
signaling)
3-182
Vol. 2A
CMPPD—Compare Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, A-L
Table 3-1. Comparison Predicate for CMPPD and CMPPS Instructions (Contd.)
Predicate
imm8
Description
Result: A Is 1st Operand, B Is 2nd Operand
Signals
Value
#IA on
A >B
A < B
A = B
Unordered1
QNAN
NGT_UQ
1AH
Not-greater-than (unordered, nonsignaling)
False
True
True
True
No
FALSE_OS
1BH
False (ordered, signaling)
False
False
False
False
Yes
NEQ_OS
1CH
Not-equal (ordered, signaling)
True
True
False
False
Yes
GE_OQ
1DH
Greater-than-or-equal (ordered, nonsignal-
True
False
True
False
No
ing)
GT_OQ
1EH
Greater-than (ordered, nonsignaling)
True
False
False
False
No
TRUE_US
1FH
True (unordered, signaling)
True
True
True
True
Yes
NOTES:
1. If either operand A or B is a NAN.
The unordered relationship is true when at least one of the two source operands being compared is a NaN; the
ordered relationship is true when neither source operand is a NaN.
A subsequent computational instruction that uses the mask result in the destination operand as an input operand
will not generate an exception, because a mask of all 0s corresponds to a floating-point value of +0.0 and a mask
of all 1s corresponds to a QNaN.
Note that processors with “CPUID.1H:ECX.AVX =0” do not implement the “greater-than”, “greater-than-or-equal”,
“not-greater than”, and “not-greater-than-or-equal relations” predicates. These comparisons can be made either
by using the inverse relationship (that is, use the “not-less-than-or-equal” to make a “greater-than” comparison)
or by using software emulation. When using software emulation, the program must swap the operands (copying
registers when necessary to protect the data that will now be in the destination), and then perform the compare
using a different predicate. The predicate to be used for these emulations is listed in the first 8 rows of Table 3-7
(Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2A) under the heading Emulation.
Compilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand
CMPPD instruction, for processors with “CPUID.1H:ECX.AVX =0”. See Table 3-2. The compiler should treat
reserved imm8 values as illegal syntax.
:
Table 3-2. Pseudo-Op and CMPPD Implementation
Pseudo-Op
CMPPD Implementation
CMPEQPD xmm1, xmm2
CMPPD xmm1, xmm2, 0
CMPLTPD xmm1, xmm2
CMPPD xmm1, xmm2, 1
CMPLEPD xmm1, xmm2
CMPPD xmm1, xmm2, 2
CMPUNORDPD xmm1, xmm2
CMPPD xmm1, xmm2, 3
CMPNEQPD xmm1, xmm2
CMPPD xmm1, xmm2, 4
CMPNLTPD xmm1, xmm2
CMPPD xmm1, xmm2, 5
CMPNLEPD xmm1, xmm2
CMPPD xmm1, xmm2, 6
CMPORDPD xmm1, xmm2
CMPPD xmm1, xmm2, 7
The greater-than relations that the processor does not implement require more than one instruction to emulate in
software and therefore should not be implemented as pseudo-ops. (For these, the programmer should reverse the
operands of the corresponding less than relations and use move instructions to ensure that the mask is moved to
the correct destination register and that the source operand is left intact.)
Processors with “CPUID.1H:ECX.AVX =1” implement the full complement of 32 predicates shown in Table 3-3, soft-
ware emulation is no longer needed. Compilers and assemblers may implement the following three-operand
pseudo-ops in addition to the four-operand VCMPPD instruction. See Table 3-3, where the notations of reg1 reg2,
and reg3 represent either XMM registers or YMM registers. The compiler should treat reserved imm8 values as
CMPPD—Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-183
INSTRUCTION SET REFERENCE, A-L
illegal syntax. Alternately, intrinsics can map the pseudo-ops to pre-defined constants to support a simpler intrinsic
interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded VCMPPD
instructions in a similar fashion by extending the syntax listed in Table 3-3.
:
Table 3-3. Pseudo-Op and VCMPPD Implementation
Pseudo-Op
CMPPD Implementation
VCMPEQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
0
VCMPLTPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
1
VCMPLEPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
2
VCMPUNORDPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
3
VCMPNEQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3, 4
VCMPNLTPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
5
VCMPNLEPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
6
VCMPORDPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
7
VCMPEQ_UQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
8
VCMPNGEPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
9
VCMPNGTPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
0AH
VCMPFALSEPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
0BH
VCMPNEQ_OQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3, 0CH
VCMPGEPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
0DH
VCMPGTPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
0EH
VCMPTRUEPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
0FH
VCMPEQ_OSPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
10H
VCMPLT_OQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
11H
VCMPLE_OQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
12H
VCMPUNORD_SPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
13H
VCMPNEQ_USPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3, 14H
VCMPNLT_UQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
15H
VCMPNLE_UQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
16H
VCMPORD_SPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
17H
VCMPEQ_USPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
18H
VCMPNGE_UQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
19H
VCMPNGT_UQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
1AH
VCMPFALSE_OSPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
1BH
VCMPNEQ_OSPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3, 1CH
VCMPGE_OQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
1DH
VCMPGT_OQPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
1EH
VCMPTRUE_USPD reg1, reg2, reg3
VCMPPD reg1, reg2, reg3,
1FH
3-184
Vol. 2A
CMPPD—Compare Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, A-L
Operation
CASE (COMPARISON PREDICATE) OF
0: OP3 := EQ_OQ; OP5 := EQ_OQ;
1: OP3 := LT_OS; OP5 := LT_OS;
2: OP3 := LE_OS; OP5 := LE_OS;
3: OP3 := UNORD_Q; OP5 := UNORD_Q;
4: OP3 := NEQ_UQ; OP5 := NEQ_UQ;
5: OP3 := NLT_US; OP5 := NLT_US;
6: OP3 := NLE_US; OP5 := NLE_US;
7: OP3 := ORD_Q; OP5 := ORD_Q;
8: OP5 := EQ_UQ;
9: OP5 := NGE_US;
10: OP5 := NGT_US;
11: OP5 := FALSE_OQ;
12: OP5 := NEQ_OQ;
13: OP5 := GE_OS;
14: OP5 := GT_OS;
15: OP5 := TRUE_UQ;
16: OP5 := EQ_OS;
17: OP5 := LT_OQ;
18: OP5 := LE_OQ;
19: OP5 := UNORD_S;
20: OP5 := NEQ_US;
21: OP5 := NLT_UQ;
22: OP5 := NLE_UQ;
23: OP5 := ORD_S;
24: OP5 := EQ_US;
25: OP5 := NGE_UQ;
26: OP5 := NGT_UQ;
27: OP5 := FALSE_OS;
28: OP5 := NEQ_OS;
29: OP5 := GE_OQ;
30: OP5 := GT_OQ;
31: OP5 := TRUE_US;
DEFAULT: Reserved;
ESAC;
CMPPD—Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-185
INSTRUCTION SET REFERENCE, A-L
VCMPPD (EVEX encoded versions)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k2[j] OR *no writemask*
THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN
CMP := SRC1[i+63:i] OP5 SRC2[63:0]
ELSE
CMP := SRC1[i+63:i] OP5 SRC2[i+63:i]
FI;
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking only
FI;
ENDFOR
DEST[MAX_KL-1:KL] := 0
VCMPPD (VEX.256 encoded version)
CMP0 := SRC1[63:0] OP5 SRC2[63:0];
CMP1 := SRC1[127:64] OP5 SRC2[127:64];
CMP2 := SRC1[191:128] OP5 SRC2[191:128];
CMP3 := SRC1[255:192] OP5 SRC2[255:192];
IF CMP0 = TRUE
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0000000000000000H; FI;
IF CMP1 = TRUE
THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;
ELSE DEST[127:64] := 0000000000000000H; FI;
IF CMP2 = TRUE
THEN DEST[191:128] := FFFFFFFFFFFFFFFFH;
ELSE DEST[191:128] := 0000000000000000H; FI;
IF CMP3 = TRUE
THEN DEST[255:192] := FFFFFFFFFFFFFFFFH;
ELSE DEST[255:192] := 0000000000000000H; FI;
DEST[MAXVL-1:256] := 0
VCMPPD (VEX.128 encoded version)
CMP0 := SRC1[63:0] OP5 SRC2[63:0];
CMP1 := SRC1[127:64] OP5 SRC2[127:64];
IF CMP0 = TRUE
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0000000000000000H; FI;
IF CMP1 = TRUE
THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;
ELSE DEST[127:64] := 0000000000000000H; FI;
DEST[MAXVL-1:128] := 0
3-186
Vol. 2A
CMPPD—Compare Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, A-L
CMPPD (128-bit Legacy SSE version)
CMP0 := SRC1[63:0] OP3 SRC2[63:0];
CMP1 := SRC1[127:64] OP3 SRC2[127:64];
IF CMP0 = TRUE
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0000000000000000H; FI;
IF CMP1 = TRUE
THEN DEST[127:64] := FFFFFFFFFFFFFFFFH;
ELSE DEST[127:64] := 0000000000000000H; FI;
DEST[MAXVL-1:128] (Unmodified)
Intel C/C++ Compiler Intrinsic Equivalent
VCMPPD __mmask8 _mm512_cmp_pd_mask( __m512d a, __m512d b, int imm);
VCMPPD __mmask8 _mm512_cmp_round_pd_mask( __m512d a, __m512d b, int imm, int sae);
VCMPPD __mmask8 _mm512_mask_cmp_pd_mask( __mmask8 k1, __m512d a, __m512d b, int imm);
VCMPPD __mmask8 _mm512_mask_cmp_round_pd_mask( __mmask8 k1, __m512d a, __m512d b, int imm, int sae);
VCMPPD __mmask8 _mm256_cmp_pd_mask( __m256d a, __m256d b, int imm);
VCMPPD __mmask8 _mm256_mask_cmp_pd_mask( __mmask8 k1, __m256d a, __m256d b, int imm);
VCMPPD __mmask8 _mm_cmp_pd_mask( __m128d a, __m128d b, int imm);
VCMPPD __mmask8 _mm_mask_cmp_pd_mask( __mmask8 k1, __m128d a, __m128d b, int imm);
VCMPPD __m256 _mm256_cmp_pd(__m256d a, __m256d b, int imm)
(V)CMPPD __m128 _mm_cmp_pd(__m128d a, __m128d b, int imm)
SIMD Floating-Point Exceptions
Invalid if SNaN operand and invalid if QNaN and predicate as listed in Table 3-1.
Denormal
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions”.
EVEX-encoded instructions, see Table 2-46, “Type E2 Class Exception Conditions”.
CMPPD—Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-187
INSTRUCTION SET REFERENCE, A-L
CMPPS—Compare Packed Single Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
NP 0F C2 /r ib
A
V/V
SSE
Compare packed single precision floating-point values in
CMPPS xmm1, xmm2/m128,
xmm2/m128 and xmm1 using bits 2:0 of imm8 as a
imm8
comparison predicate.
VEX.128.0F.WIG C2 /r ib
B
V/V
AVX
Compare packed single precision floating-point values in
VCMPPS xmm1, xmm2,
xmm3/m128 and xmm2 using bits 4:0 of imm8 as a
xmm3/m128, imm8
comparison predicate.
VEX.256.0F.WIG C2 /r ib
B
V/V
AVX
Compare packed single precision floating-point values in
VCMPPS ymm1, ymm2,
ymm3/m256 and ymm2 using bits 4:0 of imm8 as a
ymm3/m256, imm8
comparison predicate.
EVEX.128.0F.W0 C2 /r ib
C
V/V
AVX512VL
Compare packed single precision floating-point values in
VCMPPS k1 {k2}, xmm2,
AVX512F
xmm3/m128/m32bcst and xmm2 using bits 4:0 of imm8 as
xmm3/m128/m32bcst, imm8
a comparison predicate with writemask k2 and leave the
result in mask register k1.
EVEX.256.0F.W0 C2 /r ib
C
V/V
AVX512VL
Compare packed single precision floating-point values in
VCMPPS k1 {k2}, ymm2,
AVX512F
ymm3/m256/m32bcst and ymm2 using bits 4:0 of imm8 as
ymm3/m256/m32bcst, imm8
a comparison predicate with writemask k2 and leave the
result in mask register k1.
EVEX.512.0F.W0 C2 /r ib
C
V/V
AVX512F
Compare packed single precision floating-point values in
VCMPPS k1 {k2}, zmm2,
zmm3/m512/m32bcst and zmm2 using bits 4:0 of imm8 as
zmm3/m512/m32bcst{sae}, imm8
a comparison predicate with writemask k2 and leave the
result in mask register k1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
imm8
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Performs a SIMD compare of the packed single precision floating-point values in the second source operand and the
first source operand and returns the result of the comparison to the destination operand. The comparison predicate
operand (immediate byte) specifies the type of comparison performed on each of the pairs of packed values.
EVEX encoded versions: The first source operand (second operand) is a ZMM/YMM/XMM register. The second
source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector
broadcasted from a 32-bit memory location. The destination operand (first operand) is an opmask register.
Comparison results are written to the destination operand under the writemask k2. Each comparison result is a
single mask bit of 1 (comparison true) or 0 (comparison false).
VEX.256 encoded version: The first source operand (second operand) is a YMM register. The second source operand
(third operand) can be a YMM register or a 256-bit memory location. The destination operand (first operand) is a
YMM register. Eight comparisons are performed with results written to the destination operand. The result of each
comparison is a doubleword mask of all 1s (comparison true) or all 0s (comparison false).
128-bit Legacy SSE version: The first source and destination operand (first operand) is an XMM register. The
second source operand (second operand) can be an XMM register or 128-bit memory location. Bits (MAXVL-1:128)
of the corresponding ZMM destination register remain unchanged. Four comparisons are performed with results
written to bits 127:0 of the destination operand. The result of each comparison is a doubleword mask of all 1s
(comparison true) or all 0s (comparison false).
VEX.128 encoded version: The first source operand (second operand) is an XMM register. The second source
operand (third operand) can be an XMM register or a 128-bit memory location. Bits (MAXVL-1:128) of the destina-
3-188
Vol. 2A
CMPPS—Compare Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, A-L
tion ZMM register are zeroed. Four comparisons are performed with results written to bits 127:0 of the destination
operand.
The comparison predicate operand is an 8-bit immediate:
For instructions encoded using the VEX prefix and EVEX prefix, bits 4:0 define the type of comparison to be
performed (see Table 3-1). Bits 5 through 7 of the immediate are reserved.
For instruction encodings that do not use VEX prefix, bits 2:0 define the type of comparison to be made (see
the first 8 rows of Table 3-1). Bits 3 through 7 of the immediate are reserved.
The unordered relationship is true when at least one of the two source operands being compared is a NaN; the
ordered relationship is true when neither source operand is a NaN.
A subsequent computational instruction that uses the mask result in the destination operand as an input operand
will not generate an exception, because a mask of all 0s corresponds to a floating-point value of +0.0 and a mask
of all 1s corresponds to a QNaN.
Note that processors with “CPUID.1H:ECX.AVX =0” do not implement the “greater-than”, “greater-than-or-equal”,
“not-greater than”, and “not-greater-than-or-equal relations” predicates. These comparisons can be made either
by using the inverse relationship (that is, use the “not-less-than-or-equal” to make a “greater-than” comparison)
or by using software emulation. When using software emulation, the program must swap the operands (copying
registers when necessary to protect the data that will now be in the destination), and then perform the compare
using a different predicate. The predicate to be used for these emulations is listed in the first 8 rows of Table 3-7
(Intel 64 and IA-32 Architectures Software Developer’s Manual Volume 2A) under the heading Emulation.
Compilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand
CMPPS instruction, for processors with “CPUID.1H:ECX.AVX =0”. See Table 3-4. The compiler should treat reserved
imm8 values as illegal syntax.
:
Table 3-4. Pseudo-Op and CMPPS Implementation
Pseudo-Op
CMPPS Implementation
CMPEQPS xmm1, xmm2
CMPPS xmm1, xmm2, 0
CMPLTPS xmm1, xmm2
CMPPS xmm1, xmm2, 1
CMPLEPS xmm1, xmm2
CMPPS xmm1, xmm2, 2
CMPUNORDPS xmm1, xmm2
CMPPS xmm1, xmm2, 3
CMPNEQPS xmm1, xmm2
CMPPS xmm1, xmm2, 4
CMPNLTPS xmm1, xmm2
CMPPS xmm1, xmm2, 5
CMPNLEPS xmm1, xmm2
CMPPS xmm1, xmm2, 6
CMPORDPS xmm1, xmm2
CMPPS xmm1, xmm2, 7
The greater-than relations that the processor does not implement require more than one instruction to emulate in
software and therefore should not be implemented as pseudo-ops. (For these, the programmer should reverse the
operands of the corresponding less than relations and use move instructions to ensure that the mask is moved to
the correct destination register and that the source operand is left intact.)
Processors with “CPUID.1H:ECX.AVX =1” implement the full complement of 32 predicates shown in Table 3-5, soft-
ware emulation is no longer needed. Compilers and assemblers may implement the following three-operand
pseudo-ops in addition to the four-operand VCMPPS instruction. See Table 3-5, where the notation of reg1 and
reg2 represent either XMM registers or YMM registers. The compiler should treat reserved imm8 values as illegal
syntax. Alternately, intrinsics can map the pseudo-ops to pre-defined constants to support a simpler intrinsic inter-
face. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded VCMPPS instructions
in a similar fashion by extending the syntax listed in Table 3-5.
:
CMPPS—Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-189
INSTRUCTION SET REFERENCE, A-L
Table 3-5. Pseudo-Op and VCMPPS Implementation
Pseudo-Op
CMPPS Implementation
VCMPEQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0
VCMPLTPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1
VCMPLEPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
2
VCMPUNORDPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
3
VCMPNEQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
4
VCMPNLTPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
5
VCMPNLEPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
6
VCMPORDPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
7
VCMPEQ_UQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
8
VCMPNGEPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
9
VCMPNGTPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0AH
VCMPFALSEPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0BH
VCMPNEQ_OQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0CH
VCMPGEPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0DH
VCMPGTPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0EH
VCMPTRUEPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
0FH
VCMPEQ_OSPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
10H
VCMPLT_OQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
11H
VCMPLE_OQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
12H
VCMPUNORD_SPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
13H
VCMPNEQ_USPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
14H
VCMPNLT_UQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
15H
VCMPNLE_UQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
16H
VCMPORD_SPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
17H
VCMPEQ_USPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
18H
VCMPNGE_UQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
19H
VCMPNGT_UQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1AH
VCMPFALSE_OSPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1BH
VCMPNEQ_OSPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1CH
VCMPGE_OQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1DH
VCMPGT_OQPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1EH
VCMPTRUE_USPS reg1, reg2, reg3
VCMPPS reg1, reg2, reg3,
1FH
3-190
Vol. 2A
CMPPS—Compare Packed Single Precision Floating-Point Values

 

 

 

 

 

 

 

Content      ..     65      66      67      68     ..