Introduction
These instructions work on the caches rather than on registers. Most of them take a memory operand only for its address: they name the cache line (64 bytes on current processors) that holds that byte, and read or write no data themselves.
- Write-back and flush instructions push a line out of the caches to memory, which matters for persistent memory and for devices that read memory directly.
- Prefetches are hints: they ask for a line to be brought in before it is needed. They never fault, and a processor may ignore them.
- Fences order a program’s own loads and stores. x86 already keeps most of them in order; the fences cover what it does not, such as a store followed by a load, and non-temporal stores.
Each set has its own CPUID bit, given in its rows below. The atomic operations and
the direct stores (movdiri, movdir64b) are on the
Transactions and synchronisation page,
and the non-temporal stores with their SSE and SSE2 sets.
The instructions
In the forms, m8 is a memory operand in ModRM.r/m whose address picks
the cache line. NP means that no 66, F2 or F3 prefix may be present.
Write-back and flush
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
clflush | m8 | NP 0F AE /7 | Writes the line back to memory if it is modified, and removes it from every cache in the system. CPUID leaf 1: EDX bit 19. | CLFLUSH (Intel Pentium 4, 2000) |
clflushopt | m8 | 66 0F AE /7 | The same, but ordered more weakly: flushes of different lines may overlap, so a run of them is faster. Order it with sfence. CPUID leaf 7: EBX bit 23. | CLFLUSHOPT (Intel Skylake, 2015) |
clwb | m8 | 66 0F AE /6 | Writes the line back to memory if it is modified, and may keep it in the cache. Meant for persistent memory. CPUID leaf 7: EBX bit 24. | CLWB (Intel Skylake-SP, 2017) |
cldemote | m8 | NP 0F 1C /0 | A hint to move the line from the core’s own caches to a cache further out, shared with the other cores, so that another core reads it sooner. Without the feature it is a no-operation. CPUID leaf 7: ECX bit 25. | CLDEMOTE (Intel Atom P5900 (Tremont), 2020) |
clzero | rAX (implicit) | 0F 01 FC | Writes zeros to the whole cache line that holds the address in rAX (the low bits are ignored). CPUID leaf 8000_0008h: EBX bit 0. | CLZERO (AMD Zen, 2017) |
wbinvd | – | 0F 09 | Writes every modified line in the processor’s caches back to memory and empties them, and signals external caches to do the same. Privilege level 0 only. | 80486 (Intel 80486, 1989) |
wbnoinvd | – | F3 0F 09 | Writes every modified line back but keeps the caches’ contents. Privilege level 0 only. On processors without it the F3 prefix is ignored and it runs as wbinvd. CPUID leaf 8000_0008h: EBX bit 9. | WBNOINVD (AMD Zen 2, 2019; Intel Ice Lake-SP, 2021) |
invd | – | 0F 08 | Empties the caches without writing modified lines back, so those writes are lost. Privilege level 0 only; used during start-up, before memory is set up. | 80486 (Intel 80486, 1989) |
mcommit | – | F3 0F 01 FA | Waits until the processor’s earlier stores to memory have been committed to persistence, and reports in CF whether they all were. It must be enabled with a bit in EFER. CPUID leaf 8000_0008h: EBX bit 8. | MCOMMIT (AMD, in its manual from 2019) |
Prefetch
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
prefetcht0 | m8 | 0F 18 /1 | Brings the line into every level of the cache. | SSE (Intel Pentium III, 1999) |
prefetcht1 | m8 | 0F 18 /2 | Brings the line into the second-level cache and beyond. | SSE (Intel Pentium III, 1999) |
prefetcht2 | m8 | 0F 18 /3 | Brings the line into the third-level cache and beyond. | SSE (Intel Pentium III, 1999) |
prefetchnta | m8 | 0F 18 /0 | Brings the line in as non-temporal data, which will be used once: it is kept where it pollutes the caches least. | SSE (Intel Pentium III, 1999) |
prefetch | m8 | 0F 0D /0 | Brings the line into the first-level data cache, to be read. It came with 3DNow! but stayed when 3DNow! was dropped. CPUID leaf 8000_0001h: ECX bit 8, or the 3DNow! bit. | 3DNow! (AMD K6-2, 1998) |
prefetchw | m8 | 0F 0D /1 | Brings the line in to be written: it is fetched in a state that lets a store follow without asking the other cores again. CPUID leaf 8000_0001h: ECX bit 8. | PREFETCHW (AMD K6-2, 1998; Intel Broadwell, 2014) |
prefetchwt1 | m8 | 0F 0D /2 | Brings the line in to be written, into the second-level cache. CPUID leaf 7: ECX bit 0. | PREFETCHWT1 (Intel Xeon Phi (Knights Landing), 2016) |
prefetchit0 | m8 | 0F 18 /7, RIP-relative | Brings the line in as code, to be run soon, into every level of the cache. 64-bit mode only, and only with a RIP-relative address; any other form of 0F 18 /7 is a hint no-operation. CPUID leaf 7, sub-leaf 1: EDX bit 14. | PREFETCHI (Intel Granite Rapids, 2024) |
prefetchit1 | m8 | 0F 18 /6, RIP-relative | The same, into the second-level cache and beyond. | PREFETCHI (Intel Granite Rapids, 2024) |
prefetchrst2 | m8 | 0F 18 /4 | Brings the line into the third-level cache and beyond, with the read-shared hint of MOVRS: the line will be read by several cores and rarely written. | MOVRS (Intel Diamond Rapids, announced) |
Read-shared loads
MOVRS loads data with a hint that the line is read-mostly and shared, so that the processor can keep it where several cores reach it. CPUID leaf 7, sub-leaf 1: EAX bit 31.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
movrs | r8, m8r16/r32/r64, m16/m32/m64 | 0F 38 8A /r0F 38 8B /rAPX: EVEX map 4, 8A and 8B /r | Loads a general register from memory with the read-shared hint. | MOVRS (Intel Diamond Rapids, announced) |
vmovrsb | xmm1 {k1}{z}, m128ymm1 {k1}{z}, m256zmm1 {k1}{z}, m512 | EVEX.128/256/512.F2.MAP5.W0 6F /r | Loads bytes into a vector register with the read-shared hint, under a mask. | MOVRS with AVX10.2 (Intel Diamond Rapids, announced) |
vmovrsw | as vmovrsb | EVEX.128/256/512.F2.MAP5.W1 6F /r | The same, masked by words. | MOVRS with AVX10.2 (Intel Diamond Rapids, announced) |
vmovrsd | as vmovrsb | EVEX.128/256/512.F3.MAP5.W0 6F /r | The same, masked by doublewords. | MOVRS with AVX10.2 (Intel Diamond Rapids, announced) |
vmovrsq | as vmovrsb | EVEX.128/256/512.F3.MAP5.W1 6F /r | The same, masked by quadwords. | MOVRS with AVX10.2 (Intel Diamond Rapids, announced) |
Fences
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
sfence | – | NP 0F AE F8 | Store fence: every store before it becomes globally visible before any store after it. Needed after non-temporal stores and clflushopt. | SSE (Intel Pentium III, 1999) |
lfence | – | NP 0F AE E8 | Load fence: every load before it completes before any load after it. On Intel processors, and on AMD ones set up for it, no later instruction starts until every earlier one has completed locally, which is how it is used against speculative execution. | SSE2 (Intel Pentium 4, 2000) |
mfence | – | NP 0F AE F0 | Full fence: every load and store before it becomes globally visible before any load or store after it. | SSE2 (Intel Pentium 4, 2000) |
Notes
- The fences’ ModRM. The fences are 0F AE /5, /6 and /7 with
ModRM.mod 11; the r/m bits are ignored, so 0F AE E8 to EF are all
lfence, F0 to F7mfenceand F8 to FFsfence. With F3, F2 or 66 some of those bytes are other instructions:tpause,umonitor,umwaitandincsspd. - Hint space. 0F 18 to 0F 1F are reserved by Intel as hint
no-operations, so new hints run harmlessly on old processors. The disassembler
shows the ModRM.reg values of 0F 18 and 0F 1C that name no hint, and every register
form, as
nop, as LLVM does. - MOVRS in 64-bit mode. The disassembler takes
movrsas 64-bit only, as LLVM decodes it. That is an inference from LLVM and Xen, not Intel’s own statement. - Faults.
clflush,clflushoptandclwbcheck the address like a load and can page-fault; the prefetches never fault.
Links
Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manuals – Intel’s manuals; volume 2 describes each instruction, volume 3A the caches and memory ordering
- Intel Architecture Instruction Set Extensions Programming Reference – Intel’s description of instructions not yet in the main manual, MOVRS among them
- AMD64 Architecture Programmer’s Manual, Volume 3 – AMD’s reference to the general-purpose and system instructions, with CLZERO and MCOMMIT
- x86 and amd64 instruction reference – Félix Cloutier’s web copy of the instruction pages of Intel’s manual