implement support (fpga+interp+test) for massacre instruction
[fleet.git] / src / edu / berkeley / fleet / api / Instruction.java
index 55e2b52..f021242 100644 (file)
@@ -12,7 +12,8 @@ public abstract class Instruction {
             super(pump);
             this.count = count;
         }
-        protected abstract boolean isRequeueing();
+        public boolean isStanding() { return count==0; }
+        public abstract boolean isRequeueing();
         public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
     }
 
@@ -21,21 +22,30 @@ public abstract class Instruction {
         public String toString() { return super.toString() + "unclog;"; }
     }
 
-    public static class Clog extends Instruction {
-        public Clog(Pump pump) { super(pump); }
+    public static class Massacre extends Instruction {
+        public Massacre(Pump pump) { super(pump); }
+    }
+
+    public static class Clog extends Executable {
+        public Clog(Pump pump) { super(pump, 1); }
         public String toString() { return super.toString() + "clog;"; }
+        public Instruction.Executable decrementCount() { return null; }
+        public boolean isRequeueing() { return false; }
     }
 
     public static class Kill extends CountingInstruction {
         public Kill(Pump pump, int count) { super(pump, count); }
-        protected boolean isRequeueing() { return false; }
+        public boolean isRequeueing() { return false; }
         public String toString() { return super.toString() + "kill;"; }
     }
 
-    public static class Executable extends Instruction {
+    public static abstract class Executable extends CountingInstruction {
+        public Executable(Pump pump, int count) { super(pump, count); }
+        public abstract Instruction.Executable decrementCount();
+    }
 
+    public static class Move extends Executable {
         public final Destination dest;
-        public final int         count;
 
         public final boolean     tokenIn;
         public final boolean     dataIn;
@@ -46,10 +56,10 @@ public abstract class Instruction {
         public final boolean     requeue;
         public final boolean     ignoreUntilLast;
 
-        protected boolean isRequeueing() { return requeue; }
+        public boolean isRequeueing() { return requeue; }
 
         /** count=0 denotes a standing move */
-        public Executable(Pump        pump,
+        public Move(Pump        pump,
                           Destination dest,
                           int         count,
                           boolean     tokenIn,
@@ -60,9 +70,8 @@ public abstract class Instruction {
                           boolean     tokenOut,
                           boolean     requeue,
                           boolean     ignoreUntilLast) {
-            super(pump);
+            super(pump, count);
             this.dest = dest;
-            this.count = count;
             this.tokenIn = tokenIn;
             this.dataIn = dataIn;
             this.latch = latch;
@@ -73,16 +82,18 @@ public abstract class Instruction {
             this.ignoreUntilLast = ignoreUntilLast;
             if (count < 0)
                 throw new RuntimeException("count field of an instruction must be >=0");
-        }
-
-        public boolean isStanding() {
-            return count==0;
+            if (pump.isInbox() && tokenIn && dataIn)
+                throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
+            if (pump.isOutbox() && tokenOut && dataOut)
+                throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
+            if (latch && !dataIn)
+                throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
         }
 
         public Instruction.Executable decrementCount() {
             if (count==1) return null;
-            return new Executable(pump, dest, count==0 ? 0 : count-1,
-                                  tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
+            return new Move(pump, dest, count==0 ? 0 : count-1,
+                            tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
         }
 
         public String toString() {
@@ -111,13 +122,17 @@ public abstract class Instruction {
 
     }
 
-    public static class LocalLiteral extends CountingInstruction {
+    public static class LocalLiteral extends Executable {
         public final long literal;
         public boolean isRequeueing() { return true; }
         public LocalLiteral(Pump pump, long literal, int count) {
             super(pump, count);
             this.literal = literal;
         }
+        public Instruction.Executable decrementCount() {
+            if (count==1) return null;
+            return new LocalLiteral(pump, literal, count-1);
+        }
     }
 
     public static class CodeBagDescriptor extends Instruction {