xref: /dpdk/app/test/test_bitcount.c (revision 21cab84f6f8c946fabf72fdb03ce4b274887b950)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (C) 2023 Microsoft Corporation
3  */
4 
5 #include <limits.h>
6 #include <string.h>
7 
8 #include <rte_bitops.h>
9 #include <rte_debug.h>
10 
11 #include "test.h"
12 
13 RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO);
14 
15 static int
16 test_clz32(void)
17 {
18 	size_t leading;
19 	uint32_t v = 0xffffffff;
20 
21 	for (leading = 0; v; leading++) {
22 		RTE_TEST_ASSERT(rte_clz32(v) == leading,
23 		    "Unexpected count.");
24 		v >>= 1;
25 	}
26 
27 	return 0;
28 }
29 
30 static int
31 test_clz64(void)
32 {
33 	size_t leading;
34 	uint64_t v = 0xffffffffffffffff;
35 
36 	for (leading = 0; v; leading++) {
37 		RTE_TEST_ASSERT(rte_clz64(v) == leading,
38 		    "Unexpected count.");
39 		v >>= 1;
40 	}
41 
42 	return 0;
43 }
44 
45 static int
46 test_ctz32(void)
47 {
48 	size_t trailing;
49 	uint32_t v = 1;
50 
51 	for (trailing = 0; v; trailing++) {
52 		RTE_TEST_ASSERT(rte_ctz32(v) == trailing,
53 		    "Unexpected count.");
54 		v <<= 1;
55 	}
56 
57 	return 0;
58 }
59 
60 static int
61 test_ctz64(void)
62 {
63 	size_t trailing;
64 	uint64_t v = 1;
65 
66 	for (trailing = 0; v; trailing++) {
67 		RTE_TEST_ASSERT(rte_ctz64(v) == trailing,
68 		    "Unexpected count.");
69 		v <<= 1;
70 	}
71 
72 	return 0;
73 }
74 
75 static int
76 test_popcount32(void)
77 {
78 	size_t shift;
79 	uint32_t v = 0;
80 	const size_t bits = sizeof(v) * CHAR_BIT;
81 
82 	for (shift = 0; shift < bits; shift++) {
83 		RTE_TEST_ASSERT(rte_popcount32(v) == shift,
84 		    "Unexpected count.");
85 		v <<= 1;
86 		v |= 1;
87 	}
88 
89 	RTE_TEST_ASSERT(rte_popcount32(v) == bits,
90 	    "Unexpected count.");
91 
92 	return 0;
93 }
94 
95 static int
96 test_popcount64(void)
97 {
98 	size_t shift;
99 	uint64_t v = 0;
100 	const size_t bits = sizeof(v) * CHAR_BIT;
101 
102 	for (shift = 0; shift < bits; shift++) {
103 		RTE_TEST_ASSERT(rte_popcount64(v) == shift,
104 		    "Unexpected count.");
105 		v <<= 1;
106 		v |= 1;
107 	}
108 
109 	RTE_TEST_ASSERT(rte_popcount64(v) == bits,
110 	    "Unexpected count.");
111 
112 	return 0;
113 }
114 
115 static int
116 test_bit_scan_forward(void)
117 {
118 	unsigned int bit_nr;
119 
120 	TEST_ASSERT((bit_nr = rte_ffs32(0)) == 0,
121 		"rte_ffs32 returned unexpected %d", bit_nr);
122 
123 	for (int i = 0; i < 32; ++i) {
124 		uint32_t n = RTE_BIT32(i);
125 
126 		TEST_ASSERT((bit_nr = rte_ffs32(n)) == (unsigned int)(i+1),
127 			"rte_ffs32 returned unexpected %d", bit_nr);
128 	}
129 
130 	return TEST_SUCCESS;
131 }
132 
133 static int
134 test_bit_scan_forward64(void)
135 {
136 	unsigned int bit_nr;
137 
138 	TEST_ASSERT((bit_nr = rte_ffs64(0)) == 0,
139 		"rte_ffs64 returned unexpected %d", bit_nr);
140 
141 	for (int i = 0; i < 64; ++i) {
142 		uint64_t n = RTE_BIT64(i);
143 
144 		TEST_ASSERT((bit_nr = rte_ffs64(n)) == (unsigned int)(i+1),
145 			"rte_ffs64 returned unexpected %d", bit_nr);
146 	}
147 
148 	return TEST_SUCCESS;
149 }
150 
151 static struct unit_test_suite bitcount_test_suite = {
152 	.suite_name = "bitcount autotest",
153 	.setup = NULL,
154 	.teardown = NULL,
155 	.unit_test_cases = {
156 		TEST_CASE(test_clz32),
157 		TEST_CASE(test_clz64),
158 		TEST_CASE(test_ctz32),
159 		TEST_CASE(test_ctz64),
160 		TEST_CASE(test_popcount32),
161 		TEST_CASE(test_popcount64),
162 		TEST_CASE(test_bit_scan_forward),
163 		TEST_CASE(test_bit_scan_forward64),
164 		TEST_CASES_END()
165 	}
166 };
167 
168 static int
169 test_bitcount(void)
170 {
171 	return unit_test_suite_runner(&bitcount_test_suite);
172 }
173 
174 REGISTER_FAST_TEST(bitcount_autotest, true, true, test_bitcount);
175