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