Extensions
Forms
48 (24 Legacy, 24 EVEX)
Data
Intel XED v2026.08.23

ADC adds its source and CF to its destination, and leaves the carry out of that sum in CF. That makes it the link of a chain: to add numbers wider than a register, ADD the lowest words and ADC each higher pair, every ADC taking the carry of the one before.

Wide additions in C

GCC 14 and Clang 23 at -O2 compile an unsigned __int128 addition to add on the low halves and adc on the high halves, the result in RDX:RAX. For longer numbers both offer carry built-ins: __builtin_addcll(a, b, carry_in, &carry_out), called once per word with the carry passed along, becomes one ADD and a row of ADCs, with the loads and stores between them done by MOV, which leaves CF alone.

A loop over the words is harder, because the loop’s own CMP overwrites CF. With the _addcarry_u64 intrinsic in a loop, both compilers save the carry in a register with SETC (or SETB) after each ADC and recreate it at the top with add al, -1, which sets CF exactly when AL is not 0; Clang also unrolls by four and keeps CF in the flags within each pass. Hand-written code can keep CF across the whole loop by stepping with LEA and counting with DEC, neither of which writes CF, as in Example 3-26 of Intel’s Optimization Reference Manual.

Adding a condition

ADC with 0 adds the carry alone, and CMP puts an unsigned comparison into CF, so a + (b < c) on unsigned numbers becomes cmp rsi, rdx and adc rax, 0, without a SETcc.

SBB is the subtracting counterpart. ADCX and ADOX add with a carry in CF or OF only, so that two chains can run side by side; Intel’s manual presents them, with MULX, as a way to speed up arithmetic on large integers (Section 2.8.5.10). APX gives ADC a form with a new destination register but, unlike ADD, none that leaves the flags unchanged.

Intel’s manual notes that ADC and SBB became faster in Sandy Bridge, with a throughput of one per cycle instead of 1.5 to 2 cycles before (Section 3.5.1.3).

In the optimization guide

What the optimization guide says about ADC, a line per claim. Each links to the claim in the guide, with its sources and where they differ.

Haswell and Broadwell

  • What Broadwell changed: A micro-op of Haswell’s reads three inputs only for FMA, so ADC, SBB and CMOV, which read two registers and the flags, are two micro-ops each; Broadwell makes them one, though stores and blends stay at two.

Forms

Every encoding of ADC that Intel XED knows, one row per XED instruction form (iform). How to read the notation.
InstructionEncodingRequires
ADC m8, imm8 ADC_MEMb_IMMb_80r280 /2 ibBase instruction set
ADC r8, imm8 ADC_GPR8_IMMb_80r280 /2 ibBase instruction set
ADC m16/32/64, imm16/32 ADC_MEMv_IMMz81 /2 iw/idBase instruction set
ADC r16/32/64, imm16/32 ADC_GPRv_IMMz81 /2 iw/idBase instruction set
ADC m8, imm8 not in 64-bit mode ADC_MEMb_IMMb_82r282 /2 ibBase instruction set
ADC r8, imm8 not in 64-bit mode ADC_GPR8_IMMb_82r282 /2 ibBase instruction set
ADC m16/32/64, imm8 ADC_MEMv_IMMb83 /2 ibBase instruction set
ADC r16/32/64, imm8 ADC_GPRv_IMMb83 /2 ibBase instruction set
ADC m8, r8 ADC_MEMb_GPR810 /rBase instruction set
ADC r8, r8 ADC_GPR8_GPR8_1010 /rBase instruction set
ADC m16/32/64, r16/32/64 ADC_MEMv_GPRv11 /rBase instruction set
ADC r16/32/64, r16/32/64 ADC_GPRv_GPRv_1111 /rBase instruction set
ADC r8, m8 ADC_GPR8_MEMb12 /rBase instruction set
ADC r8, r8 ADC_GPR8_GPR8_1212 /rBase instruction set
ADC r16/32/64, m16/32/64 ADC_GPRv_MEMv13 /rBase instruction set
ADC r16/32/64, r16/32/64 ADC_GPRv_GPRv_1313 /rBase instruction set
ADC AL, imm8 ADC_AL_IMMb14 ibBase instruction set
ADC rAX, imm16/32 ADC_OrAX_IMMz15 iw/idBase instruction set
LOCK ADC m8, imm8 ADC_LOCK_MEMb_IMMb_80r280 /2 ibBase instruction set
LOCK ADC m16/32/64, imm16/32 ADC_LOCK_MEMv_IMMz81 /2 iw/idBase instruction set
LOCK ADC m8, imm8 not in 64-bit mode ADC_LOCK_MEMb_IMMb_82r282 /2 ibBase instruction set
LOCK ADC m16/32/64, imm8 ADC_LOCK_MEMv_IMMb83 /2 ibBase instruction set
LOCK ADC m8, r8 ADC_LOCK_MEMb_GPR810 /rBase instruction set
LOCK ADC m16/32/64, r16/32/64 ADC_LOCK_MEMv_GPRv11 /rBase instruction set
ADC r8, r8 ADC_GPR8i8_GPR8i8_APXEVEX.LLZ.NP.MAP4.WIG 10 /r
EVEX.LLZ.NP.MAP4.WIG 12 /r
APX_F
ADC m8, r8 ADC_MEMi8_GPR8i8_APXEVEX.LLZ.NP.MAP4.WIG 10 /rAPX_F
ADC r16/32/64, r16/32/64, imm8 NDD ADC_GPRv_GPRv_IMM8_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 83 /2 ib ND=1APX_F + APX_NCI_NDD_NF
ADC r16/32/64, m16/32/64, imm8 NDD ADC_GPRv_MEMv_IMM8_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 83 /2 ib ND=1APX_F + APX_NCI_NDD_NF
ADC r8, r8, r8 NDD ADC_GPR8i8_GPR8i8_GPR8i8_APX_N3EVEX.LLZ.NP.MAP4.WIG 10 /r ND=1
EVEX.LLZ.NP.MAP4.WIG 12 /r ND=1
APX_F + APX_NCI_NDD_NF
ADC r8, m8, r8 NDD ADC_GPR8i8_MEMi8_GPR8i8_APX_N3EVEX.LLZ.NP.MAP4.WIG 10 /r ND=1APX_F + APX_NCI_NDD_NF
ADC r16/32/64, r16/32/64 ADC_GPRv_GPRv_APXEVEX.LLZ.NP.MAP4.SCALABLE 11 /r
EVEX.LLZ.NP.MAP4.SCALABLE 13 /r
APX_F
ADC m16/32/64, r16/32/64 ADC_MEMv_GPRv_APXEVEX.LLZ.NP.MAP4.SCALABLE 11 /rAPX_F
ADC r16/32/64, r16/32/64, r16/32/64 NDD ADC_GPRv_GPRv_GPRv_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 11 /r ND=1
EVEX.LLZ.NP.MAP4.SCALABLE 13 /r ND=1
APX_F + APX_NCI_NDD_NF
ADC r16/32/64, m16/32/64, r16/32/64 NDD ADC_GPRv_MEMv_GPRv_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 11 /r ND=1APX_F + APX_NCI_NDD_NF
ADC r8, m8 ADC_GPR8i8_MEMi8_APXEVEX.LLZ.NP.MAP4.WIG 12 /rAPX_F
ADC r8, r8, m8 NDD ADC_GPR8i8_GPR8i8_MEMi8_APX_N3EVEX.LLZ.NP.MAP4.WIG 12 /r ND=1APX_F + APX_NCI_NDD_NF
ADC r16/32/64, m16/32/64 ADC_GPRv_MEMv_APXEVEX.LLZ.NP.MAP4.SCALABLE 13 /rAPX_F
ADC r8, r8, imm8 NDD ADC_GPR8i8_GPR8i8_IMM8_APX_N3EVEX.LLZ.NP.MAP4.WIG 80 /2 ib ND=1APX_F + APX_NCI_NDD_NF
ADC r8, m8, imm8 NDD ADC_GPR8i8_MEMi8_IMM8_APX_N3EVEX.LLZ.NP.MAP4.WIG 80 /2 ib ND=1APX_F + APX_NCI_NDD_NF
ADC r16/32/64, r16/32/64, m16/32/64 NDD ADC_GPRv_GPRv_MEMv_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 13 /r ND=1APX_F + APX_NCI_NDD_NF
ADC r8, imm8 ADC_GPR8i8_IMM8_APXEVEX.LLZ.NP.MAP4.WIG 80 /2 ibAPX_F
ADC m8, imm8 ADC_MEMi8_IMM8_APXEVEX.LLZ.NP.MAP4.WIG 80 /2 ibAPX_F
ADC r16/32/64, imm16/32 ADC_GPRv_IMMz_APXEVEX.LLZ.NP.MAP4.SCALABLE 81 /2 iw/idAPX_F
ADC m16/32/64, imm16/32 ADC_MEMv_IMMz_APXEVEX.LLZ.NP.MAP4.SCALABLE 81 /2 iw/idAPX_F
ADC r16/32/64, r16/32/64, imm16/32 NDD ADC_GPRv_GPRv_IMMz_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 81 /2 iw/id ND=1APX_F + APX_NCI_NDD_NF
ADC r16/32/64, m16/32/64, imm16/32 NDD ADC_GPRv_MEMv_IMMz_APX_N3EVEX.LLZ.NP.MAP4.SCALABLE 81 /2 iw/id ND=1APX_F + APX_NCI_NDD_NF
ADC r16/32/64, imm8 ADC_GPRv_IMM8_APXEVEX.LLZ.NP.MAP4.SCALABLE 83 /2 ibAPX_F
ADC m16/32/64, imm8 ADC_MEMv_IMM8_APXEVEX.LLZ.NP.MAP4.SCALABLE 83 /2 ibAPX_F

Latency and throughput

What the scheduling models of LLVM 23.1.2 give for each form, not measurements: latency / reciprocal throughput in cycles, the ports under them. A row is a model, or models that agree; a dash, a form that its processors lack. Memory forms: latency from the address, ports without the load and store units. Which processors each model covers.
Modelm8, imm8
ADC m8, imm8
r8, imm8
r16, imm16
r32, imm32
r16, imm8
r32, imm8
r64, imm8
r8, r8
r16, r16
r32, r32
r64, r64
m16, imm16
m32, imm32
m64, imm32
m16, imm8
m32, imm8
m64, imm8
ADC m16, imm16
ADC m32, imm32
ADC m64, imm32
ADC m16, imm8
ADC m32, imm8
ADC m64, imm8
r64, imm32m8, r8
ADC m8, r8
m16, r16
m32, r32
m64, r64
ADC m16, r16
ADC m32, r32
ADC m64, r64
r8, m8
r16, m16
r32, m32
r64, m64
AL, imm8
rAX, imm16
rAX, imm32
Sandy Bridge9 / 1p0152 / 0.67p0159 / 1p0152 / 0.67p0159 / 1p0159 / 1p0157 / 0.67p0152 / 0.67p015
Haswell9 / 1p01562 / 0.5p01569 / 1p01562 / 0.5p01569 / 1p01569 / 1p01567 / 0.5p01562 / 0.5p0156
Broadwell, Skylake, Skylake-SP, Ice Lake8 / 1p01561 / 0.5p068 / 1p01561 / 0.5p068 / 1p01568 / 1p01566 / 0.5p062 / 0.5p0156
Alder Lake, Sapphire Rapids13 / 0.5p0 p1 p5 p6 p111 / 0.5p0612 / 0.5p0 p1 p5 p6 p111 / 0.5p0613 / 0.6p0 p1 p5 p6 p1112 / 0.6p0 p1 p5 p6 p116 / 0.5p061 / 0.5p06
Lunar Lake12 / 0.5p0123451 / 0.33p02412 / 0.5p0123451 / 0.33p02412 / 0.5p01234512 / 0.5p0123456 / 0.33p0241 / 0.33p024
Bonnell1 / 1p01 / 0.5p011 / 1p01 / 0.5p011 / 1p01 / 1p01 / 1p01 / 0.5p01
Silvermont5 / 2IEC0 IEC1 MEC1 / 0.5IEC0 IEC15 / 2IEC0 IEC1 MEC1 / 0.5IEC0 IEC15 / 2IEC0 IEC1 MEC5 / 2IEC0 IEC1 MEC4 / 1IEC0 IEC1 MEC1 / 0.5IEC0 IEC1
Piledriver6 / 2EX0 EX11 / 1EX0 EX16 / 2EX0 EX11 / 1.5EX0 EX16 / 2EX0 EX16 / 2EX0 EX15 / 1.5EX0 EX11 / 1EX0 EX1
Zen5 / 0.5ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU35 / 0.5ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU35 / 0.5ALU0 ALU1 ALU2 ALU35 / 0.5ALU0 ALU1 ALU2 ALU35 / 0.5ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU3
Zen 25 / 0.33ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU35 / 0.33ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU35 / 0.33ALU0 ALU1 ALU2 ALU35 / 0.33ALU0 ALU1 ALU2 ALU35 / 0.33ALU0 ALU1 ALU2 ALU31 / 0.25ALU0 ALU1 ALU2 ALU3
Zen 3, Zen 46 / 1ALU0 ALU1 ALU2 ALU31 / 1ALU0 ALU1 ALU2 ALU36 / 1ALU0 ALU1 ALU2 ALU31 / 1ALU0 ALU1 ALU2 ALU31 / 1.75ALU0 ALU1 ALU2 ALU36 / 1ALU0 ALU1 ALU2 ALU35 / 1ALU0 ALU1 ALU2 ALU31 / 1ALU0 ALU1 ALU2 ALU3
Jaguar6 / 1ALU0 ALU11 / 1ALU0 ALU16 / 1ALU0 ALU11 / 1ALU0 ALU16 / 1ALU0 ALU16 / 1ALU0 ALU14 / 1ALU0 ALU11 / 1ALU0 ALU1

Operation

What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.

All forms but the NDD forms
a = dest.read()                  # with LOCK: one atomic read-modify-write
b = sext(src)                    # an immediate is sign-extended to OSIZE
c = cf                           # the carry in
flags = add_flags(a, b, c)
dest.write(a + b + c)            # a 32-bit register: bits 63:32 cleared

Run on AMD Zen 5 (EPYC 9645) and an Intel processor under KVM (model hidden): 1,040 cases. The APX forms were not run: none of these processors has APX. The forms that 64-bit mode lacks were not run: the probe runs in 64-bit mode.

NDD forms
a = src1.read()
b = sext(src2)                   # an immediate is sign-extended to OSIZE
c = cf                           # the carry in
flags = add_flags(a, b, c)
dest.write(a + b + c)            # the new destination: bits 63:OSIZE
                                 # cleared, even for 8 and 16 bits

Not run on a processor: none of these processors has APX.

Operands

What each form reads and writes, as Intel XED records it: the operands of its syntax, in order, and the implicit ones that the syntax does not name. How to read.
OperandKindAction
ADC r/m8, imm8 ADC r/m16/32/64, imm16/32 ADC r/m16/32/64, imm8 LOCK ADC m8, imm8 LOCK ADC m16/32/64, imm16/32 LOCK ADC m16/32/64, imm8
r/m8/16/32/64explicitread, write
imm8/16/32explicitread
RFLAGSimplicitread, write
ADC r/m8, r8 ADC r/m16/32/64, r16/32/64 LOCK ADC m8, r8 LOCK ADC m16/32/64, r16/32/64
r/m8/16/32/64explicitread, write
r8/16/32/64explicitread
RFLAGSimplicitread, write
ADC r8, r/m8 ADC r16/32/64, r/m16/32/64
r8/16/32/64explicitread, write
r/m8/16/32/64explicitread
RFLAGSimplicitread, write
ADC AL, imm8 ADC rAX, imm16/32
AL, rAXexplicitread, write
imm8/16/32explicitread
RFLAGSimplicitread, write
ADC r8, r/m8, imm8 NDD ADC r16/32/64, r/m16/32/64, imm8 NDD ADC r16/32/64, r/m16/32/64, imm16/32 NDD
r8/16/32/64explicitwrite
r/m8/16/32/64explicitread
imm8/16/32explicitread
RFLAGSimplicitread, write
ADC r8, r/m8, r8 NDD ADC r16/32/64, r/m16/32/64, r16/32/64 NDD
r8/16/32/64explicitwrite
r/m8/16/32/64explicitread
r8/16/32/64explicitread
RFLAGSimplicitread, write
ADC r8, r8, m8 NDD ADC r16/32/64, r16/32/64, m16/32/64 NDD
r8/16/32/64explicitwrite
r8/16/32/64explicitread
m8/16/32/64explicitread
RFLAGSimplicitread, write

Flags

T tested, M modified; blank: not affected. How to read.
OFSFZFAFPFCF
All forms
MMMMMTM

Exceptions

The exception class is XED's name for the set of exception conditions that a form follows. How to read.

Legacy forms
none in XED
EVEX forms
APX-EVEX-INT

Attributes

What else XED records about the forms. How to read.

ADC m8, imm8 ADC m8, r8 ADC m16/32/64, imm16/32 ADC m16/32/64, imm8 ADC m16/32/64, r16/32/64
accepts a LOCK prefix
LOCK forms
locked: atomic read-modify-write; accepts XACQUIRE; accepts XRELEASE

CPUID and processors

Each form belongs to an XED ISA set. A form can be used when the processor reports every CPUID bit of one of its ISA set's alternatives.

CPUID requirements and processors of the XED ISA sets above. Alternatives are separated by “or”; processors follow XED’s chip model, whose AMD processors end with Zen 2, and the CPU data of this site for Zen 3 to Zen 6.
ISA setCPUIDProcessors
I86

No CPUID bit: part of the base instruction set.

Every x86-64 processor in XED’s model and Zen 3 to Zen 6
APX_F

APX_F
CPUID.(EAX=07H,ECX=1):EDX[21] APX_F

Nova Lake, Diamond Rapids
APX_F_N3

APX_F + APX_NCI_NDD_NF
CPUID.(EAX=07H,ECX=1):EDX[21] APX_F
CPUID.(EAX=29H,ECX=0):EBX[0] APX_NCI_NDD_NF

Same as APX_F

More General-purpose instructions

All 109 General-purpose instructions

More APX instructions

All 88 APX instructions

Sources

  1. Intel XED v2026.08.23 (commit 0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model.
  2. The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s -march feature sets and AMD’s Processor Programming References, which the page of each processor cites.
  3. LLVM 23.1.2's x86 scheduling models (commit 85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them.
  4. Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-9 (ADC)
  5. Intel Advanced Performance Extensions (Intel APX) Architecture Specification, revision 9.0 (355828-009, August 2026)
  6. AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
  7. Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)

The tables are derived from Intel XED, Copyright Intel Corporation, licensed under the Apache License 2.0; x86-64.net converted and reformatted them. The timings come from LLVM's scheduling models, part of the LLVM Project, licensed under the Apache License 2.0 with LLVM Exceptions. The text is our own.