1272343Sngie/*	$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $	*/
2272343Sngie/*-
3272343Sngie * Copyright (c) 2009 The NetBSD Foundation, Inc.
4272343Sngie * All rights reserved.
5272343Sngie *
6272343Sngie * This code is derived from software contributed to The NetBSD Foundation
7272343Sngie * by Joerg Sonnenberger.
8272343Sngie *
9272343Sngie * Redistribution and use in source and binary forms, with or without
10272343Sngie * modification, are permitted provided that the following conditions
11272343Sngie * are met:
12272343Sngie *
13272343Sngie * 1. Redistributions of source code must retain the above copyright
14272343Sngie *    notice, this list of conditions and the following disclaimer.
15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright
16272343Sngie *    notice, this list of conditions and the following disclaimer in
17272343Sngie *    the documentation and/or other materials provided with the
18272343Sngie *    distribution.
19272343Sngie *
20272343Sngie * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22272343Sngie * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23272343Sngie * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
24272343Sngie * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25272343Sngie * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
26272343Sngie * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27272343Sngie * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28272343Sngie * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29272343Sngie * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30272343Sngie * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31272343Sngie * SUCH DAMAGE.
32272343Sngie */
33272343Sngie
34272343Sngie#include <sys/cdefs.h>
35272343Sngie__RCSID("$NetBSD: t_popcount.c,v 1.4 2011/07/07 08:27:36 jruoho Exp $");
36272343Sngie
37272343Sngie#include <atf-c.h>
38272343Sngie#include <strings.h>
39272343Sngie
40272343Sngiestatic unsigned int byte_count[256];
41272343Sngie
42272343Sngiestatic void
43272343Sngiepopcount_init(const char *cfg_var)
44272343Sngie{
45272343Sngie	unsigned int i, j;
46272343Sngie
47272343Sngie	if (strcasecmp(cfg_var, "YES")  == 0 ||
48272343Sngie	    strcasecmp(cfg_var, "Y")    == 0 ||
49272343Sngie	    strcasecmp(cfg_var, "1")    == 0 ||
50272343Sngie	    strcasecmp(cfg_var, "T")    == 0 ||
51272343Sngie	    strcasecmp(cfg_var, "TRUE") == 0) {
52272343Sngie		for (i = 0; i < 256; ++i) {
53272343Sngie			byte_count[i] = 0;
54272343Sngie			for (j = i; j != 0; j >>= 1) {
55272343Sngie				if (j & 1)
56272343Sngie					++byte_count[i];
57272343Sngie			}
58272343Sngie		}
59272343Sngie		return;
60272343Sngie	}
61272343Sngie
62272343Sngie	atf_tc_skip("config variable \"run_popcount\" not set to YES/TRUE");
63272343Sngie}
64272343Sngie
65272343Sngieunsigned int test_parts[256] = {
66272343Sngie	0x318e53e6U, 0x11710316U, 0x62608ffaU, 0x67e0f562U,
67272343Sngie	0xe432e82cU, 0x9862e8b2U, 0x7d96a627U, 0x3f74ad31U,
68272343Sngie	0x3cecf906U, 0xcdc0dcb4U, 0x241dab64U, 0x31e6133eU,
69272343Sngie	0x23086ad4U, 0x721d5a91U, 0xc483da53U, 0x6a62af52U,
70272343Sngie	0xf3f5c386U, 0xe0de3f77U, 0x65afe528U, 0xf4816485U,
71272343Sngie	0x40ccbf08U, 0x25df49c1U, 0xae5a6ee0U, 0xab36ccadU,
72272343Sngie	0x87e1ec29U, 0x60ca2407U, 0x49d62e47U, 0xa09f2df5U,
73272343Sngie	0xaf4c1c68U, 0x8ef08d50U, 0x624cfd2fU, 0xa6a36f20U,
74272343Sngie	0x68aaf879U, 0x0fe9deabU, 0x5c9a4060U, 0x215d8f08U,
75272343Sngie	0x55e84712U, 0xea1f1681U, 0x3a10b8a1U, 0x08e06632U,
76272343Sngie	0xcbc875e2U, 0x31e53258U, 0xcd3807a4U, 0xb9d17516U,
77272343Sngie	0x8fbfd9abU, 0x6651b555U, 0x550fb381U, 0x05061b9dU,
78272343Sngie	0x35aef3f2U, 0x9175078cU, 0xae0f14daU, 0x92a2d5f8U,
79272343Sngie	0x70d968feU, 0xe86f41c5U, 0x5cfaf39fU, 0x8499b18dU,
80272343Sngie	0xb33f879aU, 0x0a68ad3dU, 0x9323ecc1U, 0x060037ddU,
81272343Sngie	0xb91a5051U, 0xa0dbebf6U, 0x3e6aa6f1U, 0x7b422b5bU,
82272343Sngie	0x599e811eU, 0x199f7594U, 0xca453365U, 0x1cda6f48U,
83272343Sngie	0xe9c75d2cU, 0x6a873217U, 0x79c45d72U, 0x143b8e37U,
84272343Sngie	0xa11df26eU, 0xaf31f80aU, 0x311bf759U, 0x2378563cU,
85272343Sngie	0x9ab95fa5U, 0xfcf4d47cU, 0x1f7db268U, 0xd64b09e1U,
86272343Sngie	0xad7936daU, 0x7a59005cU, 0x45b173d3U, 0xc1a71b32U,
87272343Sngie	0x7d9f0de2U, 0xa9ac3792U, 0x9e7f9966U, 0x7f0b8080U,
88272343Sngie	0xece6c06fU, 0x78d92a3cU, 0x6d5f8f6cU, 0xc50ca544U,
89272343Sngie	0x5d8ded27U, 0xd27a8462U, 0x4bcd13ccU, 0xd49075f2U,
90272343Sngie	0xa8d52acfU, 0x41915d97U, 0x564f7062U, 0xefb046e2U,
91272343Sngie	0xe296277aU, 0x605b0ea3U, 0x10b2c3a1U, 0x4e8e5c66U,
92272343Sngie	0x4bd8ec04U, 0x29935be9U, 0x381839f3U, 0x555d8824U,
93272343Sngie	0xd6befddbU, 0x5d8d6d6eU, 0xb2fdb7b4U, 0xb471c8fcU,
94272343Sngie	0xc2fd325bU, 0x932d2487U, 0xbdbbadefU, 0x66c8895dU,
95272343Sngie	0x5d77857aU, 0x259f1cc0U, 0x302037faU, 0xda9aa7a8U,
96272343Sngie	0xb112c6aaU, 0x78f74192U, 0xfd4da741U, 0xfa5765c1U,
97272343Sngie	0x6ea1bc5cU, 0xd283f39cU, 0x268ae67dU, 0xdedcd134U,
98272343Sngie	0xbbf92410U, 0x6b45fb55U, 0x2f75ac71U, 0x64bf2ca5U,
99272343Sngie	0x8b99675aU, 0x3f4923b6U, 0x7e610550U, 0x04b1c06dU,
100272343Sngie	0x8f92e7c6U, 0x45cb608bU, 0x2d06d1f2U, 0x79cf387aU,
101272343Sngie	0xfd3ed225U, 0x243eee20U, 0x2cbefc6fU, 0x8286cbaaU,
102272343Sngie	0x70d4c182U, 0x054e3cc6U, 0xb66c5362U, 0x0c73fa5dU,
103272343Sngie	0x539948feU, 0xec638563U, 0x0cf04ab6U, 0xec7b52f4U,
104272343Sngie	0x58eeffceU, 0x6fe8049aU, 0xb3b33332U, 0x2e33bfdbU,
105272343Sngie	0xcc817567U, 0x71ac57c8U, 0x4bab3ac7U, 0x327c558bU,
106272343Sngie	0x82a6d279U, 0x5adf71daU, 0x1074a656U, 0x3c533c1fU,
107272343Sngie	0x82fdbe69U, 0x21b4f6afU, 0xd59580e8U, 0x0de824ebU,
108272343Sngie	0xa510941bU, 0x7cd91144U, 0xa8c10631U, 0x4c839267U,
109272343Sngie	0x5d503c2fU, 0xe1567d55U, 0x23910cc7U, 0xdb1bdc34U,
110272343Sngie	0x2a866704U, 0x33e21f0cU, 0x5c7681b4U, 0x818651caU,
111272343Sngie	0xb1d18162U, 0x225ad014U, 0xadf7d6baU, 0xac548d9bU,
112272343Sngie	0xe94736e5U, 0x2279c5f1U, 0x33215d2cU, 0xdc8ab90eU,
113272343Sngie	0xf5e3d7f2U, 0xedcb15cfU, 0xc9a43c4cU, 0xfc678fc6U,
114272343Sngie	0x43796b95U, 0x3f8b700cU, 0x867bbc72U, 0x81f71fecU,
115272343Sngie	0xd00cad7dU, 0x302c458fU, 0x8ae21accU, 0x05850ce8U,
116272343Sngie	0x7764d8e8U, 0x8a36cd68U, 0x40b44bd7U, 0x1cffaeb7U,
117272343Sngie	0x2b248f34U, 0x1eefdbafU, 0x574d7437U, 0xe86cd935U,
118272343Sngie	0xf53dd1c8U, 0x1b022513U, 0xef2d249bU, 0x94fb2b08U,
119272343Sngie	0x15d3eff8U, 0x14245e1bU, 0x82aa8425U, 0x53959028U,
120272343Sngie	0x9c5f9b80U, 0x325e0c82U, 0x3e236c24U, 0x74e1dd36U,
121272343Sngie	0x9890df3fU, 0xaf9701a2U, 0x023b3413U, 0x7634c67eU,
122272343Sngie	0x55cf5e45U, 0x56d2a95bU, 0xb6db869bU, 0xac19e260U,
123272343Sngie	0xdd310740U, 0x26d68f84U, 0x45bebf17U, 0xe4a7728fU,
124272343Sngie	0xf082e66eU, 0xb2fe3c10U, 0x2db1fa2cU, 0x4b3dfcfaU,
125272343Sngie	0xc7b3a672U, 0xaeadc67bU, 0x6cce6f2bU, 0x8263dbbfU,
126272343Sngie	0xd9724d5bU, 0xbcc767b5U, 0x8d563798U, 0x2db764b4U,
127272343Sngie	0x76e0cee7U, 0xd34f9a67U, 0x035c810aU, 0x3f56bdc1U,
128272343Sngie	0x5b3f2c84U, 0x0baca8c0U, 0xfe979a77U, 0x484ca775U,
129272343Sngie	0xbdc7f104U, 0xc06c3efbU, 0xdbc5f32cU, 0x44b017e7U,
130272343Sngie};
131272343Sngie
132272343SngieATF_TC(popcount_basic);
133272343SngieATF_TC_HEAD(popcount_basic, tc)
134272343Sngie{
135272343Sngie
136272343Sngie	atf_tc_set_md_var(tc, "descr", "Test popcount results");
137272343Sngie	atf_tc_set_md_var(tc, "timeout", "0");
138272343Sngie}
139272343Sngie
140272343SngieATF_TC_BODY(popcount_basic, tc)
141272343Sngie{
142272343Sngie	unsigned int i, r;
143272343Sngie
144272343Sngie	popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO"));
145272343Sngie
146272343Sngie	for (i = 0; i < 0xffffffff; ++i) {
147272343Sngie		r = byte_count[i & 255] + byte_count[(i >> 8) & 255]
148272343Sngie		    + byte_count[(i >> 16) & 255]
149272343Sngie		    + byte_count[(i >> 24) & 255];
150272343Sngie
151272343Sngie		ATF_CHECK_EQ(r, popcount(i));
152272343Sngie	}
153272343Sngie	ATF_CHECK_EQ(popcount(0xffffffff), 32);
154272343Sngie}
155272343Sngie
156272343SngieATF_TC(popcountll_basic);
157272343SngieATF_TC_HEAD(popcountll_basic, tc)
158272343Sngie{
159272343Sngie
160272343Sngie	atf_tc_set_md_var(tc, "descr", "Test popcountll results");
161272343Sngie	atf_tc_set_md_var(tc, "timeout", "0");
162272343Sngie}
163272343Sngie
164272343SngieATF_TC_BODY(popcountll_basic, tc)
165272343Sngie{
166272343Sngie	unsigned int i, j, r, r2, p;
167272343Sngie	unsigned long long v;
168272343Sngie
169272343Sngie	popcount_init(atf_tc_get_config_var_wd(tc, "run_popcount", "NO"));
170272343Sngie
171272343Sngie	for (j = 0; j < 256; ++j) {
172272343Sngie		p = test_parts[j];
173272343Sngie		r2 = byte_count[p & 255] + byte_count[(p >> 8) & 255]
174272343Sngie		    + byte_count[(p >> 16) & 255]
175272343Sngie		    + byte_count[(p >> 24) & 255];
176272343Sngie
177272343Sngie		for (i = 0; i < 0xffffffff; ++i) {
178272343Sngie			r = byte_count[i & 255] + byte_count[(i >> 8) & 255]
179272343Sngie			    + byte_count[(i >> 16) & 255]
180272343Sngie			    + byte_count[(i >> 24) & 255] + r2;
181272343Sngie
182272343Sngie			v = (((unsigned long long)i) << 32) + p;
183272343Sngie			ATF_CHECK_EQ(r, popcountll(v));
184272343Sngie			v = (((unsigned long long)p) << 32) + i;
185272343Sngie			ATF_CHECK_EQ(r, popcountll(v));
186272343Sngie		}
187272343Sngie	}
188272343Sngie
189272343Sngie	ATF_CHECK_EQ(popcountll(0xffffffffffffffffULL), 64);
190272343Sngie}
191272343Sngie
192272343SngieATF_TP_ADD_TCS(tp)
193272343Sngie{
194272343Sngie	ATF_TP_ADD_TC(tp, popcount_basic);
195272343Sngie	ATF_TP_ADD_TC(tp, popcountll_basic);
196272343Sngie
197272343Sngie	return atf_no_error();
198272343Sngie}
199