1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <inttypes.h> 7 #include <string.h> 8 #include <math.h> 9 #include <rte_common.h> 10 #include <rte_hexdump.h> 11 #include <rte_pause.h> 12 13 #include "test.h" 14 15 #define MAX_NUM 1 << 20 16 17 #define FAIL(x)\ 18 {printf(x "() test failed!\n");\ 19 return -1;} 20 21 /* this is really a sanity check */ 22 static int 23 test_macros(int __rte_unused unused_parm) 24 { 25 #define SMALLER 0x1000U 26 #define BIGGER 0x2000U 27 #define PTR_DIFF BIGGER - SMALLER 28 #define FAIL_MACRO(x)\ 29 {printf(#x "() test failed!\n");\ 30 return -1;} 31 32 uintptr_t unused = 0; 33 34 RTE_SET_USED(unused); 35 36 if ((uintptr_t)RTE_PTR_ADD(SMALLER, PTR_DIFF) != BIGGER) 37 FAIL_MACRO(RTE_PTR_ADD); 38 if ((uintptr_t)RTE_PTR_SUB(BIGGER, PTR_DIFF) != SMALLER) 39 FAIL_MACRO(RTE_PTR_SUB); 40 if (RTE_PTR_DIFF(BIGGER, SMALLER) != PTR_DIFF) 41 FAIL_MACRO(RTE_PTR_DIFF); 42 if (RTE_MAX(SMALLER, BIGGER) != BIGGER) 43 FAIL_MACRO(RTE_MAX); 44 if (RTE_MIN(SMALLER, BIGGER) != SMALLER) 45 FAIL_MACRO(RTE_MIN); 46 47 if (strncmp(RTE_STR(test), "test", sizeof("test"))) 48 FAIL_MACRO(RTE_STR); 49 50 return 0; 51 } 52 53 static int 54 test_bsf(void) 55 { 56 uint32_t shift, pos; 57 58 /* safe versions should be able to handle 0 */ 59 if (rte_bsf32_safe(0, &pos) != 0) 60 FAIL("rte_bsf32_safe"); 61 if (rte_bsf64_safe(0, &pos) != 0) 62 FAIL("rte_bsf64_safe"); 63 64 for (shift = 0; shift < 63; shift++) { 65 uint32_t val32; 66 uint64_t val64; 67 68 val64 = 1ULL << shift; 69 if ((uint32_t)rte_bsf64(val64) != shift) 70 FAIL("rte_bsf64"); 71 if (rte_bsf64_safe(val64, &pos) != 1) 72 FAIL("rte_bsf64_safe"); 73 if (pos != shift) 74 FAIL("rte_bsf64_safe"); 75 76 if (shift > 31) 77 continue; 78 79 val32 = 1U << shift; 80 if ((uint32_t)rte_bsf32(val32) != shift) 81 FAIL("rte_bsf32"); 82 if (rte_bsf32_safe(val32, &pos) != 1) 83 FAIL("rte_bsf32_safe"); 84 if (pos != shift) 85 FAIL("rte_bsf32_safe"); 86 } 87 88 return 0; 89 } 90 91 static int 92 test_misc(void) 93 { 94 char memdump[] = "memdump_test"; 95 96 rte_memdump(stdout, "test", memdump, sizeof(memdump)); 97 rte_hexdump(stdout, "test", memdump, sizeof(memdump)); 98 99 rte_pause(); 100 101 return 0; 102 } 103 104 static int 105 test_align(void) 106 { 107 #define FAIL_ALIGN(x, i, p)\ 108 {printf(x "() test failed: %u %u\n", i, p);\ 109 return -1;} 110 #define FAIL_ALIGN64(x, j, q)\ 111 {printf(x "() test failed: %"PRIu64" %"PRIu64"\n", j, q);\ 112 return -1; } 113 #define ERROR_FLOOR(res, i, pow) \ 114 (res % pow) || /* check if not aligned */ \ 115 ((res / pow) != (i / pow)) /* check if correct alignment */ 116 #define ERROR_CEIL(res, i, pow) \ 117 (res % pow) || /* check if not aligned */ \ 118 ((i % pow) == 0 ? /* check if ceiling is invoked */ \ 119 val / pow != i / pow : /* if aligned */ \ 120 val / pow != (i / pow) + 1) /* if not aligned, hence +1 */ 121 122 uint32_t i, p, val; 123 uint64_t j, q; 124 125 for (i = 1, p = 1; i <= MAX_NUM; i ++) { 126 if (rte_align32pow2(i) != p) 127 FAIL_ALIGN("rte_align32pow2", i, p); 128 if (i == p) 129 p <<= 1; 130 } 131 132 for (i = 1, p = 1; i <= MAX_NUM; i++) { 133 if (rte_align32prevpow2(i) != p) 134 FAIL_ALIGN("rte_align32prevpow2", i, p); 135 if (rte_is_power_of_2(i + 1)) 136 p = i + 1; 137 } 138 139 for (j = 1, q = 1; j <= MAX_NUM ; j++) { 140 if (rte_align64pow2(j) != q) 141 FAIL_ALIGN64("rte_align64pow2", j, q); 142 if (j == q) 143 q <<= 1; 144 } 145 146 for (j = 1, q = 1; j <= MAX_NUM ; j++) { 147 if (rte_align64prevpow2(j) != q) 148 FAIL_ALIGN64("rte_align64prevpow2", j, q); 149 if (rte_is_power_of_2(j + 1)) 150 q = j + 1; 151 } 152 153 for (p = 2; p <= MAX_NUM; p <<= 1) { 154 155 if (!rte_is_power_of_2(p)) 156 FAIL("rte_is_power_of_2"); 157 158 for (i = 1; i <= MAX_NUM; i++) { 159 /* align floor */ 160 if (RTE_ALIGN_FLOOR((uintptr_t)i, p) % p) 161 FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p); 162 163 val = RTE_PTR_ALIGN_FLOOR((uintptr_t) i, p); 164 if (ERROR_FLOOR(val, i, p)) 165 FAIL_ALIGN("RTE_PTR_ALIGN_FLOOR", i, p); 166 167 val = RTE_ALIGN_FLOOR(i, p); 168 if (ERROR_FLOOR(val, i, p)) 169 FAIL_ALIGN("RTE_ALIGN_FLOOR", i, p); 170 171 /* align ceiling */ 172 val = RTE_PTR_ALIGN((uintptr_t) i, p); 173 if (ERROR_CEIL(val, i, p)) 174 FAIL_ALIGN("RTE_PTR_ALIGN", i, p); 175 176 val = RTE_ALIGN(i, p); 177 if (ERROR_CEIL(val, i, p)) 178 FAIL_ALIGN("RTE_ALIGN", i, p); 179 180 val = RTE_ALIGN_CEIL(i, p); 181 if (ERROR_CEIL(val, i, p)) 182 FAIL_ALIGN("RTE_ALIGN_CEIL", i, p); 183 184 val = RTE_PTR_ALIGN_CEIL((uintptr_t)i, p); 185 if (ERROR_CEIL(val, i, p)) 186 FAIL_ALIGN("RTE_PTR_ALIGN_CEIL", i, p); 187 188 /* by this point we know that val is aligned to p */ 189 if (!rte_is_aligned((void*)(uintptr_t) val, p)) 190 FAIL("rte_is_aligned"); 191 } 192 } 193 194 for (p = 1; p <= MAX_NUM / 2; p++) { 195 for (i = 1; i <= MAX_NUM / 2; i++) { 196 val = RTE_ALIGN_MUL_CEIL(i, p); 197 if (val % p != 0 || val < i) 198 FAIL_ALIGN("RTE_ALIGN_MUL_CEIL", i, p); 199 val = RTE_ALIGN_MUL_FLOOR(i, p); 200 if (val % p != 0 || val > i) 201 FAIL_ALIGN("RTE_ALIGN_MUL_FLOOR", i, p); 202 val = RTE_ALIGN_MUL_NEAR(i, p); 203 if (val % p != 0 || ((val != RTE_ALIGN_MUL_CEIL(i, p)) 204 & (val != RTE_ALIGN_MUL_FLOOR(i, p)))) 205 FAIL_ALIGN("RTE_ALIGN_MUL_NEAR", i, p); 206 } 207 } 208 209 return 0; 210 } 211 212 static int 213 test_log2(void) 214 { 215 uint32_t i, base, compare; 216 const uint32_t max = 0x10000; 217 const uint32_t step = 1; 218 219 for (i = 0; i < max; i = i + step) { 220 uint64_t i64; 221 222 /* extend range for 64-bit */ 223 i64 = (uint64_t)i << 32; 224 base = (uint32_t)ceilf(log2(i64)); 225 compare = rte_log2_u64(i64); 226 if (base != compare) { 227 printf("Wrong rte_log2_u64(%" PRIx64 ") val %x, expected %x\n", 228 i64, compare, base); 229 return TEST_FAILED; 230 } 231 232 base = (uint32_t)ceilf(log2((uint32_t)i)); 233 compare = rte_log2_u32((uint32_t)i); 234 if (base != compare) { 235 printf("Wrong rte_log2_u32(%x) val %x, expected %x\n", 236 i, compare, base); 237 return TEST_FAILED; 238 } 239 compare = rte_log2_u64((uint64_t)i); 240 if (base != compare) { 241 printf("Wrong rte_log2_u64(%x) val %x, expected %x\n", 242 i, compare, base); 243 return TEST_FAILED; 244 } 245 } 246 return 0; 247 } 248 249 static int 250 test_fls(void) 251 { 252 struct fls_test_vector { 253 uint32_t arg; 254 int rc; 255 }; 256 int expected, rc; 257 uint32_t i, arg; 258 259 const struct fls_test_vector test[] = { 260 {0x0, 0}, 261 {0x1, 1}, 262 {0x4000, 15}, 263 {0x80000000, 32}, 264 }; 265 266 for (i = 0; i < RTE_DIM(test); i++) { 267 uint64_t arg64; 268 269 arg = test[i].arg; 270 rc = rte_fls_u32(arg); 271 expected = test[i].rc; 272 if (rc != expected) { 273 printf("Wrong rte_fls_u32(0x%x) rc=%d, expected=%d\n", 274 arg, rc, expected); 275 return TEST_FAILED; 276 } 277 /* 64-bit version */ 278 arg = test[i].arg; 279 rc = rte_fls_u64(arg); 280 expected = test[i].rc; 281 if (rc != expected) { 282 printf("Wrong rte_fls_u64(0x%x) rc=%d, expected=%d\n", 283 arg, rc, expected); 284 return TEST_FAILED; 285 } 286 /* 64-bit version shifted by 32 bits */ 287 arg64 = (uint64_t)test[i].arg << 32; 288 rc = rte_fls_u64(arg64); 289 /* don't shift zero */ 290 expected = test[i].rc == 0 ? 0 : test[i].rc + 32; 291 if (rc != expected) { 292 printf("Wrong rte_fls_u64(0x%" PRIx64 ") rc=%d, expected=%d\n", 293 arg64, rc, expected); 294 return TEST_FAILED; 295 } 296 } 297 298 return 0; 299 } 300 301 static int 302 test_common(void) 303 { 304 int ret = 0; 305 ret |= test_align(); 306 ret |= test_macros(0); 307 ret |= test_misc(); 308 ret |= test_bsf(); 309 ret |= test_log2(); 310 ret |= test_fls(); 311 312 return ret; 313 } 314 315 REGISTER_TEST_COMMAND(common_autotest, test_common); 316