diff options
| author | azidar | 2016-02-09 18:53:28 -0800 |
|---|---|---|
| committer | azidar | 2016-02-09 18:57:08 -0800 |
| commit | 4160ffa5c86ff7f4d5534dec3624b7127263b782 (patch) | |
| tree | d69dfe008857f7c9d66f8c7647a4f1eaeb02fe76 /src/main/stanza/bigint.stanza | |
| parent | bb5f68948c6d75d1f02c614f3e0ae4ef9bc6e689 (diff) | |
Added license to FIRRTL files
Diffstat (limited to 'src/main/stanza/bigint.stanza')
| -rw-r--r-- | src/main/stanza/bigint.stanza | 402 |
1 files changed, 0 insertions, 402 deletions
diff --git a/src/main/stanza/bigint.stanza b/src/main/stanza/bigint.stanza deleted file mode 100644 index bc13bdbf..00000000 --- a/src/main/stanza/bigint.stanza +++ /dev/null @@ -1,402 +0,0 @@ -defpackage bigint : - import core - import verse - -val val-n-bytes = 4 -val val-n-bits = val-n-bytes * 8 -val val-all-ones = -1 ;; TODO -val val-n-half-bits = 32 / 2 -defn val-n-words (nbits: Int) -> Int : 1 + (nbits - 1) / 32 -defn val-n-half-words (nbits: Int) -> Int : (1 + (nbits - 1)) / val-n-half-bits -defn val-top-bit (v: Int) -> Int : v >> (32 - 1) -defn val-n-full-words (nbits: Int) -> Int : nbits / 32 -defn val-n-word-bits (nbits: Int) -> Int : nbits % 32 -defn mask-val (n: Int) : -1 >> (32 - n) - -public defclass BigInt <: Gettable & Settable & Lengthable -public defmulti to-bin (b: BigInt) -> String -public defmulti to-hex (b: BigInt) -> String -public defmulti num-words (b: BigInt) -> Int -public defmulti dat (b: BigInt) -> Array<Int> -public defn BigInt (len: Int) : - val d = Array<Int>(val-n-words(len)) - new BigInt : - defmethod get (this, i: Int) -> Int : d[i] - defmethod set (this, i: Int, x: Int) : d[i] = x & -1 - defmethod dat (this) -> Array<Int> : d - defmethod length (this) -> Int : len - defmethod num-words (this) -> Int : length(d) - defmethod to-hex (this) -> String : - defn as-hex (i: Int) -> String : - val str = "0123456789abcdef" - substring(str,i,i + 1) - var str = "h" - ;println(to-bin(this)) - for i in 0 to len by 4 do : - val pos = len - 4 - i - ;println(pos) - val digit = (d[pos / 32] >> (pos % 32)) & 15 - ;println(digit) - val hex = as-hex(digit) - ;println(hex) - if str == "h" and hex == "0" and (i + 4 < len) : false - else : str = string-join([str hex]) - string-join([ "\"" str "\""]) - defmethod to-bin (this) -> String : - string-join $ - generate<Char> : - defn* loop (pos:Int) : - if (pos >= 0) : - yield(if (d[pos / 32] >> (pos % 32))&1 == 1: '1' else: '0') - loop(pos - 1) - loop(len - 1) - ;defmethod to-string (this) : string-join(["BigInt<" len ">(" to-bin(this) ")"]) - defmethod to-string (this) : to-hex(this) - -defmethod print (o:OutputStream, b:BigInt) : - print(o, to-string(b)) - -defn assert (cond:True|False, msg:String) : if not cond: error(msg) - -defn assert (cond:True|False) : assert(cond, "failure") - -;; loop macro with starting values - -;; defn map-range (s:Int, e:Int, f: (Int) -> False) : -;; for i in s to e do : f(i) - -defn map! (f: (Int, Int) -> Int, d: BigInt, s0: BigInt, s1: BigInt) -> BigInt : - ;; assert(length(d) == length(s0) and length(s0) == length(s1), - ;; string-join(["LENS != " num-words(d) " " num-words(s0) " " num-words(s1)])) - for i in 0 to num-words(d) do : - d[i] = f(s0[i], s1[i]) - d - -defn mask! (d: BigInt) -> BigInt : - val n-full-words = val-n-full-words(length(d)) - val n-word-bits = val-n-word-bits(length(d)) - for i in 0 to n-full-words do : - d[i] = -1 - for i in n-full-words to num-words(d) do : - d[i] = 0 - if n-word-bits > 0 : - d[n-full-words] = mask-val(n-word-bits) - d - -defn trim! (d:BigInt) -> BigInt : - val n-full-words = val-n-full-words(length(d)) - val n-word-bits = val-n-word-bits(length(d)) - if n-word-bits > 0 : - d[n-full-words] = d[n-full-words] & mask-val(n-word-bits) - d - -defn extract! (d:BigInt, s0:BigInt, e:Int, s:Int) -> BigInt : trim!(rsh!(d, s0, s)) - -public defn bits (s0:BigInt, e:Int, s:Int) -> BigInt : extract!(BigInt(e - s + 1), s0, e, s) - -public defn bit (s0:BigInt, s:Int) -> Int : - val wi = s / 32 - val bi = s % 32 - s0[wi] >> bi - -defn inject! (d:BigInt, s0:BigInt, f:BigInt, start:Int) -> BigInt : - val bw = length(f) - val msk = mask!(BigInt(bw)) - val msk-lsh = msk << start - val inv-msk-lsh = bit-invert!(msk-lsh, msk-lsh) - val f-lsh = f << start - (s0 & inv-msk-lsh) | f-lsh - -defn map! (f: (Int) -> Int, d: BigInt, s0: BigInt) -> BigInt : - ;; assert(length(d) == length(s0), string-join(["LENS != " num-words(d) " " num-words(s0)])) - for i in 0 to num-words(d) do : - d[i] = f(s0[i]) - d - -defn fill! (f: (Int) -> Int, b: BigInt) : - for i in 0 to num-words(b) do : - b[i] = f(i) - b - -public defmethod equal? (x:BigInt, y:BigInt) -> True|False : - val tf = - if num-words(x) != num-words(y) : - false - else : - var eq? = true - for i in 0 to num-words(x) do : - val e = (x[i] == y[i]) - ;if not e : ;println-all(["NOT-EQUAL " x " AND " y " i=" i " X[i] " x[i] " Y[i] " y[i]]) - eq? = eq? and e - eq? - ;println-all(["EQUAL? " x " AND " y " " tf]) - tf - -public defn less?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : - sub!(diff, x, y) - val-top-bit(diff[num-words(diff) - 1]) == 1 - -public defn less? (x:BigInt, y:BigInt) -> True|False : op(less?!, x, y) - -public defn less-eq?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : - sub!(diff, y, x) - val-top-bit(diff[num-words(diff) - 1]) == 0 - -public defn less-eq? (x:BigInt, y:BigInt) -> True|False : op(less-eq?!, x, y) - -public defn greater?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : not less-eq?!(diff, x, y) - -public defn greater? (x:BigInt, y:BigInt) -> True|False : op(greater?!, x, y) - -public defn greater-eq?! (diff:BigInt, x:BigInt, y:BigInt) -> True|False : not less?!(diff, x, y) - -public defn greater-eq? (x:BigInt, y:BigInt) -> True|False : op(greater-eq?!, x, y) - -defn as-digit (c: Char) -> Int : - index-of("0123456789abcdef", c) as Int - -public defn BigIntLit (f: (Int) -> Int, len: Int) : - fill!(f, BigInt(len)) - -public defn BigIntLit (x: Int, w: Int) : - fill!({_ + x}, BigInt(w)) - -public defn BigIntLit (x: Int) : BigIntLit(x, sizeof(x)) - -public defn BigIntLit (s: String) : BigIntLit(s, -1) - -public defn BigIntLit (s: String, w:Int) : - val base = s[0] - val shamt = if base == 'b': 1 else if base == 'h': 4 else: 2 - val digits = substring(s, 1) - val len = if w == -1: length(digits) * shamt else: w - val lit = BigInt(len) - ;; println-all(["BASE " base " SHAMT " shamt " DIGITS " digits]) - for i in 0 to num-words(lit) do : - lit[i] = 0 - for i in 0 to length(digits) do : - val off = (length(digits) - 1 - i) * shamt - val wi = off / 32 - val bi = off % 32 - lit[wi] = lit[wi] | (as-digit(digits[i]) << bi) - ;; println-all(["OFF " off " wi " wi " bi " bi " lit[wi] " lit[wi] " => " lit]) - ;; println-all(["RES = " lit]) - lit - -public defn sizeof (in: Int) -> Int : - max(1, ceil-log2(in + 1)) - -defn op (f:(BigInt, BigInt, BigInt) -> True|False, x:BigInt, y:BigInt) -> True|False : - f(BigInt(max(length(x), length(y))), x, y) - -defn op (f:(BigInt, BigInt, BigInt) -> BigInt, x:BigInt, y:BigInt) -> BigInt : - f(BigInt(max(length(x), length(y))), x, y) - -defn op (f:(BigInt, BigInt) -> BigInt, x:BigInt) -> BigInt : - f(BigInt(length(x)), x) - -defn int (x: True|False) -> Int : if x : 1 else : 0 - -public defn plus! (d: BigInt, s0: BigInt, s1: BigInt) -> BigInt : - var carry = false - for i in 0 to num-words(d) do : - d[i] = s0[i] + s1[i] + int(carry) - carry = ((s0[i] + s1[i]) < s0[i]) or (d[i] < int(carry)) - d - -public defn plus (x:BigInt, y:BigInt) -> BigInt : op(plus!, x, y) - -public defn cat! (d: BigInt, s0: BigInt, s1: BigInt) -> BigInt : - lsh!(d, s0, length(s1)) - ;; println-all([" LSH! " s0 " " length(s1) " => " d]) - for i in 0 to num-words(s1) do : - d[i] = d[i] | s1[i] - d - -public defn cat (x:BigInt, y:BigInt) -> BigInt : - ;; println-all(["> CAT " x " " y]) - val res = cat!(BigInt(length(x) + length(y)), x, y) - ;; println-all(["< CAT " x " " y " => " res]) - res - -public defn cat (args:Streamable<BigInt>) -> BigInt : - reduce(cat, args) - -public defn sub! (d: BigInt, s0: BigInt, s1: BigInt) -> BigInt : - var borrow = false - for i in 0 to num-words(d) do : - d[i] = s0[i] - s1[i] + int(borrow) - borrow = (s0[i] < (s0[i] - s1[i])) or (s0[i] - s1[i]) < d[i] - d - -public defn sub (x:BigInt, y:BigInt) -> BigInt : op(sub!, x, y) - -public defn neg! (d: BigInt, s0: BigInt) -> BigInt : - var borrow = false - for i in 0 to num-words(d) do : - d[i] = neg(s0[i]) - int(borrow) - borrow = (s0[i] > 0) or (d[i] > 0) - d - -public defn neg (x:BigInt) -> BigInt : op(neg!, x) - -public defn neg? (x:BigInt) -> True|False : - val nw = num-words(x) - val msb = x[nw - 1] >> (length(x) - nw * 32 - 1) - if msb == 0 : false - else : true - -public defn rsha! (d:BigInt, s0:BigInt, amount:Int) -> BigInt : - val w = length(s0) - val nw = num-words(d) - val n-shift-bits = amount % 32 - val n-shift-words = amount / 32 - val n-rev-shift-bits = 32 - n-shift-bits - val is-zero-carry = n-shift-bits == 0 - val msb = s0[nw - 1] >> (w - nw * 32 - 1) - var carry = 0; - - if msb == 0 : - for i in 0 to n-shift-words do : - d[nw - i - 1] = 0 - - defn* loopy (i:Int) : - if i >= n-shift-words : - val x = s0[i] - d[i - n-shift-words] = (x >> n-shift-bits) | carry - carry = if is-zero-carry: 0 else: x << n-rev-shift-bits - loopy(i - 1) - loopy(nw - 1) - - if msb != 0 : - val boundary = (w - amount) - - defn* loop (i:Int) : - if i >= 0 : - val idx = i * 32 - if idx > boundary : - d[i] = -1 - loop(i - 1) - else : - d[i] = d[i] | (-1 << (boundary - idx)) - d[nw - 1] = d[nw - 1] & (-1 >> ((nw - 1) * 32 - w)) - loop(nw - 1) - d - -public defn signed-shift-right (b:BigInt, n:Int) -> BigInt : rsha!(BigInt(length(b)), b, n) - -public defn rsh! (d:BigInt, s0:BigInt, amount:Int) -> BigInt : - val nw = num-words(d) - var carry = 0 - val n-shift-bits = amount % 32 - val n-shift-words = amount / 32 - val n-rev-shift-bits = 32 - n-shift-bits - val is-zero-carry = n-shift-bits == 0 - for i in 0 to n-shift-words do : - d[nw - i - 1] = 0 - defn* loop (i:Int) : - if i >= n-shift-words : - val x = s0[i] - d[i - n-shift-words] = (x >> n-shift-bits) | carry - carry = if is-zero-carry: 0 else: x << n-rev-shift-bits - loop(i - 1) - loop(nw - 1) - d - -public defn shift-right (b:BigInt, n:Int) -> BigInt : rsh!(BigInt(length(b)), b, n) - -public defn lsh! (d:BigInt, s0:BigInt, amount:Int) : - ;; println-all(["LSH " s0 " AMOUNT " amount " INTO BIGINT<" length(d) ">"]) - val n-shift-bits = amount % 32 - val n-shift-words = amount / 32 - val n-rev-shift-bits = 32 - n-shift-bits - val is-zero-carry = n-shift-bits == 0 - for i in 0 to num-words(d) do : - d[i] = 0 - var carry = 0; - ;; println-all(["LSH AMOUNT " amount " VNB " 32 " NSB " n-shift-bits " NSW " n-shift-words " NRSB " n-rev-shift-bits]) - for i in 0 to (num-words(d) - n-shift-words) do : - val x = if i >= num-words(s0) : 0 else: s0[i] - ;; println-all([" SHIFTING " (i + n-shift-words) " VAL " (x << n-shift-bits)]) - d[i + n-shift-words] = (x << n-shift-bits) | carry - carry = if is-zero-carry: 0 else: x >> n-rev-shift-bits - d - -public defn shift-left (b:BigInt, n:Int) -> BigInt : lsh!(BigInt(length(b) + n), b, n) - -;; defn mul! (d: BigInt, s0: BigInt, s1: BigInt, nb0: Int, nb1: Int) -> BigInt : -;; ;; Adapted from Hacker's Delight, from Knuth -;; var nbd = nb0 + nb1 -;; for i in 0 to val-n-words(nbd) do : -;; d[i] = 0 -;; -;; half-val-t* w = reinterpret-cast<half-val-t*>(d); -;; half-val-t* u = reinterpret-cast<half-val-t*>(s0); -;; half-val-t* v = reinterpret-cast<half-val-t*>(s1); -;; val m = val-n-half-words(nb0) -;; val n = val-n-half-words(nb1) -;; val p = val-n-half-words(nbd) -;; -;; for j in 0 to n do : -;; var k = 0 -;; for i in 0 to min(m, p - j) do : -;; val t = u[i] * v[j] + w[i + j] + k -;; w[i + j] = t -;; k = t >> val-n-half-bits() -;; if ((j + m) < p) -;; w[j + m] = k -;; d - -public defn bit-xor! (d: BigInt, s0: BigInt, s1: BigInt) : map!(bit-xor, d, s0, s1) - -public defn bit-xor (b0:BigInt, b1:BigInt) : op(bit-xor!, b0, b1) - -public defn bit-or! (d: BigInt, s0: BigInt, s1: BigInt) : map!(bit-or, d, s0, s1) - -public defn bit-or (b0:BigInt, b1:BigInt) : op(bit-or!, b0, b1) - -public defn bit-and! (d: BigInt, s0: BigInt, s1: BigInt) : map!(bit-and, d, s0, s1) - -public defn bit-and (b0:BigInt, b1:BigInt) : op(bit-and!, b0, b1) - -public defn bit-invert! (d: BigInt, s0: BigInt) : map!(bit-xor, d, s0, mask!(d)) - -public defn bit-invert (b0:BigInt) : op(bit-invert!, b0) - -defn check (msg:String, x:BigInt, e:BigInt) : - println-all([msg " " x " E " e " ? " x == e]) - -defn check (msg:String, x:BigInt) : - println-all([msg " " x]) - -;;; check("Ba ", BigIntLit({ _ }, 1)) -;;; check("Bb ", BigIntLit({ _ }, 16)) -;;; check("Bc ", BigIntLit({ _ }, 32)) -;;; check("Bd ", BigIntLit({ _ }, 48)) -;;; check("Be ", BigIntLit({ _ }, 64)) -;;; check("Bf ", BigIntLit({ _ }, 65)) -;;; check("B1 ", BigIntLit(1, 8)) -;;; check("B2 ", BigIntLit(2, 8)) -;;; check("B+ ", BigIntLit(3, 8) + BigIntLit(5, 8), BigIntLit(3 + 5, 8)) -;;; check("B- ", BigIntLit(5, 8) + BigIntLit(3, 8), BigIntLit(5 + 3, 8)) -;;; check("B| ", BigIntLit(5, 8) | BigIntLit(9, 8), BigIntLit(5 | 9, 8)) -;;; check("B& ", BigIntLit(5, 8) & BigIntLit(9, 8), BigIntLit(5 & 9, 8)) -;;; check("B^ ", BigIntLit(5, 8) ^ BigIntLit(9, 8), BigIntLit(5 ^ 9, 8)) -;;; check("B< ", BigIntLit(5, 8) << 1, BigIntLit(5 << 1, 9)) -;;; check("B< ", BigIntLit(5, 3) << 10, BigIntLit(5 << 1, 13)) -;;; check("B< ", BigIntLit(5, 3) << 32, BigIntLit(5 << 1, 38)) -;;; check("B< ", BigIntLit("b1010") << 1, BigIntLit(10 << 1, 5)) -;check("S1 ", BigIntLit("hfafa") << 16, BigIntLit("hfafa0000", 32)) -;check("S1 ", BigIntLit(1,32) , BigIntLit(1,32)) -;check("S1 ", BigIntLit(0,32) , BigIntLit(0,32)) -;;; check("B< ", BigIntLit(5, 3) << 64, BigIntLit(5 << 1, 67)) -;;; check("BN ", neg(BigIntLit(2, 8)), BigIntLit(-2, 8)) -;check("S2 ", BigIntLit("b11111010") << 8, BigIntLit("b1111101000000000", 16)) -;check("C1 ", cat(BigIntLit("b11111010", 8), BigIntLit("b10111100", 8)), BigIntLit("b1111101010111100", 16)) -;check("C3 ", cat(cat(BigIntLit("b1111"), BigIntLit("b1010")), cat(BigIntLit("b1011"), BigIntLit("b1100"))), BigIntLit("b1111101010111100", 16)) -;check("C4 ", cat([BigIntLit("b1111"), BigIntLit("b1010"), BigIntLit("b1011"), BigIntLit("b1100")]), BigIntLit("b1111101010111100", 16)) -;check("C5 ", BigIntLit("b101111001"), BigIntLit("b101111001")) -;check("C6 ", cat(BigIntLit("b1"), BigIntLit("b01111001")), BigIntLit("b101111001")) -;check("C7 ", cat(BigIntLit("b11101"), BigIntLit("b101111001")), BigIntLit("b11101101111001")) -;check("C8 ", cat([BigIntLit("b11"), BigIntLit("b101"), BigIntLit("b1011"), BigIntLit("b11001")]), BigIntLit("b11101101111001")) -;check("C0 ", bits(BigIntLit("b11101101111001"), 10, 1), BigIntLit("b0110111100")) |
