1 package edu.berkeley.fleet.ies44;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.*;
6 public abstract class InstructionEncoder {
8 /** get the bits describing this box's location on the DESTINATION HORN */
9 protected abstract long getDestAddr(Destination box);
11 /** get the bits describing this box's location on the INSTRUCTION HORN */
12 protected abstract long getBoxInstAddr(BenkoBox box);
14 /** given an INSTRUCTION HORN address, retrieve the corresponding BenkoBox object */
15 protected abstract BenkoBox getBoxByInstAddr(long dest);
17 /** given a DESTINATION HORN address, retrieve the corresponding BenkoBox object */
18 protected abstract Destination getDestByAddr(long dest);
20 /** read a machine-formatted instruction from a file (into a Java object) */
21 public Instruction readInstruction(DataInputStream is) throws IOException {
24 inst = (inst << 8) | (is.readByte() & 0xff);
25 inst = (inst << 8) | (is.readByte() & 0xff);
26 inst = (inst << 8) | (is.readByte() & 0xff);
27 inst = (inst << 8) | (is.readByte() & 0xff);
28 inst = (inst << 8) | (is.readByte() & 0xff);
29 inst = (inst << 8) | (is.readByte() & 0xff);
30 return readInstruction(inst);
31 } catch (EOFException eof) {
36 // FIXME: use this more
37 private boolean getBit(int bit, long val) { return ((val & (1L << bit)) != 0); }
38 private long getSignedField(int highBit, int lowBit, long val) {
39 long ret = getField(highBit, lowBit, val);
40 if ((ret & (1L << ((highBit-lowBit)+1-1))) != 0)
41 ret |= 0xffffffffffffffffL << ((highBit-lowBit)+1);
44 private int getIntField(int highBit, int lowBit, long val) {
45 if (highBit-lowBit+1 > 32) throw new RuntimeException("too big!");
46 return (int)getField(highBit, lowBit, val);
48 private long getField(int highBit, int lowBit, long val) {
49 long mask = 0xffffffffffffffffL;
50 mask = mask << ((highBit-lowBit)+1);
52 mask = mask << lowBit;
53 long ret = val & mask;
58 private long doPutField(int highBit, int lowBit, long val) {
59 long mask = 0xffffffffffffffffL;
60 mask = mask << (highBit-lowBit+1);
66 private long putField(int highBit, int lowBit, long val) {
67 if (val < 0 || val >= (1L << (highBit-lowBit+1)))
68 throw new RuntimeException("bitfield width exceeded");
69 return doPutField(highBit, lowBit, val);
71 private long putSignedField(int highBit, int lowBit, long val) {
72 if (val <= (-1L * (1L << (highBit-lowBit+1-1))))
73 throw new RuntimeException("bitfield width exceeded");
74 if (val >= ( (1L << (highBit-lowBit+1-1))))
75 throw new RuntimeException("bitfield width exceeded");
76 return doPutField(highBit, lowBit, val);
79 // FIXME: parameterize stuff in this file
80 private static final int WBITS = 37; /* word width */
81 private static final int IBITS = 37; /* instruction width */
82 private static final int CODEBAG_SIZE_BITS = 6;
83 private static final int BENKOBOX_NAME_BITS = 11;
84 private static final int COUNT_BITS = 7;
85 private static final int OPCODE_BITS = 5;
87 public Instruction readInstruction(long instr) {
89 switch((int)getField(WBITS-1, WBITS-2, inst)) {
91 BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
92 Destination dest = getDestByAddr ((inst >> 1) & 0x7ff);
93 int count = getIntField(COUNT_BITS+BENKOBOX_NAME_BITS+1-1, BENKOBOX_NAME_BITS+1, instr);
94 boolean tokenIn = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+0, instr);
95 boolean dataIn = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+1, instr);
96 boolean latch = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+2, instr);
97 boolean dataOut = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+3, instr);
98 boolean tokenOut = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+4, instr);
99 boolean recycle = getBit(0, instr);
100 if (latch & !dataIn) return new Instruction.Kill(name, count, tokenIn);
101 return new Instruction.Executable(name, dest, count, tokenIn, dataIn,
102 latch, dataOut, tokenOut, recycle);
106 Destination name = getDestByAddr(getField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, inst));
107 long offset = getSignedField(WBITS-3-BENKOBOX_NAME_BITS, CODEBAG_SIZE_BITS, instr);
108 long size = getSignedField(CODEBAG_SIZE_BITS-1, 0, instr);
109 return new Instruction.Literal.CodeBagDescriptor(name, offset, size);
113 Destination name = getDestByAddr(getField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, inst));
114 return new Instruction.Literal.Absolute(name, getSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, instr));
118 Destination name = getDestByAddr(getField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, inst));
119 return new Instruction.Literal.Relative(name, getSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, instr));
127 public long writeInstruction(Instruction d) {
130 // Kill is encoded as Execute with the illegal combination (Latch & ~DataIn)
131 if (d instanceof Instruction.Kill) {
132 Instruction.Kill k = (Instruction.Kill)d;
133 d = new Instruction.Executable(k.benkoBox, null, k.count, k.killOnlyStandingInstructions,
134 false, true, false, false, false);
137 if (d instanceof Instruction.Executable) {
138 Instruction.Executable inst = (Instruction.Executable)d;
139 if (inst.dest != null)
140 instr |= putField(BENKOBOX_NAME_BITS, 1, getDestAddr(inst.dest));
141 instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1-1, BENKOBOX_NAME_BITS+1, inst.count);
142 instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+0, COUNT_BITS+BENKOBOX_NAME_BITS+1+0, inst.tokenIn ? 1 : 0);
143 instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+1, COUNT_BITS+BENKOBOX_NAME_BITS+1+1, inst.dataIn ? 1 : 0);
144 instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+2, COUNT_BITS+BENKOBOX_NAME_BITS+1+2, inst.latch ? 1 : 0);
145 instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+3, COUNT_BITS+BENKOBOX_NAME_BITS+1+3, inst.dataOut ? 1 : 0);
146 instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+4, COUNT_BITS+BENKOBOX_NAME_BITS+1+4, inst.tokenOut ? 1 : 0);
147 instr |= putField(0, 0, inst.recycle ? 1 : 0);
148 instr |= putField(BENKOBOX_NAME_BITS+OPCODE_BITS+COUNT_BITS+BENKOBOX_NAME_BITS+1-1,
149 OPCODE_BITS+COUNT_BITS+BENKOBOX_NAME_BITS+1,
150 getBoxInstAddr(inst.benkoBox));
152 } else if (d instanceof Instruction.Literal.CodeBagDescriptor) {
153 Instruction.Literal.CodeBagDescriptor lc = (Instruction.Literal.CodeBagDescriptor)d;
154 instr = putField(WBITS-1, WBITS-2, 1);
155 if (lc.dest != null) instr |= putField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, getDestAddr(lc.dest));
156 instr |= putSignedField(WBITS-3-BENKOBOX_NAME_BITS, CODEBAG_SIZE_BITS, lc.offset);
157 instr |= putField(CODEBAG_SIZE_BITS-1, 0, lc.size);
159 } else if (d instanceof Instruction.Literal.Absolute) {
160 Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
161 instr = putField(WBITS-1, WBITS-2, 2);
162 instr |= putField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, getDestAddr(ld.dest));
163 instr |= putSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, ld.value);
165 } else if (d instanceof Instruction.Literal.Relative) {
166 Instruction.Literal.Relative lr = (Instruction.Literal.Relative)d;
167 instr = putField(WBITS-1, WBITS-2, 3);
168 instr |= putField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, getDestAddr(lr.dest));
169 instr |= putSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, lr.offset);
175 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
176 long instr = writeInstruction(d);
177 for(int i=5; i>=0; i--)
178 os.write(getIntField(i*8+7, i*8, instr));