package edu.berkeley.fleet.ies44;
+import java.io.*;
import edu.berkeley.fleet.api.*;
-import edu.berkeley.fleet.*;
import edu.berkeley.fleet.util.*;
-import java.io.*;
-import static edu.berkeley.fleet.util.BitManipulations.*;
+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.Instruction.Counter.*;
+import static edu.berkeley.fleet.api.Predicate.*;
-public abstract class InstructionEncoder {
- public static final int WIDTH_WORD = 37;
- public static final int WIDTH_ADDR = 11;
- public static final int WIDTH_CODEBAG_SIZE = 6;
- public static final int WIDTH_COUNTER_LITERAL = 6;
-
- public static final Mask FLAGS = new Mask("...............000000................");
- public static final Mask FLAGS_A = new Mask("...............000000vvvvvvvv........");
- public static final Mask FLAGS_B = new Mask("...............000000........vvvvvvvv");
- public static final Mask REPEAT_FROM_DATA = new Mask("...............000001........00......");
- public static final Mask REPEAT_FROM_LITERAL = new Mask("...............000001........10vvvvvv");
- public static final Mask REPEAT_FROM_STANDING = new Mask("...............000001........11......");
- public static final Mask LOOP_FROM_DATA = new Mask("...............000010.........0......");
- public static final Mask LOOP_FROM_LITERAL = new Mask("...............000010.........1vvvvvv");
- public static final Mask TAKE_LOOP = new Mask("...............000011................");
- public static final Mask KILL = new Mask("...............000100................");
- public static final Mask MASSACRE = new Mask("...............000101................");
- public static final Mask CLOG = new Mask("...............000110................");
- public static final Mask UNCLOG = new Mask("...............000111................");
-
- public static final Mask SK = new Mask("...........1.........................");
- public static final Mask DL = new Mask("............1........................");
- public static final Mask P = new Mask(".............vv......................");
- public static final Mask P_A = new Mask(".............00......................");
- public static final Mask P_B = new Mask(".............10......................");
- public static final Mask P_Z = new Mask(".............01......................");
- public static final Mask P_ALWAYS = new Mask(".............11......................");
- public static final Mask MOVE = new Mask("...............001...................");
- 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_LITERAL = new Mask(".........................1vvvvvvvvvvv");
- public static final Mask PATH_DATA = new Mask(".........................01..........");
- public static final Mask PATH_NOCHANGE = new Mask(".........................00..........");
-
- public static final Mask TOP_HALF_LITERAL = new Mask("vvvvvvvvvvvvvvvvvv...................");
- public static final Mask BOT_HALF_LITERAL = new Mask("..................vvvvvvvvvvvvvvvvvvv");
- public static final Mask TOP_HALF_ONE = new Mask("111111111111111111...................");
- public static final Mask BOT_HALF_ONE = new Mask("..................1111111111111111111");
- public static final Mask LITERAL_LO = new Mask("...............010vvvvvvvvvvvvvvvvvvv");
- public static final Mask LITERAL_HI = new Mask("...............011vvvvvvvvvvvvvvvvvvv");
- public static final Mask LITERAL = new Mask("...............1..vvvvvvvvvvvvvvvvvvv");
- public static final Mask LITERAL_SEL = new Mask("................vv...................");
- public static final Mask LITERAL_LOW_ZERO = new Mask("...............100...................");
- public static final Mask LITERAL_LOW_ONE = new Mask("...............101...................");
- public static final Mask LITERAL_HIGH_ZERO = new Mask("...............110...................");
- public static final Mask LITERAL_HIGH_ONE = new Mask("...............111...................");
- public static final Mask PUMP_NAME = new Mask("vvvvvvvvvvv..........................");
+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(PUMP_NAME.getval(inst));
-
- if (UNCLOG.get(inst)) return new Instruction.UnClog(name);
- if (CLOG.get(inst)) return new Instruction.Clog(name);
- if (MASSACRE.get(inst)) return new Instruction.Massacre(name);
- if (KILL.get(inst)) return new Instruction.Kill(name, (int)(KILL.getval(inst)+1));
-
- int predicate = 0;
- if (P_ALWAYS.get(inst)) predicate = Instruction.PredicatedInstruction.P_ALWAYS;
- if (P_A.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_A;
- if (P_B.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_B;
- if (P_Z.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_Z;
+ 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));
+ }
- boolean dl = false;
- if (DL.get(inst)) dl = true;
-
- if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, dl, predicate, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER);
- if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, dl, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER);
- if (LOOP_FROM_DATA.get(inst)) return new Counter(name, dl, predicate, DATA_LATCH, LOOP_COUNTER);
- if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, dl, predicate, DATA_LATCH, REPEAT_COUNTER);
- if (REPEAT_FROM_STANDING.get(inst)) return new Counter(name, dl, predicate, STANDING, REPEAT_COUNTER);
- if (TAKE_LOOP.get(inst)) return new Counter(name, dl, predicate, LOOP_COUNTER, DATA_LATCH);
-
- if (LITERAL_LO.get(inst)) return new Instruction.HalfLiteral(name, dl, predicate, LITERAL_LO.getval(inst), 0, false);
- if (LITERAL_HI.get(inst)) return new Instruction.HalfLiteral(name, dl, predicate, LITERAL_HI.getval(inst), 0, true);
- if (LITERAL.get(inst)) {
- long literal = LITERAL.getval(inst);
- if (LITERAL_LOW_ZERO.get(inst)) literal = TOP_HALF_LITERAL.setval(0, literal);
- else if (LITERAL_LOW_ONE.get(inst)) literal = BOT_HALF_ONE.set(TOP_HALF_LITERAL.setval(0, literal));
- else if (LITERAL_HIGH_ZERO.get(inst)) literal = BOT_HALF_LITERAL.setval(0, literal);
- else if (LITERAL_HIGH_ONE.get(inst)) literal = TOP_HALF_ONE.set(BOT_HALF_LITERAL.setval(0, literal));
- if ((literal & (1L<<(WIDTH_WORD-1))) != 0) literal |= (-1L << WIDTH_WORD);
- return new Instruction.Literal(name, dl, predicate, literal);
- }
- if (FLAGS.get(inst)) return new Instruction.SetFlags(name, dl, predicate, (int)FLAGS_A.getval(inst), (int)FLAGS_B.getval(inst));
-
- if (!MOVE.get(inst)) throw new RuntimeException("unknown instruction: 0x" + Long.toString(inst, 16));
-
- Destination dest = getDestByAddr(PATH_LITERAL.getval(inst));
- boolean tokenIn = TI.get(inst);
- boolean dataIn = DI.get(inst);
- boolean latch = DC.get(inst);
- boolean dataOut = DO.get(inst);
- boolean tokenOut = TO.get(inst);
- boolean dataOutDest = PATH_DATA.get(inst);
- return new Instruction.Move(name,
- dl,
- predicate,
- dest,
- tokenIn,
- dataIn,
- latch,
- dataOutDest,
- dataOut,
- tokenOut,
- false,
- false);
+ 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 = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump));
+ if (d.dock != null)
+ instr = DISPATCH_PATH.setval(instr, getDestAddr(getUniversalSource().getPath(d.dock.getInstructionDestination(),null)));
boolean dl = false;
- if (d instanceof Instruction.PredicatedInstruction) {
- Instruction.PredicatedInstruction pi = (Instruction.PredicatedInstruction)d;
- if (pi.dl) instr = DL.set(instr);
- switch(pi.predicate) {
- case Instruction.PredicatedInstruction.P_ALWAYS: instr = P_ALWAYS.set(instr); break;
- case Instruction.PredicatedInstruction.P_IF_A: instr = P_A.set(instr); break;
- case Instruction.PredicatedInstruction.P_IF_B: instr = P_B.set(instr); break;
- case Instruction.PredicatedInstruction.P_IF_Z: instr = P_Z.set(instr); break;
- }
- }
-
- if (d instanceof Instruction.CodeBagDescriptor) {
- Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d;
- // MAJOR MAJOR FIXME: upper half here...
- d = new Instruction.HalfLiteral(lc.pump, dl, Instruction.PredicatedInstruction.P_ALWAYS,
- ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, 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 = UNCLOG.set(instr);
-
- } else if (d instanceof Instruction.Kill) {
- Instruction.Kill k = (Instruction.Kill)d;
- instr = KILL.set(instr);
- instr = KILL.setval(instr, k.count);
-
- } else if (d instanceof Instruction.Clog) {
- instr = CLOG.set(instr);
-
- } else if (d instanceof Instruction.Massacre) {
- instr = MASSACRE.set(instr);
-
- } else if (d instanceof Instruction.SetFlags) {
- Instruction.SetFlags sf = (Instruction.SetFlags)d;
- instr = FLAGS.set(instr);
- instr = FLAGS_A.setval(instr, sf.flag_a);
- instr = FLAGS_B.setval(instr, sf.flag_b);
-
- } else if (d instanceof Instruction.Literal) {
- long il = ((Instruction.Literal)d).literal;
- long literal = ((Instruction.Literal)d).literal;
- long allones = ~(-1L << WIDTH_WORD);
- il = literal = literal & allones;
- long top_half = il >> LITERAL_HIGH_ZERO.getWidth();
- long bot_half = il & ~(-1L << LITERAL_HIGH_ZERO.getWidth());
- if (((il & (-1L << 19)) & allones) == 0) instr = LITERAL.setval(LITERAL_HIGH_ZERO.set(instr), il);
- else if (((il | ~(-1L << 19)) & allones) == allones) instr = LITERAL.setval(LITERAL_HIGH_ONE.set(instr), il & ~(-1L<<19));
- else if (((il & ~(-1L << 19)) & allones) == 0) instr = LITERAL.setval(LITERAL_LOW_ZERO.set(instr), il >> 19);
- else if (((il | (-1L << 19)) & allones) == allones) instr = LITERAL.setval(LITERAL_LOW_ONE.set(instr), (il >> 19));
-
- } else if (d instanceof Instruction.HalfLiteral) {
- Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
- if (inst.pump != null) {
- if (inst.high) {
- instr = LITERAL_HI.set(instr);
- instr = LITERAL_HI.setval(instr, inst.literal);
- } else {
- instr = LITERAL_LO.set(instr);
- instr = LITERAL_LO.setval(instr, inst.literal);
+ 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 {
- instr = inst.literal;
}
- } else if (d instanceof Instruction.DecrLoop) {
- instr = DL.set(instr);
-
- } else if (d instanceof Instruction.Counter) {
- Instruction.Counter ic = (Instruction.Counter)d;
- if (ic.dest == DATA_LATCH && ic.source == LOOP_COUNTER) instr = TAKE_LOOP.set(instr);
- else if (ic.dest == LOOP_COUNTER && ic.source == DATA_LATCH) instr = LOOP_FROM_DATA.set(instr);
- else if (ic.dest == REPEAT_COUNTER && ic.source == DATA_LATCH) instr = REPEAT_FROM_DATA.set(instr);
- else if (ic.dest == REPEAT_COUNTER && ic.source == STANDING) instr = REPEAT_FROM_STANDING.set(instr);
- else if (ic.dest == REPEAT_COUNTER) instr = REPEAT_FROM_LITERAL.setval(REPEAT_FROM_LITERAL.set(instr), ic.source);
- else if (ic.dest == LOOP_COUNTER) instr = LOOP_FROM_LITERAL.setval(LOOP_FROM_LITERAL.set(instr), ic.source);
- else throw new RuntimeException();
-
- } else if (d instanceof Instruction.Move) {
- Instruction.Move inst = (Instruction.Move)d;
+ } 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.latch) instr = DC.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.dataOutDest) instr = PATH_DATA.set(instr);
+ if (inst.interruptible) instr = I.set(instr);
+
+ if (inst.latchPath) instr = PATH_DATA.set(instr);
else {
- instr = PATH_LITERAL.set(instr);
- instr = PATH_LITERAL.setval(instr, inst.dest==null?0:getDestAddr(inst.dest));
+ instr = PATH_IMMEDIATE.set(instr);
+ instr = PATH_IMMEDIATE.setval(instr, inst.path==null?0:getDestAddr(inst.path));
}
} else {
- throw new RuntimeException("unrecognized instruction " + d);
+ 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;
+ }
+}