ia32-64/x86/popcnt.html
2025-07-08 02:23:29 -03:00

161 lines
5.6 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:x86="http://www.felixcloutier.com/x86"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="style.css"></link><title>POPCNT
— Return the Count of Number of Bits Set to 1</title></head><body><header><nav><ul><li><a href='index.html'>Index</a></li><li>December 2023</li></ul></nav></header><h1>POPCNT
— Return the Count of Number of Bits Set to 1</h1>
<table>
<tr>
<th>Opcode</th>
<th>Instruction</th>
<th>Op/En</th>
<th>64-Bit Mode</th>
<th>Compat/Leg Mode</th>
<th>Description</th></tr>
<tr>
<td>F3 0F B8 /r</td>
<td>POPCNT r16, r/m16</td>
<td>RM</td>
<td>Valid</td>
<td>Valid</td>
<td>POPCNT on r/m16</td></tr>
<tr>
<td>F3 0F B8 /r</td>
<td>POPCNT r32, r/m32</td>
<td>RM</td>
<td>Valid</td>
<td>Valid</td>
<td>POPCNT on r/m32</td></tr>
<tr>
<td>F3 REX.W 0F B8 /r</td>
<td>POPCNT r64, r/m64</td>
<td>RM</td>
<td>Valid</td>
<td>N.E.</td>
<td>POPCNT on r/m64</td></tr></table>
<h2 id="instruction-operand-encoding">Instruction Operand Encoding<a class="anchor" href="#instruction-operand-encoding">
</a></h2>
<table>
<tr>
<th>Op/En</th>
<th>Operand 1</th>
<th>Operand 2</th>
<th>Operand 3</th>
<th>Operand 4</th></tr>
<tr>
<td>RM</td>
<td>ModRM:reg (w)</td>
<td>ModRM:r/m (r)</td>
<td>N/A</td>
<td>N/A</td></tr></table>
<h2 id="description">Description<a class="anchor" href="#description">
</a></h2>
<p>This instruction calculates the number of bits set to 1 in the second operand (source) and returns the count in the first operand (a destination register).</p>
<h2 id="operation">Operation<a class="anchor" href="#operation">
</a></h2>
<pre>Count = 0;
For (i=0; i &lt; OperandSize; i++)
{ IF (SRC[ i] = 1) // ith bit
THEN Count++; FI;
}
DEST := Count;
</pre>
<h2 id="flags-affected">Flags Affected<a class="anchor" href="#flags-affected">
</a></h2>
<p>OF, SF, ZF, AF, CF, PF are all cleared. ZF is set if SRC = 0, otherwise ZF is cleared.</p>
<h2 id="intel-c-c++-compiler-intrinsic-equivalent">Intel C/C++ Compiler Intrinsic Equivalent<a class="anchor" href="#intel-c-c++-compiler-intrinsic-equivalent">
</a></h2>
<pre>POPCNT int _mm_popcnt_u32(unsigned int a);
</pre>
<pre>POPCNT int64_t _mm_popcnt_u64(unsigned __int64 a);
</pre>
<h2 class="exceptions" id="protected-mode-exceptions">Protected Mode Exceptions<a class="anchor" href="#protected-mode-exceptions">
</a></h2>
<table>
<tr>
<td>#GP(0)</td>
<td>If a memory operand effective address is outside the CS, DS, ES, FS or GS segments.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td>#PF</td>
<td>(fault-code) For a page fault.</td></tr>
<tr>
<td>#AC(0)</td>
<td>If an unaligned memory reference is made while the current privilege level is 3 and alignment checking is enabled.</td></tr>
<tr>
<td rowspan="2">#UD</td>
<td>If CPUID.01H:ECX.POPCNT [Bit 23] = 0.</td></tr>
<tr>
<td>If LOCK prefix is used.</td></tr></table>
<h2 class="exceptions" id="real-address-mode-exceptions">Real-Address Mode Exceptions<a class="anchor" href="#real-address-mode-exceptions">
</a></h2>
<table>
<tr>
<td>#GP(0)</td>
<td>If any part of the operand lies outside of the effective address space from 0 to 0FFFFH.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td rowspan="2">#UD</td>
<td>If CPUID.01H:ECX.POPCNT [Bit 23] = 0.</td></tr>
<tr>
<td>If LOCK prefix is used.</td></tr></table>
<h2 class="exceptions" id="virtual-8086-mode-exceptions">Virtual 8086 Mode Exceptions<a class="anchor" href="#virtual-8086-mode-exceptions">
</a></h2>
<table>
<tr>
<td>#GP(0)</td>
<td>If any part of the operand lies outside of the effective address space from 0 to 0FFFFH.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td>#PF</td>
<td>(fault-code) For a page fault.</td></tr>
<tr>
<td>#AC(0)</td>
<td>If an unaligned memory reference is made while alignment checking is enabled.</td></tr>
<tr>
<td rowspan="2">#UD</td>
<td>If CPUID.01H:ECX.POPCNT [Bit 23] = 0.</td></tr>
<tr>
<td>If LOCK prefix is used.</td></tr></table>
<h2 class="exceptions" id="compatibility-mode-exceptions">Compatibility Mode Exceptions<a class="anchor" href="#compatibility-mode-exceptions">
</a></h2>
<p>Same exceptions as in Protected Mode.</p>
<h2 class="exceptions" id="64-bit-mode-exceptions">64-Bit Mode Exceptions<a class="anchor" href="#64-bit-mode-exceptions">
</a></h2>
<table>
<tr>
<td>#GP(0)</td>
<td>If the memory address is in a non-canonical form.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory address referencing the SS segment is in a non-canonical form.</td></tr>
<tr>
<td>#PF</td>
<td>(fault-code) For a page fault.</td></tr>
<tr>
<td>#AC(0)</td>
<td>If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.</td></tr>
<tr>
<td rowspan="2">#UD</td>
<td>If CPUID.01H:ECX.POPCNT [Bit 23] = 0.</td></tr>
<tr>
<td>If LOCK prefix is used.</td></tr></table><footer><p>
This UNOFFICIAL, mechanically-separated, non-verified reference is provided for convenience, but it may be
inc<span style="opacity: 0.2">omp</span>lete or b<sub>r</sub>oke<sub>n</sub> in various obvious or non-obvious
ways. Refer to <a href="https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4">Intel® 64 and IA-32 Architectures Software Developers Manual</a> for anything serious.
</p></footer></body></html>