/** get a constant associated with a dock; returns null if none found */
public BitVector getConstant(String constantName) {
- return null;
+ throw new RuntimeException("unknown constant \""+constantName+"\" on dock " + this);
}
public String toString() { return getShip()+"."+getName(); }
/** 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 String toString() {
String s = predicate.toString();
if (s.length()>0) s = "["+s+"] ";
- if (looping) s += "[Rq] ";
return dock+": "+s;
}
public final FlagFunction newFlagB;
/** basic constructor */
- public Set(Dock dock, SetDest dest, SetSource source) { this(dock, false, Predicate.Default, dest, source); }
- 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) {
}
/** constructor for set instructions with immediates */
- public Set(Dock dock, SetDest dest, long immediate) { this(dock, false, Predicate.Default, dest, immediate); }
- 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;
}
/** constructor for <tt>set flags</tt> instructions */
- public Set(Dock dock, FlagFunction newFlagA, FlagFunction newFlagB) { this(dock, false, Predicate.Default, newFlagA, newFlagB); }
- 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;
/** 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, BitVector immediate) { this(dock, false, Predicate.Default, immediate); }
- public Shift(Dock dock, boolean looping, Predicate predicate, BitVector immediate) {
- super(dock, looping, predicate);
+ public Shift(Dock dock, BitVector immediate) { this(dock, Predicate.Default, immediate); }
+ public Shift(Dock dock, Predicate predicate, BitVector immediate) {
+ super(dock, predicate);
this.immediate = immediate;
this.immediate.setImmutable();
if (immediate.length() != dock.getShip().getFleet().getShiftWidth())
/** a flush instruction */
public static class Flush extends Instruction {
- public Flush(Dock dock) { this(dock, false, Predicate.Default); }
- public Flush(Dock dock, boolean looping, Predicate predicate) {
- super(dock, looping, predicate);
+ 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"; }
boolean dataOut,
boolean tokenOut
) {
- this(dock, false, Predicate.Default, false, path, tokenIn, dataIn, latchData, latchPath, dataOut, tokenOut); }
+ this(dock, Predicate.Default, false, path, tokenIn, dataIn, latchData, latchPath, dataOut, tokenOut); }
public Move(Dock dock,
- boolean looping,
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;
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" : ", send to " + path.getDestination().getDock());
- if (tokenOut) ret.append(path==null ? ", token" : ", send token to " + path.getDestination().getDock());
+ if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send" : ", send to " + path.getDestination());
+ if (tokenOut) ret.append(path==null ? ", token" : ", send token to " + path.getDestination());
String s = ret.toString();
s = s.equals("") ? "nop" : s.substring(2);
if (interruptible) s = "[T] " + s;
/** a flush instruction */
public static class Abort extends Instruction {
- public Abort(Dock dock, Predicate predicate) { super(dock, false, predicate); }
+ 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, false, Predicate.IgnoreFlagD); }
+ 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.IgnoreFlagD); }
+ public Tail(Dock dock) { super(dock, Predicate.IgnoreFlagD); }
public String toString() { return dock+": tail;"; }
}
/** get a constant associated with a ship; returns null if none found */
public BitVector getConstant(String constantName) {
- return null;
+ throw new RuntimeException("unknown constant \""+constantName+"\" on ship " + this);
}
public String toString() {
}
public String getName() { return "fakedock"; }
- public ShipDescription.Constant getDockConstant(String s) { return null; }
+ public BitVector getDockConstant(String s) {
+ throw new RuntimeException("not supported");
+ }
}
private final boolean inbox;
private final boolean left;
private final boolean isDockless;
- private final HashMap<String,ShipDescription.Constant> constants = new HashMap<String,ShipDescription.Constant>();
+ private final HashMap<String,BitVector> constants = new HashMap<String,BitVector>();
DockDescription(ShipDescription ship, String name, boolean left, boolean inbox) {
this(ship, name, left, inbox, false);
boolean isLeft() { return left; }
/** Searches the dock-specific constants first, then ship-wide constants */
- public ShipDescription.Constant getConstant(String name) {
- ShipDescription.Constant ret = constants.get(name);
+ public BitVector getConstant(String name) {
+ BitVector ret = constants.get(name);
if (ret == null) ret = ship.getConstant(name);
return ret;
}
- void addConstant(String s, ShipDescription.Constant c) { constants.put(s, c); }
+ void addConstant(String s, BitVector c) { constants.put(s, c); }
}
public String getName() { return dockDescription.getName(); }
- public ShipDescription.Constant getDockConstant(String s) { return dockDescription.getConstant(s); }
+ public BitVector getDockConstant(String s) { return dockDescription.getConstant(s); }
public boolean isInputDock() { return dockDescription.isInputDock(); }
public boolean isOutputDock() { return !dockDescription.isInputDock(); }
+ public BitVector getConstant(String constantName) {
+ BitVector bv = dockDescription.getConstant(constantName);
+ if (bv==null)
+ throw new RuntimeException("unknown constant \""+constantName+"\" on dock " + this);
+ return bv;
+ }
}
public final Mask DISPATCH_PATH;
public final Mask DISPATCH_INSTR;
public final Mask NOT_INTERRUPTIBLE;
- public final Mask OS;
public final Mask P;
public final Mask P_NOT_A;
public final Mask P_A;
public final int WIDTH_WORD;
public final int WIDTH_PACKET;
- public final long DataLatch_WIDTH;
+ public final int DataLatch_WIDTH;
private final long mask;
public FleetTwoFleet() { this(false); }
DISPATCH_PATH = new Mask("v....................................");
DISPATCH_INSTR = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
- NOT_INTERRUPTIBLE = new Mask(".................1...................");
- OS = new Mask(".......1.............................");
P = new Mask(".vvvvvv..............................");
P_NOT_A = new Mask(".011110..............................");
P_A = new Mask(".011101..............................");
P_OLC_NONZERO = new Mask(".011111..............................");
P_ALWAYS = new Mask(".111111..............................");
- SHIFT = new Mask("..........101111.1vvvvvvvvvvvvvvvvvvv");
- /*
// use these when Marina gets updated to 07-Jan-2009 version of internal encoding
HEAD = new Mask(".......1.............................");
ABORT = new Mask("........1............................");
TAIL = new Mask(".........1...........................");
- */
-
- TAIL = new Mask("................1...................0");
- HEAD = null;
- ABORT = null;
-
- MOVE = new Mask("..........110111.....................");
- TI = new Mask("..........110111..1..................");
- DI = new Mask("..........110111...1.................");
- FLUSH = new Mask(".........1110111.....................");
- DC = new Mask("..........110111....1................");
- DO = new Mask("..........110111.....1...............");
- TO = new Mask("..........110111......1..............");
- PATH_IMMEDIATE = new Mask("..........110111.......1vvvvvvvvvvvvv");
- PATH_DATA = new Mask("..........110111.......00............");
- PATH_NOCHANGE = new Mask("..........110111.......01............");
-
- SET_OLC_FROM_IMMEDIATE = new Mask("..........111101.0.............vvvvvv");
- SET_OLC_FROM_DATA_LATCH = new Mask("..........111101.1...................");
- SET_OLC_FROM_OLC_MINUS_ONE = new Mask("..........111011.....................");
-
- SET_ILC_FROM_IMMEDIATE = new Mask("..........011111.0...........0.vvvvvv");
- SET_ILC_FROM_INFINITY = new Mask("..........011111.............1.......");
- SET_ILC_FROM_DATA_LATCH = new Mask("..........011111.1...................");
-
- SET_IMMEDIATE = new Mask("..........101111.0.....vvvvvvvvvvvvvv");
- SET_IMMEDIATE_EXTEND = new Mask("..........101111.0....v..............");
-
- SET_FLAGS = new Mask("..........111110.....................");
- SET_FLAGS_A = new Mask("..........111110...............vvvvvv");
- SET_FLAGS_B = new Mask("..........111110.........vvvvvv......");
+
+ // actually "is interruptible"
+ NOT_INTERRUPTIBLE = new Mask("...........1....1....................");
+
+ SHIFT = new Mask("..........1......1vvvvvvvvvvvvvvvvvvv");
+ SET_IMMEDIATE = new Mask("..........1......0.....vvvvvvvvvvvvvv");
+ SET_IMMEDIATE_EXTEND = new Mask("..........1......0....v..............");
+ MOVE = new Mask("............1........................");
+ TI = new Mask("............1.....1..................");
+ DI = new Mask("............1......1.................");
+ FLUSH = new Mask("..........1......0.....011...........");
+ DC = new Mask("............1.......1................");
+ DO = new Mask("............1........1...............");
+ TO = new Mask("............1.........1..............");
+ PATH_IMMEDIATE = new Mask("............1..........1vvvvvvvvvvvvv");
+ PATH_DATA = new Mask("............1..........00............");
+ PATH_NOCHANGE = new Mask("............1..........01............");
+
+ SET_OLC_FROM_IMMEDIATE = new Mask("..............1.10.............vvvvvv");
+ SET_OLC_FROM_DATA_LATCH = new Mask("...............1.11..................");
+ SET_OLC_FROM_OLC_MINUS_ONE = new Mask("...............1.10..................");
+
+ SET_ILC_FROM_IMMEDIATE = new Mask("...............1.00..........0.vvvvvv");
+ SET_ILC_FROM_INFINITY = new Mask("...............1.0...........1.......");
+ SET_ILC_FROM_DATA_LATCH = new Mask("...............1.01..................");
+
+ SET_FLAGS = new Mask("...............1.....................");
+ SET_FLAGS_A = new Mask("...............1...............vvvvvv");
+ SET_FLAGS_B = new Mask("...............1.........vvvvvv......");
SET_FLAGS_VALUE_A = new Mask(".....1");
SET_FLAGS_VALUE_NOT_A = new Mask("....1.");
DISPATCH_PATH = new Mask("vvvvvvvvvvv..........................");
DISPATCH_INSTR = new Mask("...........vvvvvvvvvvvvvvvvvvvvvvvvvv");
NOT_INTERRUPTIBLE = new Mask("...........1.........................");
- OS = new Mask("............1........................");
P = new Mask(".............vvv.....................");
P_NOT_A = new Mask(".............000.....................");
P_A = new Mask(".............001.....................");
return false;
}
+ public boolean isSmallEnoughToFit(BitVector immediate) {
+ boolean b = immediate.get((int)DataLatch_WIDTH);
+ for(int i=DataLatch_WIDTH+1; i<immediate.length(); i++)
+ if (immediate.get(i) != b) return false;
+ return true;
+ }
+
public int getWordWidth() { return 37; }
//////////////////////////////////////////////////////////////////////////////
if (P_NOT_A.get(inst)) predicate = NotFlagA;
if (P_NOT_B.get(inst)) predicate = NotFlagB;
- boolean looping = !OS.get(inst);
if (FLUSH.get(inst))
- return new Flush(dock, looping, predicate);
+ return new Flush(dock, predicate);
if (ABORT.get(inst))
return new Abort(dock, predicate);
- if (SHIFT.get(inst)) return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
+ if (SHIFT.get(inst)) return new Shift(dock, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
if (SET_IMMEDIATE.get(inst)) {
boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
long immediate = SET_IMMEDIATE.getval(inst);
if (extend) immediate |= (-1L << DataLatch_WIDTH);
- return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
+ return new Set(dock, predicate, SetDest.DataLatch, (immediate));
}
if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
- return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
+ return new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
if (SET_OLC_FROM_IMMEDIATE.get(inst))
- return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
+ return new Set(dock, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
if (SET_ILC_FROM_IMMEDIATE.get(inst))
- return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
+ return new Set(dock, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
if (SET_OLC_FROM_DATA_LATCH.get(inst))
- return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
+ return new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
if (SET_ILC_FROM_DATA_LATCH.get(inst))
- return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
+ return new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
if (SET_ILC_FROM_INFINITY.get(inst))
- return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
+ return new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
if (SET_FLAGS.get(inst)) {
long flag_a = SET_FLAGS_A.getval(inst);
long flag_b = SET_FLAGS_B.getval(inst);
if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
if (SET_FLAGS_VALUE_C .get(flag_b)) bp = bp.add(FlagC );
if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
- return new Set(dock, looping, predicate, ap, bp);
+ return new Set(dock, predicate, ap, bp);
}
if (MOVE.get(inst))
return new Move(dock,
- looping,
predicate,
!NOT_INTERRUPTIBLE.get(inst),
PATH_DATA.get(inst)?null:getPathByAddr(dock, PATH_IMMEDIATE.getvalAsBitVector(inst)),
boolean dl = false;
Instruction pi = d;
- if (!pi.looping) instr = OS.set(instr);
switch(pi.predicate) {
case IgnoreFlagD: instr = P_ALWAYS.set(instr); break;
case FlagD: instr = P_OLC_ZERO.set(instr); break;
}
throw new RuntimeException("inconsistency: Ship does not belong to its own Fleet!");
}
+
+ public BitVector getConstant(String constantName) {
+ BitVector bv = shipDescription.getConstant(constantName);
+ if (bv==null)
+ throw new RuntimeException("unknown constant \""+constantName+"\" on ship " + this);
+ return bv;
+ }
}
/** NOT YET FINALIZED: A description (specification) of a ship */
public class ShipDescription implements Iterable<DockDescription> {
+ private Fleet fleet;
private String name;
private LinkedHashMap<String,DockDescription> docks = new LinkedHashMap<String,DockDescription>();
private LinkedHashMap<String,DockDescription> ports = new LinkedHashMap<String,DockDescription>();
private HashMap<String,String> sections = new HashMap<String,String>();
- private HashMap<String,Constant> constants = new HashMap<String,Constant>();
+ private HashMap<String,BitVector> constants = new HashMap<String,BitVector>();
public String getName() { return name; }
public String getSection(String sectionName) { return sections.get(sectionName); }
public final LinkedList<PercolatedPort> percolatedPorts = new LinkedList<PercolatedPort>();
- public ShipDescription(String name, BufferedReader r) throws IOException {
+ public ShipDescription(Fleet fleet, String name, BufferedReader r) throws IOException {
if (name.endsWith(".ship")) name = name.substring(0, name.length()-".ship".length());
this.name = name;
+ this.fleet = fleet;
String sectionName = null;
StringBuffer sb = new StringBuffer();
while(true) {
processSection(s);
}
- public Constant getConstant(String name) {
- return constants.get(name);
+ public BitVector getConstant(String name) {
+ BitVector c = constants.get(name);
+ if (c==null) throw new RuntimeException("unknown constant " + name);
+ return c;
}
private void processSection(String section) throws IOException {
if (key.startsWith("constant")) {
String constname = key.substring("constant".length()+1).trim();
String val = s.substring(s.indexOf(':')+1).trim();
- constants.put(constname, new Constant(val));
+ constants.put(constname, new BitVector(fleet.getWordWidth()).set(Integer.parseInt(val)));
}
}
} else if (section.equals("ports")) {
else if (key.startsWith("constant")) {
String constname = key.substring("constant".length()+1).trim();
String val = s.substring(s.indexOf(':')+1).trim();
- p.addConstant(constname, new Constant(val));
+ p.addConstant(constname, new BitVector(fleet.getWordWidth()).set(Integer.parseInt(val)));
continue;
} else if (key.startsWith("shortcut to")) {
continue;
pw.println(tex);
}
- // FIXME: merge with BitMask
- public class Constant {
- public long setbits = 0;
- public long clearbits = 0;
- public boolean signExtend = false;
- public int numberOffset = 0;
- public int numberWidth = 0;
- public Constant(String s) {
- if (s.startsWith("0x")) {
- setbits = Long.parseLong(s.substring(2), 16);
- clearbits = ~setbits;
- } else if (s.length() == 37) {
- for(int i=36; i>=0; i--) {
- char c = s.charAt(36-i);
- switch(c) {
- case '0': clearbits |= (1<<i); break;
- case '1': setbits |= (1<<i); break;
- case '.': break;
- case 's': signExtend = true; numberOffset = i; numberWidth++; break;
- case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
- }
- }
- } else {
- setbits = Long.parseLong(s);
- clearbits = ~setbits;
- }
- }
- }
-
}