first pass overhaul of interpreter; still does not work
[fleet.git] / src / edu / berkeley / fleet / interpreter / InterpreterDock.java
1 package edu.berkeley.fleet.interpreter;
2 import java.util.*;
3 import edu.berkeley.sbp.util.ANSI;
4 import edu.berkeley.fleet.two.*;
5 import edu.berkeley.fleet.api.*;
6 import edu.berkeley.fleet.api.Instruction;
7 import static edu.berkeley.fleet.api.Predicate.*;
8
9 /** anything that has a source (instruction horn) address on the switch fabric */
10 class InterpreterDock extends FleetTwoDock {
11
12     // Dock State //////////////////////////////////////////////////////////////////////////////
13     
14     public boolean flag_a = false;
15     public boolean flag_b = false;
16     public boolean flag_c = false;
17     public int ilc = 1;
18     public int olc = 1;
19     public BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth());
20     public InterpreterPath pathLatch = null;
21     public boolean hatchIsOpen = true;
22     private Instruction executing = null;
23     private Queue<Instruction> instructions = new LinkedList<Instruction>();
24
25     protected void reset() {
26         ilc = 1;
27         olc = 1;
28         flag_a = false;
29         flag_b = false;
30         flag_c = false;
31         dataLatch = new BitVector(getShip().getFleet().getWordWidth());
32         pathLatch = null;
33         hatchIsOpen = true;
34         executing = null;
35         instructions.clear();
36     }
37
38     // Destinations //////////////////////////////////////////////////////////////////////////////
39
40     /** includes the epilogue fifo */
41     public InterpreterDestination instructionDestination = new InterpreterDestination(this, true);
42     public InterpreterDestination dataDestination = new InterpreterDestination(this, false);
43
44     InterpreterDock(InterpreterShip ship, DockDescription bbd) {
45         super(ship, bbd);
46     }
47
48     public void addInstruction(Instruction i) {
49         throw new RuntimeException();
50     }
51
52     public Path getPath(Destination d, BitVector signal) { return new InterpreterPath(this, (InterpreterDestination)d, signal); }
53     public Destination getInstructionDestination() { return instructionDestination; }
54     public Destination getDataDestination() { return dataDestination; }
55     public int getInstructionFifoSize() { return Integer.MAX_VALUE; }
56     public Interpreter getInterpreter() { return ((InterpreterShip)getShip()).getInterpreter(); }
57
58     // interface to subclass ///////////////////////////////////////////////////////////////////////
59
60     /** this will be invoked periodically; should return true to "consume" an instruction, false to leave it executing */
61     protected void setDataLatch(long value) { throw new RuntimeException(); }
62     protected long peekDataLatch() { throw new RuntimeException(); }
63     public boolean dataReadyForShip()            { throw new RuntimeException(); }
64     public Packet removePacketForShip()          { throw new RuntimeException(); }
65     public Packet peekPacketForShip()            { throw new RuntimeException(); }
66     public long removeDataForShip()              { throw new RuntimeException(); }
67     public final boolean readyForDataFromShip() { throw new RuntimeException(); }
68     public       void addDataFromShip(long data) { throw new RuntimeException(); }
69     public       void addDataFromFabric(Packet packet) { throw new RuntimeException(); }
70     protected final void addItemFromShip(long data) { throw new RuntimeException(); }
71
72     protected final void service() {
73             /*
74         if (executing==null && instructions.size() > 0) executing = instructions.remove();
75         if (executing==null) return;
76
77         boolean enabled = true;
78         if (executing instanceof Instruction.PredicatedInstruction) {
79             Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing;
80             switch(ip.predicate) {
81                 case IgnoreOLC:      enabled = true; break;
82                 case Default:  enabled = loopCounter!=0; break;
83                 case FlagA:   enabled = flag_a; break;
84                 case FlagB:   enabled = flag_b; break;
85                     //case FlagC:   enabled = ; break;
86                 case NotFlagA:   enabled = !flag_a; break;
87                 case NotFlagB:   enabled = !flag_b; break;
88                     //case NotFlagC:   enabled = loopCounter==0; break;
89             }
90         }
91
92         int oldLoopCounter = loopCounter;
93         if (enabled) {
94             if (executing instanceof Instruction.Set.OLC.Decrement) loopCounter = Math.max(0, loopCounter-1);
95             if (executing instanceof Instruction.Counter) {
96                 Instruction.Counter ic = (Instruction.Counter)executing;
97                 if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) {
98                     setDataLatch(oldLoopCounter); // FIXME: which is correct here?
99                 } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
100                     loopCounter = (int)peekDataLatch();
101                 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) {
102                     // FIXME: is there any way to load the "standing" value?
103                     repeatCounter = (int)peekDataLatch();
104                 } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
105                     loopCounter = ic.source;
106                 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source==Instruction.Counter.STANDING) {
107                     repeatCounter = -1;
108                 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
109                     repeatCounter = ic.source;
110                 }
111
112                 } else if (executing instanceof Instruction.Set.Flags) {
113                 Instruction.Set.Flags sf = (Instruction.Set.Flags)executing;
114                 boolean old_c = oldLoopCounter == 0;
115                 boolean old_a = flag_a;
116                 boolean old_b = flag_b;
117                 flag_a =
118                     (((sf.flag_a & sf.FLAG_A)     != 0) ?  old_a : false) |
119                     (((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
120                     (((sf.flag_a & sf.FLAG_B)     != 0) ?  old_b : false) |
121                     (((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
122                     (((sf.flag_a & sf.FLAG_C)     != 0) ?  old_c : false) |
123                     (((sf.flag_a & sf.FLAG_NOT_C) != 0) ? !old_c : false);
124                 flag_b =
125                     (((sf.flag_b & sf.FLAG_A)     != 0) ?  old_a : false) |
126                     (((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
127                     (((sf.flag_b & sf.FLAG_B)     != 0) ?  old_b : false) |
128                     (((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
129                     (((sf.flag_b & sf.FLAG_C)     != 0) ?  old_c : false) |
130                     (((sf.flag_b & sf.FLAG_NOT_C) != 0) ? !old_c : false);
131             } else if (executing instanceof Instruction.Set.OLC.Decrement) {
132             } else {
133                 if (!service(executing)) return;
134             }
135         }
136
137         if (executing==null) return;
138         if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
139             repeatCounter--;
140         } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
141             // repeat
142         } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
143             addInstruction(executing);
144             executing = null;
145         } else {
146             executing = null;
147         }
148             */
149     }
150 }