From: adam Date: Mon, 11 Feb 2008 13:08:03 +0000 (+0100) Subject: add SetFlags instruction to API and interpreter X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=2e31794004d51453a7ee97d878ce9a6997fc47e8;p=fleet.git add SetFlags instruction to API and interpreter --- diff --git a/src/edu/berkeley/fleet/api/Instruction.java b/src/edu/berkeley/fleet/api/Instruction.java index 4cfe0b2..039021e 100644 --- a/src/edu/berkeley/fleet/api/Instruction.java +++ b/src/edu/berkeley/fleet/api/Instruction.java @@ -32,6 +32,47 @@ public abstract class Instruction { 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; } diff --git a/src/edu/berkeley/fleet/assembler/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java index dcd5289..05c5aaa 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -6,6 +6,7 @@ import edu.berkeley.sbp.misc.*; 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.*; @@ -243,6 +244,24 @@ public class Parser { return literal; } + private static int parseFlags(Tree t) { + int ret = 0; + for(int i=0; i t, CodeBag cb) { if (t.head()==null) return; @@ -266,6 +285,9 @@ public class Parser { 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; diff --git a/src/edu/berkeley/fleet/assembler/fleet.g b/src/edu/berkeley/fleet/assembler/fleet.g index 0c89dea..bfe6a3b 100644 --- a/src/edu/berkeley/fleet/assembler/fleet.g +++ b/src/edu/berkeley/fleet/assembler/fleet.g @@ -20,7 +20,7 @@ Instruction = ^"unclog" ";" /ws | ^"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 @@ -28,6 +28,7 @@ RepeatCount = "" | ^"[*]" | "[" int "]" RequeueCount = "" | "," "requeue" (^"forever" | int ws "times") /ws +Flags:: = Flag +/ (ws "|" ws) Flag = ^"0" | ^"1" | ^"a" diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java index cabdca4..97f11ef 100644 --- a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -14,6 +14,9 @@ public abstract class InstructionEncoder { 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......"); @@ -90,6 +93,9 @@ public abstract class InstructionEncoder { 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); @@ -138,6 +144,12 @@ public abstract class InstructionEncoder { } 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) { @@ -179,6 +191,9 @@ public abstract class InstructionEncoder { } if (inst.standing) instr = STAND.set(instr); + } else { + throw new RuntimeException("unrecognized instruction " + d); + } return instr; } diff --git a/src/edu/berkeley/fleet/interpreter/InstructionPump.java b/src/edu/berkeley/fleet/interpreter/InstructionPump.java index b600615..b5b0960 100644 --- a/src/edu/berkeley/fleet/interpreter/InstructionPump.java +++ b/src/edu/berkeley/fleet/interpreter/InstructionPump.java @@ -11,6 +11,9 @@ abstract class InstructionPump extends InterpreterPump { public int clogged = 0; + public boolean flag_a = false; + public boolean flag_b = false; + /** the currently executing instruction */ private Instruction executing = null; @@ -96,6 +99,30 @@ abstract class InstructionPump extends InterpreterPump { } 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;