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