xref: /illumos-gate/usr/src/common/util/popcountdi2.c (revision aaceae985c2e78cadef76bf0b7b50ed887ccb3a6)
1*aaceae98SRobert Mustacchi /*
2*aaceae98SRobert Mustacchi  * University of Illinois/NCSA Open Source License
3*aaceae98SRobert Mustacchi  *
4*aaceae98SRobert Mustacchi  * Copyright (c) 2003-2012 University of Illinois at Urbana-Champaign.
5*aaceae98SRobert Mustacchi  * All rights reserved.
6*aaceae98SRobert Mustacchi  *
7*aaceae98SRobert Mustacchi  * Developed by:
8*aaceae98SRobert Mustacchi  *
9*aaceae98SRobert Mustacchi  *     LLVM Team
10*aaceae98SRobert Mustacchi  *
11*aaceae98SRobert Mustacchi  *     University of Illinois at Urbana-Champaign
12*aaceae98SRobert Mustacchi  *
13*aaceae98SRobert Mustacchi  *     http://llvm.org
14*aaceae98SRobert Mustacchi  *
15*aaceae98SRobert Mustacchi  * Permission is hereby granted, free of charge, to any person obtaining a copy
16*aaceae98SRobert Mustacchi  * of this software and associated documentation files (the "Software"), to deal
17*aaceae98SRobert Mustacchi  * with the Software without restriction, including without limitation the
18*aaceae98SRobert Mustacchi  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
19*aaceae98SRobert Mustacchi  * sell copies of the Software, and to permit persons to whom the Software is
20*aaceae98SRobert Mustacchi  * furnished to do so, subject to the following conditions:
21*aaceae98SRobert Mustacchi  *
22*aaceae98SRobert Mustacchi  *     * Redistributions of source code must retain the above copyright notice,
23*aaceae98SRobert Mustacchi  *       this list of conditions and the following disclaimers.
24*aaceae98SRobert Mustacchi  *
25*aaceae98SRobert Mustacchi  *     * Redistributions in binary form must reproduce the above copyright
26*aaceae98SRobert Mustacchi  *       notice, this list of conditions and the following disclaimers in the
27*aaceae98SRobert Mustacchi  *       documentation and/or other materials provided with the distribution.
28*aaceae98SRobert Mustacchi  *
29*aaceae98SRobert Mustacchi  *     * Neither the names of the LLVM Team, University of Illinois at
30*aaceae98SRobert Mustacchi  *       Urbana-Champaign, nor the names of its contributors may be used to
31*aaceae98SRobert Mustacchi  *       endorse or promote products derived from this Software without specific
32*aaceae98SRobert Mustacchi  *       prior written permission.
33*aaceae98SRobert Mustacchi  *
34*aaceae98SRobert Mustacchi  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35*aaceae98SRobert Mustacchi  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36*aaceae98SRobert Mustacchi  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
37*aaceae98SRobert Mustacchi  * CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38*aaceae98SRobert Mustacchi  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39*aaceae98SRobert Mustacchi  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
40*aaceae98SRobert Mustacchi  * THE SOFTWARE.
41*aaceae98SRobert Mustacchi  */
42*aaceae98SRobert Mustacchi 
43*aaceae98SRobert Mustacchi /*
44*aaceae98SRobert Mustacchi  * C compiler runtime logic for popcount() related builtins taken from LLVM. See
45*aaceae98SRobert Mustacchi  * also the Hacker's Delight 2nd Edition.
46*aaceae98SRobert Mustacchi  */
47*aaceae98SRobert Mustacchi 
48*aaceae98SRobert Mustacchi int
__popcountdi2(unsigned long long val)49*aaceae98SRobert Mustacchi __popcountdi2(unsigned long long val)
50*aaceae98SRobert Mustacchi {
51*aaceae98SRobert Mustacchi 	unsigned long long x2 = (unsigned long long)val;
52*aaceae98SRobert Mustacchi 	x2 = x2 - ((x2 >> 1) & 0x5555555555555555uLL);
53*aaceae98SRobert Mustacchi 	/* Every 2 bits holds the sum of every pair of bits (32) */
54*aaceae98SRobert Mustacchi 	x2 = ((x2 >> 2) & 0x3333333333333333uLL) + (x2 & 0x3333333333333333uLL);
55*aaceae98SRobert Mustacchi 	/*
56*aaceae98SRobert Mustacchi 	 * Every 4 bits holds the sum of every 4-set of bits (3 significant
57*aaceae98SRobert Mustacchi 	 * bits) (16)
58*aaceae98SRobert Mustacchi 	 */
59*aaceae98SRobert Mustacchi 	x2 = (x2 + (x2 >> 4)) & 0x0F0F0F0F0F0F0F0FuLL;
60*aaceae98SRobert Mustacchi 	/*
61*aaceae98SRobert Mustacchi 	 * Every 8 bits holds the sum of every 8-set of bits (4 significant
62*aaceae98SRobert Mustacchi 	 * bits) (8).
63*aaceae98SRobert Mustacchi 	 */
64*aaceae98SRobert Mustacchi 	unsigned x = (unsigned)(x2 + (x2 >> 32));
65*aaceae98SRobert Mustacchi 	/*
66*aaceae98SRobert Mustacchi 	 * The lower 32 bits hold four 16 bit sums (5 significant bits). The
67*aaceae98SRobert Mustacchi 	 * upper 32 bits are garbage.
68*aaceae98SRobert Mustacchi 	 */
69*aaceae98SRobert Mustacchi 	x = x + (x >> 16);
70*aaceae98SRobert Mustacchi 	/*
71*aaceae98SRobert Mustacchi 	 * The lower 16 bits hold two 32 bit sums (6 significant bits). The
72*aaceae98SRobert Mustacchi 	 * upper 16 bits are garbage. Extract the 7 significant bits.
73*aaceae98SRobert Mustacchi 	 */
74*aaceae98SRobert Mustacchi 	return ((x + (x >> 8)) & 0x0000007F);
75*aaceae98SRobert Mustacchi }
76*aaceae98SRobert Mustacchi 
77*aaceae98SRobert Mustacchi int
__popcountsi2(unsigned val)78*aaceae98SRobert Mustacchi __popcountsi2(unsigned val)
79*aaceae98SRobert Mustacchi {
80*aaceae98SRobert Mustacchi 	unsigned x = (unsigned)val;
81*aaceae98SRobert Mustacchi 	x = x - ((x >> 1) & 0x55555555);
82*aaceae98SRobert Mustacchi 	/* Every 2 bits holds the sum of every pair of bits */
83*aaceae98SRobert Mustacchi 	x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
84*aaceae98SRobert Mustacchi 	/*
85*aaceae98SRobert Mustacchi 	 * Every 4 bits holds the sum of every 4-set of bits (3 significant
86*aaceae98SRobert Mustacchi 	 * bits).
87*aaceae98SRobert Mustacchi 	 */
88*aaceae98SRobert Mustacchi 	x = (x + (x >> 4)) & 0x0F0F0F0F;
89*aaceae98SRobert Mustacchi 	/*
90*aaceae98SRobert Mustacchi 	 * Every 8 bits holds the sum of every 8-set of bits (4 significant
91*aaceae98SRobert Mustacchi 	 * bits).
92*aaceae98SRobert Mustacchi 	 */
93*aaceae98SRobert Mustacchi 	x = (x + (x >> 16));
94*aaceae98SRobert Mustacchi 	/*
95*aaceae98SRobert Mustacchi 	 * The lower 16 bits hold two 8 bit sums (5 significant bits). The
96*aaceae98SRobert Mustacchi 	 * upper 16 bits are garbage. Extract the 6 significant bits.
97*aaceae98SRobert Mustacchi 	 */
98*aaceae98SRobert Mustacchi 	return ((x + (x >> 8)) & 0x0000003F);  /* (6 significant bits) */
99*aaceae98SRobert Mustacchi }
100