cleanup obsolete stuff
[fleet.git] / src / edu / berkeley / fleet / api / Instruction.java
1 package edu.berkeley.fleet.api;
2
3 public abstract class Instruction {
4
5     public final Pump pump;
6     public Instruction(Pump pump) { this.pump = pump; }
7     public String toString() { return pump+": "; }
8
9     public boolean isLooping() { return true; }
10     public boolean isRepeating() { return false; }
11     public boolean isSK() { return false; }
12     public boolean isDL() { return false; }
13
14     public static class Clog extends Instruction {
15         public Clog(Pump pump) { super(pump); }
16         public String toString() { return super.toString() + "clog;"; }
17         public boolean isLooping() { return false; }
18     }
19
20     public static class UnClog extends Instruction {
21         public UnClog(Pump pump) { super(pump); }
22         public String toString() { return super.toString() + "unclog;"; }
23     }
24
25     public static class Massacre extends Instruction {
26         public Massacre(Pump pump) { super(pump); }
27     }
28
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))+";"; }
33     }
34
35     public static class PredicatedInstruction extends Instruction {
36         public static final int P_ALWAYS = 0x0001;
37         public static final int P_IF_A   = 0x0002;
38         public static final int P_IF_B   = 0x0003;
39         public static final int P_IF_Z   = 0x0004;
40
41         public final int predicate;
42         public PredicatedInstruction(Pump pump, int predicate) { super(pump); this.predicate = predicate; }
43         public String toString() {
44             switch(predicate) {
45                 case P_ALWAYS: return        super.toString();
46                 case P_IF_A:   return "[a] "+super.toString();
47                 case P_IF_B:   return "[b] "+super.toString();
48                 case P_IF_Z:   return "[z] "+super.toString();
49             }
50             throw new Error();
51         }
52     }
53
54     public static class SetFlags extends PredicatedInstruction {
55         public static final int FLAG_Z     = 0x0001;
56         public static final int FLAG_NOT_Z = 0x0002;
57         public static final int FLAG_S     = 0x0004;
58         public static final int FLAG_NOT_S = 0x0008;
59         public static final int FLAG_B     = 0x0010;
60         public static final int FLAG_NOT_B = 0x0020;
61         public static final int FLAG_A     = 0x0040;
62         public static final int FLAG_NOT_A = 0x0080;
63
64         public final int flag_a;
65         public final int flag_b;
66         public SetFlags(Pump pump, int predicate, int flag_a, int flag_b) {
67             super(pump, predicate);
68             this.flag_a = flag_a;
69             this.flag_b = flag_b;
70         }
71         public SetFlags(Pump pump, int flag_a, int flag_b) { this(pump, P_ALWAYS, flag_a, flag_b); }
72
73         public boolean isLooping() { return true; }
74         private String printFlag(int flag) {
75             if (flag==0) return "0";
76             if ((flag & (FLAG_Z | FLAG_NOT_Z)) == (FLAG_Z | FLAG_NOT_Z)) return "1";
77             if ((flag & (FLAG_B | FLAG_NOT_B)) == (FLAG_B | FLAG_NOT_B)) return "1";
78             if ((flag & (FLAG_A | FLAG_NOT_A)) == (FLAG_A | FLAG_NOT_A)) return "1";
79             if ((flag & (FLAG_S | FLAG_NOT_S)) == (FLAG_S | FLAG_NOT_S)) return "1";
80             String ret = "";
81             if ((flag & FLAG_A)     != 0) ret += (ret.length()>=0?"|":"") +  "a";
82             if ((flag & FLAG_NOT_A) != 0) ret += (ret.length()>=0?"|":"") + "!a";
83             if ((flag & FLAG_B)     != 0) ret += (ret.length()>=0?"|":"") +  "b";
84             if ((flag & FLAG_NOT_B) != 0) ret += (ret.length()>=0?"|":"") + "!b";
85             if ((flag & FLAG_S)     != 0) ret += (ret.length()>=0?"|":"") +  "s";
86             if ((flag & FLAG_NOT_S) != 0) ret += (ret.length()>=0?"|":"") + "!s";
87             if ((flag & FLAG_Z)     != 0) ret += (ret.length()>=0?"|":"") +  "z";
88             if ((flag & FLAG_NOT_Z) != 0) ret += (ret.length()>=0?"|":"") + "!z";
89             return ret;
90         }
91         public String toString() {
92             return super.toString() + " setflags a=" + printFlag(flag_a) + ", b=" + printFlag(flag_b);
93         }
94     }
95
96     public static class DecrLoop extends PredicatedInstruction {
97         public DecrLoop(Pump pump) { super(pump, P_ALWAYS); }
98         public DecrLoop(Pump pump, int predicate) { super(pump, predicate); }
99         public boolean isDL() { return true; }
100         public boolean isLooping() { return true; }
101     }
102
103     public static class Counter extends PredicatedInstruction {
104         public static final int DATA_LATCH = -1;
105         public static final int REPEAT_COUNTER = -2;
106         public static final int LOOP_COUNTER = -3;
107         public static final int STANDING = -3;
108         public final int source;
109         public final int dest;
110         public Counter(Pump pump, int source, int dest) { this(pump, P_ALWAYS, source, dest); }
111         public Counter(Pump pump, int predicate, int source, int dest) {
112             super(pump, predicate);
113             this.source = source;
114             this.dest = dest;
115         }
116         public String toString() {
117             if (source==LOOP_COUNTER && dest==DATA_LATCH) return "take loop counter;";
118             StringBuffer ret = new StringBuffer();
119             ret.append("load ");
120             switch(dest) {
121                 case LOOP_COUNTER: ret.append("loop"); break;
122                 case REPEAT_COUNTER: ret.append("repeat"); break;
123                 default: throw new RuntimeException("invalid");
124             }
125             ret.append(" counter");
126             if (source == STANDING)
127                 ret.append(" with *");
128             else if (source >= 0) {
129                 ret.append(" with " + source);
130             } else if (source!=DATA_LATCH) {
131                 throw new RuntimeException("invalid");
132             }
133             ret.append(";");
134             return ret.toString();
135         }
136         public boolean isLooping() { return true; }
137     }
138
139     public static class Move extends PredicatedInstruction {
140         public final Destination dest;
141
142         public final boolean     tokenIn;
143         public final boolean     dataIn;
144         public final boolean     latch;
145         public final boolean     dataOutDest;
146         public final boolean     dataOut;
147         public final boolean     tokenOut;
148         public final boolean     requeue;
149         public final boolean     ignoreUntilLast;
150
151         /** count=0 denotes a standing move */
152         public Move(Pump        pump,
153                     int         predicate,
154                     Destination dest,
155                     boolean     tokenIn,
156                     boolean     dataIn,
157                     boolean     latch,
158                     boolean     dataOutDest,
159                     boolean     dataOut,
160                     boolean     tokenOut,
161                     boolean     requeue,
162                     boolean     ignoreUntilLast) {
163             super(pump, predicate);
164             this.dest = dest;
165             this.tokenIn = tokenIn;
166             this.dataIn = dataIn;
167             this.latch = latch;
168             this.dataOutDest = dataOutDest;
169             this.dataOut = dataOut;
170             this.tokenOut = tokenOut;
171             this.requeue = requeue;
172             this.ignoreUntilLast = ignoreUntilLast;
173             if (pump.isInbox() && tokenIn && dataIn)
174                 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
175             if (pump.isOutbox() && tokenOut && dataOut)
176                 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
177             if (latch && !dataIn)
178                 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
179         }
180
181         public String toString() {
182             // FIXME
183             String ret = super.toString();
184             boolean needcomma = false;
185             if (tokenIn)           { ret += (needcomma ? ", " : "") + "wait";    needcomma = true; }
186             if (dataIn && latch)  {
187                 if (pump.isInbox())
188                     ret += (needcomma ? ", " : "") + "receive";
189                 else
190                     ret += (needcomma ? ", " : "") + "take";
191                 needcomma = true;
192             }
193             if (dataIn && !latch)  { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
194             if (dataOut)  {
195                 if (pump.isInbox() || dest==null)
196                     ret += (needcomma ? ", " : "") + "deliver";
197                 else
198                     ret += (needcomma ? ", " : "") + "sendto "+dest;
199                 needcomma = true;
200             }
201             if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
202             return ret;
203         }
204
205         public boolean isLooping() { return true; }
206         public boolean isRepeating() { return true; }
207     }
208
209     /*
210     public static class FullLiteral extends Executable {
211         public final long literal;
212         public boolean isRequeueing() { return true; }
213         public HalfLiteral(Pump pump, long literal) {
214             super(pump, 1);
215             this.literal = literal;
216         }
217         public Instruction.Executable decrementCount() {
218             if (count==1) return null;
219             return new FullLiteral(pump, literal, count-1, high);
220         }
221     }
222     */
223
224     public static class HalfLiteral extends PredicatedInstruction {
225         public final long literal;
226         public final boolean high;
227         public boolean isRequeueing() { return true; }
228         public HalfLiteral(Pump pump, int predicate, long literal, int count, boolean high) {
229             super(pump, predicate);
230             this.literal = literal;
231             this.high = high;
232         }
233         public boolean isLooping() { return true; }
234     }
235
236
237     public static class CodeBagDescriptor extends PredicatedInstruction {
238         // address of CBD, relative to address that this instruction was loaded from
239         public final long offset;
240         public final long size;
241         public CodeBagDescriptor(Pump pump, long offset, long size) { this(pump, P_ALWAYS, offset, size); }
242         public CodeBagDescriptor(Pump pump, int predicate, long offset, long size) {
243             super(pump, predicate);
244             this.offset = offset;
245             this.size = size;
246         }
247         public String toString() {
248             String off = ""+offset;
249             if (offset > 0) off = "+"+off;
250             return "(CBD @"+off+"+"+size+"): sendto " + pump;
251         }
252     }
253
254 }