package edu.berkeley.fleet.ies44;
-import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.*;
import java.io.*;
-import static edu.berkeley.fleet.util.BitManipulations.*;
+import edu.berkeley.fleet.api.*;
+import edu.berkeley.fleet.util.*;
+import edu.berkeley.fleet.api.Instruction.Set;
+import static edu.berkeley.fleet.api.Instruction.Set.*;
+import static edu.berkeley.fleet.api.Instruction.*;
+import static edu.berkeley.fleet.api.Predicate.*;
-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_MASK_LITERAL = 20;
- public static final int WIDTH_MASK_LITERAL = 6;
- public static final int MASK_LITERAL = 13; // this is an excessive approximation
-
- 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 = 14;
- public static final int WIDTH_MASK_KILL = 26-14;
- public static final int MASK_KILL = 0;
-
- 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 = 14;
- public static final int WIDTH_MASK_CLOG = 26-14;
- public static final int MASK_CLOG = 2;
-
- public static final int OFFSET_MASK_LOAD_LOOP_TO_DATA = 14;
- public static final int WIDTH_MASK_LOAD_LOOP_TO_DATA = 12;
- public static final int MASK_LOAD_LOOP_TO_DATA = 0;
-
- public static final int OFFSET_MASK_LOAD_LITERAL_TO_LOOP = 14;
- public static final int WIDTH_MASK_LOAD_LITERAL_TO_LOOP = 12;
- public static final int MASK_LOAD_LITERAL_TO_LOOP = 1;
-
- public static final int OFFSET_MASK_LOAD_LITERAL_TO_REPEAT = 14;
- public static final int WIDTH_MASK_LOAD_LITERAL_TO_REPEAT = 12;
- public static final int MASK_LOAD_LITERAL_TO_REPEAT = 2;
-
- public static final int OFFSET_MASK_LOAD_DATA_TO_REPEAT = 14;
- public static final int WIDTH_MASK_LOAD_DATA_TO_REPEAT = 12;
- public static final int MASK_LOAD_DATA_TO_REPEAT = 3;
-
- public static final int OFFSET_MASK_LOAD_DATA_TO_LOOP = 14;
- public static final int WIDTH_MASK_LOAD_DATA_TO_LOOP = 12;
- public static final int MASK_LOAD_DATA_TO_LOOP = 4;
-
- public static final int OFFSET_MASK_DECR_LOOP = 14;
- public static final int WIDTH_MASK_DECR_LOOP = 12;
- public static final int MASK_DECR_LOOP = 5;
-
- 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_COUNTER_LITERAL = 0;
- public static final int WIDTH_COUNTER_LITERAL = 6;
-
- 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_LITERAL_LOADHIGH = 19;
- 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 = 0;
- public static final int WIDTH_LITERAL = 19;
+public abstract class InstructionEncoder {
+ public static final Mask PACKET_TOKEN = new Mask("v.................................................");
+ public static final Mask PACKET_DATA = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv............");
+ public static final Mask PACKET_SIGNAL = new Mask("......................................v...........");
+ public static final Mask PACKET_DEST = new Mask(".......................................vvvvvvvvvvv");
+
+ public static final Mask CBD_SIZE = new Mask("...............................vvvvvv");
+ public static final Mask CBD_OFFSET = new Mask("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv......");
+
+ public static final int WIDTH_WORD = PACKET_DATA.valmaskwidth;
+ public static final int WIDTH_PACKET = PACKET_TOKEN.width;
+
+ public static final Mask DISPATCH_PATH = new Mask("vvvvvvvvvvv..........................");
+ public static final Mask I = new Mask("...........1.........................");
+ public static final Mask OS = new Mask("............1........................");
+ public static final Mask P = new Mask(".............vvv.....................");
+ public static final Mask P_NOT_A = new Mask(".............000.....................");
+ public static final Mask P_A = new Mask(".............001.....................");
+ public static final Mask P_NOT_B = new Mask(".............010.....................");
+ public static final Mask P_B = new Mask(".............011.....................");
+ public static final Mask P_NOT_C = new Mask(".............100.....................");
+ public static final Mask P_C = new Mask(".............101.....................");
+ public static final Mask P_OLC = new Mask(".............110.....................");
+ public static final Mask P_ALWAYS = new Mask(".............111.....................");
+
+ public static final Mask SHIFT = new Mask("................00vvvvvvvvvvvvvvvvvvv");
+
+ public static final Mask TAIL = new Mask("................11...................");
+
+ public static final Mask MOVE = new Mask("................01...................");
+ public static final Mask TI = new Mask("..................1..................");
+ public static final Mask DI = new Mask("...................1.................");
+ public static final Mask DC = new Mask("....................1................");
+ public static final Mask DO = new Mask(".....................1...............");
+ public static final Mask TO = new Mask("......................1..............");
+ public static final Mask PATH_IMMEDIATE = new Mask(".......................1vvvvvvvvvvvvv");
+ public static final Mask PATH_DATA = new Mask(".......................01............");
+ public static final Mask PATH_NOCHANGE = new Mask(".......................00............");
+
+ public static final Mask SET = new Mask("................10...................");
+
+ public static final Mask SET_OLC_FROM_IMMEDIATE = new Mask("................1010000100.....vvvvvv");
+ public static final Mask SET_OLC_FROM_DATA_LATCH = new Mask("................1010000010...........");
+ public static final Mask SET_OLC_FROM_OLC_MINUS_ONE = new Mask("................1010000001...........");
+
+ public static final Mask SET_ILC_FROM_IMMEDIATE = new Mask("................1001000100.....vvvvvv");
+ public static final Mask SET_ILC_FROM_INFINITY = new Mask("................1001000010...........");
+ public static final Mask SET_ILC_FROM_DATA_LATCH = new Mask("................1001000001...........");
+
+ public static final Mask SET_IMMEDIATE = new Mask("................1000100.vvvvvvvvvvvvv");
+ public static final Mask SET_IMMEDIATE_EXTEND = new Mask("................1000100v.............");
+
+ public static final Mask SET_FLAGS = new Mask("................1000010..............");
+ public static final Mask SET_FLAGS_A = new Mask("................1000010..vvvvvv......");
+ public static final Mask SET_FLAGS_B = new Mask("................1000010........vvvvvv");
+ public static final Mask SET_FLAGS_VALUE_A = new Mask("1.....");
+ public static final Mask SET_FLAGS_VALUE_NOT_A = new Mask(".1....");
+ public static final Mask SET_FLAGS_VALUE_B = new Mask("..1...");
+ public static final Mask SET_FLAGS_VALUE_NOT_B = new Mask("...1..");
+ public static final Mask SET_FLAGS_VALUE_C = new Mask("....1.");
+ public static final Mask SET_FLAGS_VALUE_NOT_C = new Mask(".....1");
+
+ public static final Mask SET_TAPL_FROM_IMMEDIATE = new Mask("................1000001.vvvvvvvvvvvvv");
+
+
+ public static final long DataLatch_WIDTH = SET_IMMEDIATE.valmaskmax-SET_IMMEDIATE.valmaskmin+1; // FIXME: this is an abstraction breakage
+ private static final long mask = ~(-1L << DataLatch_WIDTH);
+ public static boolean isSmallEnoughToFit(long immediate) {
+ if ((immediate & ~mask) == 0) return true;
+ if ((immediate | mask) == -1L) return true;
+ return false;
+ }
/** get the bits describing this box's location on the DESTINATION HORN */
- protected abstract long getDestAddr(Destination box);
+ protected abstract long getDestAddr(Path box);
- /** get the bits describing this box's location on the INSTRUCTION HORN */
- protected abstract long getBoxInstAddr(Pump box);
+ /** decode a path, given the starting point and the bits that comprise it */
+ protected abstract Path getPathByAddr(Dock source, long dest);
- /** given an INSTRUCTION HORN address, retrieve the corresponding Pump object */
- protected abstract Pump getBoxByInstAddr(long dest);
-
- /** given a DESTINATION HORN address, retrieve the corresponding Pump object */
- protected abstract Destination getDestByAddr(long dest);
+ /** FIXME: this is a hack for now */
+ protected abstract Dock getUniversalSource();
/** read a machine-formatted instruction from a file (into a Java object) */
- public Instruction readInstruction(DataInputStream is) throws IOException {
+ public Instruction readInstruction(Dock dispatchFrom, DataInputStream is) throws IOException {
long inst = 0;
try {
inst = (inst << 8) | (is.readByte() & 0xff);
inst = (inst << 8) | (is.readByte() & 0xff);
inst = (inst << 8) | (is.readByte() & 0xff);
inst = (inst << 8) | (is.readByte() & 0xff);
- return readInstruction(inst);
+ return readInstruction(dispatchFrom, inst);
} catch (EOFException eof) {
return null;
}
}
- public Instruction readInstruction(long inst) {
- Pump name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
-
- int count_literal = getIntField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1, OFFSET_COUNTER_LITERAL, inst);
- if (getIntField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1, OFFSET_MASK_LOAD_LOOP_TO_DATA,inst)==MASK_LOAD_LOOP_TO_DATA)
- return new Instruction.Counter(name, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH);
- else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1, OFFSET_MASK_LOAD_DATA_TO_REPEAT,inst)==MASK_LOAD_DATA_TO_REPEAT)
- return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER);
- else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1, OFFSET_MASK_LOAD_DATA_TO_LOOP,inst)==MASK_LOAD_DATA_TO_LOOP)
- return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER);
- else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1, OFFSET_MASK_LOAD_LITERAL_TO_LOOP,inst)==MASK_LOAD_LITERAL_TO_LOOP)
- return new Instruction.Counter(name, count_literal, Instruction.Counter.LOOP_COUNTER);
- else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1, OFFSET_MASK_LOAD_LITERAL_TO_REPEAT,inst)==MASK_LOAD_LITERAL_TO_REPEAT)
- return new Instruction.Counter(name, count_literal, Instruction.Counter.REPEAT_COUNTER);
- else if (getIntField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP,inst)==MASK_DECR_LOOP)
- return new Instruction.DecrLoop(name);
-
- 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, getField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst), 0,
- getField(OFFSET_LITERAL_LOADHIGH, OFFSET_LITERAL_LOADHIGH, inst)!=0);
- if (dataOutDest) tokenOut = false;
- return new Instruction.Move(name,
- dest,
- count,
- tokenIn,
- dataIn,
- latch,
- dataOutDest,
- dataOut,
- tokenOut,
- requeue,
- ignoreUntilLast);
+ public Instruction readInstruction(Dock dispatchFrom, long inst) {
+ Dock dock = getPathByAddr(getUniversalSource(), DISPATCH_PATH.getval(inst)).getDestination().getDock();
+
+ if (TAIL.get(inst)) return new Tail(dock);
+
+ Predicate predicate = Default;
+ if (P_ALWAYS.get(inst)) predicate = IgnoreOLC;
+ if (P_OLC.get(inst)) predicate = Default;
+ if (P_A.get(inst)) predicate = FlagA;
+ if (P_B.get(inst)) predicate = FlagB;
+ if (P_C.get(inst)) predicate = FlagC;
+ if (P_NOT_A.get(inst)) predicate = NotFlagA;
+ if (P_NOT_B.get(inst)) predicate = NotFlagB;
+ if (P_NOT_C.get(inst)) predicate = NotFlagC;
+
+ boolean looping = !OS.get(inst);
+ if (SHIFT.get(inst)) return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getWordWidth()).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));
+ }
+
+ if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
+ return new Set(dock, looping, 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)));
+ if (SET_ILC_FROM_IMMEDIATE.get(inst))
+ return new Set(dock, looping, 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);
+ if (SET_ILC_FROM_DATA_LATCH.get(inst))
+ return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
+ if (SET_ILC_FROM_INFINITY.get(inst))
+ return new Set(dock, looping, 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);
+ FlagFunction ap = FlagFunction.ZERO;
+ FlagFunction bp = FlagFunction.ZERO;
+ if (SET_FLAGS_VALUE_A .get(flag_a)) ap = ap.add(FlagA );
+ if (SET_FLAGS_VALUE_NOT_A.get(flag_a)) ap = ap.add(NotFlagA );
+ if (SET_FLAGS_VALUE_B .get(flag_a)) ap = ap.add(FlagB );
+ if (SET_FLAGS_VALUE_NOT_B.get(flag_a)) ap = ap.add(NotFlagB );
+ if (SET_FLAGS_VALUE_C .get(flag_a)) ap = ap.add(FlagC );
+ if (SET_FLAGS_VALUE_NOT_C.get(flag_a)) ap = ap.add(NotFlagC );
+ if (SET_FLAGS_VALUE_A .get(flag_b)) bp = bp.add(FlagA );
+ if (SET_FLAGS_VALUE_NOT_A.get(flag_b)) bp = bp.add(NotFlagA );
+ if (SET_FLAGS_VALUE_B .get(flag_b)) bp = bp.add(FlagB );
+ 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);
+ }
+ if (SET_TAPL_FROM_IMMEDIATE.get(inst))
+ return new Set(dock, looping, predicate, SetDest.TAPL, getPathByAddr(dock, SET_TAPL_FROM_IMMEDIATE.getval(inst)));
+ if (MOVE.get(inst))
+ return new Move(dock,
+ looping,
+ predicate,
+ I.get(inst),
+ getPathByAddr(dock, PATH_IMMEDIATE.getval(inst)),
+ TI.get(inst),
+ DI.get(inst),
+ DC.get(inst),
+ PATH_DATA.get(inst),
+ DO.get(inst),
+ TO.get(inst)
+ );
+ throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
}
- public long writeInstruction(Instruction d) {
+ public long writeInstruction(Dock dispatchFrom, Instruction d) {
long instr = 0;
- 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;
- // MAJOR MAJOR FIXME: upper half here...
- d = new Instruction.LocalLiteral(lc.pump, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false);
+ if (d.dock != null)
+ instr = DISPATCH_PATH.setval(instr, getDestAddr(getUniversalSource().getPath(d.dock.getInstructionDestination(),null)));
+
+ boolean dl = false;
+ Instruction pi = d;
+ if (!pi.looping) instr = OS.set(instr);
+ switch(pi.predicate) {
+ case IgnoreOLC: instr = P_ALWAYS.set(instr); break;
+ case Default: instr = P_OLC.set(instr); break;
+ case FlagA: instr = P_A.set(instr); break;
+ case FlagB: instr = P_B.set(instr); break;
+ case FlagC: instr = P_C.set(instr); break;
+ case NotFlagA: instr = P_NOT_A.set(instr); break;
+ case NotFlagB: instr = P_NOT_B.set(instr); break;
+ case NotFlagC: instr = P_NOT_C.set(instr); break;
}
- if (d instanceof Instruction.UnClog) {
- instr |= putField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG, MASK_UNCLOG);
-
- } else if (d instanceof Instruction.Kill) {
- Instruction.Kill k = (Instruction.Kill)d;
- 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);
+ if (d instanceof Tail) {
+ instr = TAIL.set(instr);
+
+ } else if (d instanceof Shift) {
+ Shift shift = (Shift)d;
+ instr = SHIFT.set(instr);
+ instr = SHIFT.setval(instr, shift.immediate);
+
+ } else if (d instanceof Set) {
+ Set s = (Set)d;
+ switch(s.dest) {
+ case InnerLoopCounter:
+ switch(s.source) {
+ case DataLatch:
+ instr = SET_ILC_FROM_DATA_LATCH.set(instr);
+ break;
+ case Immediate:
+ instr = SET_ILC_FROM_IMMEDIATE.setval(SET_ILC_FROM_IMMEDIATE.set(instr), s.immediate);
+ break;
+ case Infinity:
+ instr = SET_ILC_FROM_INFINITY.set(instr);
+ break;
+ }
+ break;
+ case OuterLoopCounter:
+ switch(s.source) {
+ case Decrement:
+ instr = SET_OLC_FROM_OLC_MINUS_ONE.set(instr);
+ break;
+ case DataLatch:
+ instr = SET_OLC_FROM_DATA_LATCH.set(instr);
+ break;
+ case Immediate:
+ instr = SET_OLC_FROM_IMMEDIATE.setval(SET_OLC_FROM_IMMEDIATE.set(instr), s.immediate);
+ break;
+ }
+ break;
+ case TAPL: {
+ instr = SET_TAPL_FROM_IMMEDIATE.set(instr);
+ instr = SET_TAPL_FROM_IMMEDIATE.setval(instr, getDestAddr(s.path));
+ break;
+ }
+ case Flags: {
+ instr = SET_FLAGS.set(instr);
+ instr = SET_FLAGS_A.setval(instr, flagFunctionToLong(s.newFlagA));
+ instr = SET_FLAGS_B.setval(instr, flagFunctionToLong(s.newFlagB));
+ break;
+ }
+ case DataLatch: {
+ instr = SET_IMMEDIATE.set(instr);
+ instr = SET_IMMEDIATE_EXTEND.setval(instr, s.immediate < 0 ? 1 : 0);
+ instr = SET_IMMEDIATE.setval(instr, s.immediate & ~(-1L << DataLatch_WIDTH));
+ break;
+ }
+ }
- } 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 |= putField(OFFSET_LITERAL+WIDTH_LITERAL-1, OFFSET_LITERAL, inst.literal);
- instr |= putField(OFFSET_LITERAL_LOADHIGH, OFFSET_LITERAL_LOADHIGH, (inst.high?1:0));
- } else {
- instr = inst.literal;
+ } else if (d instanceof Move) {
+ Move inst = (Move)d;
+ instr = MOVE.set(instr);
+ if (inst.tokenIn) instr = TI.set(instr);
+ if (inst.dataIn) instr = DI.set(instr);
+ if (inst.latchData) instr = DC.set(instr);
+ if (inst.dataOut) instr = DO.set(instr);
+ if (inst.tokenOut) instr = TO.set(instr);
+ if (inst.interruptible) instr = I.set(instr);
+
+ if (inst.latchPath) instr = PATH_DATA.set(instr);
+ else {
+ instr = PATH_IMMEDIATE.set(instr);
+ instr = PATH_IMMEDIATE.setval(instr, inst.path==null?0:getDestAddr(inst.path));
}
- } else if (d instanceof Instruction.DecrLoop) {
- instr |= putField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP, MASK_DECR_LOOP);
-
- } else if (d instanceof Instruction.Counter) {
- Instruction.Counter ic = (Instruction.Counter)d;
- if (ic.dest == Instruction.Counter.DATA_LATCH && ic.source == Instruction.Counter.LOOP_COUNTER)
- instr |= putField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1,
- OFFSET_MASK_LOAD_LOOP_TO_DATA, MASK_LOAD_LOOP_TO_DATA);
- else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
- instr |= putField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1,
- OFFSET_MASK_LOAD_DATA_TO_REPEAT, MASK_LOAD_DATA_TO_REPEAT);
- else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
- instr |= putField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1,
- OFFSET_MASK_LOAD_DATA_TO_LOOP, MASK_LOAD_DATA_TO_LOOP);
- else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
- instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1,
- OFFSET_MASK_LOAD_LITERAL_TO_REPEAT, MASK_LOAD_LITERAL_TO_REPEAT);
- instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
- OFFSET_COUNTER_LITERAL, ic.source);
- } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
- instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1,
- OFFSET_MASK_LOAD_LITERAL_TO_LOOP, MASK_LOAD_LITERAL_TO_LOOP);
- instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
- OFFSET_COUNTER_LITERAL, ic.source);
- } else throw new RuntimeException();
-
- } 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_DI, OFFSET_DI, inst.dataIn?1:0);
- instr |= putField(OFFSET_DL, OFFSET_DL, inst.latch?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 {
+ throw new RuntimeException("unrecognized instruction " + d.getClass().getName());
}
return instr;
}
- public void writeInstruction(DataOutputStream os, Instruction d) throws IOException {
- long instr = writeInstruction(d);
+ public void writeInstruction(DataOutputStream os, Dock dispatchFrom, Instruction d) throws IOException {
+ long instr = writeInstruction(dispatchFrom, d);
for(int i=5; i>=0; i--)
- os.write(getIntField(i*8+7, i*8, instr));
- }
+ os.write(BitManipulations.getIntField(i*8+7, i*8, instr));
+ }
-}
\ No newline at end of file
+ private static long flagFunctionToLong(FlagFunction ff) {
+ long ret = 0;
+ for(Predicate p : ff)
+ switch(p) {
+ case FlagA : ret = SET_FLAGS_VALUE_A .set(ret); break;
+ case NotFlagA : ret = SET_FLAGS_VALUE_NOT_A.set(ret); break;
+ case FlagB : ret = SET_FLAGS_VALUE_B .set(ret); break;
+ case NotFlagB : ret = SET_FLAGS_VALUE_NOT_B.set(ret); break;
+ case FlagC : ret = SET_FLAGS_VALUE_C .set(ret); break;
+ case NotFlagC : ret = SET_FLAGS_VALUE_NOT_C.set(ret); break;
+ default: throw new RuntimeException();
+ }
+ return ret;
+ }
+}