• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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