Instruction
ADOX
Adds two unsigned integers and the overflow flag and changes only OF, so a carry chain can run next to an ADCX chain; APX adds a three-operand form.
ADOX adds its source and OF to its destination and puts the carry out in OF, changing no other flag. It is ADCX with OF in place of CF, and exists so that a second carry chain can run beside an ADCX or ADC chain; the ADCX page shows the two working together in a row of a multiplication, with MULX supplying the products.
OF as a carry
After ADOX, OF holds an unsigned carry, not a signed overflow. In one of
Zen 5’s cases, adox rcx, [mem] with RCX all ones, the memory operand 1
and OF clear gave 0 and set OF; CF, already clear, stayed so.
ADD on the same values would set CF and clear OF, as -1
plus 1 does not overflow. A JO or SETO after ADOX
therefore tests the carry. A chain is started with OF clear, usually by
an XOR that zeroes some register, since XOR clears CF and OF together.
Encoding
ADCX and ADOX share the bytes 0F 38 F6 and differ only in the mandatory prefix: 66 for ADCX, F3 for ADOX. Without a prefix and with a memory operand the same bytes are WRSSD, the shadow-stack write of CET. As for ADCX, the destination is a register of 32 or 64 bits, the source a register or memory, and no form takes an immediate. APX adds EVEX forms reaching its new registers and an NDD form with a separate destination.
Independence depends on the processor
The two chains help only where the processor renames OF apart from CF. Intel’s optimization manual says that its Core processors rename CF, OF and the other arithmetic flags as separate registers, while Crestmont, an Atom core, keeps them in one: there ADCX and ADOX depend on each other unless an instruction that writes all the flags without reading them comes between, and hand-tuned code gets less parallelism (Section 4.1.9.8). The same manual places ADCX and ADOX on the shift units of Golden Cove (Table 2-4).
AMD’s Zen 5 instruction table lists ADOX as one macro-op with a latency of one cycle, at four per cycle on ALUs 0 to 3, where it gives ADCX and ADC one per cycle.
GCC 14 and Clang 23 at -O2 compile the intrinsic _addcarryx_u64 to
ADC, never ADOX, so the instruction comes from hand-written assembly.
In the optimization guide
What the optimization guide says about ADOX, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Crestmont and Gracemont
- Integer execution: The E-cores keep the arithmetic flags as one register, so ADCX and ADOX depend on each other unless an instruction that writes all flags comes between them.
Haswell and Broadwell
- What Broadwell changed: Broadwell adds ADCX and ADOX, RDSEED and PREFETCHW, which
-march=broadwellenables in LLVM; code built that way can fault on Haswell, which has none of them.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
ADOX r32, r32
ADOX_GPR32d_GPR32d | F3 0F 38 F6 /r | ADX |
ADOX r32, m32
ADOX_GPR32d_MEMd | F3 0F 38 F6 /r | ADX |
ADOX r64, r64 64-bit mode only
ADOX_GPR64q_GPR64q | F3 REX.W 0F 38 F6 /r | ADX |
ADOX r64, m64 64-bit mode only
ADOX_GPR64q_MEMq | F3 REX.W 0F 38 F6 /r | ADX |
ADOX r32, r32
ADOX_GPR32i32_GPR32i32_APX | EVEX.LLZ.F3.MAP4.W0 66 /r | APX_F + ADX |
ADOX r32, m32
ADOX_GPR32i32_MEMi32_APX | EVEX.LLZ.F3.MAP4.W0 66 /r | APX_F + ADX |
ADOX r64, r64
ADOX_GPR64i64_GPR64i64_APX | EVEX.LLZ.F3.MAP4.W1 66 /r | APX_F + ADX |
ADOX r64, m64
ADOX_GPR64i64_MEMi64_APX | EVEX.LLZ.F3.MAP4.W1 66 /r | APX_F + ADX |
ADOX r32, r32, r32 NDD
ADOX_GPR32i32_GPR32i32_GPR32i32_APX_N3 | EVEX.LLZ.F3.MAP4.W0 66 /r ND=1 | APX_F + APX_NCI_NDD_NF + ADX |
ADOX r32, r32, m32 NDD
ADOX_GPR32i32_GPR32i32_MEMi32_APX_N3 | EVEX.LLZ.F3.MAP4.W0 66 /r ND=1 | APX_F + APX_NCI_NDD_NF + ADX |
ADOX r64, r64, r64 NDD
ADOX_GPR64i64_GPR64i64_GPR64i64_APX_N3 | EVEX.LLZ.F3.MAP4.W1 66 /r ND=1 | APX_F + APX_NCI_NDD_NF + ADX |
ADOX r64, r64, m64 NDD
ADOX_GPR64i64_GPR64i64_MEMi64_APX_N3 | EVEX.LLZ.F3.MAP4.W1 66 /r ND=1 | APX_F + APX_NCI_NDD_NF + ADX |
Latency and throughput
| Model | r32, r32r64, r64 | r32, m32r64, m64 |
|---|---|---|
| Broadwell, Skylake, Skylake-SP, Ice Lake, Alder Lake, Sapphire Rapids | 1 / 0.5p06 | 6 / 0.5p06 |
| Lunar Lake | 1 / 0.33p024 | 6 / 0.33p024 |
| Zen | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 |
| Zen 2 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 5 / 0.33ALU0 ALU1 ALU2 ALU3 |
| Zen 3, Zen 4 | 1 / 1ALU0 ALU1 ALU2 ALU3 | 5 / 1ALU0 ALU1 ALU2 ALU3 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
a = dest.read()
b = src.read()
c = of # the carry in, from OF
r = a + b + c
of = r >> OSIZE & 1 # the carry out, in OF: an unsigned carry,
# not a signed overflow; CF, SF, ZF, AF and
# PF keep their values
dest.write(r) # a 32-bit register: bits 63:32 cleared
Run on AMD Zen 5 (EPYC 9645): 96 cases. The APX forms were not run: none of these processors has APX.
a = src1.read()
b = src2.read()
c = of # the carry in, from OF
r = a + b + c
of = r >> OSIZE & 1 # the unsigned carry out, in OF; no other
# flag changes
dest.write(r) # the new destination: bits 63:32 cleared
Not run on a processor: none of these processors has APX.
Operands
| Operand | Kind | Action |
|---|---|---|
ADOX r32, r/m32 ADOX r64, r/m64 64-bit mode only | ||
r32/64 | explicit | read, write |
r/m32/64 | explicit | read |
RFLAGS | implicit | read, write |
ADOX r32, r32, r/m32 NDD ADOX r64, r64, r/m64 NDD | ||
r32/64 | explicit | write |
r32/64 | explicit | read |
r/m32/64 | explicit | read |
RFLAGS | implicit | read, write |
Flags
| OF |
|---|
| All forms |
| TM |
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
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.
| ISA set | CPUID | Processors |
|---|---|---|
ADOX_ADCX | ADX | Broadwell, Skylake, Comet Lake, Cannon Lake, Ice Lake (client), Tiger Lake, Alder Lake, Arrow Lake, Panther Lake, Nova Lake, Skylake-SP, Cascade Lake, Cooper Lake, Ice Lake (server), Sapphire Rapids, Emerald Rapids, Granite Rapids, Diamond Rapids, Sierra Forest, Clearwater Forest, Knights Landing, Knights Mill, Zen, Zen+, Zen 2, Zen 3, Zen 4, Zen 5, Zen 6 |
APX_F_ADX | APX_F + ADX | Nova Lake, Diamond Rapids |
APX_F_ADX_N3 | APX_F + APX_NCI_NDD_NF + ADX | Same as APX_F_ADX |
More ADX instructions
More APX instructions
Sources
- Intel XED v2026.08.23 (commit
0bcb6237345c): forms, encodings, operands, flags, exception classes, attributes, ISA sets, CPUID bits and chip model. - The CPU data of x86-64.net: Zen 3 to Zen 6, from GCC’s
-marchfeature sets and AMD’s Processor Programming References, which the page of each processor cites. - LLVM 23.1.2's x86 scheduling models (commit
85ac56026243): the latency, reciprocal throughput and ports of each form, as llvm-mca reports them. - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (325383-093, September 2026): Volume 2A, page 3-31 (ADOX)
- Intel Advanced Performance Extensions (Intel APX) Architecture Specification, revision 9.0 (355828-009, August 2026)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, October 2026)
- Intel 64 and IA-32 Architectures Optimization Reference Manual, Volume 1 (248966-051, October 2026)
- Software Optimization Guide for the AMD Zen5 Microarchitecture (58455, rev. 1.00, August 2024), Wayback Machine copy of AMD's ZIP
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.