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