1 package edu.berkeley.fleet.api;
3 public abstract class Instruction {
5 public final Pump pump;
6 public Instruction(Pump pump) { this.pump = pump; }
7 public String toString() { return pump+": "; }
9 public static abstract class CountingInstruction extends Instruction {
10 public final int count;
11 public CountingInstruction(Pump pump, int count) {
15 public boolean isStanding() { return count==0; }
16 public abstract boolean isRequeueing();
17 public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
20 public static class UnClog extends Instruction {
21 public UnClog(Pump pump) { super(pump); }
22 public String toString() { return super.toString() + "unclog;"; }
25 public static class Massacre extends Instruction {
26 public Massacre(Pump pump) { super(pump); }
29 public static class Clog extends Executable {
30 public Clog(Pump pump) { super(pump, 1); }
31 public String toString() { return super.toString() + "clog;"; }
32 public Instruction.Executable decrementCount() { return null; }
33 public boolean isRequeueing() { return false; }
36 public static class Kill extends CountingInstruction {
37 public Kill(Pump pump, int count) { super(pump, count); }
38 public boolean isRequeueing() { return false; }
39 public String toString() { return super.toString() + "kill;"; }
42 public static abstract class Executable extends CountingInstruction {
43 public Executable(Pump pump, int count) { super(pump, count); }
44 public abstract Instruction.Executable decrementCount();
47 public static class DecrLoop extends Executable {
48 public DecrLoop(Pump pump) { super(pump, 1); }
49 public Instruction.Executable decrementCount() { return null; }
50 public boolean isRequeueing() { return false; }
53 public static class Counter extends Executable {
54 public static final int DATA_LATCH = -1;
55 public static final int REPEAT_COUNTER = -2;
56 public static final int LOOP_COUNTER = -3;
57 public final int source;
58 public final int dest;
59 public Instruction.Executable decrementCount() { return null; }
60 public boolean isRequeueing() { return false; }
61 public Counter(Pump pump, int source, int dest) {
66 public String toString() {
67 if (source==LOOP_COUNTER && dest==DATA_LATCH) return "take loop counter;";
68 StringBuffer ret = new StringBuffer();
71 case LOOP_COUNTER: ret.append("loop"); break;
72 case REPEAT_COUNTER: ret.append("repeat"); break;
73 default: throw new RuntimeException("invalid");
75 ret.append(" counter");
77 ret.append(" with " + source);
78 } else if (source!=DATA_LATCH) {
79 throw new RuntimeException("invalid");
82 return ret.toString();
86 public static class Move extends Executable {
87 public final Destination dest;
89 public final boolean tokenIn;
90 public final boolean dataIn;
91 public final boolean latch;
92 public final boolean dataOutDest;
93 public final boolean dataOut;
94 public final boolean tokenOut;
95 public final boolean requeue;
96 public final boolean ignoreUntilLast;
98 public boolean isRequeueing() { return requeue; }
100 /** count=0 denotes a standing move */
101 public Move(Pump pump,
111 boolean ignoreUntilLast) {
114 this.tokenIn = tokenIn;
115 this.dataIn = dataIn;
117 this.dataOutDest = dataOutDest;
118 this.dataOut = dataOut;
119 this.tokenOut = tokenOut;
120 this.requeue = requeue;
121 this.ignoreUntilLast = ignoreUntilLast;
123 throw new RuntimeException("count field of an instruction must be >=0");
124 if (pump.isInbox() && tokenIn && dataIn)
125 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
126 if (pump.isOutbox() && tokenOut && dataOut)
127 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
128 if (latch && !dataIn)
129 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
132 public Instruction.Executable decrementCount() {
133 if (count==1) return null;
134 return new Move(pump, dest, count==0 ? 0 : count-1,
135 tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
138 public String toString() {
140 String ret = super.toString();
141 boolean needcomma = false;
142 if (tokenIn) { ret += (needcomma ? ", " : "") + "wait"; needcomma = true; }
143 if (dataIn && latch) {
145 ret += (needcomma ? ", " : "") + "receive";
147 ret += (needcomma ? ", " : "") + "take";
150 if (dataIn && !latch) { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
152 if (pump.isInbox() || dest==null)
153 ret += (needcomma ? ", " : "") + "deliver";
155 ret += (needcomma ? ", " : "") + "sendto "+dest;
158 if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
164 public static class LocalLiteral extends Executable {
165 public final long literal;
166 public final boolean high;
167 public boolean isRequeueing() { return true; }
168 public LocalLiteral(Pump pump, long literal, int count, boolean high) {
170 this.literal = literal;
173 public Instruction.Executable decrementCount() {
174 if (count==1) return null;
175 return new LocalLiteral(pump, literal, count-1, high);
179 public static class CodeBagDescriptor extends Instruction {
180 /** address of CBD, relative to address that this instruction was loaded from */
181 public final long offset;
182 public final long size;
183 public CodeBagDescriptor(Pump pump, long offset, long size) {
185 this.offset = offset;
188 public String toString() {
189 String off = ""+offset;
190 if (offset > 0) off = "+"+off;
191 return "(CBD @"+off+"+"+size+"): sendto " + pump;