|
|
FI;
FI;
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 CR4.FRED = 1 and CPL = 0 and L bit = 0
CALL-Call Procedure
Vol. 2A
3-127
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 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;
CALL-Call Procedure
Vol. 2A
3-128
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 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 (DPL ≠ CPL)
THEN #GP(new code segment selector); FI;
IF CR4.FRED = 1 and CPL = 0 and L bit = 0
THEN GP(new code segment selector); FI;
IF segment not present
THEN #NP(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;
CALL-Call Procedure
Vol. 2A
3-129
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)
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:
CALL-Call Procedure
Vol. 2A
3-130
IF call gate (DPL < CPL) or (RPL > DPL) or (CR4.FRED = 1)
THEN #GP(call-gate selector); FI;
IF call gate not present
THEN #NP(call-gate selector); FI;
IF call-gate code-segment selector is NULL
THEN #GP(0); FI;
IF call-gate code-segment selector index 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
CALL-Call Procedure
Vol. 2A
3-131
IF IA32_EFER.LMA = 0 and new stack segment not present
THEN #SS(NewSS); FI;
IF CallGateSize = 32
THEN
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
CALL-Call Procedure
Vol. 2A
3-132
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 *)
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;
CALL-Call Procedure
Vol. 2A
3-133
FI;
CS(RPL) := CPL
IF ShadowStackEnabled(CPL)
(* Align to next 8 byte boundary *)
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;
CALL-Call Procedure
Vol. 2A
3-134
END;
Flags Affected
All flags are affected if a task switch occurs; no flags are affected if a task switch does not occur.
Protected Mode Exceptions
#GP(0)
If 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-135
#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.
If FRED transitions are enabled and the selector references a call gate.
#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).
CALL-Call Procedure
Vol. 2A
3-136
#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.
If FRED transitions are enabled and the selector references a call gate.
If FRED transitions are enabled, CPL is 0, and the instruction would enter compatibility mode.
#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-137
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.
CBW/CWDE/CDQE-Convert Byte to Word/Convert Word to Doubleword/Convert Doubleword to Quadword
Vol. 2A
3-138
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.07H.00H:EBX.SMAP[20] = 0.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.07H.00H:EBX.SMAP[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.07H.00H:EBX.SMAP[20] = 0.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If the CPL > 0.
If CPUID.07H.00H:EBX.SMAP[20] = 0.
CLAC-Clear AC Flag in EFLAGS Register
Vol. 2A
3-139
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.
CLC-Clear Carry Flag
Vol. 2A
3-140
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-141
CLDEMOTE-Cache Line Demote
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
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 optimi-
zation, 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
transactional abort.
1. The Mod field of the ModR/M byte cannot have value 11B.
CLDEMOTE-Cache Line Demote
Vol. 2A
3-142
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-143
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 CLFLUSH (CPUID.01H:EDX[19]).
The aligned cache line size affected is also indicated by the value in CPUID.01H:EBX[15:8].
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.
CLFLUSH-Flush Cache Line
Vol. 2A
3-144
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.CLFLUSH[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.CLFLUSH[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.CLFLUSH[19] = 0.
If the LOCK prefix is used.
CLFLUSH-Flush Cache Line
Vol. 2A
3-145
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.07H.00H:EBX[23]). The aligned cache line size affected is also indicated by the value in
CPUID.01H:EBX[15:8].
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 transac-
tional 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)
CLFLUSHOPT-Flush Cache Line Optimized
Vol. 2A
3-146
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.07H.00H:EBX.CLFLUSHOPT[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.07H.00H:EBX.CLFLUSHOPT[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.07H.00H:EBX.CLFLUSHOPT[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-147
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.
CLI-Clear Interrupt Flag
Vol. 2A
3-148
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-149
CLRSSBSY-Clear Busy Flag in a Supervisor Shadow Stack Token
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
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.
This instruction cannot be executed when FRED transitions are enabled. FRED transitions do not use supervisor
shadow stack tokens.
Operation
IF CR4.CET = 0 OR CR4.FRED = 1
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.
CLRSSBSY-Clear Busy Flag in a Supervisor Shadow Stack Token
Vol. 2A
3-150
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-writable 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
If the LOCK prefix is used.
If CR4.CET = 0.
IF IA32_S_CET.SH_STK_EN = 0.
If CR4.FRED = 1.
#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-writable 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.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CR4.CET = 0.
If CR4.FRED = 1.
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.
#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-151
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 27, “Virtual Machine Control Structures,” of the Intel® 64 and IA-32 Architectures Software Devel-
oper’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.
CLTS-Clear Task-Switched Flag in CR0
Vol. 2A
3-152
CLUI-Clear User Interrupt Flag
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
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.00H:EDX.UINTR[5] = 0.
CLUI-Clear User Interrupt Flag
Vol. 2A
3-153
CLWB-Cache Line Write Back
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
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 CPUID.07H.00H:EBX.CLWB[24]. The aligned cache line size
affected is also indicated by the value in CPUID.01H:EBX[15:8].
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.
CLWB-Cache Line Write Back
Vol. 2A
3-154
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.07H.00H:EBX.CLWB[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.07H.00H:EBX.CLWB[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.07H.00H:EBX.CLWB[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-155
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.
CMC-Complement Carry Flag
Vol. 2A
3-156
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-157
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).
CMOVcc-Conditional Move
Vol. 2A
3-158
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-159
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.
CMOVcc-Conditional Move
Vol. 2A
3-160
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/m81, imm8
MI
Valid
Valid
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/m81, r81
MR
Valid
Valid
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 r81, r/m81
RM
Valid
Valid
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:
1. With a REX prefix in 64-bit mode, attempts to access AH, BH, CH, or DH will instead access SPL, DIL, BPL, or SIL, respectively.
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.
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.
CMP-Compare Two Operands
Vol. 2A
3-161
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.
CMP-Compare Two Operands
Vol. 2A
3-162
CMPccXADD-Compare and Add if Condition is Met
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E6 !(11):rrr:bbb
value in m32. If below or equal (CF=1 or ZF=1),
CMPBEXADD m32, r32, r32
add value from r32 (third operand) to m32 and
write new value in m32. The second operand is
always updated with the original value from
m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E6 !(11):rrr:bbb
value in m64. If below or equal (CF=1 or ZF=1),
CMPBEXADD m64, r64, r64
add value from r64 (third operand) to m64 and
write new value in m64. The second operand is
always updated with the original value from
m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E2 !(11):rrr:bbb
value in m32. If below (CF=1), add value from
CMPBXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E2 !(11):rrr:bbb
value in m64. If below (CF=1), add value from
CMPBXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 EE !(11):rrr:bbb
value in m32. If less or equal (ZF=1 or SF≠OF),
CMPLEXADD m32, r32, r32
add value from r32 (third operand) to m32 and
write new value in m32. The second operand is
always updated with the original value from
m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 EE !(11):rrr:bbb
value in m64. If less or equal (ZF=1 or SF≠OF),
CMPLEXADD m64, r64, r64
add value from r64 (third operand) to m64 and
write new value in m64. The second operand is
always updated with the original value from
m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 EC !(11):rrr:bbb
value in m32. If less (SF≠OF), add value from r32
CMPLXADD m32, r32, r32
(third operand) to m32 and write new value in
m32. The second operand is always updated
with the original value from m32.
VEX.128.66.0F38.W1 EC !(11):rrr:bbb
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
value in m64. If less (SF≠OF), add value from r64
CMPLXADD m64, r64, r64
(third operand) to m64 and write new value in
m64. The second operand is always updated
with the original value from m64.
VEX.128.66.0F38.W0 E7 !(11):rrr:bbb
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
value in m32. If not below or equal (CF=0 and
CMPNBEXADD m32, r32, r32
ZF=0), add value from r32 (third operand) to
m32 and write new value in m32. The second
operand is always updated with the original
value from m32.
CMPccXADD-Compare and Add if Condition is Met
Vol. 2A
3-163
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
VEX.128.66.0F38.W1 E7 !(11):rrr:bbb
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
value in m64. If not below or equal (CF=0 and
CMPNBEXADD m64, r64, r64
ZF=0), add value from r64 (third operand) to
m64 and write new value in m64. The second
operand is always updated with the original
value from m64.
VEX.128.66.0F38.W0 E3 !(11):rrr:bbb
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
value in m32. If not below (CF=0), add value from
CMPNBXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E3 !(11):rrr:bbb
value in m64. If not below (CF=0), add value from
CMPNBXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 EF !(11):rrr:bbb
value in m32. If not less or equal (ZF=0 and
CMPNLEXADD m32, r32, r32
SF=OF), add value from r32 (third operand) to
m32 and write new value in m32. The second
operand is always updated with the original
value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 EF !(11):rrr:bbb
value in m64. If not less or equal (ZF=0 and
CMPNLEXADD m64, r64, r64
SF=OF), add value from r64 (third operand) to
m64 and write new value in m64. The second
operand is always updated with the original
value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 ED !(11):rrr:bbb
value in m32. If not less (SF=OF), add value from
CMPNLXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 ED !(11):rrr:bbb
value in m64. If not less (SF=OF), add value from
CMPNLXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E1 !(11):rrr:bbb
value in m32. If not overflow (OF=0), add value
CMPNOXADD m32, r32, r32
from r32 (third operand) to m32 and write new
value in m32. The second operand is always
updated with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E1 !(11):rrr:bbb
value in m64. If not overflow (OF=0), add value
CMPNOXADD m64, r64, r64
from r64 (third operand) to m64 and write new
value in m64. The second operand is always
updated with the original value from m64.
CMPccXADD-Compare and Add if Condition is Met
Vol. 2A
3-164
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 EB !(11):rrr:bbb
value in m32. If not parity (PF=0), add value from
CMPNPXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 EB !(11):rrr:bbb
value in m64. If not parity (PF=0), add value from
CMPNPXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E9 !(11):rrr:bbb
value in m32. If not sign (SF=0), add value from
CMPNSXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E9 !(11):rrr:bbb
value in m64. If not sign (SF=0), add value from
CMPNSXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E5 !(11):rrr:bbb
value in m32. If not zero (ZF=0), add value from
CMPNZXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E5 !(11):rrr:bbb
value in m64. If not zero (ZF=0), add value from
CMPNZXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E0 !(11):rrr:bbb
value in m32. If overflow (OF=1), add value from
CMPOXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E0 !(11):rrr:bbb
value in m64. If overflow (OF=1), add value from
CMPOXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 EA !(11):rrr:bbb
value in m32. If parity (PF=1), add value from
CMPPXADD m32, r32, r32
r32 (third operand) to m32 and write new value
in m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 EA !(11):rrr:bbb
value in m64. If parity (PF=1), add value from
CMPPXADD m64, r64, r64
r64 (third operand) to m64 and write new value
in m64. The second operand is always updated
with the original value from m64.
CMPccXADD-Compare and Add if Condition is Met
Vol. 2A
3-165
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E8 !(11):rrr:bbb
value in m32. If sign (SF=1), add value from r32
CMPSXADD m32, r32, r32
(third operand) to m32 and write new value in
m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E8 !(11):rrr:bbb
value in m64. If sign (SF=1), add value from r64
CMPSXADD m64, r64, r64
(third operand) to m64 and write new value in
m64. The second operand is always updated
with the original value from m64.
A
V/N.E.
CMPCCXADD
Compare value in r32 (second operand) with
VEX.128.66.0F38.W0 E4 !(11):rrr:bbb
value in m32. If zero (ZF=1), add value from r32
CMPZXADD m32, r32, r32
(third operand) to m32 and write new value in
m32. The second operand is always updated
with the original value from m32.
A
V/N.E.
CMPCCXADD
Compare value in r64 (second operand) with
VEX.128.66.0F38.W1 E4 !(11):rrr:bbb
value in m64. If zero (ZF=1), add value from r64
CMPZXADD m64, r64, r64
(third operand) to m64 and write new value in
m64. The second operand is always updated
with the original value from m64.
Instruction Operand Encoding1
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:r/m (r, w)
ModRM:reg (r, w)
VEX.vvvv (r)
N/A
Description
This instruction compares the value from memory with the value of the second operand. If the specified condition
is met, then the processor will add the third operand to the memory operand and write it into memory, else the
memory is unchanged by this instruction.
This instruction must have MODRM.MOD equal to 0, 1, or 2. The value 3 for MODRM.MOD is reserved and will cause
an invalid opcode exception (#UD).
The second operand is always updated with the original value of the memory operand. The EFLAGS conditions are
updated from the results of the comparison.The instruction uses an implicit lock. This instruction does not permit
the use of an explicit lock prefix.
Operation
CMPCCXADD srcdest1, srcdest2, src3
tmp1 := load lock srcdest1
tmp2 := tmp1 + src3
EFLAGS.CS,OF,SF,ZF,AF,PF := CMP tmp1, srcdest2
IF <condition>:
srcdest1 := store unlock tmp2
ELSE
srcdest1 := store unlock tmp1
srcdest2 :=tmp1
1. ModRM.MOD != 011B
CMPccXADD-Compare and Add if Condition is Met
Vol. 2A
3-166
Flags Affected
The EFLAGS conditions are updated from the results of the comparison.
Intel C/C++ Compiler Intrinsic Equivalent
CMPCCXADD int _cmpccxadd_epi32 (void* __A, int __B, int __C, const int __D);
CMPCCXADD __int64 _cmpccxadd_epi64 (void* __A, __int64 __B, __int64 __C, const int __D);
SIMD Floating-Point Exceptions
None.
Exceptions
Exceptions Type 14; see Table 2-31.
CMPccXADD-Compare and Add if Condition is Met
Vol. 2A
3-167
CMPPD-Compare Packed Double Precision Floating-Point Values
Opcode/
Op /
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
66 0F C2 /r ib
A
V/V
SSE2
Compare packed double precision floating-point
CMPPD xmm1, xmm2/m128, imm8
values 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
VCMPPD xmm1, xmm2, xmm3/m128,
values in xmm3/m128 and xmm2 using bits 4:0 of
imm8
imm8 as a comparison predicate.
VEX.256.66.0F.WIG C2 /r ib
B
V/V
AVX
Compare packed double precision floating-point
VCMPPD ymm1, ymm2, ymm3/m256,
values in ymm3/m256 and ymm2 using bits 4:0 of
imm8
imm8 as a comparison predicate.
EVEX.128.66.0F.W1 C2 /r ib
C
V/V
(AVX512VL AND
Compare packed double precision floating-point
VCMPPD k1 {k2}, xmm2,
AVX512F) OR
values in xmm3/m128/m64bcst and xmm2 using
xmm3/m128/m64bcst, imm8
AVX10.1
bits 4:0 of 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 AND
Compare packed double precision floating-point
VCMPPD k1 {k2}, ymm2,
AVX512F) OR
values in ymm3/m256/m64bcst and ymm2 using
ymm3/m256/m64bcst, imm8
AVX10.1
bits 4:0 of 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
VCMPPD k1 {k2}, zmm2,
OR AVX10.1
values in zmm3/m512/m64bcst and zmm2 using
zmm3/m512/m64bcst {sae}, imm8
bits 4:0 of 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
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-168
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).
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-8). 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-8). Bits 3 through 7 of the immediate are reserved.
Table 3-8. 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
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-169
Table 3-8. 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
NGE_UQ
19H
Not-greater-than-or-equal (unordered, non-
False
True
False
True
No
signaling)
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.01H:ECX.AVX[28] = 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 oper-
ands (copying registers when necessary to protect the data that will now be in the destination), and then perform
the compare using a different predicate.
Compilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand
CMPPD instruction, for processors with “CPUID.01H:ECX.AVX[28] = 0”. See Table 3-9. The compiler should treat
reserved imm8 values as illegal syntax.
:
Table 3-9. 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.01H:ECX.AVX[28] = 1” implement the full complement of 32 predicates shown in
Table 3-10, software emulation is no longer needed. Compilers and assemblers may implement the following
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-170
three-operand pseudo-ops in addition to the four-operand VCMPPD instruction. See Table 3-10, where the nota-
tions of reg1 reg2, and reg3 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 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-10.
:
Table 3-10. 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
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-171
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;
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;
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-172
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
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)
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-173
(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-8, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-48, “Type E2 Class Exception Conditions.”
CMPPD-Compare Packed Double Precision Floating-Point Values
Vol. 2A
3-174
CMPPS-Compare Packed Single Precision Floating-Point Values
Opcode/
Op /
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
NP 0F C2 /r ib
A
V/V
SSE
Compare packed single precision floating-point values in
CMPPS xmm1, xmm2/m128, imm8
xmm2/m128 and xmm1 using bits 2:0 of imm8 as a
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 AND
Compare packed single precision floating-point values in
VCMPPS k1 {k2}, xmm2,
AVX512F) OR
xmm3/m128/m32bcst and xmm2 using bits 4:0 of
xmm3/m128/m32bcst, imm8
AVX10.1
imm8 as 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 AND
Compare packed single precision floating-point values in
VCMPPS k1 {k2}, ymm2,
AVX512F) OR
ymm3/m256/m32bcst and ymm2 using bits 4:0 of
ymm3/m256/m32bcst, imm8
AVX10.1
imm8 as 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,
OR AVX10.1
zmm3/m512/m32bcst and zmm2 using bits 4:0 of imm8
zmm3/m512/m32bcst {sae}, 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 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 pred-
icate 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).
CMPPS-Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-175
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. 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-8). 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-8). 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.01H:ECX.AVX[28] = 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 oper-
ands (copying registers when necessary to protect the data that will now be in the destination), and then perform
the compare using a different predicate.
Compilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand
CMPPS instruction, for processors with “CPUID.01H:ECX.AVX[28] = 0”. See Table 3-11. The compiler should treat
reserved imm8 values as illegal syntax.
:
Table 3-11. 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.01H:ECX.AVX[28] = 1” implement the full complement of 32 predicates shown in Table
3-12, software 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-12, 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 interface. 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-12.
:
CMPPS-Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-176
Table 3-12. 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
CMPPS-Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-177
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;
VCMPPS (EVEX Encoded Versions)
(KL, VL) = (4, 128), (8, 256), (16, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k2[j] OR *no writemask*
THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN
CMP := SRC1[i+31:i] OP5 SRC2[31:0]
ELSE
CMP := SRC1[i+31:i] OP5 SRC2[i+31:i]
FI;
IF CMP = TRUE
THEN DEST[j] := 1;
ELSE DEST[j] := 0; FI;
ELSE
DEST[j] := 0
; zeroing-masking onlyFI;
FI;
CMPPS-Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-178
ENDFOR
DEST[MAX_KL-1:KL] := 0
VCMPPS (VEX.256 Encoded Version)
CMP0 := SRC1[31:0] OP5 SRC2[31:0];
CMP1 := SRC1[63:32] OP5 SRC2[63:32];
CMP2 := SRC1[95:64] OP5 SRC2[95:64];
CMP3 := SRC1[127:96] OP5 SRC2[127:96];
CMP4 := SRC1[159:128] OP5 SRC2[159:128];
CMP5 := SRC1[191:160] OP5 SRC2[191:160];
CMP6 := SRC1[223:192] OP5 SRC2[223:192];
CMP7 := SRC1[255:224] OP5 SRC2[255:224];
IF CMP0 = TRUE
THEN DEST[31:0] :=FFFFFFFFH;
ELSE DEST[31:0] := 000000000H; FI;
IF CMP1 = TRUE
THEN DEST[63:32] := FFFFFFFFH;
ELSE DEST[63:32] :=000000000H; FI;
IF CMP2 = TRUE
THEN DEST[95:64] := FFFFFFFFH;
ELSE DEST[95:64] := 000000000H; FI;
IF CMP3 = TRUE
THEN DEST[127:96] := FFFFFFFFH;
ELSE DEST[127:96] := 000000000H; FI;
IF CMP4 = TRUE
THEN DEST[159:128] := FFFFFFFFH;
ELSE DEST[159:128] := 000000000H; FI;
IF CMP5 = TRUE
THEN DEST[191:160] := FFFFFFFFH;
ELSE DEST[191:160] := 000000000H; FI;
IF CMP6 = TRUE
THEN DEST[223:192] := FFFFFFFFH;
ELSE DEST[223:192] :=000000000H; FI;
IF CMP7 = TRUE
THEN DEST[255:224] := FFFFFFFFH;
ELSE DEST[255:224] := 000000000H; FI;
DEST[MAXVL-1:256] := 0
VCMPPS (VEX.128 Encoded Version)
CMP0 := SRC1[31:0] OP5 SRC2[31:0];
CMP1 := SRC1[63:32] OP5 SRC2[63:32];
CMP2 := SRC1[95:64] OP5 SRC2[95:64];
CMP3 := SRC1[127:96] OP5 SRC2[127:96];
IF CMP0 = TRUE
THEN DEST[31:0] :=FFFFFFFFH;
ELSE DEST[31:0] := 000000000H; FI;
IF CMP1 = TRUE
THEN DEST[63:32] := FFFFFFFFH;
ELSE DEST[63:32] := 000000000H; FI;
IF CMP2 = TRUE
THEN DEST[95:64] := FFFFFFFFH;
ELSE DEST[95:64] := 000000000H; FI;
IF CMP3 = TRUE
THEN DEST[127:96] := FFFFFFFFH;
CMPPS-Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-179
ELSE DEST[127:96] :=000000000H; FI;
DEST[MAXVL-1:128] := 0
CMPPS (128-bit Legacy SSE Version)
CMP0 := SRC1[31:0] OP3 SRC2[31:0];
CMP1 := SRC1[63:32] OP3 SRC2[63:32];
CMP2 := SRC1[95:64] OP3 SRC2[95:64];
CMP3 := SRC1[127:96] OP3 SRC2[127:96];
IF CMP0 = TRUE
THEN DEST[31:0] :=FFFFFFFFH;
ELSE DEST[31:0] := 000000000H; FI;
IF CMP1 = TRUE
THEN DEST[63:32] := FFFFFFFFH;
ELSE DEST[63:32] := 000000000H; FI;
IF CMP2 = TRUE
THEN DEST[95:64] := FFFFFFFFH;
ELSE DEST[95:64] := 000000000H; FI;
IF CMP3 = TRUE
THEN DEST[127:96] := FFFFFFFFH;
ELSE DEST[127:96] :=000000000H; FI;
DEST[MAXVL-1:128] (Unmodified)
Intel C/C++ Compiler Intrinsic Equivalent
VCMPPS __mmask16 _mm512_cmp_ps_mask( __m512 a, __m512 b, int imm);
VCMPPS __mmask16 _mm512_cmp_round_ps_mask( __m512 a, __m512 b, int imm, int sae);
VCMPPS __mmask16 _mm512_mask_cmp_ps_mask( __mmask16 k1, __m512 a, __m512 b, int imm);
VCMPPS __mmask16 _mm512_mask_cmp_round_ps_mask( __mmask16 k1, __m512 a, __m512 b, int imm, int sae);
VCMPPS __mmask8 _mm256_cmp_ps_mask( __m256 a, __m256 b, int imm);
VCMPPS __mmask8 _mm256_mask_cmp_ps_mask( __mmask8 k1, __m256 a, __m256 b, int imm);
VCMPPS __mmask8 _mm_cmp_ps_mask( __m128 a, __m128 b, int imm);
VCMPPS __mmask8 _mm_mask_cmp_ps_mask( __mmask8 k1, __m128 a, __m128 b, int imm);
VCMPPS __m256 _mm256_cmp_ps(__m256 a, __m256 b, int imm)
CMPPS __m128 _mm_cmp_ps(__m128 a, __m128 b, int imm)
SIMD Floating-Point Exceptions
Invalid if SNaN operand and invalid if QNaN and predicate as listed in Table 3-8, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-48, “Type E2 Class Exception Conditions.”
CMPPS-Compare Packed Single Precision Floating-Point Values
Vol. 2A
3-180
CMPS/CMPSB/CMPSW/CMPSD/CMPSQ-Compare String Operands
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
A6
CMPS m8, m8
ZO
Valid
Valid
For legacy mode, compare byte at address DS:(E)SI with
byte at address ES:(E)DI; For 64-bit mode compare byte
at address (R|E)SI to byte at address (R|E)DI. The status
flags are set accordingly.
A7
CMPS m16, m16
ZO
Valid
Valid
For legacy mode, compare word at address DS:(E)SI
with word at address ES:(E)DI; For 64-bit mode
compare word at address (R|E)SI with word at address
(R|E)DI. The status flags are set accordingly.
A7
CMPS m32, m32
ZO
Valid
Valid
For legacy mode, compare dword at address DS:(E)SI at
dword at address ES:(E)DI; For 64-bit mode compare
dword at address (R|E)SI at dword at address (R|E)DI.
The status flags are set accordingly.
REX.W + A7
CMPS m64, m64
ZO
Valid
N.E.
Compares quadword at address (R|E)SI with quadword
at address (R|E)DI and sets the status flags accordingly.
A6
CMPSB
ZO
Valid
Valid
For legacy mode, compare byte at address DS:(E)SI with
byte at address ES:(E)DI; For 64-bit mode compare byte
at address (R|E)SI with byte at address (R|E)DI. The
status flags are set accordingly.
A7
CMPSW
ZO
Valid
Valid
For legacy mode, compare word at address DS:(E)SI
with word at address ES:(E)DI; For 64-bit mode
compare word at address (R|E)SI with word at address
(R|E)DI. The status flags are set accordingly.
A7
CMPSD
ZO
Valid
Valid
For legacy mode, compare dword at address DS:(E)SI
with dword at address ES:(E)DI; For 64-bit mode
compare dword at address (R|E)SI with dword at
address (R|E)DI. The status flags are set accordingly.
REX.W + A7
CMPSQ
ZO
Valid
N.E.
Compares quadword at address (R|E)SI with quadword
at address (R|E)DI and sets the status flags accordingly.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Compares the byte, word, doubleword, or quadword specified with the first source operand with the byte, word,
doubleword, or quadword specified with the second source operand and sets the status flags in the EFLAGS register
according to the results.
Both source operands are located in memory. The address of the first source operand is read from DS:SI, DS:ESI
or RSI (depending on the address-size attribute of the instruction is 16, 32, or 64, respectively). The address of the
second source operand is read from ES:DI, ES:EDI or RDI (again depending on the address-size attribute of the
instruction is 16, 32, or 64). The DS segment may be overridden with a segment override prefix, but the ES
segment cannot be overridden.
At the assembly-code level, two forms of this instruction are allowed: the “explicit-operands” form and the “no-
operands” form. The explicit-operands form (specified with the CMPS mnemonic) allows the two source operands
to be specified explicitly. Here, the source operands should be symbols that indicate the size and location of the
source values. This explicit-operand form is provided to allow documentation. However, note that the documenta-
tion provided by this form can be misleading. That is, the source operand symbols must specify the correct type
(size) of the operands (bytes, words, or doublewords, quadwords), but they do not have to specify the correct loca-
CMPS/CMPSB/CMPSW/CMPSD/CMPSQ-Compare String Operands
Vol. 2A
3-181
tion. Locations of the source operands are always specified by the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) regis-
ters, which must be loaded correctly before the compare string instruction is executed.
The no-operands form provides “short forms” of the byte, word, and doubleword versions of the CMPS instructions.
Here also the DS:(E)SI (or RSI) and ES:(E)DI (or RDI) registers are assumed by the processor to specify the loca-
tion of the source operands. The size of the source operands is selected with the mnemonic: CMPSB (byte compar-
ison), CMPSW (word comparison), CMPSD (doubleword comparison), or CMPSQ (quadword comparison using
REX.W).
After the comparison, the (E/R)SI and (E/R)DI registers increment or decrement automatically according to the
setting of the DF flag in the EFLAGS register. (If the DF flag is 0, the (E/R)SI and (E/R)DI register increment; if the
DF flag is 1, the registers decrement.) The registers increment or decrement by 1 for byte operations, by 2 for word
operations, 4 for doubleword operations. If operand size is 64, RSI and RDI registers increment by 8 for quadword
operations.
The CMPS, CMPSB, CMPSW, CMPSD, and CMPSQ instructions can be preceded by the REPE prefix or the REPNE
prefix for block comparisons. See "REPE/REPZ-Repeat String Operation While Zero (Prefix)" and
"REPNE/REPNZ-Repeat String Operation While Not Zero (Prefix)" in Chapter 4 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 2B, for a description of the REPE and REPNE prefixes.
In 64-bit mode, the instruction’s default address size is 64 bits, 32 bit address size is supported using the prefix
67H. Use of the REX.W prefix promotes doubleword operation to 64 bits (see CMPSQ). See the summary chart at
the beginning of this section for encoding data and limits.
Operation
temp := SRC1 - SRC2;
SetStatusFlags(temp);
IF (64-Bit Mode)
THEN
IF (Byte comparison)
THEN IF DF = 0
THEN
(R|E)SI := (R|E)SI + 1;
(R|E)DI := (R|E)DI + 1;
ELSE
(R|E)SI := (R|E)SI - 1;
(R|E)DI := (R|E)DI - 1;
FI;
ELSE IF (Word comparison)
THEN IF DF = 0
THEN
(R|E)SI := (R|E)SI + 2;
(R|E)DI := (R|E)DI + 2;
ELSE
(R|E)SI := (R|E)SI - 2;
(R|E)DI := (R|E)DI - 2;
FI;
ELSE IF (Doubleword comparison)
THEN IF DF = 0
THEN
(R|E)SI := (R|E)SI + 4;
(R|E)DI := (R|E)DI + 4;
ELSE
(R|E)SI := (R|E)SI - 4;
(R|E)DI := (R|E)DI - 4;
FI;
ELSE (* Quadword comparison *)
CMPS/CMPSB/CMPSW/CMPSD/CMPSQ-Compare String Operands
Vol. 2A
3-182
THEN IF DF = 0
(R|E)SI := (R|E)SI + 8;
(R|E)DI := (R|E)DI + 8;
ELSE
(R|E)SI := (R|E)SI - 8;
(R|E)DI := (R|E)DI - 8;
FI;
FI;
ELSE (* Non-64-bit Mode *)
IF (byte comparison)
THEN IF DF = 0
THEN
(E)SI := (E)SI + 1;
(E)DI := (E)DI + 1;
ELSE
(E)SI := (E)SI - 1;
(E)DI := (E)DI - 1;
FI;
ELSE IF (Word comparison)
THEN IF DF = 0
(E)SI := (E)SI + 2;
(E)DI := (E)DI + 2;
ELSE
(E)SI := (E)SI - 2;
(E)DI := (E)DI - 2;
FI;
ELSE (* Doubleword comparison *)
THEN IF DF = 0
(E)SI := (E)SI + 4;
(E)DI := (E)DI + 4;
ELSE
(E)SI := (E)SI - 4;
(E)DI := (E)DI - 4;
FI;
FI;
FI;
Flags Affected
The CF, OF, SF, ZF, AF, and PF flags are set according to the temporary result of the comparison.
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.
CMPS/CMPSB/CMPSW/CMPSD/CMPSQ-Compare String Operands
Vol. 2A
3-183
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.
CMPS/CMPSB/CMPSW/CMPSD/CMPSQ-Compare String Operands
Vol. 2A
3-184
CMPSD-Compare Scalar Double Precision Floating-Point Value
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
F2 0F C2 /r ib
A
V/V
SSE2
Compare low double precision floating-point value in
CMPSD xmm1, xmm2/m64, imm8
xmm2/m64 and xmm1 using bits 2:0 of imm8 as
comparison predicate.
VEX.LIG.F2.0F.WIG C2 /r ib
B
V/V
AVX
Compare low double precision floating-point value in
VCMPSD xmm1, xmm2, xmm3/m64,
xmm3/m64 and xmm2 using bits 4:0 of imm8 as
imm8
comparison predicate.
EVEX.LLIG.F2.0F.W1 C2 /r ib
C
V/V
AVX512F
Compare low double precision floating-point value in
VCMPSD k1 {k2}, xmm2,
OR AVX10.1
xmm3/m64 and xmm2 using bits 4:0 of imm8 as
xmm3/m64{sae}, imm8
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
Tuple1 Scalar
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Compares the low 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 predicate operand (imme-
diate operand) specifies the type of comparison performed.
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 64-bit memory location. Bits (MAXVL-1:64) of
the corresponding YMM destination register remain unchanged. The comparison result is a quadword 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 64-bit memory location. The result is stored in the low quad-
word of the destination operand; the high quadword is filled with the contents of the high quadword of the first
source operand. Bits (MAXVL-1:128) of the destination ZMM register are zeroed. The comparison result is a quad-
word mask of all 1s (comparison true) or all 0s (comparison false).
EVEX encoded version: The first source operand (second operand) is an XMM register. The second source operand
can be a XMM register or a 64-bit memory location. The destination operand (first operand) is an opmask register.
The comparison result is a single mask bit of 1 (comparison true) or 0 (comparison false), written to the destination
starting from the LSB according to the writemask k2. Bits (MAX_KL-1:128) of the destination register are cleared.
The comparison predicate operand is an 8-bit immediate:
• For instructions encoded using the VEX prefix, bits 4:0 define the type of comparison to be performed (see
Table 3-8). 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-8). 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.01H:ECX.AVX[28] = 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
CMPSD-Compare Scalar Double Precision Floating-Point Value
Vol. 2A
3-185
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 oper-
ands (copying registers when necessary to protect the data that will now be in the destination), and then perform
the compare using a different predicate.
Compilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand
CMPSD instruction, for processors with “CPUID.01H:ECX.AVX[28] = 0”. See Table 3-13. The compiler should treat
reserved imm8 values as illegal syntax.
:
Table 3-13. Pseudo-Op and CMPSD Implementation
Pseudo-Op
CMPSD Implementation
CMPEQSD xmm1, xmm2
CMPSD xmm1, xmm2, 0
CMPLTSD xmm1, xmm2
CMPSD xmm1, xmm2, 1
CMPLESD xmm1, xmm2
CMPSD xmm1, xmm2, 2
CMPUNORDSD xmm1, xmm2
CMPSD xmm1, xmm2, 3
CMPNEQSD xmm1, xmm2
CMPSD xmm1, xmm2, 4
CMPNLTSD xmm1, xmm2
CMPSD xmm1, xmm2, 5
CMPNLESD xmm1, xmm2
CMPSD xmm1, xmm2, 6
CMPORDSD xmm1, xmm2
CMPSD 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.01H:ECX.AVX[28] = 1” implement the full complement of 32 predicates shown in Table
3-14, software emulation is no longer needed. Compilers and assemblers may implement the following three-
operand pseudo-ops in addition to the four-operand VCMPSD instruction. See Table 3-14, where the notations of
reg1 reg2, and reg3 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 interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded
VCMPSD instructions in a similar fashion by extending the syntax listed in Table 3-14.
:
Table 3-14. Pseudo-Op and VCMPSD Implementation
Pseudo-Op
CMPSD Implementation
VCMPEQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0
VCMPLTSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1
VCMPLESD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 2
VCMPUNORDSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 3
VCMPNEQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 4
VCMPNLTSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 5
VCMPNLESD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 6
VCMPORDSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 7
VCMPEQ_UQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 8
VCMPNGESD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 9
VCMPNGTSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0AH
VCMPFALSESD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0BH
VCMPNEQ_OQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0CH
VCMPGESD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0DH
CMPSD-Compare Scalar Double Precision Floating-Point Value
Vol. 2A
3-186
Table 3-14. Pseudo-Op and VCMPSD Implementation (Contd.)
Pseudo-Op
CMPSD Implementation
VCMPGTSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0EH
VCMPTRUESD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 0FH
VCMPEQ_OSSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 10H
VCMPLT_OQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 11H
VCMPLE_OQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 12H
VCMPUNORD_SSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 13H
VCMPNEQ_USSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 14H
VCMPNLT_UQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 15H
VCMPNLE_UQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 16H
VCMPORD_SSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 17H
VCMPEQ_USSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 18H
VCMPNGE_UQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 19H
VCMPNGT_UQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1AH
VCMPFALSE_OSSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1BH
VCMPNEQ_OSSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1CH
VCMPGE_OQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1DH
VCMPGT_OQSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1EH
VCMPTRUE_USSD reg1, reg2, reg3
VCMPSD reg1, reg2, reg3, 1FH
Software should ensure VCMPSD is encoded with VEX.L = 0. Encoding VCMPSD with VEX.L = 1 may encounter
unpredictable behavior across different processor generations.
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;
CMPSD-Compare Scalar Double Precision Floating-Point Value
Vol. 2A
3-187
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;
VCMPSD (EVEX Encoded Version)
CMP0 := SRC1[63:0] OP5 SRC2[63:0];
IF k2[0] or *no writemask*
THEN
IF CMP0 = TRUE
THEN DEST[0] := 1;
ELSE DEST[0] := 0; FI;
ELSE
DEST[0] := 0
; zeroing-masking only
FI;
DEST[MAX_KL-1:1] := 0
CMPSD (128-bit Legacy SSE Version)
CMP0 := DEST[63:0] OP3 SRC[63:0];
IF CMP0 = TRUE
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0000000000000000H; FI;
DEST[MAXVL-1:64] (Unmodified)
VCMPSD (VEX.128 Encoded Version)
CMP0 := SRC1[63:0] OP5 SRC2[63:0];
IF CMP0 = TRUE
THEN DEST[63:0] := FFFFFFFFFFFFFFFFH;
ELSE DEST[63:0] := 0000000000000000H; FI;
DEST[127:64] := SRC1[127:64]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VCMPSD __mmask8 _mm_cmp_sd_mask( __m128d a, __m128d b, int imm);
VCMPSD __mmask8 _mm_cmp_round_sd_mask( __m128d a, __m128d b, int imm, int sae);
VCMPSD __mmask8 _mm_mask_cmp_sd_mask( __mmask8 k1, __m128d a, __m128d b, int imm);
VCMPSD __mmask8 _mm_mask_cmp_round_sd_mask( __mmask8 k1, __m128d a, __m128d b, int imm, int sae);
(V)CMPSD __m128d _mm_cmp_sd(__m128d a, __m128d b, const int imm)
SIMD Floating-Point Exceptions
Invalid if SNaN operand, Invalid if QNaN and predicate as listed in Table 3-8, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-20, “Type 3 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-49, “Type E3 Class Exception Conditions.”
CMPSD-Compare Scalar Double Precision Floating-Point Value
Vol. 2A
3-188
CMPSS-Compare Scalar Single Precision Floating-Point Value
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
F3 0F C2 /r ib
A
V/V
SSE
Compare low single precision floating-point value in
CMPSS xmm1, xmm2/m32, imm8
xmm2/m32 and xmm1 using bits 2:0 of imm8 as
comparison predicate.
VEX.LIG.F3.0F.WIG C2 /r ib
B
V/V
AVX
Compare low single precision floating-point value in
VCMPSS xmm1, xmm2, xmm3/m32,
xmm3/m32 and xmm2 using bits 4:0 of imm8 as
imm8
comparison predicate.
EVEX.LLIG.F3.0F.W0 C2 /r ib
C
V/V
AVX512F
Compare low single precision floating-point value in
VCMPSS k1 {k2}, xmm2,
OR AVX10.1
xmm3/m32 and xmm2 using bits 4:0 of imm8 as
xmm3/m32{sae}, imm8
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
Tuple1 Scalar
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Compares the low 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 (imme-
diate operand) specifies the type of comparison performed.
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 32-bit memory location. Bits (MAXVL-1:32) of
the corresponding YMM destination register remain unchanged. The comparison result 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 32-bit memory location. The result is stored in the low 32 bits
of the destination operand; bits 127:32 of the destination operand are copied from the first source operand. Bits
(MAXVL-1:128) of the destination ZMM register are zeroed. The comparison result is a doubleword mask of all 1s
(comparison true) or all 0s (comparison false).
EVEX encoded version: The first source operand (second operand) is an XMM register. The second source operand
can be a XMM register or a 32-bit memory location. The destination operand (first operand) is an opmask register.
The comparison result is a single mask bit of 1 (comparison true) or 0 (comparison false), written to the destination
starting from the LSB according to the writemask k2. Bits (MAX_KL-1:128) of the destination register are cleared.
The comparison predicate operand is an 8-bit immediate:
• For instructions encoded using the VEX prefix, bits 4:0 define the type of comparison to be performed (see
Table 3-8). 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-8). 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.
CMPSS-Compare Scalar Single Precision Floating-Point Value
Vol. 2A
3-189
Note that processors with “CPUID.01H:ECX.AVX[28] = 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 oper-
ands (copying registers when necessary to protect the data that will now be in the destination), and then perform
the compare using a different predicate.
Compilers and assemblers may implement the following two-operand pseudo-ops in addition to the three-operand
CMPSS instruction, for processors with “CPUID.01H:ECX.AVX[28] = 0”. See Table 3-15. The compiler should treat
reserved imm8 values as illegal syntax.
:
Table 3-15. Pseudo-Op and CMPSS Implementation
Pseudo-Op
CMPSS Implementation
CMPEQSS xmm1, xmm2
CMPSS xmm1, xmm2, 0
CMPLTSS xmm1, xmm2
CMPSS xmm1, xmm2, 1
CMPLESS xmm1, xmm2
CMPSS xmm1, xmm2, 2
CMPUNORDSS xmm1, xmm2
CMPSS xmm1, xmm2, 3
CMPNEQSS xmm1, xmm2
CMPSS xmm1, xmm2, 4
CMPNLTSS xmm1, xmm2
CMPSS xmm1, xmm2, 5
CMPNLESS xmm1, xmm2
CMPSS xmm1, xmm2, 6
CMPORDSS xmm1, xmm2
CMPSS 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.01H:ECX.AVX[28] = 1” implement the full complement of 32 predicates shown in Table
3-14, software emulation is no longer needed. Compilers and assemblers may implement the following three-
operand pseudo-ops in addition to the four-operand VCMPSS instruction. See Table 3-16, where the notations of
reg1 reg2, and reg3 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 interface. Compilers and assemblers may implement three-operand pseudo-ops for EVEX encoded
VCMPSS instructions in a similar fashion by extending the syntax listed in Table 3-16.
:
Table 3-16. Pseudo-Op and VCMPSS Implementation
Pseudo-Op
CMPSS Implementation
VCMPEQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0
VCMPLTSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1
VCMPLESS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 2
VCMPUNORDSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 3
VCMPNEQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 4
VCMPNLTSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 5
VCMPNLESS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 6
VCMPORDSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 7
VCMPEQ_UQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 8
VCMPNGESS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 9
VCMPNGTSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0AH
VCMPFALSESS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0BH
VCMPNEQ_OQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0CH
CMPSS-Compare Scalar Single Precision Floating-Point Value
Vol. 2A
3-190
Table 3-16. Pseudo-Op and VCMPSS Implementation (Contd.)
Pseudo-Op
CMPSS Implementation
VCMPGESS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0DH
VCMPGTSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0EH
VCMPTRUESS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 0FH
VCMPEQ_OSSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 10H
VCMPLT_OQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 11H
VCMPLE_OQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 12H
VCMPUNORD_SSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 13H
VCMPNEQ_USSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 14H
VCMPNLT_UQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 15H
VCMPNLE_UQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 16H
VCMPORD_SSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 17H
VCMPEQ_USSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 18H
VCMPNGE_UQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 19H
VCMPNGT_UQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1AH
VCMPFALSE_OSSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1BH
VCMPNEQ_OSSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1CH
VCMPGE_OQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1DH
VCMPGT_OQSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1EH
VCMPTRUE_USSS reg1, reg2, reg3
VCMPSS reg1, reg2, reg3, 1FH
Software should ensure VCMPSS is encoded with VEX.L = 0. Encoding VCMPSS with VEX.L = 1 may encounter
unpredictable behavior across different processor generations.
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;
CMPSS-Compare Scalar Single Precision Floating-Point Value
Vol. 2A
3-191
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;
VCMPSS (EVEX Encoded Version)
CMP0 := SRC1[31:0] OP5 SRC2[31:0];
IF k2[0] or *no writemask*
THEN
IF CMP0 = TRUE
THEN DEST[0] := 1;
ELSE DEST[0] := 0; FI;
ELSE
DEST[0] := 0
; zeroing-masking only
FI;
DEST[MAX_KL-1:1] := 0
CMPSS (128-bit Legacy SSE Version)
CMP0 := DEST[31:0] OP3 SRC[31:0];
IF CMP0 = TRUE
THEN DEST[31:0] := FFFFFFFFH;
ELSE DEST[31:0] := 00000000H; FI;
DEST[MAXVL-1:32] (Unmodified)
VCMPSS (VEX.128 Encoded Version)
CMP0 := SRC1[31:0] OP5 SRC2[31:0];
IF CMP0 = TRUE
THEN DEST[31:0] := FFFFFFFFH;
ELSE DEST[31:0] := 00000000H; FI;
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VCMPSS __mmask8 _mm_cmp_ss_mask( __m128 a, __m128 b, int imm);
VCMPSS __mmask8 _mm_cmp_round_ss_mask( __m128 a, __m128 b, int imm, int sae);
VCMPSS __mmask8 _mm_mask_cmp_ss_mask( __mmask8 k1, __m128 a, __m128 b, int imm);
VCMPSS __mmask8 _mm_mask_cmp_round_ss_mask( __mmask8 k1, __m128 a, __m128 b, int imm, int sae);
(V)CMPSS __m128 _mm_cmp_ss(__m128 a, __m128 b, const int imm)
SIMD Floating-Point Exceptions
Invalid if SNaN operand, Invalid if QNaN and predicate as listed in Table 3-8, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-20, “Type 3 Class Exception Conditions.”
CMPSS-Compare Scalar Single Precision Floating-Point Value
Vol. 2A
3-192
EVEX-encoded instructions, see Table 2-49, “Type E3 Class Exception Conditions.”
CMPSS-Compare Scalar Single Precision Floating-Point Value
Vol. 2A
3-193
CMPXCHG-Compare and Exchange
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F B0/r
CMPXCHG r/m81, r81
MR
Valid
Valid2
Compare AL with r/m8. If equal, ZF is set and
r8 is loaded into r/m8. Else, clear ZF and load
r/m8 into AL.
0F B1/r
CMPXCHG r/m16, r16
MR
Valid
Valid2
Compare AX with r/m16. If equal, ZF is set and
r16 is loaded into r/m16. Else, clear ZF and
load r/m16 into AX.
0F B1/r
CMPXCHG r/m32, r32
MR
Valid
Valid2
Compare EAX with r/m32. If equal, ZF is set
and r32 is loaded into r/m32. Else, clear ZF
and load r/m32 into EAX.
REX.W + 0F B1/r
CMPXCHG r/m64, r64
MR
Valid
N.E.
Compare RAX with r/m64. If equal, ZF is set
and r64 is loaded into r/m64. Else, clear ZF
and load r/m64 into RAX.
NOTES:
1. With a REX prefix in 64-bit mode, attempts to access AH, BH, CH, or DH will instead access SPL, DIL, BPL, or SIL, respectively.
2. See the IA-32 Architecture Compatibility section below.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
MR
ModRM:r/m (r, w)
ModRM:reg (r)
N/A
N/A
Description
Compares the value in the AL, AX, EAX, or RAX register with the first operand (destination operand). If the two
values are equal, the second operand (source operand) is loaded into the destination operand. Otherwise, the
destination operand is loaded into the AL, AX, EAX or RAX register. RAX register is available only in 64-bit mode.
This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the
interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the
comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is
written into the destination. (The processor never produces a locked read without also producing a locked write.)
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.
IA-32 Architecture Compatibility
This instruction is not supported on Intel processors earlier than the Intel486 processors.
Operation
(* Accumulator = AL, AX, EAX, or RAX depending on whether a byte, word, doubleword, or quadword comparison is being performed *)
TEMP := DEST
IF accumulator = TEMP
THEN
ZF := 1;
DEST := SRC;
ELSE
ZF := 0;
accumulator := TEMP;
DEST := TEMP;
FI;
CMPXCHG-Compare and Exchange
Vol. 2A
3-194
Flags Affected
The ZF flag is set if the values in the destination operand and register AL, AX, or EAX are equal; otherwise it is
cleared. The CF, PF, AF, SF, and OF flags are set according to the results of the comparison operation.
Protected Mode Exceptions
#GP(0)
If the destination is located in a non-writable segment.
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 but the destination is not a memory operand.
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 but the destination is not a memory operand.
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 but the destination is not a memory operand.
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 but the destination is not a memory operand.
CMPXCHG-Compare and Exchange
Vol. 2A
3-195
CMPXCHG8B/CMPXCHG16B-Compare and Exchange Bytes
Opcode/
Op/
64-Bit
Compat/
Description
Instruction
En
Mode
Leg Mode
0F C7 /1
M
Valid
Valid*
Compare EDX:EAX with m64. If equal, set ZF and load
ECX:EBX into m64. Else, clear ZF and load m64 into EDX:EAX.
CMPXCHG8B m64
REX.W + 0F C7 /1
M
Valid
N.E.
Compare RDX:RAX with m128. If equal, set ZF and load
RCX:RBX into m128. Else, clear ZF and load m128 into
CMPXCHG16B m128
RDX:RAX.
NOTES:
*See IA-32 Architecture Compatibility section below.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (r, w)
N/A
N/A
N/A
Description
Compares the 64-bit value in EDX:EAX (or 128-bit value in RDX:RAX if operand size is 128 bits) with the operand
(destination operand). If the values are equal, the 64-bit value in ECX:EBX (or 128-bit value in RCX:RBX) is stored
in the destination operand. Otherwise, the value in the destination operand is loaded into EDX:EAX (or RDX:RAX).
The destination operand is an 8-byte memory location (or 16-byte memory location if operand size is 128 bits). For
the EDX:EAX and ECX:EBX register pairs, EDX and ECX contain the high-order 32 bits and EAX and EBX contain the
low-order 32 bits of a 64-bit value. For the RDX:RAX and RCX:RBX register pairs, RDX and RCX contain the high-
order 64 bits and RAX and RBX contain the low-order 64bits of a 128-bit value.
This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically. To simplify the
interface to the processor’s bus, the destination operand receives a write cycle without regard to the result of the
comparison. The destination operand is written back if the comparison fails; otherwise, the source operand is
written into the destination. (The processor never produces a locked read without also producing a locked write.)
In 64-bit mode, default operation size is 64 bits. Use of the REX.W prefix promotes operation to 128 bits. Note that
CMPXCHG16B requires that the destination (memory) operand be 16-byte aligned. See the summary chart at the
beginning of this section for encoding data and limits. For information on the CPUID flag that indicates CMPX-
CHG16B, see Chapter 21 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1.
IA-32 Architecture Compatibility
This instruction encoding is not supported on Intel processors earlier than the Pentium processors.
CMPXCHG8B/CMPXCHG16B-Compare and Exchange Bytes
Vol. 2A
3-196
|
||
|
|
|