New upstream version 18.02
[deb_dpdk.git] / test / test / test_reciprocal_division.c
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);