cmpccxadd

Compare and Add if Condition is Met

CMPccXADD m32, r32, r32

Atomically adds if condition is met.

Details

Atomically compares a value in memory with an operand and adds a second operand to memory if the condition is met. This instruction is part of the APX (Advanced Performance eXtensions) and operates under EVEX encoding with implicit condition code selection via the embedded immediate. The instruction performs a compare-and-add loop at the CPU microarchitecture level, setting ZF based on the comparison result and CF/OF/SF based on the add operation if executed.

Pseudocode Operation

temp ← [dest]; ZF ← (temp == src1); if (condition_met) { [dest] ← [dest] + src2; CF ← carry_from_add; OF ← overflow_from_add; SF ← sign_of_result; } src1 ← temp;

Example

CMPccXADD [rbp-4], eax, eax

Encoding

Binary Layout
66
+0
0F
+1
38
+2
E0
+3
 
Format EVEX
Opcode VEX.128.66.0F38.W0 E0 /r
Extension CMPccXADD

Operands

  • dest
    Mem
  • src1
    Reg
  • src2
    Reg

Reference (Intel® SDM)

Instruction Forms

Opcode Instruction Op/En 64/32-bit Mode CPUID Description
VEX.128.66.0F38.W1 EC !(11):rrr:bbb CMPCCXADD A V/N.E. Compare value in r64 (second operand) with CMPLXADD m64, r64, r64 value in m64. If less (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.
VEX.128.66.0F38.W0 E7 !(11):rrr:bbb CMPCCXADD A V/N.E. Compare value in r32 (second operand) with CMPNBEXADD m32, r32, r32 value in m32. If not below or equal (CF=0 and 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 CMPCCXADD A V/N.E. Compare value in r64 (second operand) with CMPNBEXADD m64, r64, r64 value in m64. If not below or equal (CF=0 and 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 CMPCCXADD A V/N.E. A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A CMPCCXADD A Compare value in r32 (second operand) with CMPNBXADD m32, r32, r32 value in m32. If not below (CF=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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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 V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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 V/N.E. 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. V/N.E. 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. V/N.E. 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. V/N.E. 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 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

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);

Flags Affected

The EFLAGS conditions are updated from the results of the comparison.

Exceptions

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