import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.*;
import java.io.*;
-import static edu.berkeley.fleet.ies44.BitManipulations.*;
+import static edu.berkeley.fleet.util.BitManipulations.*;
public abstract class InstructionEncoder {
- public static final int WIDTH_WORD = 37; /* word width */
- public static final int WIDTH_CODEBAG_SIZE = 6;
- public static final int WIDTH_PUMP_ADDR = 11;
- public static final int WIDTH_DEST_ADDR = 11;
- public static final int WIDTH_COUNT = 7;
-
- public static final int OFFSET_COUNT = 0;
- public static final int OFFSET_DEST = OFFSET_COUNT+WIDTH_COUNT;
- public static final int OFFSET_CONTROL = OFFSET_DEST+WIDTH_DEST_ADDR;
- public static final int OFFSET_RQ = OFFSET_CONTROL+0;
- public static final int OFFSET_TO = OFFSET_CONTROL+1;
- public static final int OFFSET_DO = OFFSET_CONTROL+2;
- public static final int OFFSET_DL = OFFSET_CONTROL+3;
- public static final int OFFSET_DI = OFFSET_CONTROL+4;
- public static final int OFFSET_TI = OFFSET_CONTROL+5;
- public static final int OFFSET_PUMP_ADDR = OFFSET_TI+1;
+ public static final int WIDTH_WORD = 37; /* word width */
+ public static final int WIDTH_CODEBAG_SIZE = 6;
+ public static final int WIDTH_PUMP_ADDR = 11;
+ public static final int WIDTH_DEST_ADDR = 11;
+ public static final int WIDTH_COUNT = 7;
+
+ public static final int OFFSET_MASK_LITERAL = 24;
+ public static final int WIDTH_MASK_LITERAL = 2;
+ public static final int MASK_LITERAL = 1;
+ /*
+ public static final int OFFSET_MASK_LITERAL = 20;
+ public static final int WIDTH_MASK_LITERAL = 6;
+ public static final int MASK_LITERAL = 13;
+ */
+
+ public static final int OFFSET_MASK_MASSACRE = 14;
+ public static final int WIDTH_MASK_MASSACRE = 26-14;
+ public static final int MASK_MASSACRE = 1;
+
+ //public static final int OFFSET_MASK_KILL = 21;
+ //public static final int WIDTH_MASK_KILL = 5;
+ //public static final int MASK_KILL = 5;
+ public static final int OFFSET_MASK_KILL = 14;
+ public static final int WIDTH_MASK_KILL = 26-14;
+ public static final int MASK_KILL = 0;
+
+ //public static final int OFFSET_MASK_UNCLOG = 21;
+ //public static final int WIDTH_MASK_UNCLOG = 5;
+ //public static final int MASK_UNCLOG = 2;
+ public static final int OFFSET_MASK_UNCLOG = 14;
+ public static final int WIDTH_MASK_UNCLOG = 26-14;
+ public static final int MASK_UNCLOG = 3;
+
+ //public static final int OFFSET_MASK_CLOG = 21;
+ //public static final int WIDTH_MASK_CLOG = 5;
+ //public static final int MASK_CLOG = 4;
+ public static final int OFFSET_MASK_CLOG = 14;
+ public static final int WIDTH_MASK_CLOG = 26-14;
+ public static final int MASK_CLOG = 2;
+
+ public static final int OFFSET_MASK_NORMAL = 25;
+ public static final int WIDTH_MASK_NORMAL = 1;
+ public static final int MASK_NORMAL = 1;
+
+ public static final int OFFSET_COUNT = 0;
+ public static final int OFFSET_DEST = OFFSET_COUNT+WIDTH_COUNT;
+ public static final int OFFSET_CONTROL = OFFSET_DEST+WIDTH_DEST_ADDR;
+ public static final int OFFSET_RQ = OFFSET_CONTROL+0;
+ public static final int OFFSET_IG = OFFSET_CONTROL+1;
+ public static final int OFFSET_TO = OFFSET_CONTROL+2;
+ public static final int OFFSET_DO = OFFSET_CONTROL+3;
+ public static final int OFFSET_DL = OFFSET_CONTROL+4;
+ public static final int OFFSET_DI = OFFSET_CONTROL+5;
+ public static final int OFFSET_TI = OFFSET_CONTROL+6;
+ public static final int OFFSET_INSTRUCTIONTYPE = OFFSET_CONTROL+7;
+ public static final int OFFSET_PUMP_ADDR = OFFSET_INSTRUCTIONTYPE+1;
+
+ public static final int OFFSET_LITERAL = OFFSET_COUNT+WIDTH_COUNT;
+ public static final int WIDTH_LITERAL = OFFSET_MASK_LITERAL - OFFSET_LITERAL;
/** get the bits describing this box's location on the DESTINATION HORN */
protected abstract long getDestAddr(Destination box);
}
}
- public Instruction readInstruction(long instr) {
- long inst = instr;
- switch((int)getField(WIDTH_WORD-1, WIDTH_WORD-2, inst)) {
- case 0: {
- 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));
- int count = getIntField( OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst);
- boolean tokenIn = getBit(OFFSET_TI, instr);
- boolean dataIn = getBit(OFFSET_DI, instr);
- boolean latch = getBit(OFFSET_DL, instr);
- boolean dataOut = getBit(OFFSET_DO, instr);
- boolean tokenOut = getBit(OFFSET_TO, instr);
- boolean requeue = getBit(OFFSET_RQ, instr);
- boolean dataOutDest = dataOut && tokenOut;
- if (latch & !dataIn) return new Instruction.Kill(name, count, tokenIn);
- return new Instruction.Executable(name, dest, count, tokenIn, dataIn, latch, dataOutDest,
- dataOut, tokenOut, requeue);
- }
-
- case 1: {
- Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, inst));
- long offset = getSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, WIDTH_CODEBAG_SIZE, instr);
- long size = getSignedField(WIDTH_CODEBAG_SIZE-1, 0, instr);
- return new Instruction.Literal.CodeBagDescriptor(name, offset, size);
- }
+ public Instruction readInstruction(long inst) {
+ Pump name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, 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);
+ if (getIntField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE,inst)==MASK_MASSACRE)
+ return new Instruction.Massacre(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 dataOut = getBit(OFFSET_DO, inst);
+ boolean tokenOut = getBit(OFFSET_TO, inst);
+ boolean requeue = getBit(OFFSET_RQ, inst);
+ boolean ignoreUntilLast = getBit(OFFSET_IG, inst);
+ 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, getSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), 0);
+ if (dataOutDest) tokenOut = false;
+ return new Instruction.Move(name,
+ dest,
+ count,
+ tokenIn,
+ dataIn,
+ latch,
+ dataOutDest,
+ dataOut,
+ tokenOut,
+ requeue,
+ ignoreUntilLast);
+ }
- case 2: {
- Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_PUMP_ADDR+1, inst));
- return new Instruction.Literal.Absolute(name, getSignedField(WIDTH_WORD-3-WIDTH_PUMP_ADDR, 0, instr));
- }
+ public long writeInstruction(Instruction d) {
+ long instr = 0;
- case 3: {
- Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_PUMP_ADDR+1, inst));
- return new Instruction.Literal.Relative(name, getSignedField(WIDTH_WORD-3-WIDTH_PUMP_ADDR, 0, instr));
- }
+ if (d.pump != null)
+ instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(d.pump));
+ if (d instanceof Instruction.CodeBagDescriptor) {
+ Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
+ d = new Instruction.LocalLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1);
}
- return null;
- }
+ if (d instanceof Instruction.UnClog) {
+ instr |= putField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG, MASK_UNCLOG);
- public long writeInstruction(Instruction d) {
- long instr = 0;
-
- // Kill is encoded as Execute with the illegal combination (Latch & ~DataIn)
- if (d instanceof Instruction.Kill) {
+ } else if (d instanceof Instruction.Kill) {
Instruction.Kill k = (Instruction.Kill)d;
- d = new Instruction.Executable(k.pump, null, k.count, k.killOnlyStandingInstructions,
- false, true, false, false, false, false);
- }
+ instr |= putField(OFFSET_MASK_KILL+WIDTH_MASK_KILL-1, OFFSET_MASK_KILL, MASK_KILL);
+ instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, k.count-1);
+
+ } else if (d instanceof Instruction.Clog) {
+ instr |= putField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG, MASK_CLOG);
+
+ } else if (d instanceof Instruction.Massacre) {
+ instr |= putField(OFFSET_MASK_MASSACRE+WIDTH_MASK_MASSACRE-1, OFFSET_MASK_MASSACRE, MASK_MASSACRE);
+
+ } else if (d instanceof Instruction.LocalLiteral) {
+ Instruction.LocalLiteral inst = (Instruction.LocalLiteral)d;
+ if (inst.pump != null) {
+ instr |= putField(OFFSET_MASK_LITERAL+WIDTH_MASK_LITERAL-1, OFFSET_MASK_LITERAL, MASK_LITERAL);
+ instr |= putSignedField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst.literal);
+ // FIXME remove soon
+ //instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
+ } else {
+ instr = inst.literal;
+ }
- if (d instanceof Instruction.Executable) {
- Instruction.Executable inst = (Instruction.Executable)d;
- instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(inst.pump));
+ } 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);
instr |= putField(OFFSET_TI, OFFSET_TI, inst.tokenIn?1:0);
instr |= putField(OFFSET_DO, OFFSET_DO, (inst.dataOutDest||inst.dataOut)?1:0);
instr |= putField(OFFSET_TO, OFFSET_TO, (inst.dataOutDest||inst.tokenOut)?1:0);
instr |= putField(OFFSET_RQ, OFFSET_RQ, inst.requeue?1:0);
+ instr |= putField(OFFSET_IG, OFFSET_IG, inst.ignoreUntilLast?1:0);
- } else if (d instanceof Instruction.Literal.CodeBagDescriptor) {
- Instruction.Literal.CodeBagDescriptor lc = (Instruction.Literal.CodeBagDescriptor)d;
- instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 1);
- if (lc.dest != null) instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(lc.dest));
- instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, WIDTH_CODEBAG_SIZE, lc.offset);
- instr |= putField(WIDTH_CODEBAG_SIZE-1, 0, lc.size);
-
- } else if (d instanceof Instruction.Literal.Absolute) {
- Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
- instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 2);
- instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(ld.dest));
- instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, 0, ld.value);
-
- } else if (d instanceof Instruction.Literal.Relative) {
- Instruction.Literal.Relative lr = (Instruction.Literal.Relative)d;
- instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 3);
- instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(lr.dest));
- instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, 0, lr.offset);
-
}
return instr;
}