1 /*
2 * *****************************************************************************
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 *
6 * Copyright (c) 2018-2021 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 */
err(const char * msg)50 void err(const char *msg) {
51 fprintf(stderr, "%s\n", msg);
52 abort();
53 }
54
rev(uint64_t a,size_t bits)55 uint64_t rev(uint64_t a, size_t bits) {
56
57 size_t i;
58 uint64_t res = 0;
59
60 for (i = 0; i < bits; ++i) {
61 res <<= 1;
62 res |= a & 1;
63 a >>= 1;
64 }
65
66 return res;
67 }
68
mod(uint64_t a,size_t bits)69 uint64_t mod(uint64_t a, size_t bits) {
70
71 uint64_t mod;
72
73 if (bits < 64) mod = (uint64_t) ((1ULL << bits) - 1);
74 else mod = UINT64_MAX;
75
76 return a & mod;
77 }
78
rol(uint64_t a,uint64_t p,size_t bits)79 uint64_t rol(uint64_t a, uint64_t p, size_t bits) {
80
81 uint64_t res;
82
83 assert(bits <= 64);
84
85 p %= bits;
86
87 if (!p) return a;
88
89 res = (a << p) | (a >> (bits - p));
90
91 return mod(res, bits);
92 }
93
ror(uint64_t a,uint64_t p,size_t bits)94 uint64_t ror(uint64_t a, uint64_t p, size_t bits) {
95
96 uint64_t res;
97
98 assert(bits <= 64);
99
100 p %= bits;
101
102 if (!p) return a;
103
104 res = (a << (bits - p)) | (a >> p);
105
106 return mod(res, bits);
107 }
108
main(void)109 int main(void) {
110
111 uint64_t a = 0, b = 0, t;
112 size_t i;
113
114 // We attempt to open this or /dev/random to get random data.
115 int fd = open("/dev/urandom", O_RDONLY);
116
117 if (fd < 0) {
118
119 fd = open("/dev/random", O_RDONLY);
120
121 if (fd < 0) err("cannot open a random number generator");
122 }
123
124 // Generate NTESTS tests.
125 for (i = 0; i < NTESTS; ++i) {
126
127 ssize_t nread;
128
129 // Generate random data for the first operand.
130 nread = read(fd, (char*) &a, sizeof(uint64_t));
131 if (nread != sizeof(uint64_t)) err("I/O error");
132
133 // Generate random data for the second operand.
134 nread = read(fd, (char*) &b, sizeof(uint64_t));
135 if (nread != sizeof(uint64_t)) err("I/O error");
136
137 // Output the tests to stdout.
138 printf("band(%lu, %lu)\n", a, b);
139 printf("bor(%lu, %lu)\n", a, b);
140 printf("bxor(%lu, %lu)\n", a, b);
141 printf("bshl(%lu, %lu)\n", mod(a, 32), mod(b, 5));
142 printf("bshr(%lu, %lu)\n", mod(a, 32), mod(b, 5));
143 printf("bshl(%lu, %lu)\n", mod(b, 32), mod(a, 5));
144 printf("bshr(%lu, %lu)\n", mod(b, 32), mod(a, 5));
145 printf("bnot8(%lu)\nbnot8(%lu)\n", a, mod(a, 8));
146 printf("bnot16(%lu)\nbnot16(%lu)\n", a, mod(a, 16));
147 printf("bnot32(%lu)\nbnot32(%lu)\n", a, mod(a, 32));
148 printf("bnot64(%lu)\n", a);
149 printf("brev8(%lu)\nbrev8(%lu)\n", a, mod(a, 8));
150 printf("brev16(%lu)\nbrev16(%lu)\n", a, mod(a, 16));
151 printf("brev32(%lu)\nbrev32(%lu)\n", a, mod(a, 32));
152 printf("brev64(%lu)\n", a);
153 printf("brol8(%lu, %lu)\n", a, b);
154 printf("brol8(%lu, %lu)\n", mod(a, 8), b);
155 printf("brol8(%lu, %lu)\n", a, mod(b, 8));
156 printf("brol8(%lu, %lu)\n", mod(a, 8), mod(b, 8));
157 printf("brol16(%lu, %lu)\n", a, b);
158 printf("brol16(%lu, %lu)\n", mod(a, 16), b);
159 printf("brol16(%lu, %lu)\n", a, mod(b, 16));
160 printf("brol16(%lu, %lu)\n", mod(a, 16), mod(b, 16));
161 printf("brol32(%lu, %lu)\n", a, b);
162 printf("brol32(%lu, %lu)\n", mod(a, 32), b);
163 printf("brol32(%lu, %lu)\n", a, mod(b, 32));
164 printf("brol32(%lu, %lu)\n", mod(a, 32), mod(b, 32));
165 printf("brol64(%lu, %lu)\n", a, b);
166 printf("bror8(%lu, %lu)\n", a, b);
167 printf("bror8(%lu, %lu)\n", mod(a, 8), b);
168 printf("bror8(%lu, %lu)\n", a, mod(b, 8));
169 printf("bror8(%lu, %lu)\n", mod(a, 8), mod(b, 8));
170 printf("bror16(%lu, %lu)\n", a, b);
171 printf("bror16(%lu, %lu)\n", mod(a, 16), b);
172 printf("bror16(%lu, %lu)\n", a, mod(b, 16));
173 printf("bror16(%lu, %lu)\n", mod(a, 16), mod(b, 16));
174 printf("bror32(%lu, %lu)\n", a, b);
175 printf("bror32(%lu, %lu)\n", mod(a, 32), b);
176 printf("bror32(%lu, %lu)\n", a, mod(b, 32));
177 printf("bror32(%lu, %lu)\n", mod(a, 32), mod(b, 32));
178 printf("bror64(%lu, %lu)\n", a, b);
179 printf("bmod8(%lu)\nbmod8(%lu)\n", a, mod(a, 8));
180 printf("bmod16(%lu)\nbmod16(%lu)\n", a, mod(a, 16));
181 printf("bmod32(%lu)\nbmod32(%lu)\n", a, mod(a, 32));
182 printf("bmod64(%lu)\n", a);
183
184 // Output the results to stderr.
185 fprintf(stderr, "%lu\n", a & b);
186 fprintf(stderr, "%lu\n", a | b);
187 fprintf(stderr, "%lu\n", a ^ b);
188 fprintf(stderr, "%lu\n", mod(a, 32) << mod(b, 5));
189 fprintf(stderr, "%lu\n", mod(a, 32) >> mod(b, 5));
190 fprintf(stderr, "%lu\n", mod(b, 32) << mod(a, 5));
191 fprintf(stderr, "%lu\n", mod(b, 32) >> mod(a, 5));
192 t = mod(~a, 8);
193 fprintf(stderr, "%lu\n%lu\n", t, t);
194 t = mod(~a, 16);
195 fprintf(stderr, "%lu\n%lu\n", t, t);
196 t = mod(~a, 32);
197 fprintf(stderr, "%lu\n%lu\n", t, t);
198 fprintf(stderr, "%lu\n", ~a);
199 t = rev(a, 8);
200 fprintf(stderr, "%lu\n%lu\n", t, t);
201 t = rev(a, 16);
202 fprintf(stderr, "%lu\n%lu\n", t, t);
203 t = rev(a, 32);
204 fprintf(stderr, "%lu\n%lu\n", t, t);
205 t = rev(a, 64);
206 fprintf(stderr, "%lu\n", t);
207 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
208 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
209 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
210 fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
211 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
212 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
213 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
214 fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
215 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
216 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
217 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
218 fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
219 fprintf(stderr, "%lu\n", rol(a, b, 64));
220 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
221 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
222 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
223 fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
224 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
225 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
226 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
227 fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
228 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
229 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
230 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
231 fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
232 fprintf(stderr, "%lu\n", ror(a, b, 64));
233 fprintf(stderr, "%lu\n%lu\n", mod(a, 8), mod(a, 8));
234 fprintf(stderr, "%lu\n%lu\n", mod(a, 16), mod(a, 16));
235 fprintf(stderr, "%lu\n%lu\n", mod(a, 32), mod(a, 32));
236 fprintf(stderr, "%lu\n", a);
237 }
238
239 return 0;
240 }
241