1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2017 Cavium, Inc 3 */ 4 5 #include "test.h" 6 7 #include <stdio.h> 8 #include <unistd.h> 9 #include <inttypes.h> 10 11 #include <rte_common.h> 12 #include <rte_cycles.h> 13 #include <rte_random.h> 14 #include <rte_reciprocal.h> 15 16 #define MAX_ITERATIONS (1ULL << 32) 17 #define DIVIDE_ITER (100) 18 19 static int 20 test_reciprocal(void) 21 { 22 int result = 0; 23 uint32_t divisor_u32 = 0; 24 uint32_t dividend_u32; 25 uint32_t nresult_u32; 26 uint32_t rresult_u32; 27 uint64_t i, j; 28 uint64_t divisor_u64 = 0; 29 uint64_t dividend_u64; 30 uint64_t nresult_u64; 31 uint64_t rresult_u64; 32 struct rte_reciprocal reci_u32 = {0}; 33 struct rte_reciprocal_u64 reci_u64 = {0}; 34 35 rte_srand(rte_rdtsc()); 36 printf("Validating unsigned 32bit division.\n"); 37 for (i = 0; i < MAX_ITERATIONS; i++) { 38 /* Change divisor every DIVIDE_ITER iterations. */ 39 if (i % DIVIDE_ITER == 0) { 40 divisor_u32 = rte_rand(); 41 reci_u32 = rte_reciprocal_value(divisor_u32); 42 } 43 44 dividend_u32 = rte_rand(); 45 nresult_u32 = dividend_u32 / divisor_u32; 46 rresult_u32 = rte_reciprocal_divide(dividend_u32, 47 reci_u32); 48 if (nresult_u32 != rresult_u32) { 49 printf("Division failed, %"PRIu32"/%"PRIu32" = " 50 "expected %"PRIu32" result %"PRIu32"\n", 51 dividend_u32, divisor_u32, 52 nresult_u32, rresult_u32); 53 result = 1; 54 break; 55 } 56 } 57 58 printf("Validating unsigned 64bit division.\n"); 59 for (i = 0; i < MAX_ITERATIONS; i++) { 60 /* Change divisor every DIVIDE_ITER iterations. */ 61 if (i % DIVIDE_ITER == 0) { 62 divisor_u64 = rte_rand(); 63 reci_u64 = rte_reciprocal_value_u64(divisor_u64); 64 } 65 66 dividend_u64 = rte_rand(); 67 nresult_u64 = dividend_u64 / divisor_u64; 68 rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 69 &reci_u64); 70 if (nresult_u64 != rresult_u64) { 71 printf("Division failed, %"PRIu64"/%"PRIu64" = " 72 "expected %"PRIu64" result %"PRIu64"\n", 73 dividend_u64, divisor_u64, 74 nresult_u64, rresult_u64); 75 result = 1; 76 break; 77 } 78 } 79 80 printf("Validating unsigned 64bit division with 32bit divisor.\n"); 81 for (i = 0; i < MAX_ITERATIONS; i++) { 82 /* Change divisor every DIVIDE_ITER iterations. */ 83 if (i % DIVIDE_ITER == 0) { 84 divisor_u64 = rte_rand() >> 32; 85 reci_u64 = rte_reciprocal_value_u64(divisor_u64); 86 } 87 88 dividend_u64 = rte_rand(); 89 90 nresult_u64 = dividend_u64 / divisor_u64; 91 rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 92 &reci_u64); 93 94 if (nresult_u64 != rresult_u64) { 95 printf("Division failed, %"PRIu64"/%"PRIu64" = " 96 "expected %"PRIu64" result %"PRIu64"\n", 97 dividend_u64, divisor_u64, 98 nresult_u64, rresult_u64); 99 result = 1; 100 break; 101 } 102 } 103 104 printf("Validating division by power of 2.\n"); 105 for (i = 0; i < 32; i++) { 106 divisor_u64 = 1ull << i; 107 reci_u64 = rte_reciprocal_value_u64(divisor_u64); 108 reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64); 109 110 for (j = 0; j < MAX_ITERATIONS >> 4; j++) { 111 dividend_u64 = rte_rand(); 112 113 nresult_u64 = dividend_u64 / divisor_u64; 114 rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 115 &reci_u64); 116 117 if (nresult_u64 != rresult_u64) { 118 printf( 119 "Division 64 failed, %"PRIu64"/%"PRIu64" = " 120 "expected %"PRIu64" result %"PRIu64"\n", 121 dividend_u64, divisor_u64, 122 nresult_u64, rresult_u64); 123 result = 1; 124 } 125 126 nresult_u32 = (dividend_u64 >> 32) / divisor_u64; 127 rresult_u32 = rte_reciprocal_divide( 128 (dividend_u64 >> 32), reci_u32); 129 130 if (nresult_u32 != rresult_u32) { 131 printf( 132 "Division 32 failed, %"PRIu64"/%"PRIu64" = " 133 "expected %"PRIu64" result %"PRIu64"\n", 134 dividend_u64 >> 32, divisor_u64, 135 nresult_u64, rresult_u64); 136 result = 1; 137 break; 138 } 139 } 140 } 141 142 for (; i < 64; i++) { 143 divisor_u64 = 1ull << i; 144 reci_u64 = rte_reciprocal_value_u64(divisor_u64); 145 146 for (j = 0; j < MAX_ITERATIONS >> 4; j++) { 147 dividend_u64 = rte_rand(); 148 149 nresult_u64 = dividend_u64 / divisor_u64; 150 rresult_u64 = rte_reciprocal_divide_u64(dividend_u64, 151 &reci_u64); 152 153 if (nresult_u64 != rresult_u64) { 154 printf("Division failed, %"PRIu64"/%"PRIu64" = " 155 "expected %"PRIu64" result %"PRIu64"\n", 156 dividend_u64, divisor_u64, 157 nresult_u64, rresult_u64); 158 result = 1; 159 break; 160 } 161 } 162 } 163 164 return result; 165 } 166 167 REGISTER_TEST_COMMAND(reciprocal_division, test_reciprocal); 168