diff options
| author | azidar | 2015-08-19 17:14:15 -0700 |
|---|---|---|
| committer | azidar | 2015-08-19 17:14:15 -0700 |
| commit | be50b579346da77f4e94adc1c1d0f9a492be038e (patch) | |
| tree | 8ecbcbeac57520c6077311f7d0fa8936ef13dd73 /src | |
| parent | 8eec7cf373bdf02f23164cd7bbf0d02354cbc31f (diff) | |
Switched to new bigint library
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/stanza/bigint2.stanza | 93 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-ir.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-lexer.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/firrtl-test-main.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/flo.stanza | 4 | ||||
| -rw-r--r-- | src/main/stanza/ir-parser.stanza | 2 | ||||
| -rw-r--r-- | src/main/stanza/ir-utils.stanza | 3 | ||||
| -rw-r--r-- | src/main/stanza/passes.stanza | 6 |
8 files changed, 105 insertions, 9 deletions
diff --git a/src/main/stanza/bigint2.stanza b/src/main/stanza/bigint2.stanza new file mode 100644 index 00000000..9c603d0d --- /dev/null +++ b/src/main/stanza/bigint2.stanza @@ -0,0 +1,93 @@ +defpackage bigint2 : + import core + import verse + import firrtl/ir-utils + +;============ Big Int Library ============= + +;------------ Helper Functions ------------ +val word-size = 32 + +defn as-digit (c: Char) -> Int : + index-of("0123456789abcdef", c) as Int + +defn num-words (b:BigInt) : + val n = length(d(b)) + if num-bits(b) > n * word-size : + error("Number of bits greater than size of BigInt") + n + +defn to-hex (b:BigInt) -> String : + defn as-hex (i: Int) -> String : + val str = "0123456789abcdef" + substring(str,i,i + 1) + var str = "h" + val len = num-bits(b) + for i in 0 to len by 4 do : + val pos = len - 4 - i + val digit = (d(b)[pos / 32] >> (pos % 32)) & 15 + val hex = as-hex(digit) + if str == "h" and hex == "0" and (i + 4 < len) : false + else : str = string-join([str hex]) + string-join([ '\"' str '\"']) + +defn to-bin (b:BigInt) -> String : + string-join $ generate<Char> : + defn* loop (pos:Int) : + if (pos >= 0) : + yield(if (d(b)[pos / 32] >> (pos % 32))&1 == 1: '1' else: '0') + loop(pos - 1) + loop(num-bits(b) - 1) + +;------------ Library ---------------- +public defstruct BigInt : + d : Array<Int> + num-bits : Int + +public defmethod to-string (b:BigInt) : to-hex(b) + +public defmethod print (o:OutputStream, b:BigInt) : + print(o, to-string(b)) + +public defn BigIntEmpty (num-bits:Int) -> BigInt : + val num-words = (num-bits + word-size - 1) / word-size + val d = Array<Int>(num-words) + BigInt(d,num-bits) + +public defn BigIntLit (data:Int) -> BigInt : + BigIntLit(data,req-num-bits(data)) + +public defn BigIntLit (data:Int, num-bits:Int) -> BigInt : + val b = BigIntEmpty(num-bits) + d(b)[0] = data + b + +public defn BigIntLit (data:String) -> BigInt : + val base = data[0] + val shamt = if base == 'b': 1 else if base == 'h': 4 else: 2 + val digits = substring(data, 1) + val num-bits = length(digits) * shamt + BigIntLit(digits,shamt,num-bits) + +public defn BigIntLit (digits:String, shamt:Int, num-bits:Int) -> BigInt : + val lit = BigIntEmpty(num-bits) + ;; println-all(["BASE " base " SHAMT " shamt " DIGITS " digits]) + for i in 0 to num-words(lit) do : + d(lit)[i] = 0 + for i in 0 to length(digits) do : + val off = (length(digits) - 1 - i) * shamt + val wi = off / word-size + val bi = off % word-size + d(lit)[wi] = d(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 + +;------------------- Library API ----------------- + +public defn bits (b:BigInt, high:Int, low:Int) -> BigInt : b + +public defn bit (b:BigInt, index:Int) -> BigInt : b + + + diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza index bdc063d4..fbe22463 100644 --- a/src/main/stanza/firrtl-ir.stanza +++ b/src/main/stanza/firrtl-ir.stanza @@ -1,7 +1,7 @@ defpackage firrtl/ir2 : import core import verse - import bigint + import bigint2 public defmulti info! (x:?) -> FileInfo public defmethod info! (x:?) : FileInfo() diff --git a/src/main/stanza/firrtl-lexer.stanza b/src/main/stanza/firrtl-lexer.stanza index 7581b26c..9d50d8ab 100644 --- a/src/main/stanza/firrtl-lexer.stanza +++ b/src/main/stanza/firrtl-lexer.stanza @@ -2,7 +2,7 @@ defpackage firrtl/lexer : import core import core/stringeater import verse - import bigint + import bigint2 ;=============== PUBLIC INTERFACE =========================== public defn lex (text:String) -> List<Token> : diff --git a/src/main/stanza/firrtl-test-main.stanza b/src/main/stanza/firrtl-test-main.stanza index f22c49f1..77365d12 100644 --- a/src/main/stanza/firrtl-test-main.stanza +++ b/src/main/stanza/firrtl-test-main.stanza @@ -3,7 +3,7 @@ #include<"compiler/stz-algorithms.stanza"> #include<"compiler/stz-parser.stanza"> #include<"compiler/stz-lexer.stanza"> -#include("bigint.stanza") +#include("bigint2.stanza") #include("firrtl-lexer.stanza") #include("firrtl-ir.stanza") #include("ir-utils.stanza") diff --git a/src/main/stanza/flo.stanza b/src/main/stanza/flo.stanza index 7ef942f2..16360543 100644 --- a/src/main/stanza/flo.stanza +++ b/src/main/stanza/flo.stanza @@ -4,7 +4,7 @@ defpackage firrtl/flo : import firrtl/ir-utils import firrtl/ir2 import firrtl/passes - import bigint + import bigint2 ;============= Flo Backend ================ @@ -127,7 +127,7 @@ defn emit! (e:Expression,top:Symbol) : print(" ") emit!(arg, top) for const in consts(e) do : - print-all([" " const "'" sizeof(const)]) + print-all([" " const "'" req-num-bits(const)]) (e) : error("SHOULDN'T EMIT THIS") ;; print-all(["EMIT(" e ")"]) ;(e) : emit-all(["mov'" prim-width(type(e)) " " e], top) ;TODO, not sure which one is right diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza index 76e7f6ca..71236795 100644 --- a/src/main/stanza/ir-parser.stanza +++ b/src/main/stanza/ir-parser.stanza @@ -4,7 +4,7 @@ defpackage firrtl/parser : import firrtl/ir2 import stz/parser import firrtl/lexer - import bigint + import bigint2 ;======= Convenience Functions ======== defn first-info? (form) -> FileInfo|False : diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza index 3dd0585d..25006659 100644 --- a/src/main/stanza/ir-utils.stanza +++ b/src/main/stanza/ir-utils.stanza @@ -127,6 +127,9 @@ public defn to-int (x:Long) -> Int : if x > to-long(2147483647) or x < to-long(-2147483648) : error("Long too big to convert to Int") else : to-int(to-string(x)) +public defn req-num-bits (i: Int) -> Int : + max(1, ceil-log2(i + 1)) + ;============== PRINTERS =================================== defmethod print (o:OutputStream, d:Flip) : diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza index 89f77694..8bf35915 100644 --- a/src/main/stanza/passes.stanza +++ b/src/main/stanza/passes.stanza @@ -6,7 +6,7 @@ defpackage firrtl/passes : import firrtl/primops import firrtl-main import firrtl/errors - import bigint + import bigint2 ;============== Pass List ================ public val standard-passes = to-list $ [ @@ -1978,14 +1978,14 @@ defn gen-constraints (m:Module, h:HashTable<Symbol,Type>, v:Vector<WGeq>) -> Mod match(width(e)) : (w:UnknownWidth) : val w* = VarWidth(firrtl-gensym(`w,width-name-hash)) - add(v,WGeq(w*,IntWidth(length(to-bin(value(e)))))) + add(v,WGeq(w*,IntWidth(num-bits(value(e))))) UIntValue(value(e),w*) (w) : e (e:SIntValue) : match(width(e)) : (w:UnknownWidth) : val w* = VarWidth(firrtl-gensym(`w,width-name-hash)) - add(v,WGeq(w*,IntWidth(1 + length(to-bin(value(e)))))) + add(v,WGeq(w*,IntWidth(1 + num-bits(value(e))))) SIntValue(value(e),w*) (w) : e (e) : e |
