aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorazidar2015-04-29 11:42:37 -0700
committerazidar2015-04-29 11:42:37 -0700
commitddc0dfe7a5f942ad1066b86b4f3ba9494493c6ed (patch)
treec440e3569707a0451da1330a2fd036718c36a9d7 /src
parentc46608d92bd493fa33c3c5122341c716ca75ecb0 (diff)
Added dshl and dshr
Diffstat (limited to 'src')
-rw-r--r--src/main/stanza/firrtl-ir.stanza6
-rw-r--r--src/main/stanza/ir-parser.stanza6
-rw-r--r--src/main/stanza/ir-utils.stanza16
-rw-r--r--src/main/stanza/passes.stanza9
-rw-r--r--src/main/stanza/primop.stanza40
5 files changed, 58 insertions, 19 deletions
diff --git a/src/main/stanza/firrtl-ir.stanza b/src/main/stanza/firrtl-ir.stanza
index 0e5400b2..63a28211 100644
--- a/src/main/stanza/firrtl-ir.stanza
+++ b/src/main/stanza/firrtl-ir.stanza
@@ -99,6 +99,12 @@ public val AS-UINT-S-OP = new PrimOp
public val AS-SINT-OP = new PrimOp
public val AS-SINT-U-OP = new PrimOp
public val AS-SINT-S-OP = new PrimOp
+public val DYN-SHIFT-LEFT-OP = new PrimOp
+public val DYN-SHIFT-LEFT-U-OP = new PrimOp
+public val DYN-SHIFT-LEFT-S-OP = new PrimOp
+public val DYN-SHIFT-RIGHT-OP = new PrimOp
+public val DYN-SHIFT-RIGHT-U-OP = new PrimOp
+public val DYN-SHIFT-RIGHT-S-OP = new PrimOp
public val SHIFT-LEFT-OP = new PrimOp
public val SHIFT-LEFT-U-OP = new PrimOp
public val SHIFT-LEFT-S-OP = new PrimOp
diff --git a/src/main/stanza/ir-parser.stanza b/src/main/stanza/ir-parser.stanza
index 6e6ba1a2..0e339cf3 100644
--- a/src/main/stanza/ir-parser.stanza
+++ b/src/main/stanza/ir-parser.stanza
@@ -117,6 +117,12 @@ OPERATORS[`as-UInt-s] = AS-UINT-S-OP
OPERATORS[`as-SInt] = AS-SINT-OP
OPERATORS[`as-SInt-u] = AS-SINT-U-OP
OPERATORS[`as-SInt-s] = AS-SINT-S-OP
+OPERATORS[`dshl] = DYN-SHIFT-LEFT-OP
+OPERATORS[`dshl-u] = DYN-SHIFT-LEFT-U-OP
+OPERATORS[`dshl-s] = DYN-SHIFT-LEFT-S-OP
+OPERATORS[`dshr] = DYN-SHIFT-RIGHT-OP
+OPERATORS[`dshr-u] = DYN-SHIFT-RIGHT-U-OP
+OPERATORS[`dshr-s] = DYN-SHIFT-RIGHT-S-OP
OPERATORS[`shl] = SHIFT-LEFT-OP
OPERATORS[`shl-u] = SHIFT-LEFT-U-OP
OPERATORS[`shl-s] = SHIFT-LEFT-S-OP
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index 1131c1b3..6754a8bd 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -113,6 +113,12 @@ defmethod print (o:OutputStream, op:PrimOp) :
AS-SINT-OP : "as-SInt"
AS-SINT-U-OP : "as-SInt-u"
AS-SINT-S-OP : "as-SInt-s"
+ DYN-SHIFT-LEFT-OP : "dshl"
+ DYN-SHIFT-LEFT-U-OP : "dshl-u"
+ DYN-SHIFT-LEFT-S-OP : "dshl-s"
+ DYN-SHIFT-RIGHT-OP : "dshr"
+ DYN-SHIFT-RIGHT-U-OP : "dshr-u"
+ DYN-SHIFT-RIGHT-S-OP : "dshr-s"
SHIFT-LEFT-OP : "shl"
SHIFT-LEFT-U-OP : "shl-u"
SHIFT-LEFT-S-OP : "shl-s"
@@ -416,3 +422,13 @@ public defn contains (l:List<Char>, c:Char) :
public defn merge!<?K,?V> (a:HashTable<?K,?V>, b:HashTable<K,V>) :
for e in b do :
a[key(e)] = value(e)
+
+public defn pow (x:Int,y:Int) -> Int :
+ var x* = 1
+ var y* = y
+ while y* != 0 :
+ x* = x* * x
+ y* = y* - 1
+ x*
+
+
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 31d8fc5f..0b586080 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -1297,6 +1297,8 @@ public defstruct MinusWidth <: Width :
arg2 : Width
public defstruct MaxWidth <: Width :
args : List<Width>
+public defstruct ExpWidth <: Width :
+ arg1 : Width
public defmulti map<?T> (f: Width -> Width, w:?T&Width) -> T
defmethod map (f: Width -> Width, w:Width) -> Width :
@@ -1304,6 +1306,7 @@ defmethod map (f: Width -> Width, w:Width) -> Width :
(w:MaxWidth) : MaxWidth(map(f,args(w)))
(w:PlusWidth) : PlusWidth(f(arg1(w)),f(arg2(w)))
(w:MinusWidth) : MinusWidth(f(arg1(w)),f(arg2(w)))
+ (w:ExpWidth) : ExpWidth(f(arg1(w)))
(w) : w
public defmethod print (o:OutputStream, w:VarWidth) :
@@ -1314,6 +1317,8 @@ public defmethod print (o:OutputStream, w:PlusWidth) :
print-all(o,[ arg1(w) " + " arg2(w)])
public defmethod print (o:OutputStream, w:MinusWidth) :
print-all(o,[ arg1(w) " - " arg2(w)])
+public defmethod print (o:OutputStream, w:ExpWidth) :
+ print-all(o,[ "exp(" arg1(w) ")"])
public definterface Constraint
public defstruct WGeq <: Constraint :
@@ -1407,6 +1412,9 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
look(w)
has?
defn evaluate (h:HashTable<Symbol,Width>) -> HashTable<Symbol,Int> :
+ defn apply (a:Int|False,f:(Int) -> Int) -> Int|False :
+ if a typeof Int : f(a as Int)
+ else : false
defn apply (a:Int|False,b:Int|False, f: (Int,Int) -> Int) -> Int|False :
if a typeof Int and b typeof Int : f(a as Int, b as Int)
else : false
@@ -1422,6 +1430,7 @@ defn solve-constraints (l:List<WGeq>) -> HashTable<Symbol,Int> :
(w:MaxWidth) : apply-l(map(solve,args(w)),max)
(w:PlusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{_ + _})
(w:MinusWidth) : apply(solve(arg1(w)),solve(arg2(w)),{_ - _})
+ (w:ExpWidth) : apply(2,solve(arg1(w)),{pow(_,_) - 1})
(w:IntWidth) : width(w)
(w) : error("Shouldn't be here")
diff --git a/src/main/stanza/primop.stanza b/src/main/stanza/primop.stanza
index 455da396..60868799 100644
--- a/src/main/stanza/primop.stanza
+++ b/src/main/stanza/primop.stanza
@@ -208,6 +208,20 @@ public defn lower-and-type-primop (e:DoPrim) -> DoPrim :
(t1:SIntType) : AS-SINT-S-OP
AS-SINT-U-OP : DoPrim(op(e),args(e),consts(e),s())
AS-SINT-S-OP : DoPrim(op(e),args(e),consts(e),s())
+ DYN-SHIFT-LEFT-OP :
+ DoPrim{_,args(e),consts(e),of-type(args(e)[0])} $
+ match(type(args(e)[0]),type(args(e)[1])) :
+ (t1:UIntType,t2:UIntType) : DYN-SHIFT-LEFT-U-OP
+ (t1:SIntType,t2:UIntType) : DYN-SHIFT-LEFT-S-OP
+ DYN-SHIFT-LEFT-U-OP : DoPrim(op(e),args(e),consts(e),u())
+ DYN-SHIFT-LEFT-S-OP : DoPrim(op(e),args(e),consts(e),s())
+ DYN-SHIFT-RIGHT-OP :
+ DoPrim{_,args(e),consts(e),of-type(args(e)[0])} $
+ match(type(args(e)[0]),type(args(e)[1])) :
+ (t1:UIntType,t2:UIntType) : DYN-SHIFT-RIGHT-U-OP
+ (t1:SIntType,t2:UIntType) : DYN-SHIFT-RIGHT-S-OP
+ DYN-SHIFT-RIGHT-U-OP : DoPrim(op(e),args(e),consts(e),u())
+ DYN-SHIFT-RIGHT-S-OP : DoPrim(op(e),args(e),consts(e),s())
SHIFT-LEFT-OP :
DoPrim{_,args(e),consts(e),of-type(args(e)[0])} $
match(type(args(e)[0])) :
@@ -255,26 +269,8 @@ public defn primop-gen-constraints (e:DoPrim,v:Vector<WGeq>) -> Type :
for (l in ls) do :
add(v,WGeq(l,m))
m
- ;defn new-width (w:Width) -> Width:
- ; val w* = VarWidth(gensym(`w))
- ; add(v,WGeq(w*,w))
- ; ;add(v,WGeq(w,w*))
- ; w*
- ;defn width-plus-const (l:List<Expression>,c:List<Int>) -> Width :
- ; new-width(PlusWidth(width!(l[0]),IntWidth(c[0])))
- ;defn width-minus-const (l:List<Expression>,c:List<Int>) -> Width :
- ; new-width(MinusWidth(width!(l[0]),IntWidth(c[0])))
- ;defn max-width (l:List<Expression>) -> Width :
- ; new-width(MaxWidth(map(width!,l)))
- ;defn max-plus-one (l:List<Expression>) -> Width :
- ; new-width(PlusWidth(MaxWidth(list(width!(l[0]),width!(l[1]))),IntWidth(1)))
- ;defn sum (l:List<Expression>) -> Width :
- ; new-width(PlusWidth(width!(l[0]),width!(l[1])))
-
println-all-debug(["Looking at " op(e) " with inputs " args(e)])
- val all-args-not-equal = to-list([MUX-UU-OP,MUX-SS-OP,CONCAT-OP,BIT-AND-OP,BIT-NOT-OP,BIT-OR-OP,BIT-XOR-OP,BIT-AND-REDUCE-OP,BIT-OR-REDUCE-OP,BIT-XOR-REDUCE-OP,AS-UINT-U-OP,AS-UINT-S-OP,AS-SINT-U-OP,AS-SINT-S-OP])
- ;val consts-gte-args = list(PAD-U-OP,PAD-S-OP)
-
+ val all-args-not-equal = to-list([MUX-UU-OP,MUX-SS-OP,CONCAT-OP,BIT-AND-OP,BIT-NOT-OP,BIT-OR-OP,BIT-XOR-OP,BIT-AND-REDUCE-OP,BIT-OR-REDUCE-OP,BIT-XOR-REDUCE-OP,AS-UINT-U-OP,AS-UINT-S-OP,AS-SINT-U-OP,AS-SINT-S-OP,DYN-SHIFT-LEFT-U-OP,DYN-SHIFT-LEFT-S-OP,DYN-SHIFT-RIGHT-U-OP,DYN-SHIFT-RIGHT-S-OP])
val w-var = VarWidth(gensym(`w))
val w* =
@@ -358,6 +354,12 @@ public defn primop-gen-constraints (e:DoPrim,v:Vector<WGeq>) -> Type :
AS-UINT-S-OP : all-equal(List(w-var,map(width!,args(e))))
AS-SINT-U-OP : all-equal(List(w-var,map(width!,args(e))))
AS-SINT-S-OP : all-equal(List(w-var,map(width!,args(e))))
+ DYN-SHIFT-LEFT-U-OP :
+ PlusWidth(width!(args(e)[0]),ExpWidth(width!(args(e)[1])))
+ DYN-SHIFT-LEFT-S-OP :
+ PlusWidth(width!(args(e)[0]),ExpWidth(width!(args(e)[1])))
+ DYN-SHIFT-RIGHT-U-OP : width!(args(e)[0])
+ DYN-SHIFT-RIGHT-S-OP : width!(args(e)[0])
add(v,WGeq(w-var,w*))
match(type(e)) :