summaryrefslogtreecommitdiff
path: root/scripts/bitfuncgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/bitfuncgen.c')
-rw-r--r--scripts/bitfuncgen.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/scripts/bitfuncgen.c b/scripts/bitfuncgen.c
new file mode 100644
index 000000000000..8fae531b9286
--- /dev/null
+++ b/scripts/bitfuncgen.c
@@ -0,0 +1,240 @@
+/*
+ * *****************************************************************************
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2018-2021 Gavin D. Howard and contributors.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *****************************************************************************
+ *
+ * A generator for bitwise operations test.
+ *
+ */
+
+#include <assert.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+
+#define NTESTS (100)
+
+/**
+ * Abort with an error message.
+ * @param msg The error message.
+ */
+void err(const char *msg) {
+ fprintf(stderr, "%s\n", msg);
+ abort();
+}
+
+uint64_t rev(uint64_t a, size_t bits) {
+
+ size_t i;
+ uint64_t res = 0;
+
+ for (i = 0; i < bits; ++i) {
+ res <<= 1;
+ res |= a & 1;
+ a >>= 1;
+ }
+
+ return res;
+}
+
+uint64_t mod(uint64_t a, size_t bits) {
+
+ uint64_t mod;
+
+ if (bits < 64) mod = (uint64_t) ((1ULL << bits) - 1);
+ else mod = UINT64_MAX;
+
+ return a & mod;
+}
+
+uint64_t rol(uint64_t a, uint64_t p, size_t bits) {
+
+ uint64_t res;
+
+ assert(bits <= 64);
+
+ p %= bits;
+
+ if (!p) return a;
+
+ res = (a << p) | (a >> (bits - p));
+
+ return mod(res, bits);
+}
+
+uint64_t ror(uint64_t a, uint64_t p, size_t bits) {
+
+ uint64_t res;
+
+ assert(bits <= 64);
+
+ p %= bits;
+
+ if (!p) return a;
+
+ res = (a << (bits - p)) | (a >> p);
+
+ return mod(res, bits);
+}
+
+int main(void) {
+
+ uint64_t a = 0, b = 0, t;
+ size_t i;
+
+ // We attempt to open this or /dev/random to get random data.
+ int fd = open("/dev/urandom", O_RDONLY);
+
+ if (fd < 0) {
+
+ fd = open("/dev/random", O_RDONLY);
+
+ if (fd < 0) err("cannot open a random number generator");
+ }
+
+ // Generate NTESTS tests.
+ for (i = 0; i < NTESTS; ++i) {
+
+ ssize_t nread;
+
+ // Generate random data for the first operand.
+ nread = read(fd, (char*) &a, sizeof(uint64_t));
+ if (nread != sizeof(uint64_t)) err("I/O error");
+
+ // Generate random data for the second operand.
+ nread = read(fd, (char*) &b, sizeof(uint64_t));
+ if (nread != sizeof(uint64_t)) err("I/O error");
+
+ // Output the tests to stdout.
+ printf("band(%lu, %lu)\n", a, b);
+ printf("bor(%lu, %lu)\n", a, b);
+ printf("bxor(%lu, %lu)\n", a, b);
+ printf("bshl(%lu, %lu)\n", mod(a, 32), mod(b, 5));
+ printf("bshr(%lu, %lu)\n", mod(a, 32), mod(b, 5));
+ printf("bshl(%lu, %lu)\n", mod(b, 32), mod(a, 5));
+ printf("bshr(%lu, %lu)\n", mod(b, 32), mod(a, 5));
+ printf("bnot8(%lu)\nbnot8(%lu)\n", a, mod(a, 8));
+ printf("bnot16(%lu)\nbnot16(%lu)\n", a, mod(a, 16));
+ printf("bnot32(%lu)\nbnot32(%lu)\n", a, mod(a, 32));
+ printf("bnot64(%lu)\n", a);
+ printf("brev8(%lu)\nbrev8(%lu)\n", a, mod(a, 8));
+ printf("brev16(%lu)\nbrev16(%lu)\n", a, mod(a, 16));
+ printf("brev32(%lu)\nbrev32(%lu)\n", a, mod(a, 32));
+ printf("brev64(%lu)\n", a);
+ printf("brol8(%lu, %lu)\n", a, b);
+ printf("brol8(%lu, %lu)\n", mod(a, 8), b);
+ printf("brol8(%lu, %lu)\n", a, mod(b, 8));
+ printf("brol8(%lu, %lu)\n", mod(a, 8), mod(b, 8));
+ printf("brol16(%lu, %lu)\n", a, b);
+ printf("brol16(%lu, %lu)\n", mod(a, 16), b);
+ printf("brol16(%lu, %lu)\n", a, mod(b, 16));
+ printf("brol16(%lu, %lu)\n", mod(a, 16), mod(b, 16));
+ printf("brol32(%lu, %lu)\n", a, b);
+ printf("brol32(%lu, %lu)\n", mod(a, 32), b);
+ printf("brol32(%lu, %lu)\n", a, mod(b, 32));
+ printf("brol32(%lu, %lu)\n", mod(a, 32), mod(b, 32));
+ printf("brol64(%lu, %lu)\n", a, b);
+ printf("bror8(%lu, %lu)\n", a, b);
+ printf("bror8(%lu, %lu)\n", mod(a, 8), b);
+ printf("bror8(%lu, %lu)\n", a, mod(b, 8));
+ printf("bror8(%lu, %lu)\n", mod(a, 8), mod(b, 8));
+ printf("bror16(%lu, %lu)\n", a, b);
+ printf("bror16(%lu, %lu)\n", mod(a, 16), b);
+ printf("bror16(%lu, %lu)\n", a, mod(b, 16));
+ printf("bror16(%lu, %lu)\n", mod(a, 16), mod(b, 16));
+ printf("bror32(%lu, %lu)\n", a, b);
+ printf("bror32(%lu, %lu)\n", mod(a, 32), b);
+ printf("bror32(%lu, %lu)\n", a, mod(b, 32));
+ printf("bror32(%lu, %lu)\n", mod(a, 32), mod(b, 32));
+ printf("bror64(%lu, %lu)\n", a, b);
+ printf("bmod8(%lu)\nbmod8(%lu)\n", a, mod(a, 8));
+ printf("bmod16(%lu)\nbmod16(%lu)\n", a, mod(a, 16));
+ printf("bmod32(%lu)\nbmod32(%lu)\n", a, mod(a, 32));
+ printf("bmod64(%lu)\n", a);
+
+ // Output the results to stderr.
+ fprintf(stderr, "%lu\n", a & b);
+ fprintf(stderr, "%lu\n", a | b);
+ fprintf(stderr, "%lu\n", a ^ b);
+ fprintf(stderr, "%lu\n", mod(a, 32) << mod(b, 5));
+ fprintf(stderr, "%lu\n", mod(a, 32) >> mod(b, 5));
+ fprintf(stderr, "%lu\n", mod(b, 32) << mod(a, 5));
+ fprintf(stderr, "%lu\n", mod(b, 32) >> mod(a, 5));
+ t = mod(~a, 8);
+ fprintf(stderr, "%lu\n%lu\n", t, t);
+ t = mod(~a, 16);
+ fprintf(stderr, "%lu\n%lu\n", t, t);
+ t = mod(~a, 32);
+ fprintf(stderr, "%lu\n%lu\n", t, t);
+ fprintf(stderr, "%lu\n", ~a);
+ t = rev(a, 8);
+ fprintf(stderr, "%lu\n%lu\n", t, t);
+ t = rev(a, 16);
+ fprintf(stderr, "%lu\n%lu\n", t, t);
+ t = rev(a, 32);
+ fprintf(stderr, "%lu\n%lu\n", t, t);
+ t = rev(a, 64);
+ fprintf(stderr, "%lu\n", t);
+ fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", rol(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", rol(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", rol(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", rol(a, b, 64));
+ fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", ror(mod(a, 8), mod(b, 8), 8));
+ fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", ror(mod(a, 16), mod(b, 16), 16));
+ fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", ror(mod(a, 32), mod(b, 32), 32));
+ fprintf(stderr, "%lu\n", ror(a, b, 64));
+ fprintf(stderr, "%lu\n%lu\n", mod(a, 8), mod(a, 8));
+ fprintf(stderr, "%lu\n%lu\n", mod(a, 16), mod(a, 16));
+ fprintf(stderr, "%lu\n%lu\n", mod(a, 32), mod(a, 32));
+ fprintf(stderr, "%lu\n", a);
+ }
+
+ return 0;
+}