| 1 | #! /usr/bin/python |
| 2 | ### -*-python-*- |
| 3 | ### |
| 4 | ### Generate input script and expected output for bit manipulation, |
| 5 | ### particularly 64-bit arithmetic. |
| 6 | |
| 7 | import sys as SYS |
| 8 | import random as R |
| 9 | |
| 10 | if SYS.version_info >= (3,): xrange = range |
| 11 | |
| 12 | NVEC = 64 |
| 13 | WD = 64 |
| 14 | LIMIT = 1 << WD |
| 15 | MASK = LIMIT - 1 |
| 16 | FMT = "%%0%dx" % (WD/4) |
| 17 | |
| 18 | def rol(x, n): return ((x << n) | (x >> (WD - n))) & MASK |
| 19 | def ror(x, n): return ((x >> n) | (x << (WD - n))) & MASK |
| 20 | |
| 21 | class BaseVector (object): |
| 22 | def __init__(me): |
| 23 | me._all = [] |
| 24 | def newseed(me, seed): |
| 25 | me._curr = [] |
| 26 | me._all.append((seed, me._curr)) |
| 27 | def _append(me, *args): |
| 28 | if len(args) != len(me._REGS): |
| 29 | raise TypeError("expected %d arguments" % len(me._REGS)) |
| 30 | me._curr.append(args) |
| 31 | def write(me): |
| 32 | print("") |
| 33 | print("[%s]" % me._NAME) |
| 34 | for seed, vv in me._all: |
| 35 | print("") |
| 36 | print(";;; seed = 0x%08x" % seed) |
| 37 | for v in vv: |
| 38 | print("") |
| 39 | for r, x in zip(me._REGS, v): print("%s = %s" % (r, me._RFMT[r] % x)) |
| 40 | |
| 41 | class ShiftVector (BaseVector): |
| 42 | _REGS = ["x", "n", "z"] |
| 43 | _RFMT = { "x": FMT, "n": "%d", "z": FMT } |
| 44 | def add(me, r): |
| 45 | for i in xrange(NVEC): |
| 46 | x = r.randrange(LIMIT) |
| 47 | n = r.randrange(70)%WD |
| 48 | z = me._op(x, n) |
| 49 | me._append(x, n, z) |
| 50 | for i in xrange(4): |
| 51 | x = r.randrange(LIMIT) |
| 52 | z = me._op(x, WD/2) |
| 53 | me._append(x, WD/2, z) |
| 54 | class LSLVector (ShiftVector): |
| 55 | _NAME = "lsl64" |
| 56 | def _op(me, x, n): return (x << n)&MASK |
| 57 | class LSRVector (ShiftVector): |
| 58 | _NAME = "lsr64" |
| 59 | def _op(me, x, n): return (x >> n)&MASK |
| 60 | class ROLVector (ShiftVector): |
| 61 | _NAME = "rol64" |
| 62 | def _op(me, x, n): return rol(x, n) |
| 63 | class RORVector (ShiftVector): |
| 64 | _NAME = "ror64" |
| 65 | def _op(me, x, n): return ror(x, n) |
| 66 | |
| 67 | class ArithVector (BaseVector): |
| 68 | _REGS = ["x", "y", "z"] |
| 69 | _RFMT = { "x": FMT, "y": FMT, "z": FMT } |
| 70 | def add(me, r): |
| 71 | for i in xrange(NVEC): |
| 72 | x = r.randrange(LIMIT) |
| 73 | y = r.randrange(LIMIT) |
| 74 | z = me._op(x, y) |
| 75 | me._append(x, y, z) |
| 76 | class AddVector (ArithVector): |
| 77 | _NAME = "add64" |
| 78 | def _op(me, x, y): return (x + y)&MASK |
| 79 | class SubVector (ArithVector): |
| 80 | _NAME = "sub64" |
| 81 | def _op(me, x, y): return (x - y)&MASK |
| 82 | |
| 83 | VECS = [LSLVector(), LSRVector(), ROLVector(), RORVector(), |
| 84 | AddVector(), SubVector()] |
| 85 | |
| 86 | for arg in SYS.argv[1:]: |
| 87 | if arg == "-": seed = R.SystemRandom().randrange(1 << 32) |
| 88 | else: seed = int(arg, 0) |
| 89 | r = R.Random(seed) |
| 90 | for v in VECS: v.newseed(seed); v.add(r) |
| 91 | |
| 92 | print(";;; -*-conf-*- Test vectors for 64-bit arithmetic macros") |
| 93 | print(";;; [generated]") |
| 94 | |
| 95 | for v in VECS: v.write() |