1 package edu.berkeley.fleet.ies44;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.*;
4 import edu.berkeley.fleet.util.*;
6 import static edu.berkeley.fleet.util.BitManipulations.*;
7 import static edu.berkeley.fleet.api.Instruction.*;
8 import static edu.berkeley.fleet.api.Instruction.Counter.*;
10 public abstract class InstructionEncoder {
12 public static final int WIDTH_WORD = 37;
13 public static final int WIDTH_ADDR = 11;
14 public static final int WIDTH_CODEBAG_SIZE = 6;
15 public static final int WIDTH_COUNTER_LITERAL = 6;
17 public static final Mask REPEAT_FROM_DATA = new Mask("...............000001.........0......");
18 public static final Mask REPEAT_FROM_LITERAL = new Mask("...............000001.........1vvvvvv");
19 public static final Mask LOOP_FROM_DATA = new Mask("...............000010.........0......");
20 public static final Mask LOOP_FROM_LITERAL = new Mask("...............000010.........1vvvvvv");
21 public static final Mask TAKE_LOOP = new Mask("...............000011................");
22 public static final Mask KILL = new Mask("...............000100..........vvvvvv");
23 public static final Mask MASSACRE = new Mask("...............000101................");
24 public static final Mask CLOG = new Mask("...............000110................");
25 public static final Mask UNCLOG = new Mask("...............000111................");
27 public static final Mask SK = new Mask("...........1.........................");
28 public static final Mask DL = new Mask("............1........................");
29 public static final Mask P = new Mask(".............vv......................");
30 public static final Mask MOVE = new Mask("...............001...................");
31 public static final Mask STAND = new Mask("...................1.................");
32 public static final Mask TI = new Mask("....................1................");
33 public static final Mask DI = new Mask(".....................1...............");
34 public static final Mask DC = new Mask("......................1..............");
35 public static final Mask DO = new Mask(".......................1.............");
36 public static final Mask TO = new Mask("........................1............");
37 public static final Mask PATH_LITERAL = new Mask(".........................1vvvvvvvvvvv");
38 public static final Mask PATH_DATA = new Mask(".........................01..........");
39 public static final Mask PATH_NOCHANGE = new Mask(".........................00..........");
41 public static final Mask LITERAL_LO = new Mask("...............010vvvvvvvvvvvvvvvvvvv");
42 public static final Mask LITERAL_HI = new Mask("...............011vvvvvvvvvvvvvvvvvvv");
43 public static final Mask LITERAL = new Mask("...............1..vvvvvvvvvvvvvvvvvvv");
44 public static final Mask LITERAL_SEL = new Mask("................vv...................");
45 public static final Mask PUMP_NAME = new Mask("vvvvvvvvvvv..........................");
48 /** get the bits describing this box's location on the DESTINATION HORN */
49 protected abstract long getDestAddr(Destination box);
51 /** get the bits describing this box's location on the INSTRUCTION HORN */
52 protected abstract long getBoxInstAddr(Pump box);
54 /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
55 protected abstract Pump getBoxByInstAddr(long dest);
57 /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
58 protected abstract Destination getDestByAddr(long dest);
60 /** read a machine-formatted instruction from a file (into a Java object) */
61 public Instruction readInstruction(DataInputStream is) throws IOException {
64 inst = (inst << 8) | (is.readByte() & 0xff);
65 inst = (inst << 8) | (is.readByte() & 0xff);
66 inst = (inst << 8) | (is.readByte() & 0xff);
67 inst = (inst << 8) | (is.readByte() & 0xff);
68 inst = (inst << 8) | (is.readByte() & 0xff);
69 inst = (inst << 8) | (is.readByte() & 0xff);
70 return readInstruction(inst);
71 } catch (EOFException eof) {
76 public Instruction readInstruction(long inst) {
77 Pump name = getBoxByInstAddr(PUMP_NAME.getval(inst));
79 if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER);
80 if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
81 if (LOOP_FROM_DATA.get(inst)) return new Counter(name, DATA_LATCH, LOOP_COUNTER);
82 if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, DATA_LATCH, REPEAT_COUNTER);
83 if (TAKE_LOOP.get(inst)) return new Counter(name, LOOP_COUNTER, DATA_LATCH);
85 if (DL.get(inst)) return new Instruction.DecrLoop(name);
87 if (UNCLOG.get(inst)) return new Instruction.UnClog(name);
88 if (CLOG.get(inst)) return new Instruction.Clog(name);
89 if (MASSACRE.get(inst)) return new Instruction.Massacre(name);
90 if (KILL.get(inst)) return new Instruction.Kill(name, (int)(KILL.getval(inst)+1));
91 if (LITERAL_LO.get(inst)) return new Instruction.HalfLiteral(name, LITERAL_LO.getval(inst), 0, false);
92 if (LITERAL_HI.get(inst)) return new Instruction.HalfLiteral(name, LITERAL_HI.getval(inst), 0, true);
94 Destination dest = getDestByAddr(PATH_LITERAL.getval(inst));
95 boolean tokenIn = TI.get(inst);
96 boolean dataIn = DI.get(inst);
97 boolean latch = DC.get(inst);
98 boolean dataOut = DO.get(inst);
99 boolean tokenOut = TO.get(inst);
100 boolean standing = STAND.get(inst);
101 boolean dataOutDest = PATH_DATA.get(inst);
102 return new Instruction.Move(name,
115 public long writeInstruction(Instruction d) {
119 instr = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump));
121 if (d instanceof Instruction.CodeBagDescriptor) {
122 Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
123 // MAJOR MAJOR FIXME: upper half here...
124 d = new Instruction.HalfLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
127 if (d instanceof Instruction.UnClog) {
128 instr = UNCLOG.set(instr);
130 } else if (d instanceof Instruction.Kill) {
131 Instruction.Kill k = (Instruction.Kill)d;
132 instr = KILL.set(instr);
133 instr = KILL.setval(instr, k.count);
135 } else if (d instanceof Instruction.Clog) {
136 instr = CLOG.set(instr);
138 } else if (d instanceof Instruction.Massacre) {
139 instr = MASSACRE.set(instr);
141 } else if (d instanceof Instruction.HalfLiteral) {
142 Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
143 if (inst.pump != null) {
145 instr = LITERAL_HI.set(instr);
146 instr = LITERAL_HI.setval(instr, inst.literal);
148 instr = LITERAL_LO.set(instr);
149 instr = LITERAL_LO.setval(instr, inst.literal);
152 instr = inst.literal;
155 } else if (d instanceof Instruction.DecrLoop) {
156 instr = DL.set(instr);
158 } else if (d instanceof Instruction.Counter) {
159 Instruction.Counter ic = (Instruction.Counter)d;
160 if (ic.dest == DATA_LATCH && ic.source == LOOP_COUNTER) instr = TAKE_LOOP.set(instr);
161 else if (ic.dest == REPEAT_COUNTER && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
162 else if (ic.dest == LOOP_COUNTER && ic.source == DATA_LATCH) instr = LOOP_FROM_DATA.set(instr);
163 else if (ic.dest == REPEAT_COUNTER) instr = REPEAT_FROM_LITERAL.setval(REPEAT_FROM_LITERAL.set(instr), ic.source);
164 else if (ic.dest == LOOP_COUNTER) instr = LOOP_FROM_LITERAL.setval(LOOP_FROM_LITERAL.set(instr), ic.source);
165 else throw new RuntimeException();
167 } else if (d instanceof Instruction.Move) {
168 Instruction.Move inst = (Instruction.Move)d;
169 instr = MOVE.set(instr);
170 if (inst.tokenIn) instr = TI.set(instr);
171 if (inst.dataIn) instr = DI.set(instr);
172 if (inst.latch) instr = DC.set(instr);
173 if (inst.dataOut) instr = DO.set(instr);
174 if (inst.tokenOut) instr = TO.set(instr);
175 if (inst.dataOutDest) instr = PATH_DATA.set(instr);
177 instr = PATH_LITERAL.set(instr);
178 instr = PATH_LITERAL.setval(instr, inst.dest==null?0:getDestAddr(inst.dest));
180 if (inst.standing) instr = STAND.set(instr);
186 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
187 long instr = writeInstruction(d);
188 for(int i=5; i>=0; i--)
189 os.write(getIntField(i*8+7, i*8, instr));