Instruction
IDIV
Divides a signed double-width dividend in rDX:rAX (AX for bytes) by the operand into quotient and remainder; APX adds a form that keeps the flags.
- Extensions
- Forms
- 12 (4 Legacy, 8 EVEX)
- Data
- Intel XED v2026.08.23
IDIV is the signed counterpart of DIV: it divides
rDX:rAX (AX for bytes) by its operand and leaves the quotient in rAX
(AL) and the remainder in rDX (AH). The quotient is rounded toward zero
and the remainder takes the sign of the dividend, which is what C’s /
and % require: -7 / 2 gives -3 with remainder -1, and 7 / -2 gives -3
with remainder 1.
The upper half holds the sign
The dividend is twice as wide as the divisor, so dividing one register
by another needs an upper half filled with copies of the lower half’s
sign bit. GCC 14 and Clang 23 at -O2 emit CQO before
idiv rsi and CDQ before idiv esi. The
xor edx, edx that prepares DIV is wrong here: with RDX = 0 and
RAX = -7, the dividend is 2^64 - 7, and IDIV by 2 returns
9,223,372,036,854,775,804 instead of -3, with no fault to show it.
Intel’s optimization manual allows the XOR in place of CDQ only when
the dividend is known to be positive (Section 3.5.1.1).
Two divide errors
IDIV raises #DE for a divisor of 0 and for a quotient that does not fit
in rAX (AL for bytes). With a sign-extended dividend, the second case
has one instance per size: the most negative number divided by -1,
whose quotient is one too large (2^63 for 64 bits). Since IDIV computes
both results at once, LONG_MIN % -1 faults too, although its
remainder, 0, would fit. For bytes the dividend is all of AX, so
-128 / -1 overflows AL. C leaves these cases undefined, and neither
compiler checks for them. In the cases recorded on Zen 5, dividing 7
by 0, LONG_MIN by -1 and INT_MIN by -1 each raised #DE at the
IDIV, which Linux 7.3 hands to the program as SIGFPE with si_code
FPE_INTDIV and si_addr pointing at the instruction.
Narrowing 64-bit divisions
Clang 23 puts a test before a 64-bit IDIV: it ORs the two operands and,
when bits 63:32 of the result are zero, so that both are nonnegative
32-bit values, runs xor edx, edx and the 32-bit div esi instead.
GCC 14 emits the CQO and IDIV alone. Division by a constant uses
neither: both compilers multiply by a scaled reciprocal, as for
DIV.
In the optimization guide
What the optimization guide says about IDIV, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Bulldozer to Excavator
- Integer execution: DIV and IDIV are microcoded, and their time grows with the width of the dividend’s value on Bulldozer and of the quotient’s from Piledriver on, up to 76 and 72 cycles for 64-bit operands, so a division by a constant is best done by multiplying. sources differ
Golden Cove and Raptor Cove
- Integer execution: Integer division runs on port 1; LLVM’s models give a 32-bit DIV 15 cycles and a 64-bit one 18, the latter three micro-ops that keep port 1 busy for three cycles.
Haswell and Broadwell
- Integer execution and bypass: A 64-bit integer divide is much slower than a 32-bit one, so LLVM, tuning for Haswell or Broadwell, uses the 32-bit divide when both 64-bit operands turn out positive and below 2^32. sources differ
Ice Lake to Rocket Lake
- Integer execution: A new integer divider on port 1 makes DIV and IDIV much faster than on Skylake, in latency and in throughput; neither Intel nor Agner Fog gives numbers. sources differ
Jaguar and Puma
- Integer execution: The radix-4 divider produces two quotient bits a cycle: AMD’s spreadsheet gives DIV and IDIV at most 25 cycles with 32-bit operands and 41 with 64-bit ones, ending early when the quotient is small. sources differ
Sandy Bridge and Ivy Bridge
- Integer and vector execution: One divider, on port 0, serves integer division and also the square root and floating-point division operations, so only one of them runs at a time; LLVM’s model gives an 8-, 16-, 32- or 64-bit integer divide the same 25-cycle latency and a throughput of one every 10 cycles.
Silvermont to Goldmont Plus
- Out-of-order and in-order execution: Division is microcoded and slow on Silvermont, up to 135 cycles at 64 bits; Goldmont takes 11 to 41. sources differ
Skylake to Cooper Lake
- Integer execution: Integer division is slow: LLVM’s models give a 64-bit DIV 76 cycles and 32 micro-ops and a 64-bit IDIV 102 cycles, against 18 on Golden Cove.
Tremont
- Integer execution: Three ALU ports run simple integer operations, three a cycle; shifts go to port 00 only, and multiplication, division,
popcnt,crc32and the bit operations to port 01 only.
Zen and Zen+
- Integer execution: The divider, on ALU 2, yields two bits of the quotient a cycle: AMD’s spreadsheet gives a 64-bit DIV 41 cycles and a 32-bit one 25, as LLVM’s model does.
Zen 2
- Integer execution: The divider produces two bits of the quotient a cycle, so division is slow: AMD’s spreadsheet gives a 64-bit DIV 41 cycles and a 32-bit one 25, as LLVM’s model does, far more than on Zen 3.
Zen 3
- Integer execution: Division runs on ALU 0 and takes about 8 cycles plus 1 for every 9 bits of the quotient, and a typical 64-bit division can start every 8 cycles. sources differ
Zen 4
- Integer execution:
xor edx, edxbefore DIV, or CDQ or CQO before IDIV, with the same operand size and a divisor in a register other than rDX, saves a macro-op: the pair is dispatched as one fewer. - Integer execution: Division takes about 8 cycles plus 1 for every 9 bits of the quotient, and a typical 64-bit division can start every 8 cycles. sources differ
Zen 5
- Integer execution: Division takes about 8 cycles plus 1 for every 9 bits of the quotient, and a typical 64-bit division can start every 8 cycles.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
IDIV m8
IDIV_MEMb | F6 /7 | Base instruction set |
IDIV r8
IDIV_GPR8 | F6 /7 | Base instruction set |
IDIV m16/32/64
IDIV_MEMv | F7 /7 | Base instruction set |
IDIV r16/32/64
IDIV_GPRv | F7 /7 | Base instruction set |
IDIV r8
IDIV_GPR8i8_APX | EVEX.LLZ.NP.MAP4.WIG F6 /7 | APX_F |
IDIV m8
IDIV_MEMi8_APX | EVEX.LLZ.NP.MAP4.WIG F6 /7 | APX_F |
IDIV r8 NF
IDIV_GPR8i8_APX_N3 | EVEX.LLZ.NP.MAP4.WIG F6 /7 NF=1 | APX_F + APX_NCI_NDD_NF |
IDIV m8 NF
IDIV_MEMi8_APX_N3 | EVEX.LLZ.NP.MAP4.WIG F6 /7 NF=1 | APX_F + APX_NCI_NDD_NF |
IDIV r16/32/64
IDIV_GPRv_APX | EVEX.LLZ.NP.MAP4.SCALABLE F7 /7 | APX_F |
IDIV m16/32/64
IDIV_MEMv_APX | EVEX.LLZ.NP.MAP4.SCALABLE F7 /7 | APX_F |
IDIV r16/32/64 NF
IDIV_GPRv_APX_N3 | EVEX.LLZ.NP.MAP4.SCALABLE F7 /7 NF=1 | APX_F + APX_NCI_NDD_NF |
IDIV m16/32/64 NF
IDIV_MEMv_APX_N3 | EVEX.LLZ.NP.MAP4.SCALABLE F7 /7 NF=1 | APX_F + APX_NCI_NDD_NF |
Latency and throughput
| Model | m8 | r8 | m16 | m32 | m64 | r16 | r32 | r64 |
|---|---|---|---|---|---|---|---|---|
| Sandy Bridge | 30 / 10SBDivider p0 | 25 / 10SBDivider p0 | 30 / 10SBDivider p0 | 30 / 10SBDivider p0 | 30 / 10SBDivider p0 | 25 / 10SBDivider p0 | 25 / 10SBDivider p0 | 25 / 10SBDivider p0 |
| Haswell | 29 / 10HWDivider p0 | 23 / 1p0156 | 29 / 10HWDivider p0 | 29 / 10HWDivider p0 | 29 / 10HWDivider p0 | 112 / 16.5p0156 | 112 / 16.5p0156 | 112 / 16.5p0156 |
| Broadwell | 35 / 2p0156 | 25 / 10BWDivider p0 | 35 / 2p0156 | 35 / 2p0156 | 35 / 2p0156 | 25 / 10BWDivider p0 | 25 / 10BWDivider p0 | 25 / 10BWDivider p0 |
| Skylake | 28 / 4p0156 | 25 / 10SKLDivider p0 | 28 / 4p0156 | 28 / 4p0156 | 28 / 4p0156 | 102 / 16.5p0156 | 102 / 16.5p0156 | 102 / 16.5p0156 |
| Skylake-SP | 28 / 4p0156 | 25 / 10SKXDivider p0 | 28 / 4p0156 | 28 / 4p0156 | 28 / 4p0156 | 102 / 16.5p0156 | 102 / 16.5p0156 | 102 / 16.5p0156 |
| Ice Lake | 28 / 4p0156 | 25 / 10ICXDivider p0 | 28 / 4p0156 | 28 / 4p0156 | 28 / 4p0156 | 102 / 16.5p0156 | 102 / 16.5p0156 | 102 / 16.5p0156 |
| Alder Lake, Sapphire Rapids | 22 / 3p1 | 17 / 3p1 | 20 / 3p0 p1 p5 p6 p11 | 19 / 3p0 p1 p5 p6 p11 | 23 / 3p1 | 16 / 3p0 p1 p5 p6 p11 | 15 / 3p0 p1 p5 p6 p11 | 18 / 3p1 |
| Lunar Lake | 22 / 1p135 | 17 / 1p135 | 20 / 1p012345 | 19 / 1p012345 | 22 / 1p135 | 16 / 1p012345 | 15 / 1p012345 | 18 / 1p135 |
| Bonnell | 62 / 62p1 | 62 / 62p01 | 62 / 62p1 | 62 / 62p1 | 130 / 130p1 | 62 / 62p01 | 62 / 62p01 | 130 / 130p01 |
| Silvermont | 29 / 25SLMDivider | 25 / 25IEC0 IEC1 SLMDivider | 29 / 25SLMDivider | 29 / 25SLMDivider | 29 / 25SLMDivider | 25 / 25IEC0 IEC1 SLMDivider | 25 / 25IEC0 IEC1 SLMDivider | 25 / 25IEC0 IEC1 SLMDivider |
| Piledriver | 16 / 12Div EX1 | 12 / 12Div EX1 | 19 / 17Div EX1 | 18 / 25Div EX1 | 18 / 14Div EX1 | 15 / 17Div EX1 | 14 / 25Div EX1 | 14 / 14Div EX1 |
| Zen, Zen 2 | 19 / 15ALU2 Divider | 15 / 15ALU2 Divider | 21 / 17ALU2 Divider | 29 / 25ALU2 Divider | 45 / 41ALU2 Divider | 17 / 17ALU2 Divider | 25 / 25ALU2 Divider | 41 / 41ALU2 Divider |
| Zen 3 | 14 / 10ALU0 | 10 / 10ALU0 | 15 / 11ALU0 | 17 / 13ALU0 | 21 / 17ALU0 | 11 / 11ALU0 | 13 / 13ALU0 | 17 / 17ALU0 |
| Zen 4 | 13 / 9ALU0 | 9 / 9ALU0 | 14 / 10ALU0 | 16 / 12ALU0 | 22 / 18ALU0 | 10 / 10ALU0 | 12 / 12ALU0 | 18 / 181ALU0 |
| Jaguar | 15 / 12ALU1 Div | 12 / 12ALU1 Div | 20 / 17ALU1 Div | 28 / 25ALU1 Div | 44 / 41ALU1 Div | 17 / 17ALU1 Div | 25 / 25ALU1 Div | 41 / 41ALU1 Div |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
d = signed(src)
if d == 0:
fault(DE) # a divide by zero
if OSIZE == 8:
n = signed(ax) # the dividend: AX, DX:AX, EDX:EAX or
else: # RDX:RAX, signed
n = signed(rDX) << OSIZE | rAX
q = abs(n) // abs(d) # the quotient rounds toward zero
if (n < 0) != (d < 0):
q = -q
big = 1 << (OSIZE - 1)
if not -big <= q < big:
fault(DE) # the quotient does not fit in rAX: as
# for the smallest number divided by -1
r = n - q * d # the remainder has the dividend's sign
if OSIZE == 8:
al = q
ah = r
else: # EAX and EDX: bits 63:32 cleared
rAX = q
rDX = r
if not nf: # NF=1 (APX) leaves the flags as they were
of = sf = zf = af = pf = cf = UNDEFINEDRun on AMD Zen 5 (EPYC 9645): 84 cases. The APX forms were not run: none of these processors has APX.
Operands
| Operand | Kind | Action |
|---|---|---|
IDIV r/m8 | ||
r/m8 | explicit | read |
AX | implicit | read, write |
RFLAGS | implicit | write |
IDIV r/m16/32/64 | ||
r/m16/32/64 | explicit | read |
rAX | implicit | read, write |
rDX | implicit | read, write |
RFLAGS | implicit | write |
IDIV r/m8 NF | ||
r/m8 | explicit | read |
AX | implicit | read, write |
IDIV r/m16/32/64 NF | ||
r/m16/32/64 | explicit | read |
rAX | implicit | read, write |
rDX | implicit | read, write |
Flags
| OF | SF | ZF | AF | PF | CF |
|---|---|---|---|---|---|
| NF forms | |||||
| Not affected | |||||
| Other forms | |||||
| U | U | U | U | U | U |
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 |
|---|---|---|
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 | Nova Lake, Diamond Rapids |
APX_F_N3 | APX_F + APX_NCI_NDD_NF | Same as APX_F |
More General-purpose instructions
- CBW
- CDQ
- CDQE
- CLC
- CLD
- CLI
- CMC
- CMP
- CMPS
- CMPXCHG
- CMPXCHG8B
- CPUID
- CQO
- CWD
- CWDE
- DAA
- DAS
- DEC
- DIV
- ENTER
- IMUL
- IN
- INC
- INS
- INT
- INT1
- INT3
- INTO
- IRET
- Jcc
- JCXZ
- JECXZ
- JMP
- JRCXZ
- LDS
- LEA
- LEAVE
- LES
- LFS
- LGS
All 109 General-purpose 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-448 (IDIV)
- 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)
- Linux 7.3: arch/x86/kernel/traps.c, lines 375-384 (#DE becomes SIGFPE with FPE_INTDIV)
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.