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 public abstract long getBoxAddr(BenkoBox box);
11 /** get the bits describing this box's location on the INSTRUCTION HORN */
12 public abstract long getBoxInstAddr(BenkoBox box);
14 /** given a DESTINATION HORN address, retrieve the corresponding BenkoBox object */
15 public abstract BenkoBox getBoxByAddr(long dest);
17 /** given an INSTRUCTION HORN address, retrieve the corresponding BenkoBox object */
18 public abstract BenkoBox getBoxByInstAddr(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 public Instruction readInstruction(long instr) {
38 long head = inst & (0x3L << (24+11));
39 head = head >> (24+11);
42 BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
43 BenkoBox dest = getBoxByAddr ((inst >> 1) & 0x7ff);
44 int count = ((int)(instr >> 12)) & 0x7f;
45 boolean tokenIn = (instr & (1L << (11+1+7+0))) != 0;
46 boolean dataIn = ( instr & (1L << (11+1+7+1))) != 0;
47 boolean latch = ( instr & (1L << (11+1+7+2))) != 0;
48 boolean dataOut = (instr & (1L << (11+1+7+3))) != 0;
49 boolean tokenOut = (instr & (1L << (11+1+7+4))) != 0;
50 boolean recycle = (instr & (1L)) != 0;
51 if (latch & !dataIn) return new Instruction.Kill(name, count, tokenIn);
52 return new Instruction.Executable(name, dest, count, tokenIn, dataIn,
53 latch, dataOut, tokenOut, recycle);
57 BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
58 int offset = ((int)(instr >> 6)) & ~(0xffffffff << 18);
59 if ((offset & (1<<17)) != 0) offset |= (0xffffffff << 18);
60 int size = ((int)(instr )) & ~(0xffffffff << 6);
61 return new Instruction.Literal.CodeBagDescriptor(name, offset, size);
65 BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
66 int val = ((int)(instr )) & ~(0xffffffff << 24);
67 return new Instruction.Literal.Absolute(name, val);
71 BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
72 int val = ((int)(instr )) & ~(0xffffffff << 24);
73 return new Instruction.Literal.Relative(name, val);
81 public long writeInstruction(Instruction d) {
84 // Kill is encoded as Execute with the illegal combination (Latch & ~DataIn)
85 if (d instanceof Instruction.Kill) {
86 Instruction.Kill k = (Instruction.Kill)d;
87 d = new Instruction.Executable(k.benkoBox, null, k.count, k.killOnlyStandingInstructions,
88 false, true, false, false, false);
91 if (d instanceof Instruction.Executable) {
92 Instruction.Executable inst = (Instruction.Executable)d;
93 BenkoBox dest = inst.dest;
94 instr = dest==null ? 0 : (getBoxAddr(dest) << 1);
95 if (inst.count >= (1<<8))
96 throw new RuntimeException("count field must be less than 128");
97 instr |= (((long)inst.count) << (11+1));
98 if (inst.tokenIn) instr |= (1L << (11+1+7+0));
99 if (inst.dataIn) instr |= (1L << (11+1+7+1));
100 if (inst.latch) instr |= (1L << (11+1+7+2));
101 if (inst.dataOut) instr |= (1L << (11+1+7+3));
102 if (inst.tokenOut) instr |= (1L << (11+1+7+4));
103 if (inst.recycle) instr |= (1L);
104 instr |= (getBoxInstAddr(inst.benkoBox) << (11+5+7+1));
106 } else if (d instanceof Instruction.Literal.CodeBagDescriptor) {
107 Instruction.Literal.CodeBagDescriptor lc = (Instruction.Literal.CodeBagDescriptor)d;
108 instr = (1L << (11+24));
110 instr |= (getBoxAddr(lc.dest)) << 24;
111 if (lc.size >= (1<<6))
112 throw new RuntimeException("codebag sizes must be less than 2^6");
113 if (lc.offset >= (1<<17) || lc.offset <= (-1 * (1<<17)))
114 throw new RuntimeException("codebag offsets must be in the range -(2^17)..2^17");
115 int off = (int)lc.offset;
116 off &= ~(0xffffffff << 18);
118 instr |= (((long)lc.size));
120 } else if (d instanceof Instruction.Literal.Absolute) {
121 Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
122 instr = (2L << (11+24));
123 instr |= (getBoxAddr(ld.dest)) << 24;
124 if (ld.value >= (1<<25))
125 throw new RuntimeException("literals must be less than 2^24");
126 instr |= ((long)ld.value);
128 } else if (d instanceof Instruction.Literal.Relative) {
129 Instruction.Literal.Relative lr = (Instruction.Literal.Relative)d;
130 instr = (3L << (11+24));
131 instr |= (getBoxAddr(lr.dest)) << 24;
132 if (lr.offset >= (1<<25))
133 throw new RuntimeException("literals must be less than 2^24");
134 instr |= ((long)lr.offset);
140 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
141 long instr = writeInstruction(d);
142 os.write((int)((instr >> (5*8)) & 0xff));
143 os.write((int)((instr >> (4*8)) & 0xff));
144 os.write((int)((instr >> (3*8)) & 0xff));
145 os.write((int)((instr >> (2*8)) & 0xff));
146 os.write((int)((instr >> (1*8)) & 0xff));
147 os.write((int)((instr >> (0*8)) & 0xff));