xref: /netbsd-src/tests/lib/libc/string/t_popcount.c (revision 1c3ef2c7410ac4a1d7deda9630ea677342837cbe)
1*1c3ef2c7Sjruoho /*	$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $	*/
2974b291aSjoerg /*-
3974b291aSjoerg  * Copyright (c) 2009 The NetBSD Foundation, Inc.
4974b291aSjoerg  * All rights reserved.
5974b291aSjoerg  *
6974b291aSjoerg  * This code is derived from software contributed to The NetBSD Foundation
7974b291aSjoerg  * by Joerg Sonnenberger.
8974b291aSjoerg  *
9974b291aSjoerg  * Redistribution and use in source and binary forms, with or without
10974b291aSjoerg  * modification, are permitted provided that the following conditions
11974b291aSjoerg  * are met:
12974b291aSjoerg  *
13974b291aSjoerg  * 1. Redistributions of source code must retain the above copyright
14974b291aSjoerg  *    notice, this list of conditions and the following disclaimer.
15974b291aSjoerg  * 2. Redistributions in binary form must reproduce the above copyright
16974b291aSjoerg  *    notice, this list of conditions and the following disclaimer in
17974b291aSjoerg  *    the documentation and/or other materials provided with the
18974b291aSjoerg  *    distribution.
19974b291aSjoerg  *
20974b291aSjoerg  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21974b291aSjoerg  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22974b291aSjoerg  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23974b291aSjoerg  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
24974b291aSjoerg  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25974b291aSjoerg  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26974b291aSjoerg  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27974b291aSjoerg  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28974b291aSjoerg  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29974b291aSjoerg  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30974b291aSjoerg  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31974b291aSjoerg  * SUCH DAMAGE.
32974b291aSjoerg  */
33974b291aSjoerg 
34974b291aSjoerg #include <sys/cdefs.h>
35*1c3ef2c7Sjruoho __RCSID("$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $");
36974b291aSjoerg 
37974b291aSjoerg #include <atf-c.h>
38974b291aSjoerg #include <strings.h>
39974b291aSjoerg 
40974b291aSjoerg static unsigned int byte_count[256];
41974b291aSjoerg 
42974b291aSjoerg static void
popcount_init(const char * cfg_var)43a583a258Spgoyette popcount_init(const char *cfg_var)
44974b291aSjoerg {
45974b291aSjoerg 	unsigned int i, j;
46974b291aSjoerg 
47a583a258Spgoyette 	if (strcasecmp(cfg_var, "YES")  == 0 ||
48a583a258Spgoyette 	    strcasecmp(cfg_var, "Y")    == 0 ||
49a583a258Spgoyette 	    strcasecmp(cfg_var, "1")    == 0 ||
50a583a258Spgoyette 	    strcasecmp(cfg_var, "T")    == 0 ||
51a583a258Spgoyette 	    strcasecmp(cfg_var, "TRUE") == 0) {
52974b291aSjoerg 		for (i = 0; i < 256; ++i) {
53974b291aSjoerg 			byte_count[i] = 0;
54974b291aSjoerg 			for (j = i; j != 0; j >>= 1) {
55974b291aSjoerg 				if (j & 1)
56974b291aSjoerg 					++byte_count[i];
57974b291aSjoerg 			}
58974b291aSjoerg 		}
59a583a258Spgoyette 		return;
60a583a258Spgoyette 	}
61a583a258Spgoyette 
62a583a258Spgoyette 	atf_tc_skip("config variable \"run_popcount\" not set to YES/TRUE");
63974b291aSjoerg }
64974b291aSjoerg 
65974b291aSjoerg unsigned int test_parts[256] = {
66974b291aSjoerg 	0x318e53e6U, 0x11710316U, 0x62608ffaU, 0x67e0f562U,
67974b291aSjoerg 	0xe432e82cU, 0x9862e8b2U, 0x7d96a627U, 0x3f74ad31U,
68974b291aSjoerg 	0x3cecf906U, 0xcdc0dcb4U, 0x241dab64U, 0x31e6133eU,
69974b291aSjoerg 	0x23086ad4U, 0x721d5a91U, 0xc483da53U, 0x6a62af52U,
70974b291aSjoerg 	0xf3f5c386U, 0xe0de3f77U, 0x65afe528U, 0xf4816485U,
71974b291aSjoerg 	0x40ccbf08U, 0x25df49c1U, 0xae5a6ee0U, 0xab36ccadU,
72974b291aSjoerg 	0x87e1ec29U, 0x60ca2407U, 0x49d62e47U, 0xa09f2df5U,
73974b291aSjoerg 	0xaf4c1c68U, 0x8ef08d50U, 0x624cfd2fU, 0xa6a36f20U,
74974b291aSjoerg 	0x68aaf879U, 0x0fe9deabU, 0x5c9a4060U, 0x215d8f08U,
75974b291aSjoerg 	0x55e84712U, 0xea1f1681U, 0x3a10b8a1U, 0x08e06632U,
76974b291aSjoerg 	0xcbc875e2U, 0x31e53258U, 0xcd3807a4U, 0xb9d17516U,
77974b291aSjoerg 	0x8fbfd9abU, 0x6651b555U, 0x550fb381U, 0x05061b9dU,
78974b291aSjoerg 	0x35aef3f2U, 0x9175078cU, 0xae0f14daU, 0x92a2d5f8U,
79974b291aSjoerg 	0x70d968feU, 0xe86f41c5U, 0x5cfaf39fU, 0x8499b18dU,
80974b291aSjoerg 	0xb33f879aU, 0x0a68ad3dU, 0x9323ecc1U, 0x060037ddU,
81974b291aSjoerg 	0xb91a5051U, 0xa0dbebf6U, 0x3e6aa6f1U, 0x7b422b5bU,
82974b291aSjoerg 	0x599e811eU, 0x199f7594U, 0xca453365U, 0x1cda6f48U,
83974b291aSjoerg 	0xe9c75d2cU, 0x6a873217U, 0x79c45d72U, 0x143b8e37U,
84974b291aSjoerg 	0xa11df26eU, 0xaf31f80aU, 0x311bf759U, 0x2378563cU,
85974b291aSjoerg 	0x9ab95fa5U, 0xfcf4d47cU, 0x1f7db268U, 0xd64b09e1U,
86974b291aSjoerg 	0xad7936daU, 0x7a59005cU, 0x45b173d3U, 0xc1a71b32U,
87974b291aSjoerg 	0x7d9f0de2U, 0xa9ac3792U, 0x9e7f9966U, 0x7f0b8080U,
88974b291aSjoerg 	0xece6c06fU, 0x78d92a3cU, 0x6d5f8f6cU, 0xc50ca544U,
89974b291aSjoerg 	0x5d8ded27U, 0xd27a8462U, 0x4bcd13ccU, 0xd49075f2U,
90974b291aSjoerg 	0xa8d52acfU, 0x41915d97U, 0x564f7062U, 0xefb046e2U,
91974b291aSjoerg 	0xe296277aU, 0x605b0ea3U, 0x10b2c3a1U, 0x4e8e5c66U,
92974b291aSjoerg 	0x4bd8ec04U, 0x29935be9U, 0x381839f3U, 0x555d8824U,
93974b291aSjoerg 	0xd6befddbU, 0x5d8d6d6eU, 0xb2fdb7b4U, 0xb471c8fcU,
94974b291aSjoerg 	0xc2fd325bU, 0x932d2487U, 0xbdbbadefU, 0x66c8895dU,
95974b291aSjoerg 	0x5d77857aU, 0x259f1cc0U, 0x302037faU, 0xda9aa7a8U,
96974b291aSjoerg 	0xb112c6aaU, 0x78f74192U, 0xfd4da741U, 0xfa5765c1U,
97974b291aSjoerg 	0x6ea1bc5cU, 0xd283f39cU, 0x268ae67dU, 0xdedcd134U,
98974b291aSjoerg 	0xbbf92410U, 0x6b45fb55U, 0x2f75ac71U, 0x64bf2ca5U,
99974b291aSjoerg 	0x8b99675aU, 0x3f4923b6U, 0x7e610550U, 0x04b1c06dU,
100974b291aSjoerg 	0x8f92e7c6U, 0x45cb608bU, 0x2d06d1f2U, 0x79cf387aU,
101974b291aSjoerg 	0xfd3ed225U, 0x243eee20U, 0x2cbefc6fU, 0x8286cbaaU,
102974b291aSjoerg 	0x70d4c182U, 0x054e3cc6U, 0xb66c5362U, 0x0c73fa5dU,
103974b291aSjoerg 	0x539948feU, 0xec638563U, 0x0cf04ab6U, 0xec7b52f4U,
104974b291aSjoerg 	0x58eeffceU, 0x6fe8049aU, 0xb3b33332U, 0x2e33bfdbU,
105974b291aSjoerg 	0xcc817567U, 0x71ac57c8U, 0x4bab3ac7U, 0x327c558bU,
106974b291aSjoerg 	0x82a6d279U, 0x5adf71daU, 0x1074a656U, 0x3c533c1fU,
107974b291aSjoerg 	0x82fdbe69U, 0x21b4f6afU, 0xd59580e8U, 0x0de824ebU,
108974b291aSjoerg 	0xa510941bU, 0x7cd91144U, 0xa8c10631U, 0x4c839267U,
109974b291aSjoerg 	0x5d503c2fU, 0xe1567d55U, 0x23910cc7U, 0xdb1bdc34U,
110974b291aSjoerg 	0x2a866704U, 0x33e21f0cU, 0x5c7681b4U, 0x818651caU,
111974b291aSjoerg 	0xb1d18162U, 0x225ad014U, 0xadf7d6baU, 0xac548d9bU,
112974b291aSjoerg 	0xe94736e5U, 0x2279c5f1U, 0x33215d2cU, 0xdc8ab90eU,
113974b291aSjoerg 	0xf5e3d7f2U, 0xedcb15cfU, 0xc9a43c4cU, 0xfc678fc6U,
114974b291aSjoerg 	0x43796b95U, 0x3f8b700cU, 0x867bbc72U, 0x81f71fecU,
115974b291aSjoerg 	0xd00cad7dU, 0x302c458fU, 0x8ae21accU, 0x05850ce8U,
116974b291aSjoerg 	0x7764d8e8U, 0x8a36cd68U, 0x40b44bd7U, 0x1cffaeb7U,
117974b291aSjoerg 	0x2b248f34U, 0x1eefdbafU, 0x574d7437U, 0xe86cd935U,
118974b291aSjoerg 	0xf53dd1c8U, 0x1b022513U, 0xef2d249bU, 0x94fb2b08U,
119974b291aSjoerg 	0x15d3eff8U, 0x14245e1bU, 0x82aa8425U, 0x53959028U,
120974b291aSjoerg 	0x9c5f9b80U, 0x325e0c82U, 0x3e236c24U, 0x74e1dd36U,
121974b291aSjoerg 	0x9890df3fU, 0xaf9701a2U, 0x023b3413U, 0x7634c67eU,
122974b291aSjoerg 	0x55cf5e45U, 0x56d2a95bU, 0xb6db869bU, 0xac19e260U,
123974b291aSjoerg 	0xdd310740U, 0x26d68f84U, 0x45bebf17U, 0xe4a7728fU,
124974b291aSjoerg 	0xf082e66eU, 0xb2fe3c10U, 0x2db1fa2cU, 0x4b3dfcfaU,
125974b291aSjoerg 	0xc7b3a672U, 0xaeadc67bU, 0x6cce6f2bU, 0x8263dbbfU,
126974b291aSjoerg 	0xd9724d5bU, 0xbcc767b5U, 0x8d563798U, 0x2db764b4U,
127974b291aSjoerg 	0x76e0cee7U, 0xd34f9a67U, 0x035c810aU, 0x3f56bdc1U,
128974b291aSjoerg 	0x5b3f2c84U, 0x0baca8c0U, 0xfe979a77U, 0x484ca775U,
129974b291aSjoerg 	0xbdc7f104U, 0xc06c3efbU, 0xdbc5f32cU, 0x44b017e7U,
130974b291aSjoerg };
131974b291aSjoerg 
132*1c3ef2c7Sjruoho ATF_TC(popcount_basic);
ATF_TC_HEAD(popcount_basic,tc)133*1c3ef2c7Sjruoho ATF_TC_HEAD(popcount_basic, tc)
134974b291aSjoerg {
135974b291aSjoerg 
136a583a258Spgoyette 	atf_tc_set_md_var(tc, "descr", "Test popcount results");
137974b291aSjoerg 	atf_tc_set_md_var(tc, "timeout", "0");
138974b291aSjoerg }
139974b291aSjoerg 
ATF_TC_BODY(popcount_basic,tc)140*1c3ef2c7Sjruoho ATF_TC_BODY(popcount_basic, tc)
141974b291aSjoerg {
142974b291aSjoerg 	unsigned int i, r;
143974b291aSjoerg 
144a583a258Spgoyette 	popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO"));
145974b291aSjoerg 
146974b291aSjoerg 	for (i = 0; i < 0xffffffff; ++i) {
147974b291aSjoerg 		r = byte_count[i & 255] + byte_count[(i >> 8) & 255]
148974b291aSjoerg 		    + byte_count[(i >> 16) & 255]
149974b291aSjoerg 		    + byte_count[(i >> 24) & 255];
150974b291aSjoerg 
151974b291aSjoerg 		ATF_CHECK_EQ(r, popcount(i));
152974b291aSjoerg 	}
153974b291aSjoerg 	ATF_CHECK_EQ(popcount(0xffffffff), 32);
154974b291aSjoerg }
155974b291aSjoerg 
156*1c3ef2c7Sjruoho ATF_TC(popcountll_basic);
ATF_TC_HEAD(popcountll_basic,tc)157*1c3ef2c7Sjruoho ATF_TC_HEAD(popcountll_basic, tc)
158a583a258Spgoyette {
159a583a258Spgoyette 
160a583a258Spgoyette 	atf_tc_set_md_var(tc, "descr", "Test popcountll results");
161a583a258Spgoyette 	atf_tc_set_md_var(tc, "timeout", "0");
162a583a258Spgoyette }
163a583a258Spgoyette 
ATF_TC_BODY(popcountll_basic,tc)164*1c3ef2c7Sjruoho ATF_TC_BODY(popcountll_basic, tc)
165974b291aSjoerg {
166974b291aSjoerg 	unsigned int i, j, r, r2, p;
167974b291aSjoerg 	unsigned long long v;
168974b291aSjoerg 
169a583a258Spgoyette 	popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO"));
170974b291aSjoerg 
171974b291aSjoerg 	for (j = 0; j < 256; ++j) {
172974b291aSjoerg 		p = test_parts[j];
173974b291aSjoerg 		r2 = byte_count[p & 255] + byte_count[(p >> 8) & 255]
174974b291aSjoerg 		    + byte_count[(p >> 16) & 255]
175974b291aSjoerg 		    + byte_count[(p >> 24) & 255];
176974b291aSjoerg 
177974b291aSjoerg 		for (i = 0; i < 0xffffffff; ++i) {
178974b291aSjoerg 			r = byte_count[i & 255] + byte_count[(i >> 8) & 255]
179974b291aSjoerg 			    + byte_count[(i >> 16) & 255]
180974b291aSjoerg 			    + byte_count[(i >> 24) & 255] + r2;
181974b291aSjoerg 
182974b291aSjoerg 			v = (((unsigned long long)i) << 32) + p;
183974b291aSjoerg 			ATF_CHECK_EQ(r, popcountll(v));
184974b291aSjoerg 			v = (((unsigned long long)p) << 32) + i;
185974b291aSjoerg 			ATF_CHECK_EQ(r, popcountll(v));
186974b291aSjoerg 		}
187974b291aSjoerg 	}
188974b291aSjoerg 
18955f6a48cSdrochner 	ATF_CHECK_EQ(popcountll(0xffffffffffffffffULL), 64);
190974b291aSjoerg }
191974b291aSjoerg 
ATF_TP_ADD_TCS(tp)192974b291aSjoerg ATF_TP_ADD_TCS(tp)
193974b291aSjoerg {
194*1c3ef2c7Sjruoho 	ATF_TP_ADD_TC(tp, popcount_basic);
195*1c3ef2c7Sjruoho 	ATF_TP_ADD_TC(tp, popcountll_basic);
196974b291aSjoerg 
197974b291aSjoerg 	return atf_no_error();
198974b291aSjoerg }
199