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