Instruction
NEG
Replaces an operand with its two's complement; APX adds three-operand forms and forms that leave the flags unchanged.
- Extensions
- Forms
- 18 (6 Legacy, 12 EVEX)
- Data
- Intel XED v2026.08.23
NEG replaces its operand with 0 minus the operand, the two’s complement, and sets the flags as that subtraction would. Two consequences are easy to miss:
- CF tells whether the operand was nonzero. Subtracting anything but 0 from 0 borrows, so NEG sets CF for every operand except 0.
- The most negative number stays as it is. For 64 bits, -2^63 has no positive counterpart, so NEG leaves it unchanged and sets OF; that is the only operand for which OF is set.
In compiled code
GCC 14 and Clang 23 at -O2 compile -x to a NEG, and use its flags in
three places:
- Absolute value.
labs(x)becomesmov rax, rdi,neg raxandcmovs rax, rdi: when the negated value is negative, x was positive and is kept. For the most negative x both values are the same, and so is the result, which C leaves undefined. - A mask from “nonzero”. Both compilers end
x ? -1 : 0withneg ediandsbb eax, eax: SBB of a register from itself turns the CF that NEG set into all ones or all zeros, without a branch. - Wide negation. For an
__int128, NEG negates the low half and its CF is the borrow into the high half: both compilers emitxor edx, edx,neg raxandsbb rdx, rsi, which subtracts the high half and the borrow from 0.
NEG also appears in the idioms of other instructions: x & -x, which
keeps the lowest set bit, is NEG and AND (or
BLSI), and an atomic_fetch_sub whose old value is used
becomes NEG and LOCK XADD, since x86 has no exchanging
subtraction. NOT differs from NEG by one: ~x equals
-x - 1.
Forms
| Instruction | Encoding | Requires |
|---|---|---|
NEG m8
NEG_MEMb | F6 /3 | Base instruction set |
NEG r8
NEG_GPR8 | F6 /3 | Base instruction set |
NEG m16/32/64
NEG_MEMv | F7 /3 | Base instruction set |
NEG r16/32/64
NEG_GPRv | F7 /3 | Base instruction set |
LOCK NEG m8
NEG_LOCK_MEMb | F6 /3 | Base instruction set |
LOCK NEG m16/32/64
NEG_LOCK_MEMv | F7 /3 | Base instruction set |
NEG r8
NEG_GPR8i8_APX | EVEX.LLZ.NP.MAP4.WIG F6 /3 | APX_F |
NEG m8
NEG_MEMi8_APX | EVEX.LLZ.NP.MAP4.WIG F6 /3 | APX_F |
NEG r8 NF
NEG_GPR8i8_APX_N3 | EVEX.LLZ.NP.MAP4.WIG F6 /3 NF=1 | APX_F + APX_NCI_NDD_NF |
NEG m8 NF
NEG_MEMi8_APX_N3 | EVEX.LLZ.NP.MAP4.WIG F6 /3 NF=1 | APX_F + APX_NCI_NDD_NF |
NEG r8, r8 NDD NF optional
NEG_GPR8i8_GPR8i8_APX_N3 | EVEX.LLZ.NP.MAP4.WIG F6 /3 ND=1 NF=0/1 | APX_F + APX_NCI_NDD_NF |
NEG r8, m8 NDD NF optional
NEG_GPR8i8_MEMi8_APX_N3 | EVEX.LLZ.NP.MAP4.WIG F6 /3 ND=1 NF=0/1 | APX_F + APX_NCI_NDD_NF |
NEG r16/32/64
NEG_GPRv_APX | EVEX.LLZ.NP.MAP4.SCALABLE F7 /3 | APX_F |
NEG m16/32/64
NEG_MEMv_APX | EVEX.LLZ.NP.MAP4.SCALABLE F7 /3 | APX_F |
NEG r16/32/64 NF
NEG_GPRv_APX_N3 | EVEX.LLZ.NP.MAP4.SCALABLE F7 /3 NF=1 | APX_F + APX_NCI_NDD_NF |
NEG m16/32/64 NF
NEG_MEMv_APX_N3 | EVEX.LLZ.NP.MAP4.SCALABLE F7 /3 NF=1 | APX_F + APX_NCI_NDD_NF |
NEG r16/32/64, r16/32/64 NDD NF optional
NEG_GPRv_GPRv_APX_N3 | EVEX.LLZ.NP.MAP4.SCALABLE F7 /3 ND=1 NF=0/1 | APX_F + APX_NCI_NDD_NF |
NEG r16/32/64, m16/32/64 NDD NF optional
NEG_GPRv_MEMv_APX_N3 | EVEX.LLZ.NP.MAP4.SCALABLE F7 /3 ND=1 NF=0/1 | APX_F + APX_NCI_NDD_NF |
Latency and throughput
| Model | m8 | r8r16r32r64 | m16m32m64 | NEG m8 | NEG m16NEG m32NEG m64 |
|---|---|---|---|---|---|
| Sandy Bridge | 7 / 1p015 | 1 / 0.33p015 | 7 / 1p015 | 7 / 1p015 | 7 / 1p015 |
| Haswell, Broadwell, Skylake, Skylake-SP | 7 / 1p0156 | 1 / 0.25p0156 | 7 / 1p0156 | 7 / 1p0156 | 7 / 1p0156 |
| Ice Lake | 7 / 0.5p0156 | 1 / 0.25p0156 | 7 / 0.5p0156 | 7 / 0.5p0156 | 7 / 0.5p0156 |
| Alder Lake, Sapphire Rapids | 13 / 0.5p0 p1 p5 p6 p11 | 1 / 0.2p0 p1 p5 p6 p11 | 12 / 0.5p0 p1 p5 p6 p11 | 13 / 0.5p0 p1 p5 p6 p11 | 12 / 0.5p0 p1 p5 p6 p11 |
| Lunar Lake | 13 / 0.5p012345 | 1 / 0.33p135 | 12 / 0.67p135 | 13 / 0.5p012345 | 12 / 0.67p135 |
| Bonnell | 1 / 1p0 | 1 / 0.5p01 | 1 / 1p0 | 1 / 1p0 | 1 / 1p0 |
| Silvermont | 5 / 2IEC0 IEC1 MEC | 1 / 0.5IEC0 IEC1 | 5 / 2IEC0 IEC1 MEC | 5 / 2IEC0 IEC1 MEC | 5 / 2IEC0 IEC1 MEC |
| Piledriver | 6 / 2EX0 EX1 | 1 / 1EX0 EX1 | 6 / 2EX0 EX1 | 6 / 2EX0 EX1 | 6 / 2EX0 EX1 |
| Zen | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 5 / 0.5ALU0 ALU1 ALU2 ALU3 | 5 / 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 |
| Zen 3, Zen 4 | 6 / 0.67ALU0 ALU1 ALU2 ALU3 | 1 / 0.25ALU0 ALU1 ALU2 ALU3 | 6 / 0.67ALU0 ALU1 ALU2 ALU3 | 6 / 0.67ALU0 ALU1 ALU2 ALU3 | 6 / 0.67ALU0 ALU1 ALU2 ALU3 |
| Jaguar | 6 / 1ALU0 ALU1 | 1 / 0.5ALU0 ALU1 | 6 / 1ALU0 ALU1 | 19 / 19ALU0 ALU1 | 19 / 19ALU0 ALU1 |
Operation
What the forms do, in pseudocode that our tests run against results recorded on real processors. How to read.
a = dest.read() # with LOCK: one atomic read-modify-write
if not nf: # NF=1 (APX) leaves the flags as they were
flags = sub_flags(0, a) # as 0 - a: CF is 1 unless a is 0
dest.write(-a) # the smallest negative number stays as it
# is, with OF set
Run on AMD Zen 5 (EPYC 9645): 72 cases. The APX forms were not run: none of these processors has APX.
a = src.read()
if not nf: # NF=1 leaves the flags as they were
flags = sub_flags(0, a) # as 0 - a: CF is 1 unless a is 0
dest.write(-a) # the new destination: bits 63:OSIZE
# cleared, even for 8 and 16 bits
Not run on a processor: none of these processors has APX.
Operands
| Operand | Kind | Action |
|---|---|---|
NEG r/m8 NEG r/m16/32/64 LOCK NEG m8 LOCK NEG m16/32/64 | ||
r/m8/16/32/64 | explicit | read, write |
RFLAGS | implicit | write |
NEG r/m8 NF NEG r/m16/32/64 NF | ||
r/m8/16/32/64 | explicit | read, write |
NEG r8, r/m8 NDD NF optional NEG r16/32/64, r/m16/32/64 NDD NF optional | ||
r8/16/32/64 | explicit | write |
r/m8/16/32/64 | explicit | read |
RFLAGS | implicit | write (NF=0) |
Flags
| When | OF | SF | ZF | AF | PF | CF |
|---|---|---|---|---|---|---|
| NF forms | ||||||
| Not affected | ||||||
| NDD forms | ||||||
| NF=0 | M | M | M | M | M | M |
| Other forms | ||||||
| M | M | M | M | M | M | |
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
Attributes
What else XED records about the forms. How to read.
- Legacy memory forms without LOCK
- accepts a LOCK prefix
- LOCK 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 |
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
- JECXZ
- JMP
- JRCXZ
- LDS
- LEA
- LEAVE
- LES
- LFS
- LGS
- LODS
- LOOP
- LOOPE
- LOOPNE
- LSS
- MOV
- MOVS
- MOVSX
- MOVSXD
- MOVZX
- MUL
- NOP
- NOT
- OR
- OUT
- OUTS
- PAUSE
- POP
- POPA
- POPF
- PUSH
- PUSHA
- PUSHF
- RCL
- RCR
- RET
- ROL
- ROR
- SALC
- SAR
- SBB
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 2B, page 4-158 (NEG)
- 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)
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.