1 package edu.berkeley.fleet.ies44;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.*;
5 import static edu.berkeley.fleet.ies44.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_COUNT = 0;
16 public static final int OFFSET_DEST = OFFSET_COUNT+WIDTH_COUNT;
17 public static final int OFFSET_CONTROL = OFFSET_DEST+WIDTH_DEST_ADDR;
18 public static final int OFFSET_RQ = OFFSET_CONTROL+0;
19 public static final int OFFSET_TO = OFFSET_CONTROL+1;
20 public static final int OFFSET_DO = OFFSET_CONTROL+2;
21 public static final int OFFSET_DL = OFFSET_CONTROL+3;
22 public static final int OFFSET_DI = OFFSET_CONTROL+4;
23 public static final int OFFSET_TI = OFFSET_CONTROL+5;
24 public static final int OFFSET_PUMP_ADDR = OFFSET_TI+1;
26 /** get the bits describing this box's location on the DESTINATION HORN */
27 protected abstract long getDestAddr(Destination box);
29 /** get the bits describing this box's location on the INSTRUCTION HORN */
30 protected abstract long getBoxInstAddr(Pump box);
32 /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
33 protected abstract Pump getBoxByInstAddr(long dest);
35 /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
36 protected abstract Destination getDestByAddr(long dest);
38 /** read a machine-formatted instruction from a file (into a Java object) */
39 public Instruction readInstruction(DataInputStream is) throws IOException {
42 inst = (inst << 8) | (is.readByte() & 0xff);
43 inst = (inst << 8) | (is.readByte() & 0xff);
44 inst = (inst << 8) | (is.readByte() & 0xff);
45 inst = (inst << 8) | (is.readByte() & 0xff);
46 inst = (inst << 8) | (is.readByte() & 0xff);
47 inst = (inst << 8) | (is.readByte() & 0xff);
48 return readInstruction(inst);
49 } catch (EOFException eof) {
54 public Instruction readInstruction(long instr) {
56 switch((int)getField(WIDTH_WORD-1, WIDTH_WORD-2, inst)) {
58 Pump name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
59 Destination dest = getDestByAddr (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst));
60 int count = getIntField( OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst);
61 boolean tokenIn = getBit(OFFSET_TI, instr);
62 boolean dataIn = getBit(OFFSET_DI, instr);
63 boolean latch = getBit(OFFSET_DL, instr);
64 boolean dataOut = getBit(OFFSET_DO, instr);
65 boolean tokenOut = getBit(OFFSET_TO, instr);
66 boolean requeue = getBit(OFFSET_RQ, instr);
67 boolean dataOutDest = dataOut && tokenOut;
68 if (latch & !dataIn) return new Instruction.Kill(name, count, tokenIn);
69 return new Instruction.Executable(name, dest, count, tokenIn, dataIn, latch, dataOutDest,
70 dataOut, tokenOut, requeue);
74 Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, inst));
75 long offset = getSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, WIDTH_CODEBAG_SIZE, instr);
76 long size = getSignedField(WIDTH_CODEBAG_SIZE-1, 0, instr);
77 return new Instruction.Literal.CodeBagDescriptor(name, offset, size);
81 Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_PUMP_ADDR+1, inst));
82 return new Instruction.Literal.Absolute(name, getSignedField(WIDTH_WORD-3-WIDTH_PUMP_ADDR, 0, instr));
86 Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_PUMP_ADDR+1, inst));
87 return new Instruction.Literal.Relative(name, getSignedField(WIDTH_WORD-3-WIDTH_PUMP_ADDR, 0, instr));
95 public long writeInstruction(Instruction d) {
98 // Kill is encoded as Execute with the illegal combination (Latch & ~DataIn)
99 if (d instanceof Instruction.Kill) {
100 Instruction.Kill k = (Instruction.Kill)d;
101 d = new Instruction.Executable(k.pump, null, k.count, k.killOnlyStandingInstructions,
102 false, true, false, false, false, false);
105 if (d instanceof Instruction.Executable) {
106 Instruction.Executable inst = (Instruction.Executable)d;
107 instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(inst.pump));
108 instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst.dest==null?0:getDestAddr(inst.dest));
109 instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
110 instr |= putField(OFFSET_TI, OFFSET_TI, inst.tokenIn?1:0);
111 instr |= putField(OFFSET_DI, OFFSET_DI, inst.dataIn?1:0);
112 instr |= putField(OFFSET_DL, OFFSET_DL, inst.latch?1:0);
113 instr |= putField(OFFSET_DO, OFFSET_DO, (inst.dataOutDest||inst.dataOut)?1:0);
114 instr |= putField(OFFSET_TO, OFFSET_TO, (inst.dataOutDest||inst.tokenOut)?1:0);
115 instr |= putField(OFFSET_RQ, OFFSET_RQ, inst.requeue?1:0);
117 } else if (d instanceof Instruction.Literal.CodeBagDescriptor) {
118 Instruction.Literal.CodeBagDescriptor lc = (Instruction.Literal.CodeBagDescriptor)d;
119 instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 1);
120 if (lc.dest != null) instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(lc.dest));
121 instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, WIDTH_CODEBAG_SIZE, lc.offset);
122 instr |= putField(WIDTH_CODEBAG_SIZE-1, 0, lc.size);
124 } else if (d instanceof Instruction.Literal.Absolute) {
125 Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
126 instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 2);
127 instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(ld.dest));
128 instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, 0, ld.value);
130 } else if (d instanceof Instruction.Literal.Relative) {
131 Instruction.Literal.Relative lr = (Instruction.Literal.Relative)d;
132 instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 3);
133 instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(lr.dest));
134 instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, 0, lr.offset);
140 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
141 long instr = writeInstruction(d);
142 for(int i=5; i>=0; i--)
143 os.write(getIntField(i*8+7, i*8, instr));