Instruction
XCHG
Swaps two operands; with a memory operand it is atomic even without a LOCK prefix.
- Extensions
- Forms
- 5 (5 Legacy)
- Data
- Intel XED v2026.08.23
XCHG swaps two operands. Between registers that is all it does. With a memory operand it is also an atomic instruction: the processor locks the location for the read and the write as if a LOCK prefix were there, whether or not it is, so no other processor can change the value in between.
Uses of the lock
- Atomic exchange. C11’s
atomic_exchangeon alongcompiles to a MOV of the new value into RAX andxchg qword ptr [rip + g], rax, with GCC 14 and Clang 23 at -O2. - Sequentially consistent stores. A locked instruction is never
reordered with loads or stores before or after it, while plain MOVs
let a load complete before an earlier store. Both compilers
therefore compile a sequentially consistent
atomic_storeto XCHG and drop the old value (see MOV). - Test-and-set locks.
mov eax, 1followed byxchg eax, [lock]takes a lock word and leaves in EAX whether it was already taken;test eax, eaxand a branch retry while it was, with PAUSE in the waiting loop. Releasing such a lock is a plain store of 0.
XCHG always writes, and returns only the old value. An update that depends on that value, such as “store x only if the location still holds y”, needs CMPXCHG with LOCK; an atomic addition is XADD.
Split locks
The lock covers any operand, aligned or not, but one that spans two cache lines cannot be locked within a cache: Intel’s and AMD’s manuals both make it a bus lock, which involves every processor of the system. Where the processor supports split-lock disable, system software can make such an access raise #AC(0) instead (Intel’s Volume 3A, Section 11.1.2.3).
The one-byte forms
90+r swaps rAX with another register in one byte. The slot for rAX itself, 90, is NOP, and F3 90 is PAUSE; the Operation section below shows which register forms clear bits 63:32.
In the optimization guide
What the optimization guide says about XCHG, a line per claim. Each links to the claim in the guide, with its sources and where they differ.
Out of order
- Move elimination: A register-to-register copy can be made at renaming, by pointing the destination at the physical register of the source; the move then has no latency and uses no execution unit.
Zen and Zen+
- Integer execution: Register-to-register moves of 32-bit and 64-bit general registers and of XMM registers, and
xchgof general registers, take no execution cycle, while a YMM move renames only its lower half and moves the upper one in a pipe. sources differ
Zen 2
- Integer execution: Register-to-register moves of general registers of 32 and 64 bits,
xchgof them and moves of whole XMM and YMM registers take no execution cycle, where Zen 1 moves the upper half of a YMM register in a pipe. sources differ
Zen 3
- Integer execution: Register-to-register moves of general registers of 32 and 64 bits,
xchgof them and moves of whole XMM and YMM registers take no execution cycle, nor do the zeroing idioms such asxor eax, eaxandvpxor, which also break the dependency on the old value;sbb eax, eaxdepends only on the carry flag, andpcmpeqd xmm0, xmm0sets all ones without waiting. sources differ
Zen 4
- Integer execution: Register-to-register moves of general registers of 32 and 64 bits,
xchgof them and moves of whole vector registers take no execution cycle, nor do the zeroing idioms such asxor eax, eaxandvpxor, which also break the dependency on the old value;sbb eax, eaxdepends only on the carry flag. sources differ
Forms
| Instruction | Encoding | Requires |
|---|---|---|
XCHG m8, r8
XCHG_MEMb_GPR8 | 86 /r | Base instruction set |
XCHG r8, r8
XCHG_GPR8_GPR8 | 86 /r | Base instruction set |
XCHG m16/32/64, r16/32/64
XCHG_MEMv_GPRv | 87 /r | Base instruction set |
XCHG r16/32/64, r16/32/64
XCHG_GPRv_GPRv | 87 /r | Base instruction set |
XCHG r16/32/64, rAX
XCHG_GPRv_OrAX | 90+r | Base instruction set |
Latency and throughput
| Model | m8, r8 | r8, r8 | m16, r16 | m32, r32 | m64, r64 | r16, r16r16, rAX | r32, r32r64, r64r32, rAXr64, rAX |
|---|---|---|---|---|---|---|---|
| Sandy Bridge | 6 / 1p015 | 2 / 1p015 | 6 / 1p015 | 6 / 1p015 | 6 / 1p015 | 2 / 1p015 | 2 / 1p015 |
| Haswell | 9 / 1p0156 | 2 / 0.75p0156 | 9 / 1p0156 | 9 / 1p0156 | 9 / 1p0156 | 2 / 0.75p0156 | 2 / 0.75p0156 |
| Broadwell | 8 / 1p0156 | 2 / 0.75p0156 | 8 / 1p0156 | 8 / 1p0156 | 8 / 1p0156 | 2 / 0.75p0156 | 2 / 0.75p0156 |
| Skylake, Skylake-SP, Ice Lake | 10 / 1.25p0156 | 2 / 0.75p0156 | 10 / 1.25p0156 | 10 / 1.25p0156 | 10 / 1.25p0156 | 2 / 0.75p0156 | 2 / 0.75p0156 |
| Alder Lake, Sapphire Rapids | 40 / 1p0 p1 p5 p6 p11 | 2 / 0.6p0 p1 p5 p6 p11 | 39 / 1p0 p1 p5 p6 p11 | 39 / 1p0 p1 p5 p6 p11 | 39 / 1.2p0 p1 p5 p6 p11 | 2 / 0.6p0 p1 p5 p6 p11 | 2 / 0.6p0 p1 p5 p6 p11 |
| Lunar Lake | 40 / 0.83p012345 | 2 / 0.5p012345 | 39 / 0.83p012345 | 39 / 0.83p012345 | 39 / 1p012345 | 2 / 0.5p012345 | 2 / 0.5p012345 |
| Bonnell | 3 / 1.5p1 | 2 / 1p01 | 3 / 1.5p1 | 3 / 1.5p1 | 3 / 1.5p1 | 2 / 1p01 | 2 / 1p01 |
| Silvermont | 4 / 2IEC0 IEC1 MEC | 3 / 1.5IEC0 IEC1 | 4 / 2IEC0 IEC1 MEC | 4 / 2IEC0 IEC1 MEC | 4 / 2IEC0 IEC1 MEC | 3 / 1.5IEC0 IEC1 | 3 / 1.5IEC0 IEC1 |
| Piledriver | 5 / 2EX0 EX1 | 1 / 1EX1 | 5 / 2EX0 EX1 | 5 / 2EX0 EX1 | 5 / 2EX0 EX1 | 1 / 1EX1 | 1 / 1EX1 |
| Zen | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 0.5ALU0 ALU1 ALU2 ALU3 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 0.5ALU0 ALU1 ALU2 ALU3 |
| Zen 2 | 5 / 0.33ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 5 / 0.33ALU0 ALU1 ALU2 ALU3 | 5 / 0.33ALU0 ALU1 ALU2 ALU3 | 5 / 0.33ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 |
| Zen 3, Zen 4 | 7 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 0.5ALU0 ALU1 ALU2 ALU3 | 7 / 0.5ALU0 ALU1 ALU2 ALU3 | 6 / 0.5ALU0 ALU1 ALU2 ALU3 | 6 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 0.5ALU0 ALU1 ALU2 ALU3 | 0 / 0.33 |
| Jaguar | 16 / 16ALU0 ALU1 | 2 / 1.5ALU0 ALU1 | 16 / 16ALU0 ALU1 | 16 / 16ALU0 ALU1 | 16 / 16ALU0 ALU1 | 1 / 1ALU0 ALU1 | 1 / 1ALU0 ALU1 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
a = dest.read() # memory: one atomic read and write, with
b = src.read() # or without LOCK
dest.write(b) # 32-bit registers: bits 63:32 cleared in
src.write(a) # both, even for XCHG EAX, EAX (87 C0)
# the byte 90, which would be XCHG EAX, EAX, is NOP instead: it clears
# nothing (XCHG R8D, EAX, 41 90, does)Run on AMD Zen 5 (EPYC 9645): 67 cases.
Operands
| Operand | Kind | Action |
|---|---|---|
XCHG r/m8, r8 XCHG r/m16/32/64, r16/32/64 | ||
r/m8/16/32/64 | explicit | read, write |
r8/16/32/64 | explicit | read, write |
XCHG r16/32/64, rAX | ||
r16/32/64 | explicit | read, write |
rAX | explicit | read, write |
Flags
None: XED records no flag that the forms test or change.
Attributes
What else XED records about the forms. How to read.
- Memory 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.
| 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 |
More General-purpose 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 2D, page 6-32 (XCHG)
- Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3 (325384-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 2: System Programming (24593, rev. 3.46, October 2026)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, 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.