aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/firrtl/PrimOps.scala
diff options
context:
space:
mode:
authorazidar2016-01-30 01:02:48 -0800
committerazidar2016-02-09 18:55:26 -0800
commitf6917276250258091e98a51719b35cf5935ceabf (patch)
treeb9b3db517d4c69563c4adfca8f07a21e88c3d5d6 /src/main/scala/firrtl/PrimOps.scala
parent0181686fe4bdf24f9e22f406c43dbeb98789cb8b (diff)
WIP. Finished to working ir, resolve kinds, and infer types
Diffstat (limited to 'src/main/scala/firrtl/PrimOps.scala')
-rw-r--r--src/main/scala/firrtl/PrimOps.scala422
1 files changed, 329 insertions, 93 deletions
diff --git a/src/main/scala/firrtl/PrimOps.scala b/src/main/scala/firrtl/PrimOps.scala
index 4732e756..56d1053c 100644
--- a/src/main/scala/firrtl/PrimOps.scala
+++ b/src/main/scala/firrtl/PrimOps.scala
@@ -9,38 +9,38 @@ import DebugUtils._
object PrimOps extends LazyLogging {
private val mapPrimOp2String = Map[PrimOp, String](
- AddOp -> "add",
- SubOp -> "sub",
- MulOp -> "mul",
- DivOp -> "div",
- RemOp -> "rem",
- LessOp -> "lt",
- LessEqOp -> "leq",
- GreaterOp -> "gt",
- GreaterEqOp -> "geq",
- EqualOp -> "eq",
- NEqualOp -> "neq",
- PadOp -> "pad",
- AsUIntOp -> "asUInt",
- AsSIntOp -> "asSInt",
- AsClockOp -> "asClock",
- ShiftLeftOp -> "shl",
- ShiftRightOp -> "shr",
- DynShiftLeftOp -> "dshl",
- DynShiftRightOp -> "dshr",
- ConvertOp -> "cvt",
- NegOp -> "neg",
- BitNotOp -> "not",
- BitAndOp -> "and",
- BitOrOp -> "or",
- BitXorOp -> "xor",
- BitAndReduceOp -> "andr",
- BitOrReduceOp -> "orr",
- BitXorReduceOp -> "xorr",
- ConcatOp -> "cat",
- BitsSelectOp -> "bits",
- HeadOp -> "head",
- TailOp -> "tail"
+ ADD_OP -> "add",
+ SUB_OP -> "sub",
+ MUL_OP -> "mul",
+ DIV_OP -> "div",
+ REM_OP -> "rem",
+ LESS_OP -> "lt",
+ LESS_EQ_OP -> "leq",
+ GREATER_OP -> "gt",
+ GREATER_EQ_OP -> "geq",
+ EQUAL_OP -> "eq",
+ NEQUAL_OP -> "neq",
+ PAD_OP -> "pad",
+ AS_UINT_OP -> "asUInt",
+ AS_SINT_OP -> "asSInt",
+ AS_CLOCK_OP -> "asClock",
+ SHIFT_LEFT_OP -> "shl",
+ SHIFT_RIGHT_OP -> "shr",
+ DYN_SHIFT_LEFT_OP -> "dshl",
+ DYN_SHIFT_RIGHT_OP -> "dshr",
+ NEG_OP -> "neg",
+ CONVERT_OP -> "cvt",
+ NOT_OP -> "not",
+ AND_OP -> "and",
+ OR_OP -> "or",
+ XOR_OP -> "xor",
+ AND_REDUCE_OP -> "andr",
+ OR_REDUCE_OP -> "orr",
+ XOR_REDUCE_OP -> "xorr",
+ CONCAT_OP -> "cat",
+ BITS_SELECT_OP -> "bits",
+ HEAD_OP -> "head",
+ TAIL_OP -> "tail"
)
private val mapString2PrimOp = mapPrimOp2String.map(_.swap)
def fromString(op: String): PrimOp = mapString2PrimOp(op)
@@ -50,67 +50,303 @@ object PrimOps extends LazyLogging {
}
// Borrowed from Stanza implementation
- def lowerAndTypePrimOp(e: DoPrim): DoPrim = {
- def uAnd(op1: Expression, op2: Expression): Type = {
- (op1.getType, op2.getType) match {
- case (t1: UIntType, t2: UIntType) => UIntType(UnknownWidth)
- case (t1: SIntType, t2) => SIntType(UnknownWidth)
- case (t1, t2: SIntType) => SIntType(UnknownWidth)
- case _ => UnknownType()
- }
- }
- def ofType(op: Expression): Type = {
- op.getType match {
- case t: UIntType => UIntType(UnknownWidth)
- case t: SIntType => SIntType(UnknownWidth)
- case _ => UnknownType()
- }
- }
+ def set_primop_type (e:DoPrim) : DoPrim = {
+ //println-all(["Inferencing primop type: " e])
+ def PLUS (w1:Width,w2:Width) : Width = PlusWidth(w1,w2)
+ def MAX (w1:Width,w2:Width) : Width = MaxWidth(Seq(w1,w2))
+ def MINUS (w1:Width,w2:Width) : Width = MinusWidth(w1,w2)
+ def POW (w1:Width) : Width = ExpWidth(w1)
+ def MIN (w1:Width,w2:Width) : Width = MinWidth(Seq(w1,w2))
+ val o = e.op
+ val a = e.args
+ val c = e.consts
+ def t1 () = tpe(a(0))
+ def t2 () = tpe(a(1))
+ def t3 () = tpe(a(2))
+ def w1 () = widthBANG(tpe(a(0)))
+ def w2 () = widthBANG(tpe(a(1)))
+ def w3 () = widthBANG(tpe(a(2)))
+ def c1 () = IntWidth(c(0))
+ def c2 () = IntWidth(c(1))
+ o match {
+ case ADD_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case SUB_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1:SIntType, t2:UIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(MAX(w1(),w2()),ONE))
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case MUL_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(PLUS(w1(),w2()))
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
+ case (t1:SIntType, t2:UIntType) => SIntType(PLUS(w1(),w2()))
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),w2()))
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case DIV_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(w1())
+ case (t1:UIntType, t2:SIntType) => SIntType(PLUS(w1(),ONE))
+ case (t1:SIntType, t2:UIntType) => SIntType(w1())
+ case (t1:SIntType, t2:SIntType) => SIntType(PLUS(w1(),ONE))
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case REM_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(MIN(w1(),w2()))
+ case (t1:UIntType, t2:SIntType) => UIntType(MIN(w1(),w2()))
+ case (t1:SIntType, t2:UIntType) => SIntType(MIN(w1(),PLUS(w2(),ONE)))
+ case (t1:SIntType, t2:SIntType) => SIntType(MIN(w1(),w2()))
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case LESS_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => BoolType()
+ case (t1:SIntType, t2:UIntType) => BoolType()
+ case (t1:UIntType, t2:SIntType) => BoolType()
+ case (t1:SIntType, t2:SIntType) => BoolType()
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case LESS_EQ_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => BoolType()
+ case (t1:SIntType, t2:UIntType) => BoolType()
+ case (t1:UIntType, t2:SIntType) => BoolType()
+ case (t1:SIntType, t2:SIntType) => BoolType()
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case GREATER_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => BoolType()
+ case (t1:SIntType, t2:UIntType) => BoolType()
+ case (t1:UIntType, t2:SIntType) => BoolType()
+ case (t1:SIntType, t2:SIntType) => BoolType()
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case GREATER_EQ_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => BoolType()
+ case (t1:SIntType, t2:UIntType) => BoolType()
+ case (t1:UIntType, t2:SIntType) => BoolType()
+ case (t1:SIntType, t2:SIntType) => BoolType()
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case EQUAL_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => BoolType()
+ case (t1:SIntType, t2:UIntType) => BoolType()
+ case (t1:UIntType, t2:SIntType) => BoolType()
+ case (t1:SIntType, t2:SIntType) => BoolType()
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case NEQUAL_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => BoolType()
+ case (t1:SIntType, t2:UIntType) => BoolType()
+ case (t1:UIntType, t2:SIntType) => BoolType()
+ case (t1:SIntType, t2:SIntType) => BoolType()
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case PAD_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(MAX(w1(),c1()))
+ case (t1:SIntType) => SIntType(MAX(w1(),c1()))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AS_UINT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(w1())
+ case (t1:SIntType) => UIntType(w1())
+ case (t1:ClockType) => UIntType(ONE)
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AS_SINT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => SIntType(w1())
+ case (t1:SIntType) => SIntType(w1())
+ case (t1:ClockType) => SIntType(ONE)
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AS_CLOCK_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => ClockType()
+ case (t1:SIntType) => ClockType()
+ case (t1:ClockType) => ClockType()
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case SHIFT_LEFT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(PLUS(w1(),c1()))
+ case (t1:SIntType) => SIntType(PLUS(w1(),c1()))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case SHIFT_RIGHT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(MINUS(w1(),c1()))
+ case (t1:SIntType) => SIntType(MINUS(w1(),c1()))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case DYN_SHIFT_LEFT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(PLUS(w1(),POW(w2())))
+ case (t1:SIntType) => SIntType(PLUS(w1(),POW(w2())))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case DYN_SHIFT_RIGHT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(w1())
+ case (t1:SIntType) => SIntType(w1())
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case CONVERT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => SIntType(PLUS(w1(),ONE))
+ case (t1:SIntType) => SIntType(w1())
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case NEG_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => SIntType(PLUS(w1(),ONE))
+ case (t1:SIntType) => SIntType(PLUS(w1(),ONE))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case NOT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(w1())
+ case (t1:SIntType) => UIntType(w1())
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AND_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:SIntType) => UIntType(MAX(w1(),w2()))
+ case (t1,t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case OR_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:SIntType, t2:SIntType) => UIntType(MAX(w1(),w2()))
+ case (t1,t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case XOR_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:UIntType, t2:UIntType) => UIntType(MAX(w1(),w2()))
+ case (t1:SIntType, t2:UIntType) => UIntType(MAX(w1(),w2()))
+ case (t1:UIntType, t2:SIntType) => UIntType(MAX(w1(),w2()))
+ case (t1:SIntType, t2:SIntType) => UIntType(MAX(w1(),w2()))
+ case (t1,t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case AND_REDUCE_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => BoolType()
+ case (t1:SIntType) => BoolType()
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case OR_REDUCE_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => BoolType()
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case XOR_REDUCE_OP => {
+ val t = (t1()) match {
+ case (t1:SIntType) => BoolType()
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case CONCAT_OP => {
+ val t = (t1(),t2()) match {
+ case (t1:SIntType, t2:SIntType) => UIntType(PLUS(w1(),w2()))
+ case (t1, t2) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case BITS_SELECT_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(PLUS(MINUS(c1(),c2()),ONE))
+ case (t1:SIntType) => UIntType(PLUS(MINUS(c1(),c2()),ONE))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case HEAD_OP => {
+ val t = (t1()) match {
+ case (t1:UIntType) => UIntType(c1())
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
+ case TAIL_OP => {
+ val t = (t1()) match {
+ case (t1:SIntType) => UIntType(MINUS(w1(),c1()))
+ case (t1) => UnknownType()
+ }
+ DoPrim(o,a,c,t)
+ }
- logger.debug(s"lowerAndTypePrimOp on ${e.op.getClass.getSimpleName}")
- // TODO fix this
- val tpe = UIntType(UnknownWidth)
- //val tpe = e.op match {
- // case Add => uAnd(e.args(0), e.args(1))
- // case Sub => SIntType(UnknownWidth)
- // case Addw => uAnd(e.args(0), e.args(1))
- // case Subw => uAnd(e.args(0), e.args(1))
- // case Mul => uAnd(e.args(0), e.args(1))
- // case Div => uAnd(e.args(0), e.args(1))
- // case Mod => ofType(e.args(0))
- // case Quo => uAnd(e.args(0), e.args(1))
- // case Rem => ofType(e.args(1))
- // case Lt => UIntType(UnknownWidth)
- // case Leq => UIntType(UnknownWidth)
- // case Gt => UIntType(UnknownWidth)
- // case Geq => UIntType(UnknownWidth)
- // case Eq => UIntType(UnknownWidth)
- // case Neq => UIntType(UnknownWidth)
- // case Eqv => UIntType(UnknownWidth)
- // case Neqv => UIntType(UnknownWidth)
- // case Mux => ofType(e.args(1))
- // case Pad => ofType(e.args(0))
- // case AsUInt => UIntType(UnknownWidth)
- // case AsSInt => SIntType(UnknownWidth)
- // case Shl => ofType(e.args(0))
- // case Shr => ofType(e.args(0))
- // case Dshl => ofType(e.args(0))
- // case Dshr => ofType(e.args(0))
- // case Cvt => SIntType(UnknownWidth)
- // case Neg => SIntType(UnknownWidth)
- // case Not => ofType(e.args(0))
- // case And => ofType(e.args(0))
- // case Or => ofType(e.args(0))
- // case Xor => ofType(e.args(0))
- // case Andr => UIntType(UnknownWidth)
- // case Orr => UIntType(UnknownWidth)
- // case Xorr => UIntType(UnknownWidth)
- // case Cat => UIntType(UnknownWidth)
- // case Bit => UIntType(UnknownWidth)
- // case Bits => UIntType(UnknownWidth)
- // case _ => ???
- //}
- DoPrim(e.op, e.args, e.consts, tpe)
- }
+ }
+ }
}