1 package edu.berkeley.fleet.ies44;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.*;
5 import static edu.berkeley.fleet.util.BitManipulations.*;
7 public abstract class InstructionEncoder {
9 public static final int WIDTH_WORD = 37; /* word width */
10 public static final int WIDTH_CODEBAG_SIZE = 6;
11 public static final int WIDTH_PUMP_ADDR = 11;
12 public static final int WIDTH_DEST_ADDR = 11;
13 public static final int WIDTH_COUNT = 7;
15 public static final int OFFSET_MASK_LITERAL = 24;
16 public static final int WIDTH_MASK_LITERAL = 2;
17 public static final int MASK_LITERAL = 1;
19 public static final int OFFSET_MASK_LITERAL = 20;
20 public static final int WIDTH_MASK_LITERAL = 6;
21 public static final int MASK_LITERAL = 13;
24 public static final int OFFSET_MASK_MASSACRE = 14;
25 public static final int WIDTH_MASK_MASSACRE = 26-14;
26 public static final int MASK_MASSACRE = 1;
28 //public static final int OFFSET_MASK_KILL = 21;
29 //public static final int WIDTH_MASK_KILL = 5;
30 //public static final int MASK_KILL = 5;
31 public static final int OFFSET_MASK_KILL = 14;
32 public static final int WIDTH_MASK_KILL = 26-14;
33 public static final int MASK_KILL = 0;
35 //public static final int OFFSET_MASK_UNCLOG = 21;
36 //public static final int WIDTH_MASK_UNCLOG = 5;
37 //public static final int MASK_UNCLOG = 2;
38 public static final int OFFSET_MASK_UNCLOG = 14;
39 public static final int WIDTH_MASK_UNCLOG = 26-14;
40 public static final int MASK_UNCLOG = 3;
42 //public static final int OFFSET_MASK_CLOG = 21;
43 //public static final int WIDTH_MASK_CLOG = 5;
44 //public static final int MASK_CLOG = 4;
45 public static final int OFFSET_MASK_CLOG = 14;
46 public static final int WIDTH_MASK_CLOG = 26-14;
47 public static final int MASK_CLOG = 2;
49 public static final int OFFSET_MASK_NORMAL = 25;
50 public static final int WIDTH_MASK_NORMAL = 1;
51 public static final int MASK_NORMAL = 1;
53 public static final int OFFSET_COUNT = 0;
54 public static final int OFFSET_DEST = OFFSET_COUNT+WIDTH_COUNT;
55 public static final int OFFSET_CONTROL = OFFSET_DEST+WIDTH_DEST_ADDR;
56 public static final int OFFSET_RQ = OFFSET_CONTROL+0;
57 public static final int OFFSET_IG = OFFSET_CONTROL+1;
58 public static final int OFFSET_TO = OFFSET_CONTROL+2;
59 public static final int OFFSET_DO = OFFSET_CONTROL+3;
60 public static final int OFFSET_DL = OFFSET_CONTROL+4;
61 public static final int OFFSET_DI = OFFSET_CONTROL+5;
62 public static final int OFFSET_TI = OFFSET_CONTROL+6;
63 public static final int OFFSET_INSTRUCTIONTYPE = OFFSET_CONTROL+7;
64 public static final int OFFSET_PUMP_ADDR = OFFSET_INSTRUCTIONTYPE+1;
66 public static final int OFFSET_LITERAL = OFFSET_COUNT+WIDTH_COUNT;
67 public static final int WIDTH_LITERAL = OFFSET_MASK_LITERAL - OFFSET_LITERAL;
69 /** get the bits describing this box's location on the DESTINATION HORN */
70 protected abstract long getDestAddr(Destination box);
72 /** get the bits describing this box's location on the INSTRUCTION HORN */
73 protected abstract long getBoxInstAddr(Pump box);
75 /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
76 protected abstract Pump getBoxByInstAddr(long dest);
78 /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
79 protected abstract Destination getDestByAddr(long dest);
81 /** read a machine-formatted instruction from a file (into a Java object) */
82 public Instruction readInstruction(DataInputStream is) throws IOException {
85 inst = (inst << 8) | (is.readByte() & 0xff);
86 inst = (inst << 8) | (is.readByte() & 0xff);
87 inst = (inst << 8) | (is.readByte() & 0xff);
88 inst = (inst << 8) | (is.readByte() & 0xff);
89 inst = (inst << 8) | (is.readByte() & 0xff);
90 inst = (inst << 8) | (is.readByte() & 0xff);
91 return readInstruction(inst);
92 } catch (EOFException eof) {
97 public Instruction readInstruction(long inst) {
98 Pump name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
99 if (getIntField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,inst)==MASK_UNCLOG)
100 return new Instruction.UnClog(name);
101 if (getIntField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,inst)==MASK_CLOG)
102 return new Instruction.Clog(name);
103 if (getIntField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE,inst)==MASK_MASSACRE)
104 return new Instruction.Massacre(name);
105 int count = getIntField( OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst);
106 if (getIntField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,inst)==MASK_KILL)
107 return new Instruction.Kill(name, count);
108 Destination dest = getDestByAddr (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst));
109 boolean tokenIn = getBit(OFFSET_TI, inst);
110 boolean dataIn = getBit(OFFSET_DI, inst);
111 boolean latch = getBit(OFFSET_DL, inst);
112 boolean dataOut = getBit(OFFSET_DO, inst);
113 boolean tokenOut = getBit(OFFSET_TO, inst);
114 boolean requeue = getBit(OFFSET_RQ, inst);
115 boolean ignoreUntilLast = getBit(OFFSET_IG, inst);
116 boolean dataOutDest = name.isOutbox() && dataOut && tokenOut;
117 boolean isLiteral = getIntField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, inst)==MASK_LITERAL;
119 return new Instruction.LocalLiteral(name, getSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), 0);
120 if (dataOutDest) tokenOut = false;
121 return new Instruction.Move(name,
134 public long writeInstruction(Instruction d) {
138 instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(d.pump));
140 if (d instanceof Instruction.CodeBagDescriptor) {
141 Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
142 d = new Instruction.LocalLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1);
145 if (d instanceof Instruction.UnClog) {
146 instr |= putField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG, MASK_UNCLOG);
148 } else if (d instanceof Instruction.Kill) {
149 Instruction.Kill k = (Instruction.Kill)d;
150 instr |= putField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL, MASK_KILL);
151 instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, k.count-1);
153 } else if (d instanceof Instruction.Clog) {
154 instr |= putField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG, MASK_CLOG);
156 } else if (d instanceof Instruction.Massacre) {
157 instr |= putField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE, MASK_MASSACRE);
159 } else if (d instanceof Instruction.LocalLiteral) {
160 Instruction.LocalLiteral inst = (Instruction.LocalLiteral)d;
161 if (inst.pump != null) {
162 instr |= putField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, MASK_LITERAL);
163 instr |= putSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst.literal);
165 //instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
167 instr = inst.literal;
170 } else if (d instanceof Instruction.Move) {
171 Instruction.Move inst = (Instruction.Move)d;
172 instr |= putField(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1, OFFSET_MASK_NORMAL, MASK_NORMAL);
173 instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst.dest==null?0:getDestAddr(inst.dest));
174 instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
175 instr |= putField(OFFSET_TI, OFFSET_TI, inst.tokenIn?1:0);
176 instr |= putField(OFFSET_DI, OFFSET_DI, inst.dataIn?1:0);
177 instr |= putField(OFFSET_DL, OFFSET_DL, inst.latch?1:0);
178 instr |= putField(OFFSET_DO, OFFSET_DO, (inst.dataOutDest||inst.dataOut)?1:0);
179 instr |= putField(OFFSET_TO, OFFSET_TO, (inst.dataOutDest||inst.tokenOut)?1:0);
180 instr |= putField(OFFSET_RQ, OFFSET_RQ, inst.requeue?1:0);
181 instr |= putField(OFFSET_IG, OFFSET_IG, inst.ignoreUntilLast?1:0);
187 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
188 long instr = writeInstruction(d);
189 for(int i=5; i>=0; i--)
190 os.write(getIntField(i*8+7, i*8, instr));