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