xref: /dpdk/app/test/test_reciprocal_division.c (revision 2a454f84f715608ee709a4c6ba00edf2e4b62b69)
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
test_reciprocal(void)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 	printf("Validating unsigned 32bit division.\n");
36 	for (i = 0; i < MAX_ITERATIONS; i++) {
37 		/* Change divisor every DIVIDE_ITER iterations. */
38 		if (i % DIVIDE_ITER == 0) {
39 			divisor_u32 = rte_rand();
40 			reci_u32 = rte_reciprocal_value(divisor_u32);
41 		}
42 
43 		dividend_u32 = rte_rand();
44 		nresult_u32 = dividend_u32 / divisor_u32;
45 		rresult_u32 = rte_reciprocal_divide(dividend_u32,
46 				reci_u32);
47 		if (nresult_u32 != rresult_u32) {
48 			printf("Division failed, %"PRIu32"/%"PRIu32" = "
49 					"expected %"PRIu32" result %"PRIu32"\n",
50 					dividend_u32, divisor_u32,
51 					nresult_u32, rresult_u32);
52 			result = 1;
53 			break;
54 		}
55 	}
56 
57 	printf("Validating unsigned 64bit division.\n");
58 	for (i = 0; i < MAX_ITERATIONS; i++) {
59 		/* Change divisor every DIVIDE_ITER iterations. */
60 		if (i % DIVIDE_ITER == 0) {
61 			divisor_u64 = rte_rand();
62 			reci_u64 = rte_reciprocal_value_u64(divisor_u64);
63 		}
64 
65 		dividend_u64 = rte_rand();
66 		nresult_u64 = dividend_u64 / divisor_u64;
67 		rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
68 				&reci_u64);
69 		if (nresult_u64 != rresult_u64) {
70 			printf("Division failed,  %"PRIu64"/%"PRIu64" = "
71 					"expected %"PRIu64" result %"PRIu64"\n",
72 					dividend_u64, divisor_u64,
73 					nresult_u64, rresult_u64);
74 			result = 1;
75 			break;
76 		}
77 	}
78 
79 	printf("Validating unsigned 64bit division with 32bit divisor.\n");
80 	for (i = 0; i < MAX_ITERATIONS; i++) {
81 		/* Change divisor every DIVIDE_ITER iterations. */
82 		if (i % DIVIDE_ITER == 0) {
83 			divisor_u64 = rte_rand() >> 32;
84 			reci_u64 = rte_reciprocal_value_u64(divisor_u64);
85 		}
86 
87 		dividend_u64 = rte_rand();
88 
89 		nresult_u64 = dividend_u64 / divisor_u64;
90 		rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
91 				&reci_u64);
92 
93 		if (nresult_u64 != rresult_u64) {
94 			printf("Division failed, %"PRIu64"/%"PRIu64" = "
95 					"expected %"PRIu64" result %"PRIu64"\n",
96 					dividend_u64, divisor_u64,
97 					nresult_u64, rresult_u64);
98 			result = 1;
99 			break;
100 		}
101 	}
102 
103 	printf("Validating division by power of 2.\n");
104 	for (i = 0; i < 32; i++) {
105 		divisor_u64 = 1ull << i;
106 		reci_u64 = rte_reciprocal_value_u64(divisor_u64);
107 		reci_u32 = rte_reciprocal_value((uint32_t)divisor_u64);
108 
109 		for (j = 0; j < MAX_ITERATIONS >> 4; j++) {
110 			dividend_u64 = rte_rand();
111 
112 			nresult_u64 = dividend_u64 / divisor_u64;
113 			rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
114 					&reci_u64);
115 
116 			if (nresult_u64 != rresult_u64) {
117 				printf(
118 				"Division 64 failed, %"PRIu64"/%"PRIu64" = "
119 					"expected %"PRIu64" result %"PRIu64"\n",
120 						dividend_u64, divisor_u64,
121 						nresult_u64, rresult_u64);
122 				result = 1;
123 			}
124 
125 			nresult_u32 = (dividend_u64 >> 32) / divisor_u64;
126 			rresult_u32 = rte_reciprocal_divide(
127 					(dividend_u64 >> 32), reci_u32);
128 
129 			if (nresult_u32 != rresult_u32) {
130 				printf(
131 				"Division 32 failed, %"PRIu64"/%"PRIu64" = "
132 					"expected %"PRIu64" result %"PRIu64"\n",
133 						dividend_u64 >> 32, divisor_u64,
134 						nresult_u64, rresult_u64);
135 				result = 1;
136 				break;
137 			}
138 		}
139 	}
140 
141 	for (; i < 64; i++) {
142 		divisor_u64 = 1ull << i;
143 		reci_u64 = rte_reciprocal_value_u64(divisor_u64);
144 
145 		for (j = 0; j < MAX_ITERATIONS >> 4; j++) {
146 			dividend_u64 = rte_rand();
147 
148 			nresult_u64 = dividend_u64 / divisor_u64;
149 			rresult_u64 = rte_reciprocal_divide_u64(dividend_u64,
150 					&reci_u64);
151 
152 			if (nresult_u64 != rresult_u64) {
153 				printf("Division failed, %"PRIu64"/%"PRIu64" = "
154 					"expected %"PRIu64" result %"PRIu64"\n",
155 						dividend_u64, divisor_u64,
156 						nresult_u64, rresult_u64);
157 				result = 1;
158 				break;
159 			}
160 		}
161 	}
162 
163 	return result;
164 }
165 
166 REGISTER_PERF_TEST(reciprocal_division, test_reciprocal);
167