checkpoint synthesizing
[fleet.git] / src / edu / berkeley / fleet / ies44 / InstructionEncoder.java
1 package edu.berkeley.fleet.ies44;
2 import edu.berkeley.fleet.api.*;
3 import edu.berkeley.fleet.*;
4 import java.io.*;
5 import static edu.berkeley.fleet.util.BitManipulations.*;
6
7 public abstract class InstructionEncoder {
8
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;
14
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;
18     /*
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;
22     */
23
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;
27
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;
34
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;
41
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;
48
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;
52
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;
65
66     public static final int OFFSET_LITERAL         = OFFSET_COUNT+WIDTH_COUNT;
67     public static final int WIDTH_LITERAL          = OFFSET_MASK_LITERAL - OFFSET_LITERAL;
68
69     /** get the bits describing this box's location on the DESTINATION HORN */
70     protected abstract long getDestAddr(Destination box);
71
72     /** get the bits describing this box's location on the INSTRUCTION HORN */
73     protected abstract long getBoxInstAddr(Pump box);
74
75     /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
76     protected abstract Pump getBoxByInstAddr(long dest);
77     
78     /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
79     protected abstract Destination getDestByAddr(long dest);
80
81     /** read a machine-formatted instruction from a file (into a Java object) */
82     public Instruction readInstruction(DataInputStream is) throws IOException {
83         long inst = 0;
84         try {
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) {
93             return null;
94         }
95     }
96
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         int count           = getIntField(                 OFFSET_COUNT+WIDTH_COUNT-1,         OFFSET_COUNT,     inst);
104         if (getIntField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,inst)==MASK_KILL)
105             return new Instruction.Kill(name, count);
106         Destination dest    = getDestByAddr   (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1,      OFFSET_DEST,      inst));
107         boolean tokenIn     = getBit(OFFSET_TI, inst);
108         boolean dataIn      = getBit(OFFSET_DI, inst);
109         boolean latch       = getBit(OFFSET_DL, inst);
110         boolean dataOut     = getBit(OFFSET_DO, inst);
111         boolean tokenOut    = getBit(OFFSET_TO, inst);
112         boolean requeue     = getBit(OFFSET_RQ, inst);
113         boolean ignoreUntilLast = getBit(OFFSET_IG, inst);
114         boolean dataOutDest = name.isOutbox() && dataOut && tokenOut;
115         boolean isLiteral   = getIntField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, inst)==MASK_LITERAL;
116         if (isLiteral)
117             return new Instruction.LocalLiteral(name, getSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), count);
118         if (dataOutDest) tokenOut = false;
119         return new Instruction.Move(name,
120                                     dest,
121                                     count,
122                                     tokenIn,
123                                     dataIn,
124                                     latch,
125                                     dataOutDest,
126                                     dataOut,
127                                     tokenOut,
128                                     requeue,
129                                     ignoreUntilLast);
130     }
131
132     public long writeInstruction(Instruction d) {
133         long instr = 0;
134
135         if (d.pump != null)
136             instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(d.pump));
137
138         if (d instanceof Instruction.CodeBagDescriptor) {
139             Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
140             d = new Instruction.LocalLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1);
141         }
142
143         if (d instanceof Instruction.UnClog) {
144             instr |= putField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,       MASK_UNCLOG);
145
146         } else if (d instanceof Instruction.Kill) {
147             Instruction.Kill k = (Instruction.Kill)d;
148             instr |= putField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,       MASK_KILL);
149             instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,         OFFSET_COUNT,           k.count-1);
150
151         } else if (d instanceof Instruction.Clog) {
152             instr |= putField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,       MASK_CLOG);
153
154         } else if (d instanceof Instruction.LocalLiteral) {
155             Instruction.LocalLiteral inst = (Instruction.LocalLiteral)d;
156             if (inst.pump != null) {
157                 instr |= putField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL,    MASK_LITERAL);
158                 instr |= putSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1,           OFFSET_LITERAL,         inst.literal);
159                 instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,               OFFSET_COUNT,           inst.count);
160             } else {
161                 instr = inst.literal;
162             }
163
164         } else if (d instanceof Instruction.Move) {
165             Instruction.Move inst = (Instruction.Move)d;
166             instr |= putField(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1, OFFSET_MASK_NORMAL,       MASK_NORMAL);
167             instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1,      OFFSET_DEST,        inst.dest==null?0:getDestAddr(inst.dest));
168             instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1,         OFFSET_COUNT,       inst.count);
169             instr |= putField(OFFSET_TI,                          OFFSET_TI,          inst.tokenIn?1:0);
170             instr |= putField(OFFSET_DI,                          OFFSET_DI,          inst.dataIn?1:0);
171             instr |= putField(OFFSET_DL,                          OFFSET_DL,          inst.latch?1:0);
172             instr |= putField(OFFSET_DO,                          OFFSET_DO,          (inst.dataOutDest||inst.dataOut)?1:0);
173             instr |= putField(OFFSET_TO,                          OFFSET_TO,          (inst.dataOutDest||inst.tokenOut)?1:0);
174             instr |= putField(OFFSET_RQ,                          OFFSET_RQ,          inst.requeue?1:0);
175             instr |= putField(OFFSET_IG,                          OFFSET_IG,          inst.ignoreUntilLast?1:0);
176
177         }
178         return instr;
179     }
180
181     public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
182         long instr = writeInstruction(d);
183         for(int i=5; i>=0; i--)
184             os.write(getIntField(i*8+7, i*8, instr));
185    }
186
187 }