From 975cc53ac1e9da871d960f029e759ed05387df6c Mon Sep 17 00:00:00 2001 From: megacz Date: Thu, 8 Jan 2009 13:14:28 -0800 Subject: [PATCH] overhaul of interpreter, update ships to match; "make test" works now --- ships/Alu.ship | 30 +- ships/CarrySaveAdder.ship | 34 +- ships/Counter.ship | 65 ++- ships/DDR2.ship | 1 + ships/DRAM.ship | 1 + ships/Memory.ship | 57 +-- ships/Rotator.ship | 3 +- ships/Video.ship | 1 + src/edu/berkeley/fleet/interpreter/DebugDock.java | 12 +- .../berkeley/fleet/interpreter/Interpreter.java | 52 ++- .../fleet/interpreter/InterpreterDock.java | 419 +++++++++----------- .../fleet/interpreter/InterpreterShip.java | 23 ++ 12 files changed, 402 insertions(+), 296 deletions(-) diff --git a/ships/Alu.ship b/ships/Alu.ship index fa9dfd8..42003c6 100644 --- a/ships/Alu.ship +++ b/ships/Alu.ship @@ -88,31 +88,41 @@ public void service() { b = box_in2.removeDataForShip(); box_out.addDataFromShip(a-b); // SUB break; + case 9: + if (box_in1.peekDataForShip()<0 && box_in2.peekDataForShip()<0) { + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a, false); + break; + } + // fall through case 4: a = box_in1.peekDataForShip(); b = box_in2.peekDataForShip(); - box_out.addDataFromShip(Math.max(a,b)); // MAX - box_out.flag_c = !(a>b); + box_out.addDataFromShip(Math.max(a,b), !(a>b)); // MAX if (ab; + box_out.addDataFromShip(Math.min(a,b), a>b); // MIN if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip(); break; case 6: a = box_in1.removeDataForShip(); b = box_in2.removeDataForShip(); - box_out.addDataFromShip(0); // CMP - box_out.flag_c = a==b; + box_out.addDataFromShip(0, a==b); // CMP break; - default: - a = box_in1.removeDataForShip(); - b = box_in2.removeDataForShip(); - box_out.addDataFromShip(0); +/* + case 7: + box_in1.removeDataForShip(); // DROP1 break; + case 8: + box_in2.removeDataForShip(); // DROP2 + break; +*/ + default: + throw new RuntimeException("invalid opcode: " + op); } } } diff --git a/ships/CarrySaveAdder.ship b/ships/CarrySaveAdder.ship index edef42d..e6cddd6 100644 --- a/ships/CarrySaveAdder.ship +++ b/ships/CarrySaveAdder.ship @@ -14,9 +14,41 @@ values, provided sequentially at {\tt in}, and produces. == Fleeterpreter ==================================================== +int state = 0; +long temp; +long out; +public void reset() { + super.reset(); + state = 0; + temp = 0; + out = 0; +} +private long maj(long a, long b, long c) { + long ret = 0; + for(int i=0; i<64; i++) { + boolean a_ = (a&(1L<> (getFleet().getWordWidth()-1)) & 1L)!=0); + temp = (temp ^ out) ^ in; + break; + case 3: box_out.addDataFromShip(temp, false); break; } + state = (state+1) % 4; } diff --git a/ships/Counter.ship b/ships/Counter.ship index f82bc14..0acc5b7 100644 --- a/ships/Counter.ship +++ b/ships/Counter.ship @@ -20,7 +20,70 @@ data in: inOp data out: out == Fleeterpreter ==================================================== -public void service() { } + +boolean full = false; +boolean op_count = false; +boolean op_repeat = false; +boolean op_pass = false; +boolean op_drop = false; +boolean op_c1 = false; +boolean op_c2 = false; +boolean op_v1 = false; +boolean op_v2 = false; +long temp = 0; + +public void reset() { + super.reset(); + full = false; + temp = 0; +} +public void service() { + + if (full) { + if (temp < 0) { + temp = 0; + full = false; + box_inOp.removeDataForShip(); + if (op_count) box_in2.removeDataForShip(); + else if (op_repeat && op_v1) box_in1.removeDataForShip(); + else if (op_repeat && op_v2) box_in2.removeDataForShip(); + + } else if (box_out.readyForDataFromShip()) { + if (op_count) { + box_out.addDataFromShip(temp); + temp = temp - box_in2.peekDataForShip(); + } else if (op_v1 && box_in1.dataReadyForShip()) { + if (op_drop) { box_in1.removeDataForShip(); temp--; } + else { box_out.addDataFromShip(op_pass ? box_in1.removeDataForShip() : box_in1.peekDataForShip()); temp--; } + } else if (op_v2 && box_in2.dataReadyForShip()) { + if (op_drop) { box_in2.removeDataForShip(); temp--; } + else { box_out.addDataFromShip(op_pass ? box_in2.removeDataForShip() : box_in2.peekDataForShip()); temp--; } + } + + } + + } else if (box_inOp.dataReadyForShip()) { + long op = box_inOp.peekDataForShip(); + op_count = (op & 15)==12; + op_repeat = ((op>>2) & 3)==0; + op_pass = ((op>>2) & 3)==1; + op_drop = ((op>>2) & 3)==2; + op_c1 = (op_repeat || op_pass || op_drop) && !(((op>>1)&1)!=0); + op_c2 = (op_repeat || op_pass || op_drop) && (((op>>1)&1)!=0); + op_v1 = (op_repeat || op_pass || op_drop) && !(((op>>0)&1)!=0); + op_v2 = (op_repeat || op_pass || op_drop) && (((op>>0)&1)!=0); + + if (op_count && (!box_in1.dataReadyForShip() || !box_in2.dataReadyForShip())) return; + if (op_c1 && !box_in1.dataReadyForShip()) return; + if (op_c2 && !box_in2.dataReadyForShip()) return; + + full = true; + + if (op_count) temp = box_in1.removeDataForShip() - box_in2.peekDataForShip(); + if (op_c1) temp = box_in1.removeDataForShip()-1; + if (op_c2) temp = box_in2.removeDataForShip()-1; + } +} == FleetSim ============================================================== diff --git a/ships/DDR2.ship b/ships/DDR2.ship index 5360b2a..4febc7b 100644 --- a/ships/DDR2.ship +++ b/ships/DDR2.ship @@ -270,6 +270,7 @@ DDR2SDRAM DDR2SDRAM( == Test ============================================================== +#skip #expect 0 #ship debug : Debug diff --git a/ships/DRAM.ship b/ships/DRAM.ship index 978d3e0..619185f 100644 --- a/ships/DRAM.ship +++ b/ships/DRAM.ship @@ -114,6 +114,7 @@ percolate inout: ddr1_DQ 32 == Test ======================================================== +#skip // expected output #expect 10 diff --git a/ships/Memory.ship b/ships/Memory.ship index f49d3dd..dabd06b 100644 --- a/ships/Memory.ship +++ b/ships/Memory.ship @@ -105,55 +105,28 @@ sequence guarantee problem mentioned in the previous paragraph. } mem[addr] = val; } - - private long stride = 0; - private long count = 0; - private long addr = 0; - private boolean writing = false; - private Queue toDispatch = new LinkedList(); + public void reset() { + super.reset(); + mem = new long[0]; + toDispatch.clear(); + } public void service() { - if (toDispatch.size() > 0) { - //if (!box_out.readyForDataFromShip()) return; - //box_out.addDataFromShip(toDispatch.remove()); - getInterpreter().dispatch(getInterpreter().readInstruction(toDispatch.remove(), getDock("out"))); + if (!box_out.readyForDataFromShip()) return; + box_out.addDataFromShip(toDispatch.remove()); } - - if (box_inCBD.dataReadyForShip() && box_out.readyForDataFromShip()) { + if (box_inCBD.dataReadyForShip()) { long val = box_inCBD.removeDataForShip(); - long addr = val >> 6; - long size = val & 0x3f; + long addr = ((Interpreter)getFleet()).CBD_OFFSET.getval(val); + long size = ((Interpreter)getFleet()).CBD_SIZE.getval(val); for(int i=0; i 0) { - if (writing) { - if (box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) { - writeMem((int)addr, box_inDataWrite.removeDataForShip()); - box_out.addDataFromShip(0); - count--; - addr += stride; - } - } else { - if (box_out.readyForDataFromShip()) { - box_out.addDataFromShip(readMem((int)addr)); - count--; - addr += stride; - } - } - - } else if (box_inAddrRead.dataReadyForShip()) { - addr = box_inAddrRead.removeDataForShip(); - stride = 0; - count = 1; - writing = false; - - } else if (box_inAddrWrite.dataReadyForShip()) { - addr = box_inAddrWrite.removeDataForShip(); - stride = 0; - count = 1; - writing = true; + } else if (box_inAddrWrite.dataReadyForShip() && box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) { + writeMem((int)box_inAddrWrite.removeDataForShip(), box_inDataWrite.removeDataForShip()); + box_out.addDataFromShip(0,true); + } else if (box_inAddrRead.dataReadyForShip() && box_out.readyForDataFromShip()) { + box_out.addDataFromShip(readMem((int)box_inAddrRead.removeDataForShip()),false); } } diff --git a/ships/Rotator.ship b/ships/Rotator.ship index c5bbf64..9009458 100644 --- a/ships/Rotator.ship +++ b/ships/Rotator.ship @@ -26,7 +26,8 @@ public void service() { long data = box_in.removeDataForShip(); long mask = ~((-1L) << getInterpreter().getWordWidth()); data = data & mask; - box_out.addDataFromShip(((data << amount) | (data >> (getInterpreter().getWordWidth()-amount))) & mask); + long res = ((data >> amount) | (data << (getInterpreter().getWordWidth()-amount))) & mask; + box_out.addDataFromShip(res, (res & (1L << (getInterpreter().getWordWidth()-1)))!=0); } } diff --git a/ships/Video.ship b/ships/Video.ship index bfc01a9..ddf1af0 100644 --- a/ships/Video.ship +++ b/ships/Video.ship @@ -140,6 +140,7 @@ percolate up: vga_clkout 1 == Test ============================================================== +#skip // can't test much here; just make sure it accepts values #expect 0 diff --git a/src/edu/berkeley/fleet/interpreter/DebugDock.java b/src/edu/berkeley/fleet/interpreter/DebugDock.java index 59ba037..2ab6fc4 100644 --- a/src/edu/berkeley/fleet/interpreter/DebugDock.java +++ b/src/edu/berkeley/fleet/interpreter/DebugDock.java @@ -16,14 +16,13 @@ public class DebugDock { public Dock getDock() { return dock; } public int getOLC() { return dock.olc; } public int getILC() { return dock.ilc; } - public Instruction getExecuting() { return dock.executing; } + public Instruction getExecuting() { return dock.instructions.peek(); } public Queue getInstructions() { return dock.instructions; } - public Queue getEpilogue() { return dock.epilogue; } public boolean getDataReadyForShip() { return dock.dataReadyForShip; } public boolean getReadyForDataFromShip() { return dock.readyForDataFromShip;} public long getDataFromShip() { return dock.dataFromShip; } public boolean getTorpedoWaiting() { return dock.torpedoWaiting; } - public boolean isHatchOpen() { return dock.hatchIsOpen; } + public boolean isHatchOpen() { return !dock.requeueStageInCirculatingState; } public boolean getFlagA() { return dock.flag_a; } public boolean getFlagB() { return dock.flag_b; } public boolean getFlagC() { return dock.flag_c; } @@ -35,9 +34,10 @@ public class DebugDock { values.add(p.getValue()); return values; } + public Queue getEpilogue() { + throw new RuntimeException("this method has been removed"); + } public Queue getInstructionsInFabric() { - Queue instr = new LinkedList(); - for (Instruction inst : dock.epilogue) instr.add(inst); - return instr; + throw new RuntimeException("this method has been removed"); } } diff --git a/src/edu/berkeley/fleet/interpreter/Interpreter.java b/src/edu/berkeley/fleet/interpreter/Interpreter.java index 752ac72..0461167 100644 --- a/src/edu/berkeley/fleet/interpreter/Interpreter.java +++ b/src/edu/berkeley/fleet/interpreter/Interpreter.java @@ -9,14 +9,14 @@ import edu.berkeley.fleet.two.*; import edu.berkeley.fleet.assembler.*; import edu.berkeley.fleet.util.*; -public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynamicShips { +public class Interpreter extends FleetTwoFleet { /** used to allocate serial numbers; see InterpreterDestination for further detail */ int maxAllocatedDestinationSerialNumber = 0; private InterpreterShip debugShip = null; private BlockingQueue debugStream = new LinkedBlockingQueue(); - private HashMap ships = new HashMap(); + private LinkedHashMap ships = new LinkedHashMap(); public Iterator iterator() { return (Iterator)(Object)ships.values().iterator(); } public Ship getShip(String type, int ordinal) { for(Ship s : this) @@ -27,7 +27,40 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami } /** do not use this; it is going to go away */ - public Interpreter() { + public Interpreter() { this(true); } + public Interpreter(boolean logging) { + this(new String[] { + "Debug", + "Memory", + "Memory", + "Memory", + "Alu", + "Alu", + "Alu", + "Alu", + "Alu", + "Alu", + "Alu", + "Fifo", + "Fifo", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Counter", + "Lut3", + "CarrySaveAdder", + "Rotator", + }, logging); } public Interpreter(String[] ships, boolean logging) { @@ -46,8 +79,7 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami new Packet((InterpreterPath)path, new BitVector(getWordWidth()).set(il), false).send(); } - /** do not use this; it is going to go away */ - public Ship createShip(String shipType, String shipname) { + private Ship createShip(String shipType, String shipname) { try { if (ships.get(shipname)!=null) return ships.get(shipname); Class c = Class.forName("edu.berkeley.fleet.interpreter."+shipType); @@ -148,9 +180,15 @@ public class Interpreter extends FleetTwoFleet implements Parser.FleetWithDynami private Instruction[] instructions; public void flush() { } public void sendWord(Destination d, BitVector word) { - throw new RuntimeException("not implemented"); + InterpreterPath path = (InterpreterPath)debugShip.getDock("in").getPath(d, new BitVector(1)); + ((InterpreterDestination)d). + addDataFromFabric(new Packet(path, word, false)); + } + public void sendToken(Destination d) { + InterpreterPath path = (InterpreterPath)debugShip.getDock("in").getPath(d, new BitVector(1)); + ((InterpreterDestination)d). + addDataFromFabric(new Packet(path, new BitVector(getWordWidth()), true)); } - public void sendToken(Destination d) { throw new RuntimeException("not implemented"); } public InterpreterProcess(Instruction[] instructions) { this.instructions = instructions; for(Instruction i : instructions) diff --git a/src/edu/berkeley/fleet/interpreter/InterpreterDock.java b/src/edu/berkeley/fleet/interpreter/InterpreterDock.java index 11774ef..9dad01b 100644 --- a/src/edu/berkeley/fleet/interpreter/InterpreterDock.java +++ b/src/edu/berkeley/fleet/interpreter/InterpreterDock.java @@ -1,34 +1,32 @@ package edu.berkeley.fleet.interpreter; import java.util.*; -import edu.berkeley.sbp.util.ANSI; import edu.berkeley.fleet.two.*; import edu.berkeley.fleet.api.*; -import edu.berkeley.fleet.api.Instruction; -import static edu.berkeley.fleet.api.Predicate.*; /** anything that has a source (instruction horn) address on the switch fabric */ class InterpreterDock extends FleetTwoDock { // Dock State ////////////////////////////////////////////////////////////////////////////// - public boolean flag_a = false; - public boolean flag_b = false; - public boolean flag_c = false; - public int ilc = 1; - public int olc = 1; - public BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth()); - public InterpreterPath pathLatch = null; - public InterpreterPath tapl = null; - public boolean hatchIsOpen = true; + boolean flag_a = false; + boolean flag_b = false; + boolean flag_c = false; + boolean flag_d = false; + int ilc = 1; + int olc = 1; + final BitVector dataLatch = new BitVector(getShip().getFleet().getWordWidth()); + InterpreterPath pathLatch = null; + boolean requeueStageInCirculatingState = false; + boolean requeueStageHasTailInstruction = false; + boolean torpedoWaiting = false; + boolean flushing = false; - Instruction executing = null; Queue instructions = new LinkedList(); - Queue epilogue = new LinkedList(); Queue dataPackets = new LinkedList(); boolean dataReadyForShip = false; boolean readyForDataFromShip = true; long dataFromShip; - boolean torpedoWaiting = false; + boolean flagCFromShip; protected void reset() { ilc = 1; @@ -36,16 +34,17 @@ class InterpreterDock extends FleetTwoDock { flag_a = false; flag_b = false; flag_c = false; - dataLatch = new BitVector(getShip().getFleet().getWordWidth()); + flag_d = false; + dataLatch.set(0); pathLatch = null; - hatchIsOpen = true; - executing = null; + requeueStageInCirculatingState = false; + requeueStageHasTailInstruction = false; instructions.clear(); - epilogue.clear(); + dataPackets.clear(); dataReadyForShip = false; readyForDataFromShip = true; - tapl = null; torpedoWaiting = false; + flushing = false; } // Destinations ////////////////////////////////////////////////////////////////////////////// @@ -57,14 +56,34 @@ class InterpreterDock extends FleetTwoDock { if (p.isToken()) { if (torpedoWaiting) throw new RuntimeException("two torpedoes collided!"); torpedoWaiting = true; - } else { - BitVector bv = p.getValue(); - long val = 0; - for(int i=0; i 0) { - Instruction inst = epilogue.remove(); - if (inst instanceof Instruction.Head) { - // FIXME - return; - } - if (inst instanceof Instruction.Tail) - hatchIsOpen = false; - else - instructions.add(inst); - } - - if (dataReadyForShip) return; - - if (executing==null && instructions.size() > 0) { - executing = instructions.remove(); - return; - } - - if (executing==null) return; - - if (executing.looping && hatchIsOpen && olc>0) return; + if (dataReadyForShip || flushing) return; + if (instructions.size()==0) return; - boolean enabled = true; - switch(executing.predicate) { - case IgnoreFlagD: enabled = true; break; - case Default: enabled = olc>0; break; - case FlagA: enabled = flag_a; break; - case FlagB: enabled = flag_b; break; - case FlagC: enabled = flag_c; break; - case NotFlagA: enabled = !flag_a; break; - case NotFlagB: enabled = !flag_b; break; - case NotFlagC: enabled = !flag_c; break; - default: throw new RuntimeException(); - } - if (!enabled) { - if (executing.looping && olc>0) - instructions.add(executing); - executing = null; + if (instructions.peek() instanceof Instruction.Head) { + if (requeueStageInCirculatingState) { instructions.remove(); return; } + if (!requeueStageHasTailInstruction) return; + requeueStageHasTailInstruction = false; + requeueStageInCirculatingState = true; + instructions.remove(); return; } - if (executing instanceof Instruction.Move) { - Instruction.Move move = (Instruction.Move)executing; + // in the while..false idiom block below, use "break" to + // consume the instruction at instructions.peek(), or "return" + // to leave it and retry on the next call. + do { + if (!instructions.peek().predicate.evaluate(flag_a, flag_b, flag_c, flag_d)) + break; - if (move.interruptible && torpedoWaiting) { - torpedoWaiting = false; - executing = null; - ilc = 1; - olc = 0; - if (tapl != null) - new Packet(tapl, new BitVector(getInterpreter().getWordWidth()), true).send(); - hatchIsOpen = true; - return; - } + if (instructions.peek() instanceof Instruction.Move) { + Instruction.Move move = (Instruction.Move)instructions.peek(); - if (move.dataIn && !isInputDock() && readyForDataFromShip) return; - if (move.dataIn && isInputDock() && dataPackets.size()==0) return; - if (move.tokenIn && dataPackets.size()==0) return; - } + if (ilc==0) { ilc = 1; break; } - if (executing.looping && olc>0) - instructions.add(executing); + if (move.interruptible && torpedoWaiting) { + torpedoWaiting = false; + ilc = 1; + flag_d = true; + break; + } - if (executing instanceof Instruction.Shift) { - /* - Instruction.Shift shift = (Instruction.Shift)executing; - for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--) - dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth())); - for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--) - dataLatch.set(i, shift.immediate.get(i)); - executing = null; - return; - */ - throw new RuntimeException("FIXME"); - } + if (move.dataIn && !isInputDock() && readyForDataFromShip) return; + if (move.dataIn && isInputDock() && dataPackets.size()==0) return; + if (move.tokenIn && dataPackets.size()==0) return; - if (executing instanceof Instruction.Set) { - Instruction.Set set = (Instruction.Set)executing; - switch(set.dest) { - case DataLatch: - dataLatch = new BitVector(getInterpreter().getWordWidth()).setAndSignExtend(set.immediate); - break; - case InnerLoopCounter: - switch(set.source) { - case Infinity: - ilc = -1; - break; - case DataLatch: - ilc = 0; - for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++) - if (dataLatch.get(i)) - ilc |= (1 << i); - break; - case Immediate: - ilc = (int)set.immediate; - break; - default: - throw new RuntimeException("FIXME!"); + if (move.tokenIn) { + Packet p = dataPackets.remove(); + flag_c = p.getSignal().get(0); + } + if (move.dataIn) { + BitVector bv = null; + if (isInputDock()) { + Packet p = dataPackets.remove(); + bv = new BitVector(p.getValue()); + flag_c = p.getSignal().get(0); + } else { + bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip); + readyForDataFromShip = true; + flag_c = flagCFromShip; } - break; - case OuterLoopCounter: - switch(set.source) { - case Decrement: - olc = Math.max(0,olc-1); - if (olc==0) hatchIsOpen = true; - break; - case DataLatch: - olc = 0; - for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++) - if (dataLatch.get(i)) - olc |= (1 << i); - if (olc==0) hatchIsOpen = true; - break; - case Immediate: - olc = (int)set.immediate; - if (olc==0) hatchIsOpen = true; - break; - default: - throw new RuntimeException("FIXME!"); + if (move.latchData) dataLatch.set(bv); + if (move.latchPath) { + BitVector bvp = ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv); + pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, bvp); } - break; + } + + if (move.path != null) pathLatch = (InterpreterPath)move.path; + + if (move.dataOut && isInputDock()) dataReadyForShip = true; + if (move.dataOut && !isInputDock()) new Packet(pathLatch, new BitVector(dataLatch), false).send(); + if (move.tokenOut) new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send(); + + if (ilc==1) break; + if (ilc!=-1) ilc--; + return; - case Flags: { - boolean new_flag_a = false; - boolean new_flag_b = false; - for(Predicate p : set.newFlagA) - switch(p) { - case FlagA: new_flag_a |= flag_a; break; - case FlagB: new_flag_a |= flag_b; break; - case FlagC: new_flag_a |= flag_c; break; - case NotFlagA: new_flag_a |= !flag_a; break; - case NotFlagB: new_flag_a |= !flag_b; break; - case NotFlagC: new_flag_a |= !flag_c; break; + } else if (instructions.peek() instanceof Instruction.Abort) { + requeueStageInCirculatingState = false; + break; + + } else if (instructions.peek() instanceof Instruction.Flush) { + flushing = true; + break; + + } else if (instructions.peek() instanceof Instruction.Shift) { + Instruction.Shift shift = (Instruction.Shift)instructions.peek(); + for(int i=dataLatch.length()-1; i>=getShip().getFleet().getShiftWidth(); i--) + dataLatch.set(i, dataLatch.get(i-getShip().getFleet().getShiftWidth())); + for(int i=getShip().getFleet().getShiftWidth()-1; i>=0; i--) + dataLatch.set(i, shift.immediate.get(i)); + break; + + } else if (instructions.peek() instanceof Instruction.Set) { + Instruction.Set set = (Instruction.Set)instructions.peek(); + switch(set.dest) { + case DataLatch: dataLatch.setAndSignExtend(set.immediate); + break; + case InnerLoopCounter: + switch(set.source) { + case Infinity: ilc = -1; break; + case Immediate: ilc = (int)set.immediate; break; + case DataLatch: + ilc = 0; + for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_ILC_FROM_IMMEDIATE.valmaskwidth-1; i++) + if (dataLatch.get(i)) + ilc |= (1 << i); + break; + default: throw new RuntimeException("impossible"); } - for(Predicate p : set.newFlagB) - switch(p) { - case FlagA: new_flag_b |= flag_a; break; - case FlagB: new_flag_b |= flag_b; break; - case FlagC: new_flag_b |= flag_c; break; - case NotFlagA: new_flag_b |= !flag_a; break; - case NotFlagB: new_flag_b |= !flag_b; break; - case NotFlagC: new_flag_b |= !flag_c; break; + break; + case OuterLoopCounter: + switch(set.source) { + case Decrement: olc = Math.max(0,olc-1); break; + case Immediate: olc = (int)set.immediate; break; + case DataLatch: + olc = 0; + for(int i=0; i<((FleetTwoFleet)getShip().getFleet()).SET_OLC_FROM_IMMEDIATE.valmaskwidth-1; i++) + if (dataLatch.get(i)) + olc |= (1 << i); + break; + default: throw new RuntimeException("impossible"); } - flag_a = new_flag_a; - flag_b = new_flag_b; - break; + flag_d = olc==0; + break; + + case Flags: { + boolean new_flag_a = set.newFlagA.evaluate(flag_a, flag_b, flag_c, flag_d); + boolean new_flag_b = set.newFlagB.evaluate(flag_a, flag_b, flag_c, flag_d); + flag_a = new_flag_a; + flag_b = new_flag_b; + break; + } + default: throw new RuntimeException("FIXME!"); } - default: - throw new RuntimeException("FIXME!"); - } - executing = null; - return; - } - - Instruction.Move move = (Instruction.Move)executing; - - // if ILC==0, don't even bother - if (ilc==0) { ilc = 1; executing = null; return; } - - if (ilc==-1) { } - else if (ilc==1) executing = null; - else ilc--; - - Packet p = null; - if (move.tokenIn) { - p = dataPackets.remove(); - if (p.getSignal() != null) flag_c = p.getSignal().get(0); - } - if (move.dataIn) { - BitVector bv = null; - if (isInputDock()) { - p = dataPackets.remove(); - bv = new BitVector(p.getValue()); - if (p.getSignal() != null) flag_c = p.getSignal().get(0); } else { - bv = new BitVector(getInterpreter().getWordWidth()).set(dataFromShip); - readyForDataFromShip = true; + throw new RuntimeException("unimplemented instruction: " + instructions.peek()); } - if (move.latchData) dataLatch = bv; - if (move.latchPath) - pathLatch = (InterpreterPath)getInterpreter().getPathByAddr(this, ((FleetTwoFleet)getShip().getFleet()).DISPATCH_PATH.getvalAsBitVector(bv.toLong())); - // FIXME: c-flag at output docks - } + } while(false); - if (move.path != null) pathLatch = (InterpreterPath)move.path; + if (requeueStageInCirculatingState) + instructions.add(instructions.peek()); + instructions.remove(); + return; + } - if (move.dataOut && isInputDock()) dataReadyForShip = true; - if (move.dataOut && !isInputDock()) - new Packet(pathLatch, new BitVector(dataLatch), true).send(); - if (move.tokenOut) - new Packet(pathLatch, new BitVector(getInterpreter().getWordWidth()), true).send(); + // Interface for use by Subclasses /////////////////////////////////////////////////////////////////////// - return; + // all the methods below convert 64-bit longs to/from + // getWordWidth()-bit BitVectors by truncation and sign-extension. + + protected boolean dataReadyForShip() { return dataReadyForShip; } + protected final boolean readyForDataFromShip() { return readyForDataFromShip; } + protected long removeDataForShip() { + long val = peekDataForShip(); + dataReadyForShip = false; + return val; + } + protected long peekDataForShip() { + if (!dataReadyForShip) + throw new RuntimeException("peekDataForShip() invoked when dataReadyForShip()==false"); + BitVector bv = dataLatch; + long val = 0; + for(int i=0; i