1916c50ddSTyler Retzlaff /* SPDX-License-Identifier: BSD-3-Clause 2916c50ddSTyler Retzlaff * Copyright (C) 2023 Microsoft Corporation 3916c50ddSTyler Retzlaff */ 4916c50ddSTyler Retzlaff 5916c50ddSTyler Retzlaff #include <limits.h> 6916c50ddSTyler Retzlaff #include <string.h> 7916c50ddSTyler Retzlaff 8916c50ddSTyler Retzlaff #include <rte_bitops.h> 9916c50ddSTyler Retzlaff #include <rte_debug.h> 10916c50ddSTyler Retzlaff 11916c50ddSTyler Retzlaff #include "test.h" 12916c50ddSTyler Retzlaff 13916c50ddSTyler Retzlaff RTE_LOG_REGISTER(bitcount_logtype_test, test.bitcount, INFO); 14916c50ddSTyler Retzlaff 15916c50ddSTyler Retzlaff static int 16916c50ddSTyler Retzlaff test_clz32(void) 17916c50ddSTyler Retzlaff { 18916c50ddSTyler Retzlaff size_t leading; 19916c50ddSTyler Retzlaff uint32_t v = 0xffffffff; 20916c50ddSTyler Retzlaff 21916c50ddSTyler Retzlaff for (leading = 0; v; leading++) { 22916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_clz32(v) == leading, 23916c50ddSTyler Retzlaff "Unexpected count."); 24916c50ddSTyler Retzlaff v >>= 1; 25916c50ddSTyler Retzlaff } 26916c50ddSTyler Retzlaff 27916c50ddSTyler Retzlaff return 0; 28916c50ddSTyler Retzlaff } 29916c50ddSTyler Retzlaff 30916c50ddSTyler Retzlaff static int 31916c50ddSTyler Retzlaff test_clz64(void) 32916c50ddSTyler Retzlaff { 33916c50ddSTyler Retzlaff size_t leading; 34916c50ddSTyler Retzlaff uint64_t v = 0xffffffffffffffff; 35916c50ddSTyler Retzlaff 36916c50ddSTyler Retzlaff for (leading = 0; v; leading++) { 37916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_clz64(v) == leading, 38916c50ddSTyler Retzlaff "Unexpected count."); 39916c50ddSTyler Retzlaff v >>= 1; 40916c50ddSTyler Retzlaff } 41916c50ddSTyler Retzlaff 42916c50ddSTyler Retzlaff return 0; 43916c50ddSTyler Retzlaff } 44916c50ddSTyler Retzlaff 45916c50ddSTyler Retzlaff static int 46916c50ddSTyler Retzlaff test_ctz32(void) 47916c50ddSTyler Retzlaff { 48916c50ddSTyler Retzlaff size_t trailing; 49916c50ddSTyler Retzlaff uint32_t v = 1; 50916c50ddSTyler Retzlaff 51916c50ddSTyler Retzlaff for (trailing = 0; v; trailing++) { 52916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_ctz32(v) == trailing, 53916c50ddSTyler Retzlaff "Unexpected count."); 54916c50ddSTyler Retzlaff v <<= 1; 55916c50ddSTyler Retzlaff } 56916c50ddSTyler Retzlaff 57916c50ddSTyler Retzlaff return 0; 58916c50ddSTyler Retzlaff } 59916c50ddSTyler Retzlaff 60916c50ddSTyler Retzlaff static int 61916c50ddSTyler Retzlaff test_ctz64(void) 62916c50ddSTyler Retzlaff { 63916c50ddSTyler Retzlaff size_t trailing; 64916c50ddSTyler Retzlaff uint64_t v = 1; 65916c50ddSTyler Retzlaff 66916c50ddSTyler Retzlaff for (trailing = 0; v; trailing++) { 67916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_ctz64(v) == trailing, 68916c50ddSTyler Retzlaff "Unexpected count."); 69916c50ddSTyler Retzlaff v <<= 1; 70916c50ddSTyler Retzlaff } 71916c50ddSTyler Retzlaff 72916c50ddSTyler Retzlaff return 0; 73916c50ddSTyler Retzlaff } 74916c50ddSTyler Retzlaff 75916c50ddSTyler Retzlaff static int 76916c50ddSTyler Retzlaff test_popcount32(void) 77916c50ddSTyler Retzlaff { 78916c50ddSTyler Retzlaff size_t shift; 79916c50ddSTyler Retzlaff uint32_t v = 0; 80916c50ddSTyler Retzlaff const size_t bits = sizeof(v) * CHAR_BIT; 81916c50ddSTyler Retzlaff 82916c50ddSTyler Retzlaff for (shift = 0; shift < bits; shift++) { 83916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_popcount32(v) == shift, 84916c50ddSTyler Retzlaff "Unexpected count."); 85916c50ddSTyler Retzlaff v <<= 1; 86916c50ddSTyler Retzlaff v |= 1; 87916c50ddSTyler Retzlaff } 88916c50ddSTyler Retzlaff 89916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_popcount32(v) == bits, 90916c50ddSTyler Retzlaff "Unexpected count."); 91916c50ddSTyler Retzlaff 92916c50ddSTyler Retzlaff return 0; 93916c50ddSTyler Retzlaff } 94916c50ddSTyler Retzlaff 95916c50ddSTyler Retzlaff static int 96916c50ddSTyler Retzlaff test_popcount64(void) 97916c50ddSTyler Retzlaff { 98916c50ddSTyler Retzlaff size_t shift; 99916c50ddSTyler Retzlaff uint64_t v = 0; 100916c50ddSTyler Retzlaff const size_t bits = sizeof(v) * CHAR_BIT; 101916c50ddSTyler Retzlaff 102916c50ddSTyler Retzlaff for (shift = 0; shift < bits; shift++) { 103916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_popcount64(v) == shift, 104916c50ddSTyler Retzlaff "Unexpected count."); 105916c50ddSTyler Retzlaff v <<= 1; 106916c50ddSTyler Retzlaff v |= 1; 107916c50ddSTyler Retzlaff } 108916c50ddSTyler Retzlaff 109916c50ddSTyler Retzlaff RTE_TEST_ASSERT(rte_popcount64(v) == bits, 110916c50ddSTyler Retzlaff "Unexpected count."); 111916c50ddSTyler Retzlaff 112916c50ddSTyler Retzlaff return 0; 113916c50ddSTyler Retzlaff } 114916c50ddSTyler Retzlaff 115*21cab84fSTyler Retzlaff static int 116*21cab84fSTyler Retzlaff test_bit_scan_forward(void) 117*21cab84fSTyler Retzlaff { 118*21cab84fSTyler Retzlaff unsigned int bit_nr; 119*21cab84fSTyler Retzlaff 120*21cab84fSTyler Retzlaff TEST_ASSERT((bit_nr = rte_ffs32(0)) == 0, 121*21cab84fSTyler Retzlaff "rte_ffs32 returned unexpected %d", bit_nr); 122*21cab84fSTyler Retzlaff 123*21cab84fSTyler Retzlaff for (int i = 0; i < 32; ++i) { 124*21cab84fSTyler Retzlaff uint32_t n = RTE_BIT32(i); 125*21cab84fSTyler Retzlaff 126*21cab84fSTyler Retzlaff TEST_ASSERT((bit_nr = rte_ffs32(n)) == (unsigned int)(i+1), 127*21cab84fSTyler Retzlaff "rte_ffs32 returned unexpected %d", bit_nr); 128*21cab84fSTyler Retzlaff } 129*21cab84fSTyler Retzlaff 130*21cab84fSTyler Retzlaff return TEST_SUCCESS; 131*21cab84fSTyler Retzlaff } 132*21cab84fSTyler Retzlaff 133*21cab84fSTyler Retzlaff static int 134*21cab84fSTyler Retzlaff test_bit_scan_forward64(void) 135*21cab84fSTyler Retzlaff { 136*21cab84fSTyler Retzlaff unsigned int bit_nr; 137*21cab84fSTyler Retzlaff 138*21cab84fSTyler Retzlaff TEST_ASSERT((bit_nr = rte_ffs64(0)) == 0, 139*21cab84fSTyler Retzlaff "rte_ffs64 returned unexpected %d", bit_nr); 140*21cab84fSTyler Retzlaff 141*21cab84fSTyler Retzlaff for (int i = 0; i < 64; ++i) { 142*21cab84fSTyler Retzlaff uint64_t n = RTE_BIT64(i); 143*21cab84fSTyler Retzlaff 144*21cab84fSTyler Retzlaff TEST_ASSERT((bit_nr = rte_ffs64(n)) == (unsigned int)(i+1), 145*21cab84fSTyler Retzlaff "rte_ffs64 returned unexpected %d", bit_nr); 146*21cab84fSTyler Retzlaff } 147*21cab84fSTyler Retzlaff 148*21cab84fSTyler Retzlaff return TEST_SUCCESS; 149*21cab84fSTyler Retzlaff } 150*21cab84fSTyler Retzlaff 151916c50ddSTyler Retzlaff static struct unit_test_suite bitcount_test_suite = { 152916c50ddSTyler Retzlaff .suite_name = "bitcount autotest", 153916c50ddSTyler Retzlaff .setup = NULL, 154916c50ddSTyler Retzlaff .teardown = NULL, 155916c50ddSTyler Retzlaff .unit_test_cases = { 156916c50ddSTyler Retzlaff TEST_CASE(test_clz32), 157916c50ddSTyler Retzlaff TEST_CASE(test_clz64), 158916c50ddSTyler Retzlaff TEST_CASE(test_ctz32), 159916c50ddSTyler Retzlaff TEST_CASE(test_ctz64), 160916c50ddSTyler Retzlaff TEST_CASE(test_popcount32), 161916c50ddSTyler Retzlaff TEST_CASE(test_popcount64), 162*21cab84fSTyler Retzlaff TEST_CASE(test_bit_scan_forward), 163*21cab84fSTyler Retzlaff TEST_CASE(test_bit_scan_forward64), 164916c50ddSTyler Retzlaff TEST_CASES_END() 165916c50ddSTyler Retzlaff } 166916c50ddSTyler Retzlaff }; 167916c50ddSTyler Retzlaff 168916c50ddSTyler Retzlaff static int 169916c50ddSTyler Retzlaff test_bitcount(void) 170916c50ddSTyler Retzlaff { 171916c50ddSTyler Retzlaff return unit_test_suite_runner(&bitcount_test_suite); 172916c50ddSTyler Retzlaff } 173916c50ddSTyler Retzlaff 174916c50ddSTyler Retzlaff REGISTER_FAST_TEST(bitcount_autotest, true, true, test_bitcount); 175