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