1 package edu.berkeley.fleet.two;
3 import edu.berkeley.fleet.api.*;
4 import edu.berkeley.fleet.util.*;
5 import edu.berkeley.fleet.api.Instruction.Set;
6 import static edu.berkeley.fleet.api.Instruction.Set.*;
7 import static edu.berkeley.fleet.api.Instruction.*;
8 import static edu.berkeley.fleet.api.Predicate.*;
10 public abstract class FleetTwoFleet extends Fleet {
12 public static final Mask PACKET_TOKEN = new Mask("v.................................................");
13 public static final Mask PACKET_DATA = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
14 public static final Mask PACKET_SIGNAL = new Mask("......................................v...........");
15 public static final Mask PACKET_DEST = new Mask(".......................................vvvvvvvvvvv");
17 public static final Mask CBD_SIZE = new Mask("...............................vvvvvv");
18 public static final Mask CBD_OFFSET = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv......");
20 public static final int WIDTH_WORD = PACKET_DATA.valmaskwidth;
21 public static final int WIDTH_PACKET = PACKET_TOKEN.width;
23 public static final Mask DISPATCH_PATH = new Mask("vvvvvvvvvvv..........................");
24 public static final Mask I = new Mask("...........1.........................");
25 public static final Mask OS = new Mask("............1........................");
26 public static final Mask P = new Mask(".............vvv.....................");
27 public static final Mask P_NOT_A = new Mask(".............000.....................");
28 public static final Mask P_A = new Mask(".............001.....................");
29 public static final Mask P_NOT_B = new Mask(".............010.....................");
30 public static final Mask P_B = new Mask(".............011.....................");
31 public static final Mask P_NOT_C = new Mask(".............100.....................");
32 public static final Mask P_C = new Mask(".............101.....................");
33 public static final Mask P_OLC = new Mask(".............110.....................");
34 public static final Mask P_ALWAYS = new Mask(".............111.....................");
36 public static final Mask SHIFT = new Mask("................00vvvvvvvvvvvvvvvvvvv");
38 public static final Mask TAIL = new Mask("................11...................");
40 public static final Mask MOVE = new Mask("................01...................");
41 public static final Mask TI = new Mask("..................1..................");
42 public static final Mask DI = new Mask("...................1.................");
43 public static final Mask DC = new Mask("....................1................");
44 public static final Mask DO = new Mask(".....................1...............");
45 public static final Mask TO = new Mask("......................1..............");
46 public static final Mask PATH_IMMEDIATE = new Mask(".......................1vvvvvvvvvvvvv");
47 public static final Mask PATH_DATA = new Mask(".......................01............");
48 public static final Mask PATH_NOCHANGE = new Mask(".......................00............");
50 public static final Mask SET = new Mask("................10...................");
52 public static final Mask SET_OLC_FROM_IMMEDIATE = new Mask("................1010000100.....vvvvvv");
53 public static final Mask SET_OLC_FROM_DATA_LATCH = new Mask("................1010000010...........");
54 public static final Mask SET_OLC_FROM_OLC_MINUS_ONE = new Mask("................1010000001...........");
56 public static final Mask SET_ILC_FROM_IMMEDIATE = new Mask("................1001000100.....vvvvvv");
57 public static final Mask SET_ILC_FROM_INFINITY = new Mask("................1001000010...........");
58 public static final Mask SET_ILC_FROM_DATA_LATCH = new Mask("................1001000001...........");
60 public static final Mask SET_IMMEDIATE = new Mask("................1000100.vvvvvvvvvvvvv");
61 public static final Mask SET_IMMEDIATE_EXTEND = new Mask("................1000100v.............");
63 public static final Mask SET_FLAGS = new Mask("................1000010..............");
64 public static final Mask SET_FLAGS_A = new Mask("................1000010..vvvvvv......");
65 public static final Mask SET_FLAGS_B = new Mask("................1000010........vvvvvv");
66 public static final Mask SET_FLAGS_VALUE_A = new Mask("1.....");
67 public static final Mask SET_FLAGS_VALUE_NOT_A = new Mask(".1....");
68 public static final Mask SET_FLAGS_VALUE_B = new Mask("..1...");
69 public static final Mask SET_FLAGS_VALUE_NOT_B = new Mask("...1..");
70 public static final Mask SET_FLAGS_VALUE_C = new Mask("....1.");
71 public static final Mask SET_FLAGS_VALUE_NOT_C = new Mask(".....1");
73 public static final Mask SET_TAPL_FROM_IMMEDIATE = new Mask("................1000001.vvvvvvvvvvvvv");
76 public static final long DataLatch_WIDTH = SET_IMMEDIATE.valmaskmax-SET_IMMEDIATE.valmaskmin+1; // FIXME: this is an abstraction breakage
77 private static final long mask = ~(-1L << DataLatch_WIDTH);
78 public static boolean isSmallEnoughToFit(long immediate) {
79 if ((immediate & ~mask) == 0) return true;
80 if ((immediate | mask) == -1L) return true;
84 /** get the bits describing this box's location on the DESTINATION HORN */
85 protected abstract long getDestAddr(Path box);
87 /** decode a path, given the starting point and the bits that comprise it */
88 protected abstract Path getPathByAddr(Dock source, long dest);
90 /** FIXME: this is a hack for now */
91 protected abstract Dock getUniversalSource();
93 /** read a machine-formatted instruction from a file (into a Java object) */
94 public Instruction readInstruction(DataInputStream is, Dock dispatchFrom) throws IOException {
97 inst = (inst << 8) | (is.readByte() & 0xff);
98 inst = (inst << 8) | (is.readByte() & 0xff);
99 inst = (inst << 8) | (is.readByte() & 0xff);
100 inst = (inst << 8) | (is.readByte() & 0xff);
101 inst = (inst << 8) | (is.readByte() & 0xff);
102 inst = (inst << 8) | (is.readByte() & 0xff);
103 return readInstruction(inst, dispatchFrom);
104 } catch (EOFException eof) {
109 public Instruction readInstruction(long inst, Dock dispatchFrom) {
110 Dock dock = getPathByAddr(getUniversalSource(), DISPATCH_PATH.getval(inst)).getDestination().getDock();
112 if (TAIL.get(inst)) return new Tail(dock);
114 Predicate predicate = Default;
115 if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
116 if (P_OLC.get(inst)) predicate = Default;
117 if (P_A.get(inst)) predicate = FlagA;
118 if (P_B.get(inst)) predicate = FlagB;
119 if (P_C.get(inst)) predicate = FlagC;
120 if (P_NOT_A.get(inst)) predicate = NotFlagA;
121 if (P_NOT_B.get(inst)) predicate = NotFlagB;
122 if (P_NOT_C.get(inst)) predicate = NotFlagC;
124 boolean looping = !OS.get(inst);
125 if (SHIFT.get(inst)) return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getWordWidth()).set(SHIFT.getval(inst)));
126 if (SET_IMMEDIATE.get(inst)) {
127 boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
128 long immediate = SET_IMMEDIATE.getval(inst);
129 if (extend) immediate |= (-1L << DataLatch_WIDTH);
130 return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
133 if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
134 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
135 if (SET_OLC_FROM_IMMEDIATE.get(inst))
136 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
137 if (SET_ILC_FROM_IMMEDIATE.get(inst))
138 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
139 if (SET_OLC_FROM_DATA_LATCH.get(inst))
140 return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
141 if (SET_ILC_FROM_DATA_LATCH.get(inst))
142 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
143 if (SET_ILC_FROM_INFINITY.get(inst))
144 return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
145 if (SET_FLAGS.get(inst)) {
146 long flag_a = SET_FLAGS_A.getval(inst);
147 long flag_b = SET_FLAGS_B.getval(inst);
148 FlagFunction ap = FlagFunction.ZERO;
149 FlagFunction bp = FlagFunction.ZERO;
150 if (SET_FLAGS_VALUE_A .get(flag_a)) ap = ap.add(FlagA );
151 if (SET_FLAGS_VALUE_NOT_A.get(flag_a)) ap = ap.add(NotFlagA );
152 if (SET_FLAGS_VALUE_B .get(flag_a)) ap = ap.add(FlagB );
153 if (SET_FLAGS_VALUE_NOT_B.get(flag_a)) ap = ap.add(NotFlagB );
154 if (SET_FLAGS_VALUE_C .get(flag_a)) ap = ap.add(FlagC );
155 if (SET_FLAGS_VALUE_NOT_C.get(flag_a)) ap = ap.add(NotFlagC );
156 if (SET_FLAGS_VALUE_A .get(flag_b)) bp = bp.add(FlagA );
157 if (SET_FLAGS_VALUE_NOT_A.get(flag_b)) bp = bp.add(NotFlagA );
158 if (SET_FLAGS_VALUE_B .get(flag_b)) bp = bp.add(FlagB );
159 if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
160 if (SET_FLAGS_VALUE_C .get(flag_b)) bp = bp.add(FlagC );
161 if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
162 return new Set(dock, looping, predicate, ap, bp);
164 if (SET_TAPL_FROM_IMMEDIATE.get(inst))
165 return new Set(dock, looping, predicate, SetDest.TAPL, getPathByAddr(dock, SET_TAPL_FROM_IMMEDIATE.getval(inst)));
167 return new Move(dock,
171 getPathByAddr(dock, PATH_IMMEDIATE.getval(inst)),
179 throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
182 public long writeInstruction(Instruction d, Dock dispatchFrom) {
186 instr = DISPATCH_PATH.setval(instr, getDestAddr(getUniversalSource().getPath(d.dock.getInstructionDestination(),null)));
190 if (!pi.looping) instr = OS.set(instr);
191 switch(pi.predicate) {
192 case IgnoreOLC: instr = P_ALWAYS.set(instr); break;
193 case Default: instr = P_OLC.set(instr); break;
194 case FlagA: instr = P_A.set(instr); break;
195 case FlagB: instr = P_B.set(instr); break;
196 case FlagC: instr = P_C.set(instr); break;
197 case NotFlagA: instr = P_NOT_A.set(instr); break;
198 case NotFlagB: instr = P_NOT_B.set(instr); break;
199 case NotFlagC: instr = P_NOT_C.set(instr); break;
202 if (d instanceof Tail) {
203 instr = TAIL.set(instr);
205 } else if (d instanceof Shift) {
206 Shift shift = (Shift)d;
207 instr = SHIFT.set(instr);
208 instr = SHIFT.setval(instr, shift.immediate);
210 } else if (d instanceof Set) {
213 case InnerLoopCounter:
216 instr = SET_ILC_FROM_DATA_LATCH.set(instr);
219 instr = SET_ILC_FROM_IMMEDIATE.setval(SET_ILC_FROM_IMMEDIATE.set(instr), s.immediate);
222 instr = SET_ILC_FROM_INFINITY.set(instr);
226 case OuterLoopCounter:
229 instr = SET_OLC_FROM_OLC_MINUS_ONE.set(instr);
232 instr = SET_OLC_FROM_DATA_LATCH.set(instr);
235 instr = SET_OLC_FROM_IMMEDIATE.setval(SET_OLC_FROM_IMMEDIATE.set(instr), s.immediate);
240 instr = SET_TAPL_FROM_IMMEDIATE.set(instr);
241 instr = SET_TAPL_FROM_IMMEDIATE.setval(instr, getDestAddr(s.path));
245 instr = SET_FLAGS.set(instr);
246 instr = SET_FLAGS_A.setval(instr, flagFunctionToLong(s.newFlagA));
247 instr = SET_FLAGS_B.setval(instr, flagFunctionToLong(s.newFlagB));
251 instr = SET_IMMEDIATE.set(instr);
252 instr = SET_IMMEDIATE_EXTEND.setval(instr, s.immediate < 0 ? 1 : 0);
253 instr = SET_IMMEDIATE.setval(instr, s.immediate & ~(-1L << DataLatch_WIDTH));
258 } else if (d instanceof Move) {
260 instr = MOVE.set(instr);
261 if (inst.tokenIn) instr = TI.set(instr);
262 if (inst.dataIn) instr = DI.set(instr);
263 if (inst.latchData) instr = DC.set(instr);
264 if (inst.dataOut) instr = DO.set(instr);
265 if (inst.tokenOut) instr = TO.set(instr);
266 if (inst.interruptible) instr = I.set(instr);
268 if (inst.latchPath) instr = PATH_DATA.set(instr);
270 instr = PATH_IMMEDIATE.set(instr);
271 instr = PATH_IMMEDIATE.setval(instr, inst.path==null?0:getDestAddr(inst.path));
275 throw new RuntimeException("unrecognized instruction " + d.getClass().getName());
281 public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException {
282 long instr = writeInstruction(d, dispatchFrom);
283 for(int i=5; i>=0; i--)
284 os.write(BitManipulations.getIntField(i*8+7, i*8, instr));
287 private static long flagFunctionToLong(FlagFunction ff) {
289 for(Predicate p : ff)
291 case FlagA : ret = SET_FLAGS_VALUE_A .set(ret); break;
292 case NotFlagA : ret = SET_FLAGS_VALUE_NOT_A.set(ret); break;
293 case FlagB : ret = SET_FLAGS_VALUE_B .set(ret); break;
294 case NotFlagB : ret = SET_FLAGS_VALUE_NOT_B.set(ret); break;
295 case FlagC : ret = SET_FLAGS_VALUE_C .set(ret); break;
296 case NotFlagC : ret = SET_FLAGS_VALUE_NOT_C.set(ret); break;
297 default: throw new RuntimeException();