super(pump);
this.count = count;
}
- protected abstract boolean isRequeueing();
+ public boolean isStanding() { return count==0; }
+ public abstract boolean isRequeueing();
public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
}
public String toString() { return super.toString() + "unclog;"; }
}
- public static class Clog extends Instruction {
- public Clog(Pump pump) { super(pump); }
+ public static class Clog extends Executable {
+ public Clog(Pump pump) { super(pump, 1); }
public String toString() { return super.toString() + "clog;"; }
+ public Instruction.Executable decrementCount() { return null; }
+ public boolean isRequeueing() { return false; }
}
public static class Kill extends CountingInstruction {
public Kill(Pump pump, int count) { super(pump, count); }
- protected boolean isRequeueing() { return false; }
+ public boolean isRequeueing() { return false; }
public String toString() { return super.toString() + "kill;"; }
}
- public static class Executable extends Instruction {
+ public static abstract class Executable extends CountingInstruction {
+ public Executable(Pump pump, int count) { super(pump, count); }
+ public abstract Instruction.Executable decrementCount();
+ }
+ public static class Move extends Executable {
public final Destination dest;
- public final int count;
public final boolean tokenIn;
public final boolean dataIn;
public final boolean requeue;
public final boolean ignoreUntilLast;
- protected boolean isRequeueing() { return requeue; }
+ public boolean isRequeueing() { return requeue; }
/** count=0 denotes a standing move */
- public Executable(Pump pump,
+ public Move(Pump pump,
Destination dest,
int count,
boolean tokenIn,
boolean tokenOut,
boolean requeue,
boolean ignoreUntilLast) {
- super(pump);
+ super(pump, count);
this.dest = dest;
- this.count = count;
this.tokenIn = tokenIn;
this.dataIn = dataIn;
this.latch = latch;
throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
}
- public boolean isStanding() {
- return count==0;
- }
-
public Instruction.Executable decrementCount() {
if (count==1) return null;
- return new Executable(pump, dest, count==0 ? 0 : count-1,
- tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
+ return new Move(pump, dest, count==0 ? 0 : count-1,
+ tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
}
public String toString() {
}
- public static class LocalLiteral extends CountingInstruction {
+ public static class LocalLiteral extends Executable {
public final long literal;
public boolean isRequeueing() { return true; }
public LocalLiteral(Pump pump, long literal, int count) {
super(pump, count);
this.literal = literal;
}
+ public Instruction.Executable decrementCount() {
+ if (count==1) return null;
+ return new LocalLiteral(pump, literal, count-1);
+ }
}
public static class CodeBagDescriptor extends Instruction {
else if ("notify".equals(ttt.head())) { tokenOut = true; dest = portReference(ttt.child(0)); }
else if ("notifyLast".equals(ttt.head())) { tokenOut = true; ignoreUntilLast = true; dest = portReference(ttt.child(0)); }
}
- cb.add(new Instruction.Executable(pump,
- dest, count, tokenIn, dataIn,
- latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast));
+ cb.add(new Instruction.Move(pump,
+ dest, count, tokenIn, dataIn,
+ latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast));
}
}
}
public Instruction readInstruction(long inst) {
Pump name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
- Destination dest = getDestByAddr (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst));
+ if (getIntField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,inst)==MASK_UNCLOG)
+ return new Instruction.UnClog(name);
+ if (getIntField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,inst)==MASK_CLOG)
+ return new Instruction.Clog(name);
int count = getIntField( OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst);
+ if (getIntField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL,inst)==MASK_KILL)
+ return new Instruction.Kill(name, count);
+ Destination dest = getDestByAddr (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst));
boolean tokenIn = getBit(OFFSET_TI, inst);
boolean dataIn = getBit(OFFSET_DI, inst);
boolean latch = getBit(OFFSET_DL, inst);
boolean tokenOut = getBit(OFFSET_TO, inst);
boolean requeue = getBit(OFFSET_RQ, inst);
boolean ignoreUntilLast = getBit(OFFSET_IG, inst);
- boolean dataOutDest = dataOut && tokenOut;
+ boolean dataOutDest = name.isOutbox() && dataOut && tokenOut;
boolean isLiteral = getIntField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, inst)==MASK_LITERAL;
if (isLiteral)
return new Instruction.LocalLiteral(name, getIntField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), count);
- if (latch & !dataIn && !tokenIn && !dataOut && !tokenOut) return new Instruction.Clog(name);
- if (latch & !dataIn && tokenIn) return new Instruction.UnClog(name);
- if (latch & !dataIn) return new Instruction.Kill(name, count);
- return new Instruction.Executable(name, dest, count, tokenIn, dataIn, latch, dataOutDest,
- dataOut, tokenOut, requeue, ignoreUntilLast);
+ if (dataOutDest) tokenOut = false;
+ return new Instruction.Move(name,
+ dest,
+ count,
+ tokenIn,
+ dataIn,
+ latch,
+ dataOutDest,
+ dataOut,
+ tokenOut,
+ requeue,
+ ignoreUntilLast);
}
public long writeInstruction(Instruction d) {
instr = inst.literal;
}
- } else if (d instanceof Instruction.Executable) {
- Instruction.Executable inst = (Instruction.Executable)d;
+ } else if (d instanceof Instruction.Move) {
+ Instruction.Move inst = (Instruction.Move)d;
instr |= putField(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1, OFFSET_MASK_NORMAL, MASK_NORMAL);
instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst.dest==null?0:getDestAddr(inst.dest));
instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
//////////////////////////////////////////////////////////////////////////////
/** invoked by superclass */
- protected final boolean service(Instruction.Executable instruction) {
+ protected final boolean service(Instruction.Executable instruction_) {
// if data is stuck on itemPresentedToShip, wait for it to go somewhere before
// considering additional instructions
if (itemReadyForShip) return false;
// if no instruction waiting, do nothing
- if (instruction == null) return false;
+ if (instruction_ == null) return false;
+
+ if (clogged>0) return false;
+ if (instruction_ instanceof Instruction.Clog) { clogged++; return true; }
+ if (instruction_ instanceof Instruction.LocalLiteral) {
+ Instruction.LocalLiteral ll = (Instruction.LocalLiteral)instruction_;
+ register = new Packet(getInterpreter(), null, ll.literal, null);
+ return true;
+ }
+ Instruction.Move instruction = (Instruction.Move)instruction_;
// check firing conditions
if (instruction.tokenIn)
/** anything that has a source (instruction horn) address on the switch fabric */
abstract class InstructionPump extends InterpreterPump {
+ public int clogged = 0;
+
/** the currently executing instruction */
private Instruction.Executable executing = null;
boolean ret = service(executing);
if (!ret) return;
- if (executing.requeue) {
+ if (executing.isRequeueing()) {
executing = executing.decrementCount();
if (executing != null)
addInstruction(executing);
//new Packet(this, null, (int)absolute_cbd, (InterpreterDestination)cbd.pump).send();
} else if (i instanceof Instruction.UnClog) {
- //FIXME
+ Instruction.UnClog ic = (Instruction.UnClog)i;
+ ((InstructionPump)(ic.pump)).clogged--;
+
} else if (i instanceof Instruction.Kill) {
InterpreterPump pump = (InterpreterPump)(((Instruction.Kill)i).pump);
((InstructionPump)pump).kill(((Instruction.Kill)i).count, false);
-
} else {
throw new Error("unsupported: " + i.getClass().getName());
public Outbox(InterpreterShip ship, String name) { this(ship, name, new String[] { "" }); }
public Outbox(InterpreterShip ship, String name, String[] ports) { super(ship, name, ports); }
- protected final boolean service(Instruction.Executable instruction) {
+ protected final boolean service(Instruction.Executable instruction_) {
+ if (clogged>0) return false;
+ if (instruction_ instanceof Instruction.Clog) { clogged++; return true; }
+ if (instruction_ instanceof Instruction.LocalLiteral) {
+ Instruction.LocalLiteral ll = (Instruction.LocalLiteral)instruction_;
+ register = ll.literal;
+ return true;
+ }
+ Instruction.Move instruction = (Instruction.Move)instruction_;
// if no instruction waiting, do nothing
if (instruction == null) return false;
// if item to be transmitted, send it
InterpreterDestination dest = (InterpreterDestination)instruction.dest;
if (instruction.dataOutDest) {
- // FIXME
- long bits = BitManipulations.getField(InstructionEncoder.WIDTH_WORD-1,
- InstructionEncoder.WIDTH_WORD-InstructionEncoder.WIDTH_DEST_ADDR,
+ // FIXME: still not supported
+ long bits = BitManipulations.getField(InstructionEncoder.OFFSET_PUMP_ADDR+InstructionEncoder.WIDTH_PUMP_ADDR-1,
+ InstructionEncoder.OFFSET_PUMP_ADDR,
register);
+ getInterpreter().dispatch(((Interpreter)getInterpreter()).iie.readInstruction(register), bits);
+ /*
dest = (InterpreterDestination)(((Interpreter)getInterpreter()).iie.getDestByAddr(bits));
- throw new RuntimeException();
+ if (dest == null) {
+ if (pump != null) {
+
+ Pump pump = ((Interpreter)getInterpreter()).iie.getDestByInstAddr(bits);
+ }
+ }
+ */
+ //throw new RuntimeException();
+ } else {
+ new Packet(getInterpreter(), this, register, dest).send();
}
- new Packet(getInterpreter(), this, register, dest).send();
if (instruction.tokenOut)
throw new RuntimeException("outboxes may not send acks!");