X-Git-Url: https://git.distorted.org.uk/u/mdw/catacomb/blobdiff_plain/ba6e6b64033b1f9de49feccb5c9cd438354481f7..0f00dc4c8eb47e67bc0f148c2dd109f73a451e0a:/math/t/mpx-gen diff --git a/math/t/mpx-gen b/math/t/mpx-gen new file mode 100755 index 0000000..891e4d6 --- /dev/null +++ b/math/t/mpx-gen @@ -0,0 +1,118 @@ +#! /usr/bin/awk -f +# +# Generate test vectors for MPX testing + +# --- Generate an `l'-byte hex number --- + +function r(l, i, s, x) +{ + if (!l) l = len; + s = ""; + for (i = 0; i < l; i++) { + x = int(rand() * 256); + s = s sprintf("%02X", x); + } + return (s); +} + +# --- Main code --- + +BEGIN { + + # --- Initialization --- + + i = 1; + if (i in ARGV) len = ARGV[i++]; else len = 32; + if (i in ARGV) op = ARGV[i++]; else op = "+"; + if (i in ARGV) rep = ARGV[i++]; else rep = 1; + + # --- Output filters --- + # + # This is complicated. `bc' emits numbers split over multiple lines with + # backslashes. It also doesn't pad to an even number of digits, which the + # test rig is expecting, or use lower-case, which looks nicer. + # + # The first bit matches a line ending with a backslash. If it finds one, + # it appends the next line, removes the backslash/newline pair, and loops + # around to the top. + # + # The next substitution translates the whole kaboodle into lower-case. + # + # The next one looks for an off number of hex digits and prepends a zero if + # it finds one. + # + # The one after that just indents by two spaces. The final one sticks a + # semicolon on the end. + + bc = "bc | sed '\ +:top\n\ +/\\\\$/ {\n\ + N\n\ + s/\\\\\\\n\ +//;\n\ + b top;\n\ +}\n\ +y/ABCDEF/abcdef/\n\ +s/^[0-9a-f]\\([0-9a-f][0-9a-f]\\)*$/0&/\n\ +s/^/ /\n\ +$ s/$/;/'"; + out = "sed 'y/ABCDEF/abcdef/; s/^/ /'" + + # --- Main code --- + + srand(); + + while (rep--) { + x = r(); + + print "obase = 16" | bc; + print "ibase = 16" | bc; + + # --- Shifting operations --- + + if (op == "<<" || op == ">>") { + y = int(rand() * len * 4) + int(rand() * len * 4); + rop = (op == "<<" ? "*" : "/"); + z = sprintf("%X", y); + print x, y | out; + print x, rop, "(2 ^ " z ")" | bc; + } + + # --- Division --- + + else if (op == "/") { + ylen = int(rand() * len) + 1; + y = r(ylen); + print x | out; + print y | out; + print x, "/", y | bc; + print x, "%", y | bc; + } + + # --- Squaring --- + + else if (op == "2") { + print x | out; + print x, "*", x | bc; + } + + # --- Other operations --- + + else { + y = r(); + if (op == "-" && x < y) { + t = x; x = y; y = t; + } + print x | out; + print y | out; + print x, op, y | bc; + } + + close(out); + close(bc); + if (rep) + print; + } + + exit 0; +}