/** the dock which is to execute this instruction */
public final Dock dock;
- /** true if the instruction is an outer-looping instruction */
- public final boolean looping;
-
/** the instruction's predicate */
public final Predicate predicate;
- Instruction(Dock dock, boolean looping, Predicate predicate) {
+ Instruction(Dock dock, Predicate predicate) {
if (dock==null) throw new RuntimeException("dock may not be null");
if (predicate==null) throw new RuntimeException("predicate may not be null");
this.dock = dock;
- this.looping = looping;
this.predicate = predicate;
}
+ //public abstract Instruction withLooping(boolean newLooping);
+ //public abstract Instruction withPredicate(Predicate newPredicate);
+
public String toString() {
String s = predicate.toString();
if (s.length()>0) s = "["+s+"] ";
- return s+dock+": ";
+ return dock+": "+s;
}
/**
/** if <tt>source</tt> is <tt>Immediate</tt>, this is the immediate value; an integer */
public final long immediate;
- /** if <tt>source</tt> is <tt>ImmediatePath</tt>, this is the immediate path */
- public final Path path;
-
/** if <tt>dest</tt> is <tt>Flags</tt>, this is the truth table to update flag "a" */
public final FlagFunction newFlagA;
public final FlagFunction newFlagB;
/** basic constructor */
- public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, SetSource source) {
- super(dock, looping, predicate);
+ public Set(Dock dock, SetDest dest, SetSource source) { this(dock, Predicate.Default, dest, source); }
+ public Set(Dock dock, Predicate predicate, SetDest dest, SetSource source) {
+ super(dock, predicate);
OUTER: switch(dest) {
case InnerLoopCounter:
switch(source) {
this.source = source;
this.dest = dest;
this.immediate = 0;
- this.path = null;
this.newFlagA = null;
this.newFlagB = null;
}
/** constructor for set instructions with immediates */
- public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, long immediate) {
- super(dock, looping, predicate);
+ public Set(Dock dock, SetDest dest, long immediate) { this(dock, Predicate.Default, dest, immediate); }
+ public Set(Dock dock, Predicate predicate, SetDest dest, long immediate) {
+ super(dock, predicate);
if (dest!=SetDest.InnerLoopCounter && dest!=SetDest.OuterLoopCounter && dest!=SetDest.DataLatch)
throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate");
this.source = SetSource.Immediate;
this.dest = dest;
this.immediate = immediate;
- this.path = null;
- this.newFlagA = null;
- this.newFlagB = null;
- }
-
- /** constructor for set instructions with immediate paths */
- public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, Path path) {
- super(dock, looping, predicate);
- if (dest!=SetDest.TAPL)
- throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate path");
- this.source = SetSource.ImmediatePath;
- this.dest = dest;
- this.immediate = 0;
- this.path = path;
this.newFlagA = null;
this.newFlagB = null;
}
/** constructor for <tt>set flags</tt> instructions */
- public Set(Dock dock, boolean looping, Predicate predicate, FlagFunction newFlagA, FlagFunction newFlagB) {
- super(dock, looping, predicate);
+ public Set(Dock dock, FlagFunction newFlagA, FlagFunction newFlagB) { this(dock, Predicate.Default, newFlagA, newFlagB); }
+ public Set(Dock dock, Predicate predicate, FlagFunction newFlagA, FlagFunction newFlagB) {
+ super(dock, predicate);
this.source = SetSource.Immediate;
this.dest = SetDest.Flags;
this.immediate = 0;
- this.path = null;
this.newFlagA = newFlagA;
this.newFlagB = newFlagB;
}
/** possible sources for the Set instruction */
public static enum SetSource {
- Infinity, DataLatch, Immediate, ImmediatePath, Decrement;
+ Infinity, DataLatch, Immediate, Decrement;
}
/** possible destinations for the Set instruction */
public static enum SetDest {
- InnerLoopCounter, OuterLoopCounter, TAPL, Flags, DataLatch;
+ InnerLoopCounter, OuterLoopCounter, Flags, DataLatch;
}
/**
}
return ret.toString();
}
+
+ public boolean evaluate(boolean flag_a, boolean flag_b, boolean flag_c, boolean olc_zero) {
+ boolean ret = false;
+ for(Predicate p : this)
+ ret |= p.evaluate(flag_a, flag_b, flag_c, olc_zero);
+ return ret;
+ }
}
public String toString() {
switch(dest) {
case InnerLoopCounter:
switch(source) {
- case Infinity: return super.toString()+"set ilc=*";
- case DataLatch: return super.toString()+"set ilc=data";
- case Immediate: return super.toString()+"set ilc="+immediate;
+ case Infinity: return super.toString()+"set ilc=*;";
+ case DataLatch: return super.toString()+"set ilc=data;";
+ case Immediate: return super.toString()+"set ilc="+immediate+";";
}
case OuterLoopCounter:
switch(source) {
- case Decrement: return super.toString()+"set olc--";
- case DataLatch: return super.toString()+"set olc=data";
- case Immediate: return super.toString()+"set olc="+immediate;
+ case Decrement: return super.toString()+"set olc--;";
+ case DataLatch: return super.toString()+"set olc=data;";
+ case Immediate: return super.toString()+"set olc="+immediate+";";
}
- case TAPL: return super.toString()+"set tapl="+path;
- case Flags: return super.toString()+"set flags a="+newFlagA+" b="+newFlagB;
- case DataLatch: return super.toString()+"set data="+immediate;
+ case Flags: return super.toString()+"set flags a="+newFlagA+", b="+newFlagB+";";
+ case DataLatch: return super.toString()+"set word="+immediate+";";
}
throw new Error("impossible");
}
/** shifts an immediate into the low-order bits of the data latch */
public static class Shift extends Instruction {
- public final BitVector immediate;
- public Shift(Dock dock, boolean looping, Predicate predicate, BitVector immediate) {
- super(dock, looping, predicate);
- this.immediate = immediate;
+ public final DeferredBitVector immediate;
+ public Shift(Dock dock, DeferredBitVector immediate) { this(dock, Predicate.Default, immediate); }
+ public Shift(final Dock dock, Predicate predicate, final DeferredBitVector arg) {
+ super(dock, predicate);
+ this.immediate = new DeferredBitVector() {
+ public BitVector getBitVector() {
+ BitVector ret = arg.getBitVector();
+ if (ret.length() != dock.getShip().getFleet().getShiftWidth())
+ throw new RuntimeException("attempt to create a Shift instruction with a "+ret.length()+
+ "-bit immediate on a Fleet that uses "+dock.getShip().getFleet().getShiftWidth()+
+ "-bit shift instructions");
+ return ret;
+ }
+ };
}
- public String toString() { return super.toString()+"shift "+immediate; }
+ public String toString() { return super.toString()+"shift "+immediate.getBitVector(); }
+ }
+
+ /** a flush instruction */
+ public static class Flush extends Instruction {
+ public Flush(Dock dock) { this(dock, Predicate.Default); }
+ public Flush(Dock dock, Predicate predicate) {
+ super(dock, predicate);
+ if (!dock.isInputDock()) throw new RuntimeException("Flush is only allowed at input docks");
+ }
+ public String toString() { return super.toString()+"flush;"; }
}
/** all communication is performed with this instruction */
public final boolean tokenOut;
public Move(Dock dock,
- boolean looping,
+ Path path,
+ boolean tokenIn,
+ boolean dataIn,
+ boolean latchData,
+ boolean latchPath,
+ boolean dataOut,
+ boolean tokenOut
+ ) {
+ this(dock, Predicate.Default, false, path, tokenIn, dataIn, latchData, latchPath, dataOut, tokenOut); }
+ public Move(Dock dock,
Predicate predicate,
boolean interruptible,
Path path,
boolean dataOut,
boolean tokenOut
) {
- super(dock, looping, predicate);
+ super(dock, predicate);
this.path = path;
this.tokenIn = tokenIn;
this.dataIn = dataIn;
this.tokenOut = tokenOut;
this.interruptible = interruptible;
if (dock != null && dock.isInputDock() && tokenIn && dataIn)
- throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an input dock: " + this);
+ throw new RuntimeException("cannot have two \"recv\"s: " + this);
if (dock != null && dock.isOutputDock() && tokenOut && dataOut)
- throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an output dock: " + this);
+ throw new RuntimeException("cannot have two \"send\"s: " + this);
if (latchData && !dataIn)
throw new RuntimeException("cannot have latchData bit set without dataIn bit: " + this);
if (latchPath && !dataIn)
public String toString() {
StringBuffer ret = new StringBuffer();
- if (tokenIn) ret.append(", wait");
+ if (tokenIn) ret.append(", recv token");
if (dataIn) {
- if (latchPath) ret.append(dock.isInputDock() ? ", collect path" : ", recv path");
- if (latchData) ret.append(dock.isInputDock() ? ", collect" : ", recv");
- if (!latchPath && !latchData) ret.append(", discard");
+ if (latchPath && latchData) ret.append(!dock.isInputDock() ? ", collect packet" : ", recv packet");
+ if (latchPath) ret.append(!dock.isInputDock() ? ", collect path" : ", recv path");
+ else if (latchData) ret.append(!dock.isInputDock() ? ", collect" : ", recv");
+ else ret.append(!dock.isInputDock() ? ", collect nothing" : ", recv nothing");
}
if (dataOut && dock.isInputDock()) ret.append(", deliver");
- if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send" : "sendto " + path);
- if (tokenOut) ret.append(path==null ? ", token" : "tokento " + path);
+ if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send" : ", send to " + pathToString(path));
+ if (tokenOut) ret.append(path==null ? ", token" : ", send token to " + pathToString(path));
String s = ret.toString();
s = s.equals("") ? "nop" : s.substring(2);
- if (interruptible) s = "[i] " + s;
- return super.toString()+s;
+ if (interruptible) s = "[T] " + s;
+ return super.toString()+s+";";
+ }
+
+ private String pathToString(Path path) {
+ BitVector signal = path.getSignal();
+ if (signal!=null)
+ for(int i=0; i<signal.length(); i++)
+ if (signal.get(i))
+ return (path.getDestination()+":"+signal.toLong());
+ return (path.getDestination()+"");
}
}
+ /** a flush instruction */
+ public static class Abort extends Instruction {
+ public Abort(Dock dock, Predicate predicate) { super(dock, predicate); }
+ public String toString() { return super.toString()+"abort;"; }
+ }
+
+ /** marks the start of a loop; closes the hatch */
+ public static class Head extends Instruction {
+ public Head(Dock dock) { super(dock, Predicate.IgnoreFlagD); }
+ public String toString() { return dock+": head;"; }
+ }
+
/** marks the end of a loop; closes the hatch */
public static class Tail extends Instruction {
- public Tail(Dock dock) { super(dock, false, Predicate.IgnoreOLC); }
- public String toString() { return super.toString() + "tail;"; }
+ public Tail(Dock dock) { super(dock, Predicate.IgnoreFlagD); }
+ public String toString() { return dock+": tail;"; }
}
}