1 /*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2023 Gavin D. Howard and contributors.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * * Redistributions of source code must retain the above copyright notice, this
12 * list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright notice,
15 * this list of conditions and the following disclaimer in the documentation
16 * and/or other materials provided with the distribution.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 * *****************************************************************************
31 *
32 * A generator for bitwise operations test.
33 *
34 */
35
36 #include <assert.h>
37 #include <stdint.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <unistd.h>
41 #include <fcntl.h>
42 #include <limits.h>
43
44 #define NTESTS (100)
45
46 /**
47 * Abort with an error message.
48 * @param msg The error message.
49 */
50 void
err(const char * msg)51 err(const char* msg)
52 {
53 fprintf(stderr, "%s\n", msg);
54 abort();
55 }
56
57 uint64_t
rev(uint64_t a,size_t bits)58 rev(uint64_t a, size_t bits)
59 {
60 size_t i;
61 uint64_t res = 0;
62
63 for (i = 0; i < bits; ++i)
64 {
65 res <<= 1;
66 res |= a & 1;
67 a >>= 1;
68 }
69
70 return res;
71 }
72
73 uint64_t
mod(uint64_t a,size_t bits)74 mod(uint64_t a, size_t bits)
75 {
76 uint64_t mod;
77
78 if (bits < 64) mod = (uint64_t) ((1ULL << bits) - 1);
79 else mod = UINT64_MAX;
80
81 return a & mod;
82 }
83
84 uint64_t
rol(uint64_t a,uint64_t p,size_t bits)85 rol(uint64_t a, uint64_t p, size_t bits)
86 {
87 uint64_t res;
88
89 assert(bits <= 64);
90
91 p %= bits;
92
93 if (!p) return a;
94
95 res = (a << p) | (a >> (bits - p));
96
97 return mod(res, bits);
98 }
99
100 uint64_t
ror(uint64_t a,uint64_t p,size_t bits)101 ror(uint64_t a, uint64_t p, size_t bits)
102 {
103 uint64_t res;
104
105 assert(bits <= 64);
106
107 p %= bits;
108
109 if (!p) return a;
110
111 res = (a << (bits - p)) | (a >> p);
112
113 return mod(res, bits);
114 }
115
116 int
main(void)117 main(void)
118 {
119 uint64_t a = 0, b = 0, t;
120 size_t i;
121
122 // We attempt to open this or /dev/random to get random data.
123 int fd = open("/dev/urandom", O_RDONLY);
124
125 if (fd < 0)
126 {
127 fd = open("/dev/random", O_RDONLY);
128
129 if (fd < 0) err("cannot open a random number generator");
130 }
131
132 // Generate NTESTS tests.
133 for (i = 0; i < NTESTS; ++i)
134 {
135 ssize_t nread;
136
137 // Generate random data for the first operand.
138 nread = read(fd, (char*) &a, sizeof(uint64_t));
139 if (nread != sizeof(uint64_t)) err("I/O error");
140
141 // Generate random data for the second operand.
142 nread = read(fd, (char*) &b, sizeof(uint64_t));
143 if (nread != sizeof(uint64_t)) err("I/O error");
144
145 // Output the tests to stdout.
146 printf("band(%lu, %lu)\n", a, b);
147 printf("bor(%lu, %lu)\n", a, b);
148 printf("bxor(%lu, %lu)\n", a, b);
149 printf("bshl(%lu, %lu)\n", mod(a, 32), mod(b, 5));
150 printf("bshr(%lu, %lu)\n", mod(a, 32), mod(b, 5));
151 printf("bshl(%lu, %lu)\n", mod(b, 32), mod(a, 5));
152 printf("bshr(%lu, %lu)\n", mod(b, 32), mod(a, 5));
153 printf("bnot8(%lu)\nbnot8(%lu)\n", a, mod(a, 8));
154 printf("bnot16(%lu)\nbnot16(%lu)\n", a, mod(a, 16));
155 printf("bnot32(%lu)\nbnot32(%lu)\n", a, mod(a, 32));
156 printf("bnot64(%lu)\n", a);
157 printf("brev8(%lu)\nbrev8(%lu)\n", a, mod(a, 8));
158 printf("brev16(%lu)\nbrev16(%lu)\n", a, mod(a, 16));
159 printf("brev32(%lu)\nbrev32(%lu)\n", a, mod(a, 32));
160 printf("brev64(%lu)\n", a);
161 printf("brol8(%lu, %lu)\n", a, b);
162 printf("brol8(%lu, %lu)\n", mod(a, 8), b);
163 printf("brol8(%lu, %lu)\n", a, mod(b, 8));
164 printf("brol8(%lu, %lu)\n", mod(a, 8), mod(b, 8));
165 printf("brol16(%lu, %lu)\n", a, b);
166 printf("brol16(%lu, %lu)\n", mod(a, 16), b);
167 printf("brol16(%lu, %lu)\n", a, mod(b, 16));
168 printf("brol16(%lu, %lu)\n", mod(a, 16), mod(b, 16));
169 printf("brol32(%lu, %lu)\n", a, b);
170 printf("brol32(%lu, %lu)\n", mod(a, 32), b);
171 printf("brol32(%lu, %lu)\n", a, mod(b, 32));
172 printf("brol32(%lu, %lu)\n", mod(a, 32), mod(b, 32));
173 printf("brol64(%lu, %lu)\n", a, b);
174 printf("bror8(%lu, %lu)\n", a, b);
175 printf("bror8(%lu, %lu)\n", mod(a, 8), b);
176 printf("bror8(%lu, %lu)\n", a, mod(b, 8));
177 printf("bror8(%lu, %lu)\n", mod(a, 8), mod(b, 8));
178 printf("bror16(%lu, %lu)\n", a, b);
179 printf("bror16(%lu, %lu)\n", mod(a, 16), b);
180 printf("bror16(%lu, %lu)\n", a, mod(b, 16));
181 printf("bror16(%lu, %lu)\n", mod(a, 16), mod(b, 16));
182 printf("bror32(%lu, %lu)\n", a, b);
183 printf("bror32(%lu, %lu)\n", mod(a, 32), b);
184 printf("bror32(%lu, %lu)\n", a, mod(b, 32));
185 printf("bror32(%lu, %lu)\n", mod(a, 32), mod(b, 32));
186 printf("bror64(%lu, %lu)\n", a, b);
187 printf("bmod8(%lu)\nbmod8(%lu)\n", a, mod(a, 8));
188 printf("bmod16(%lu)\nbmod16(%lu)\n", a, mod(a, 16));
189 printf("bmod32(%lu)\nbmod32(%lu)\n", a, mod(a, 32));
190 printf("bmod64(%lu)\n", a);
191
192 // Output the results to stderr.
193 fprintf(stderr, "%lu\n", a & b);
194 fprintf(stderr, "%lu\n", a | b);
195 fprintf(stderr, "%lu\n", a ^ b);
196 fprintf(stderr, "%lu\n", mod(a, 32) << mod(b, 5));
197 fprintf(stderr, "%lu\n", mod(a, 32) >> mod(b, 5));
198 fprintf(stderr, "%lu\n", mod(b, 32) << mod(a, 5));
199 fprintf(stderr, "%lu\n", mod(b, 32) >> mod(a, 5));
200 t = mod(~a, 8);
201 fprintf(stderr, "%lu\n%lu\n", t, t);
202 t = mod(~a, 16);
203 fprintf(stderr, "%lu\n%lu\n", t, t);
204 t = mod(~a, 32);
205 fprintf(stderr, "%lu\n%lu\n", t, t);
206 fprintf(stderr, "%lu\n", ~a);
207 t = rev(a, 8);
208 fprintf(stderr, "%lu\n%lu\n", t, t);
209 t = rev(a, 16);
210 fprintf(stderr, "%lu\n%lu\n", t, t);
211 t = rev(a, 32);
212 fprintf(stderr, "%lu\n%lu\n", t, t);
213 t = rev(a, 64);
214 fprintf(stderr, "%lu\n", t);
215 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
216 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
217 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
218 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
219 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
220 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
221 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
222 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
223 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
224 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
225 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
226 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
227 fprintf(stderr, "%lu\n", rol(a, b, 64));
228 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
229 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
230 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
231 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
232 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
233 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
234 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
235 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
236 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
237 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
238 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
239 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
240 fprintf(stderr, "%lu\n", ror(a, b, 64));
241 fprintf(stderr, "%lu\n%lu\n", mod(a, 8), mod(a, 8));
242 fprintf(stderr, "%lu\n%lu\n", mod(a, 16), mod(a, 16));
243 fprintf(stderr, "%lu\n%lu\n", mod(a, 32), mod(a, 32));
244 fprintf(stderr, "%lu\n", a);
245 }
246
247 return 0;
248 }
249