Instruction
PUSHF
Pushes the flags onto the stack: FLAGS, EFLAGS with PUSHFD, or RFLAGS with PUSHFQ, the default in 64-bit mode.
- Extensions
- Mnemonics
- PUSHF, PUSHFD, PUSHFQ
- Forms
- 3 (3 Legacy)
- Data
- Intel XED v2026.08.23
PUSHF pushes the flags register onto the stack, where a POP can take it into a general-purpose register. In 64-bit mode it pushes all of RFLAGS, 8 bytes, and is written PUSHFQ; a 66 prefix pushes only the 16 bits of FLAGS, and the 32-bit PUSHFD cannot be encoded there. POPF is the way back.
What the image holds
The pushed value is RFLAGS as it is, with two exceptions: RF (bit 16) and VM (bit 17) always read 0 in it. Bit 1 reads 1, as it always does. So the image shows the six arithmetic flags, DF, and the system flags TF, IF, IOPL, NT, AC and ID, at any privilege level: in 64-bit mode PUSHF does not fault for want of privilege. Only virtual-8086 mode restricts it, with #GP when IOPL is below 3 and the mode’s extensions do not allow it.
Reading the flags from C
GCC 14 and Clang 23 provide __builtin_ia32_readeflags_u64() and
__builtin_ia32_writeeflags_u64(); at -O2 the first compiles to pushf
(Clang prints pushfq) and pop rax, the second to push rdi and
popf. Uses of the image include:
- IF and IOPL. Code that turns maskable interrupts off can save IF this way first and restore it with POPF. In user mode under Linux, as this site’s Zen 5 recorded it, IF reads 1 and IOPL 0.
- CPUID detection. On 32-bit processors, Intel’s manual says that a program able to set and clear ID (bit 21) runs on a processor with CPUID: PUSHFD, flip the bit, POPFD, then PUSHFD again and compare. Every x86-64 processor has CPUID, so 64-bit code skips the test.
- AC. Bit 18 enables alignment checks of user-mode data accesses where the operating system has set CR0.AM; a program sets it with PUSHF, an OR and POPF.
Cost
PUSHF writes memory and, through its POP, reads it back. The instruction table of AMD’s Zen 5 guide lists PUSHF and POPF as microcoded, while LAHF, which copies SF, ZF, AF, PF and CF into AH, is a single macro-op. On Zen 5, by that table, LAHF is the cheaper way to keep the arithmetic flags it covers, and PUSHF is worth its cost when the system flags or the whole register are needed.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
PUSHF
PUSHF | 66 9C | Base instruction set |
PUSHFD not in 64-bit mode
PUSHFD | 9C | Base instruction set |
PUSHFQ 64-bit mode only
PUSHFQ | 9CREX.W 9C | LM |
Latency and throughput
| Model | PUSHFQ |
|---|---|
| Sandy Bridge | 5 / 1p0 p1 p4 p5 p23 |
| Haswell, Broadwell, Skylake, Skylake-SP | 5 / 1p01234567 |
| Ice Lake | 5 / 1p01456789 |
| Alder Lake, Sapphire Rapids | 4 / 1p0146789 |
| Lunar Lake | 4 / 0.5p0 p1 p2 p3 p4 p5 p10 p11 p25 p26 p27 |
| Bonnell | 9 / 4.5p01 |
| Silvermont | 1 / 1IEC0 IEC1 MEC |
| Piledriver | 1 / 1AGLU01 Store |
| Zen | 1 / 0.5AGU0 AGU1 |
| Zen 2 | 1 / 0.33AGU0 AGU1 AGU2 |
| Zen 3, Zen 4 | 1 / 1AGU0 AGU1 AGU2 LSU Store |
| Jaguar | 1 / 1SAGU |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
a = rsp - OSIZE // 8 # PUSHFQ: 8 bytes; PUSHF: 2, FLAGS
store(a, OSIZE, rflags & ~0x30000) # RF and VM read as 0 here
rsp = aRun on AMD Zen 5 (EPYC 9645): 12 cases. The forms that 64-bit mode lacks were not run: the probe runs in 64-bit mode.
Operands
Flags
| OF | SF | ZF | AF | PF | CF | DF | IF | TF | AC | IOPL | NT | RF | VM | VIF | VIP | ID |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| All forms | ||||||||||||||||
| T | T | T | T | T | T | T | T | T | T | T | T | T | T | T | T | T |
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 |
I386 | No CPUID bit: part of the base instruction set. | Every x86-64 processor in XED’s model and Zen 3 to Zen 6 |
LONGMODE | LM | 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 2B, page 4-528 (PUSHF/
PUSHFD/ PUSHFQ) - Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1 (253665-093, September 2026)
- AMD64 Architecture Programmer's Manual, Volume 3: General-Purpose and System Instructions (24594, rev. 3.39, 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.