1 package edu.berkeley.fleet.interpreter;
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.*;
9 /** anything that has a source (instruction horn) address on the switch fabric */
10 class InterpreterDock extends FleetTwoDock {
12 // Dock State //////////////////////////////////////////////////////////////////////////////
14 public boolean flag_a = false;
15 public boolean flag_b = false;
16 public boolean flag_c = false;
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>();
25 protected void reset() {
31 dataLatch = new BitVector(getShip().getFleet().getWordWidth());
38 // Destinations //////////////////////////////////////////////////////////////////////////////
40 /** includes the epilogue fifo */
41 public InterpreterDestination instructionDestination = new InterpreterDestination(this, true);
42 public InterpreterDestination dataDestination = new InterpreterDestination(this, false);
44 InterpreterDock(InterpreterShip ship, DockDescription bbd) {
48 public void addInstruction(Instruction i) {
49 throw new RuntimeException();
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(); }
58 // interface to subclass ///////////////////////////////////////////////////////////////////////
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(); }
72 protected final void service() {
74 if (executing==null && instructions.size() > 0) executing = instructions.remove();
75 if (executing==null) return;
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;
92 int oldLoopCounter = loopCounter;
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) {
108 } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
109 repeatCounter = ic.source;
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;
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);
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) {
133 if (!service(executing)) return;
137 if (executing==null) return;
138 if ((executing instanceof Instruction.Move) && repeatCounter > 1) {
140 } else if ((executing instanceof Instruction.Move) && repeatCounter == -1) {
142 } else if ((executing instanceof Instruction.PredicatedInstruction && ((Instruction.PredicatedInstruction)executing).looping) && oldLoopCounter > 0) {
143 addInstruction(executing);