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 boolean isLooping() { return false; }
10 public boolean isRepeating() { return false; }
11 public boolean isStanding() { return false; }
12 public boolean isSK() { return false; }
13 public boolean isDL() { return false; }
15 public static class Clog extends Instruction {
16 public Clog(Pump pump) { super(pump); }
17 public String toString() { return super.toString() + "clog;"; }
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 Kill extends Instruction {
30 public final int count;
31 public Kill(Pump pump, int count) { super(pump); this.count = count; }
32 public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; }
35 public static class SetFlags extends Instruction {
36 public static final int FLAG_Z = 0x0001;
37 public static final int FLAG_NOT_Z = 0x0002;
38 public static final int FLAG_S = 0x0004;
39 public static final int FLAG_NOT_S = 0x0008;
40 public static final int FLAG_B = 0x0010;
41 public static final int FLAG_NOT_B = 0x0020;
42 public static final int FLAG_A = 0x0040;
43 public static final int FLAG_NOT_A = 0x0080;
45 public final int flag_a;
46 public final int flag_b;
47 public SetFlags(Pump pump, int flag_a, int flag_b) {
53 public boolean isLooping() { return true; }
54 private String printFlag(int flag) {
55 if (flag==0) return "0";
56 if ((flag & (FLAG_Z | FLAG_NOT_Z)) == (FLAG_Z | FLAG_NOT_Z)) return "1";
57 if ((flag & (FLAG_B | FLAG_NOT_B)) == (FLAG_B | FLAG_NOT_B)) return "1";
58 if ((flag & (FLAG_A | FLAG_NOT_A)) == (FLAG_A | FLAG_NOT_A)) return "1";
59 if ((flag & (FLAG_S | FLAG_NOT_S)) == (FLAG_S | FLAG_NOT_S)) return "1";
61 if ((flag & FLAG_A) != 0) ret += (ret.length()>=0?"|":"") + "a";
62 if ((flag & FLAG_NOT_A) != 0) ret += (ret.length()>=0?"|":"") + "!a";
63 if ((flag & FLAG_B) != 0) ret += (ret.length()>=0?"|":"") + "b";
64 if ((flag & FLAG_NOT_B) != 0) ret += (ret.length()>=0?"|":"") + "!b";
65 if ((flag & FLAG_S) != 0) ret += (ret.length()>=0?"|":"") + "s";
66 if ((flag & FLAG_NOT_S) != 0) ret += (ret.length()>=0?"|":"") + "!s";
67 if ((flag & FLAG_Z) != 0) ret += (ret.length()>=0?"|":"") + "z";
68 if ((flag & FLAG_NOT_Z) != 0) ret += (ret.length()>=0?"|":"") + "!z";
71 public String toString() {
72 return super.toString() + " setflags a=" + printFlag(flag_a) + ", b=" + printFlag(flag_b);
76 public static class DecrLoop extends Instruction {
77 public DecrLoop(Pump pump) { super(pump); }
78 public boolean isDL() { return true; }
79 public boolean isLooping() { return true; }
82 public static class Counter extends Instruction {
83 public static final int DATA_LATCH = -1;
84 public static final int REPEAT_COUNTER = -2;
85 public static final int LOOP_COUNTER = -3;
86 public final int source;
87 public final int dest;
88 public Counter(Pump pump, int source, int dest) {
93 public String toString() {
94 if (source==LOOP_COUNTER && dest==DATA_LATCH) return "take loop counter;";
95 StringBuffer ret = new StringBuffer();
98 case LOOP_COUNTER: ret.append("loop"); break;
99 case REPEAT_COUNTER: ret.append("repeat"); break;
100 default: throw new RuntimeException("invalid");
102 ret.append(" counter");
104 ret.append(" with " + source);
105 } else if (source!=DATA_LATCH) {
106 throw new RuntimeException("invalid");
109 return ret.toString();
111 public boolean isLooping() { return true; }
114 public static class Move extends Instruction {
115 public final Destination dest;
117 public final boolean tokenIn;
118 public final boolean dataIn;
119 public final boolean latch;
120 public final boolean dataOutDest;
121 public final boolean dataOut;
122 public final boolean tokenOut;
123 public final boolean requeue;
124 public final boolean ignoreUntilLast;
125 public final boolean standing;
127 /** count=0 denotes a standing move */
128 public Move(Pump pump,
138 boolean ignoreUntilLast) {
141 this.tokenIn = tokenIn;
142 this.dataIn = dataIn;
144 this.dataOutDest = dataOutDest;
145 this.dataOut = dataOut;
146 this.tokenOut = tokenOut;
147 this.requeue = requeue;
148 this.ignoreUntilLast = ignoreUntilLast;
149 this.standing = count==0;
150 if (pump.isInbox() && tokenIn && dataIn)
151 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
152 if (pump.isOutbox() && tokenOut && dataOut)
153 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
154 if (latch && !dataIn)
155 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
158 public String toString() {
160 String ret = super.toString();
161 boolean needcomma = false;
162 if (tokenIn) { ret += (needcomma ? ", " : "") + "wait"; needcomma = true; }
163 if (dataIn && latch) {
165 ret += (needcomma ? ", " : "") + "receive";
167 ret += (needcomma ? ", " : "") + "take";
170 if (dataIn && !latch) { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
172 if (pump.isInbox() || dest==null)
173 ret += (needcomma ? ", " : "") + "deliver";
175 ret += (needcomma ? ", " : "") + "sendto "+dest;
178 if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
182 public boolean isLooping() { return true; }
183 public boolean isRepeating() { return true; }
184 public boolean isStanding() { return standing; }
188 public static class FullLiteral extends Executable {
189 public final long literal;
190 public boolean isRequeueing() { return true; }
191 public HalfLiteral(Pump pump, long literal) {
193 this.literal = literal;
195 public Instruction.Executable decrementCount() {
196 if (count==1) return null;
197 return new FullLiteral(pump, literal, count-1, high);
202 public static class HalfLiteral extends Instruction {
203 public final long literal;
204 public final boolean high;
205 public boolean isRequeueing() { return true; }
206 public HalfLiteral(Pump pump, long literal, int count, boolean high) {
208 this.literal = literal;
211 public boolean isLooping() { return true; }
214 public static class CodeBagDescriptor extends Instruction {
215 /** address of CBD, relative to address that this instruction was loaded from */
216 public final long offset;
217 public final long size;
218 public CodeBagDescriptor(Pump pump, long offset, long size) {
220 this.offset = offset;
223 public String toString() {
224 String off = ""+offset;
225 if (offset > 0) off = "+"+off;
226 return "(CBD @"+off+"+"+size+"): sendto " + pump;