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 true; }
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;"; }
18 public boolean isLooping() { return false; }
21 public static class UnClog extends Instruction {
22 public UnClog(Pump pump) { super(pump); }
23 public String toString() { return super.toString() + "unclog;"; }
26 public static class Massacre extends Instruction {
27 public Massacre(Pump pump) { super(pump); }
30 public static class Kill extends Instruction {
31 public final int count;
32 public Kill(Pump pump, int count) { super(pump); this.count = count; }
33 public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; }
36 public static class PredicatedInstruction extends Instruction {
37 public static final int P_ALWAYS = 0x0001;
38 public static final int P_IF_A = 0x0002;
39 public static final int P_IF_B = 0x0003;
40 public static final int P_IF_Z = 0x0004;
42 public final int predicate;
43 public PredicatedInstruction(Pump pump, int predicate) { super(pump); this.predicate = predicate; }
44 public String toString() {
46 case P_ALWAYS: return super.toString();
47 case P_IF_A: return "[a] "+super.toString();
48 case P_IF_B: return "[b] "+super.toString();
49 case P_IF_Z: return "[z] "+super.toString();
55 public static class SetFlags extends PredicatedInstruction {
56 public static final int FLAG_Z = 0x0001;
57 public static final int FLAG_NOT_Z = 0x0002;
58 public static final int FLAG_S = 0x0004;
59 public static final int FLAG_NOT_S = 0x0008;
60 public static final int FLAG_B = 0x0010;
61 public static final int FLAG_NOT_B = 0x0020;
62 public static final int FLAG_A = 0x0040;
63 public static final int FLAG_NOT_A = 0x0080;
65 public final int flag_a;
66 public final int flag_b;
67 public SetFlags(Pump pump, int predicate, int flag_a, int flag_b) {
68 super(pump, predicate);
72 public SetFlags(Pump pump, int flag_a, int flag_b) { this(pump, P_ALWAYS, flag_a, flag_b); }
74 public boolean isLooping() { return true; }
75 private String printFlag(int flag) {
76 if (flag==0) return "0";
77 if ((flag & (FLAG_Z | FLAG_NOT_Z)) == (FLAG_Z | FLAG_NOT_Z)) return "1";
78 if ((flag & (FLAG_B | FLAG_NOT_B)) == (FLAG_B | FLAG_NOT_B)) return "1";
79 if ((flag & (FLAG_A | FLAG_NOT_A)) == (FLAG_A | FLAG_NOT_A)) return "1";
80 if ((flag & (FLAG_S | FLAG_NOT_S)) == (FLAG_S | FLAG_NOT_S)) return "1";
82 if ((flag & FLAG_A) != 0) ret += (ret.length()>=0?"|":"") + "a";
83 if ((flag & FLAG_NOT_A) != 0) ret += (ret.length()>=0?"|":"") + "!a";
84 if ((flag & FLAG_B) != 0) ret += (ret.length()>=0?"|":"") + "b";
85 if ((flag & FLAG_NOT_B) != 0) ret += (ret.length()>=0?"|":"") + "!b";
86 if ((flag & FLAG_S) != 0) ret += (ret.length()>=0?"|":"") + "s";
87 if ((flag & FLAG_NOT_S) != 0) ret += (ret.length()>=0?"|":"") + "!s";
88 if ((flag & FLAG_Z) != 0) ret += (ret.length()>=0?"|":"") + "z";
89 if ((flag & FLAG_NOT_Z) != 0) ret += (ret.length()>=0?"|":"") + "!z";
92 public String toString() {
93 return super.toString() + " setflags a=" + printFlag(flag_a) + ", b=" + printFlag(flag_b);
97 public static class DecrLoop extends PredicatedInstruction {
98 public DecrLoop(Pump pump) { super(pump, P_ALWAYS); }
99 public DecrLoop(Pump pump, int predicate) { super(pump, predicate); }
100 public boolean isDL() { return true; }
101 public boolean isLooping() { return true; }
104 public static class Counter extends PredicatedInstruction {
105 public static final int DATA_LATCH = -1;
106 public static final int REPEAT_COUNTER = -2;
107 public static final int LOOP_COUNTER = -3;
108 public static final int STANDING = -3;
109 public final int source;
110 public final int dest;
111 public Counter(Pump pump, int source, int dest) { this(pump, P_ALWAYS, source, dest); }
112 public Counter(Pump pump, int predicate, int source, int dest) {
113 super(pump, predicate);
114 this.source = source;
117 public String toString() {
118 if (source==LOOP_COUNTER && dest==DATA_LATCH) return "take loop counter;";
119 StringBuffer ret = new StringBuffer();
122 case LOOP_COUNTER: ret.append("loop"); break;
123 case REPEAT_COUNTER: ret.append("repeat"); break;
124 default: throw new RuntimeException("invalid");
126 ret.append(" counter");
127 if (source == STANDING)
128 ret.append(" with *");
129 else if (source >= 0) {
130 ret.append(" with " + source);
131 } else if (source!=DATA_LATCH) {
132 throw new RuntimeException("invalid");
135 return ret.toString();
137 public boolean isLooping() { return true; }
140 public static class Move extends PredicatedInstruction {
141 public final Destination dest;
143 public final boolean tokenIn;
144 public final boolean dataIn;
145 public final boolean latch;
146 public final boolean dataOutDest;
147 public final boolean dataOut;
148 public final boolean tokenOut;
149 public final boolean requeue;
150 public final boolean ignoreUntilLast;
151 public final boolean standing;
153 /** count=0 denotes a standing move */
154 public Move(Pump pump,
165 boolean ignoreUntilLast) {
166 super(pump, predicate);
168 this.tokenIn = tokenIn;
169 this.dataIn = dataIn;
171 this.dataOutDest = dataOutDest;
172 this.dataOut = dataOut;
173 this.tokenOut = tokenOut;
174 this.requeue = requeue;
175 this.ignoreUntilLast = ignoreUntilLast;
176 this.standing = count==0;
177 if (pump.isInbox() && tokenIn && dataIn)
178 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
179 if (pump.isOutbox() && tokenOut && dataOut)
180 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
181 if (latch && !dataIn)
182 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
185 public String toString() {
187 String ret = super.toString();
188 boolean needcomma = false;
189 if (tokenIn) { ret += (needcomma ? ", " : "") + "wait"; needcomma = true; }
190 if (dataIn && latch) {
192 ret += (needcomma ? ", " : "") + "receive";
194 ret += (needcomma ? ", " : "") + "take";
197 if (dataIn && !latch) { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
199 if (pump.isInbox() || dest==null)
200 ret += (needcomma ? ", " : "") + "deliver";
202 ret += (needcomma ? ", " : "") + "sendto "+dest;
205 if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
209 public boolean isLooping() { return true; }
210 public boolean isRepeating() { return true; }
211 public boolean isStanding() { return standing; }
215 public static class FullLiteral extends Executable {
216 public final long literal;
217 public boolean isRequeueing() { return true; }
218 public HalfLiteral(Pump pump, long literal) {
220 this.literal = literal;
222 public Instruction.Executable decrementCount() {
223 if (count==1) return null;
224 return new FullLiteral(pump, literal, count-1, high);
229 public static class HalfLiteral extends PredicatedInstruction {
230 public final long literal;
231 public final boolean high;
232 public boolean isRequeueing() { return true; }
233 public HalfLiteral(Pump pump, int predicate, long literal, int count, boolean high) {
234 super(pump, predicate);
235 this.literal = literal;
238 public boolean isLooping() { return true; }
242 public static class CodeBagDescriptor extends PredicatedInstruction {
243 // address of CBD, relative to address that this instruction was loaded from
244 public final long offset;
245 public final long size;
246 public CodeBagDescriptor(Pump pump, long offset, long size) { this(pump, P_ALWAYS, offset, size); }
247 public CodeBagDescriptor(Pump pump, int predicate, long offset, long size) {
248 super(pump, predicate);
249 this.offset = offset;
252 public String toString() {
253 String off = ""+offset;
254 if (offset > 0) off = "+"+off;
255 return "(CBD @"+off+"+"+size+"): sendto " + pump;