public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; }
}
+ public static class SetFlags extends Instruction {
+ public static final int FLAG_Z = 0x0001;
+ public static final int FLAG_NOT_Z = 0x0002;
+ public static final int FLAG_S = 0x0004;
+ public static final int FLAG_NOT_S = 0x0008;
+ public static final int FLAG_B = 0x0010;
+ public static final int FLAG_NOT_B = 0x0020;
+ public static final int FLAG_A = 0x0040;
+ public static final int FLAG_NOT_A = 0x0080;
+
+ public final int flag_a;
+ public final int flag_b;
+ public SetFlags(Pump pump, int flag_a, int flag_b) {
+ super(pump);
+ this.flag_a = flag_a;
+ this.flag_b = flag_b;
+ }
+
+ public boolean isLooping() { return true; }
+ private String printFlag(int flag) {
+ if (flag==0) return "0";
+ if ((flag & (FLAG_Z | FLAG_NOT_Z)) == (FLAG_Z | FLAG_NOT_Z)) return "1";
+ if ((flag & (FLAG_B | FLAG_NOT_B)) == (FLAG_B | FLAG_NOT_B)) return "1";
+ if ((flag & (FLAG_A | FLAG_NOT_A)) == (FLAG_A | FLAG_NOT_A)) return "1";
+ if ((flag & (FLAG_S | FLAG_NOT_S)) == (FLAG_S | FLAG_NOT_S)) return "1";
+ String ret = "";
+ if ((flag & FLAG_A) != 0) ret += (ret.length()>=0?"|":"") + "a";
+ if ((flag & FLAG_NOT_A) != 0) ret += (ret.length()>=0?"|":"") + "!a";
+ if ((flag & FLAG_B) != 0) ret += (ret.length()>=0?"|":"") + "b";
+ if ((flag & FLAG_NOT_B) != 0) ret += (ret.length()>=0?"|":"") + "!b";
+ if ((flag & FLAG_S) != 0) ret += (ret.length()>=0?"|":"") + "s";
+ if ((flag & FLAG_NOT_S) != 0) ret += (ret.length()>=0?"|":"") + "!s";
+ if ((flag & FLAG_Z) != 0) ret += (ret.length()>=0?"|":"") + "z";
+ if ((flag & FLAG_NOT_Z) != 0) ret += (ret.length()>=0?"|":"") + "!z";
+ return ret;
+ }
+ public String toString() {
+ return super.toString() + " setflags a=" + printFlag(flag_a) + ", b=" + printFlag(flag_b);
+ }
+ }
+
public static class DecrLoop extends Instruction {
public DecrLoop(Pump pump) { super(pump); }
public boolean isDL() { return true; }
import edu.berkeley.sbp.meta.*;
import edu.berkeley.sbp.util.*;
import static edu.berkeley.fleet.util.BitManipulations.*;
+import static edu.berkeley.fleet.api.Instruction.SetFlags.*;
import java.util.*;
import java.io.*;
return literal;
}
+ private static int parseFlags(Tree<String> t) {
+ int ret = 0;
+ for(int i=0; i<t.size(); i++) {
+ String s = t.child(i).head();
+ if (s.equals("0")) continue;
+ if (s.equals("1")) { ret |= (FLAG_A | FLAG_NOT_A); }
+ if (s.equals("a")) ret |= FLAG_A;
+ if (s.equals("!a")) ret |= FLAG_NOT_A;
+ if (s.equals("b")) ret |= FLAG_B;
+ if (s.equals("!b")) ret |= FLAG_NOT_B;
+ if (s.equals("z")) ret |= FLAG_Z;
+ if (s.equals("!z")) ret |= FLAG_NOT_Z;
+ if (s.equals("s")) ret |= FLAG_S;
+ if (s.equals("!s")) ret |= FLAG_NOT_S;
+ }
+ return ret;
+ }
+
private int anoncount = 1;
void fillCodeBag(Tree<String> t, CodeBag cb) {
if (t.head()==null) return;
count = tt.size()==0 ? 1 : (int)number(tt.child(0));
cb.add(new Instruction.Kill(pump, count));
continue;
+ } else if ("setflags".equals(tt.head())) {
+ cb.add(new Instruction.SetFlags(pump, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
+ continue;
} else if ("loop".equals(tt.head())) {
cb.add(new Instruction.Counter(pump, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH));
continue;
| ^"load" (^"loop"|^"repeat") ws "counter" ";" /ws
| "load" (^"loop"|^"repeat") ws "counter" ^"with" int ";" /ws
| ^"decrement" "loop" "counter" ";" /ws
- | ^"setflags" ws "a=" Flag ws "b=" Flag ws ";"
+ | ^"setflags" "a" "=" Flags "," "b" "=" Flags ";" /ws
| ^"kill" int ";" /ws
| ^"literal" Literal RequeueCount ";" /ws
| RepeatCount Commands RequeueCount ^";" /ws
RequeueCount = ""
| "," "requeue" (^"forever" | int ws "times") /ws
+Flags:: = Flag +/ (ws "|" ws)
Flag = ^"0"
| ^"1"
| ^"a"
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.........0......");
public static final Mask REPEAT_FROM_LITERAL = new Mask("...............000001.........1vvvvvv");
public static final Mask LOOP_FROM_DATA = new Mask("...............000010.........0......");
if (KILL.get(inst)) return new Instruction.Kill(name, (int)(KILL.getval(inst)+1));
if (LITERAL_LO.get(inst)) return new Instruction.HalfLiteral(name, LITERAL_LO.getval(inst), 0, false);
if (LITERAL_HI.get(inst)) return new Instruction.HalfLiteral(name, LITERAL_HI.getval(inst), 0, true);
+ if (FLAGS.get(inst)) return new Instruction.SetFlags(name, (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);
} 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.HalfLiteral) {
Instruction.HalfLiteral inst = (Instruction.HalfLiteral)d;
if (inst.pump != null) {
}
if (inst.standing) instr = STAND.set(instr);
+ } else {
+ throw new RuntimeException("unrecognized instruction " + d);
+
}
return instr;
}
public int clogged = 0;
+ public boolean flag_a = false;
+ public boolean flag_b = false;
+
/** the currently executing instruction */
private Instruction executing = null;
} else if (executing instanceof Instruction.DecrLoop) {
executing = null;
return;
+ } else if (executing instanceof Instruction.SetFlags) {
+ Instruction.SetFlags sf = (Instruction.SetFlags)executing;
+ boolean old_s = ((peekDataLatch() >> (getInterpreter().getWordSize()-1)) & 1) != 0;
+ boolean old_z = oldLoopCounter == 0;
+ boolean old_a = flag_a;
+ boolean old_b = flag_b;
+ flag_a =
+ (((sf.flag_a & sf.FLAG_A) != 0) ? old_a : false) |
+ (((sf.flag_a & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
+ (((sf.flag_a & sf.FLAG_B) != 0) ? old_b : false) |
+ (((sf.flag_a & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
+ (((sf.flag_a & sf.FLAG_Z) != 0) ? old_z : false) |
+ (((sf.flag_a & sf.FLAG_NOT_Z) != 0) ? !old_z : false) |
+ (((sf.flag_a & sf.FLAG_S) != 0) ? old_s : false) |
+ (((sf.flag_a & sf.FLAG_NOT_S) != 0) ? !old_s : false);
+ flag_b =
+ (((sf.flag_b & sf.FLAG_A) != 0) ? old_a : false) |
+ (((sf.flag_b & sf.FLAG_NOT_A) != 0) ? !old_a : false) |
+ (((sf.flag_b & sf.FLAG_B) != 0) ? old_b : false) |
+ (((sf.flag_b & sf.FLAG_NOT_B) != 0) ? !old_b : false) |
+ (((sf.flag_b & sf.FLAG_Z) != 0) ? old_z : false) |
+ (((sf.flag_b & sf.FLAG_NOT_Z) != 0) ? !old_z : false) |
+ (((sf.flag_b & sf.FLAG_S) != 0) ? old_s : false) |
+ (((sf.flag_b & sf.FLAG_NOT_S) != 0) ? !old_s : false);
} else if (executing instanceof Instruction.Clog) {
clogged++;
executing = null;