From: adam Date: Mon, 11 Feb 2008 15:04:56 +0000 (+0100) Subject: add support for predicates to parser and interpreter X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=a31224e605f396f77669e3a4b20be817c32109e9;p=fleet.git add support for predicates to parser and interpreter --- diff --git a/src/edu/berkeley/fleet/api/Instruction.java b/src/edu/berkeley/fleet/api/Instruction.java index 9a1cb08..788a3a1 100644 --- a/src/edu/berkeley/fleet/api/Instruction.java +++ b/src/edu/berkeley/fleet/api/Instruction.java @@ -32,7 +32,27 @@ public abstract class Instruction { public String toString() { return super.toString() + "kill"+(count==1?"":(" "+count))+";"; } } - public static class SetFlags extends Instruction { + public static class PredicatedInstruction extends Instruction { + public static final int P_ALWAYS = 0x0001; + public static final int P_IF_A = 0x0002; + public static final int P_IF_B = 0x0003; + public static final int P_IF_Z = 0x0004; + + public final int predicate; + public PredicatedInstruction(Pump pump) { super(pump); this.predicate = P_ALWAYS; } + public PredicatedInstruction(Pump pump, int predicate) { super(pump); this.predicate = predicate; } + public String toString() { + switch(predicate) { + case P_ALWAYS: return super.toString(); + case P_IF_A: return "[a] "+super.toString(); + case P_IF_B: return "[b] "+super.toString(); + case P_IF_Z: return "[z] "+super.toString(); + } + throw new Error(); + } + } + + public static class SetFlags extends PredicatedInstruction { public static final int FLAG_Z = 0x0001; public static final int FLAG_NOT_Z = 0x0002; public static final int FLAG_S = 0x0004; @@ -44,11 +64,12 @@ public abstract class Instruction { public final int flag_a; public final int flag_b; - public SetFlags(Pump pump, int flag_a, int flag_b) { - super(pump); + public SetFlags(Pump pump, int predicate, int flag_a, int flag_b) { + super(pump, predicate); this.flag_a = flag_a; this.flag_b = flag_b; } + public SetFlags(Pump pump, int flag_a, int flag_b) { this(pump, P_ALWAYS, flag_a, flag_b); } public boolean isLooping() { return true; } private String printFlag(int flag) { @@ -73,20 +94,22 @@ public abstract class Instruction { } } - public static class DecrLoop extends Instruction { + public static class DecrLoop extends PredicatedInstruction { public DecrLoop(Pump pump) { super(pump); } + public DecrLoop(Pump pump, int predicate) { super(pump, predicate); } public boolean isDL() { return true; } public boolean isLooping() { return true; } } - public static class Counter extends Instruction { + public static class Counter extends PredicatedInstruction { public static final int DATA_LATCH = -1; public static final int REPEAT_COUNTER = -2; public static final int LOOP_COUNTER = -3; public final int source; public final int dest; - public Counter(Pump pump, int source, int dest) { - super(pump); + public Counter(Pump pump, int source, int dest) { this(pump, P_ALWAYS, source, dest); } + public Counter(Pump pump, int predicate, int source, int dest) { + super(pump, predicate); this.source = source; this.dest = dest; } @@ -111,7 +134,7 @@ public abstract class Instruction { public boolean isLooping() { return true; } } - public static class Move extends Instruction { + public static class Move extends PredicatedInstruction { public final Destination dest; public final boolean tokenIn; @@ -126,17 +149,18 @@ public abstract class Instruction { /** count=0 denotes a standing move */ public Move(Pump pump, - Destination dest, - int count, - boolean tokenIn, - boolean dataIn, - boolean latch, - boolean dataOutDest, - boolean dataOut, - boolean tokenOut, - boolean requeue, - boolean ignoreUntilLast) { - super(pump); + int predicate, + Destination dest, + int count, + boolean tokenIn, + boolean dataIn, + boolean latch, + boolean dataOutDest, + boolean dataOut, + boolean tokenOut, + boolean requeue, + boolean ignoreUntilLast) { + super(pump, predicate); this.dest = dest; this.tokenIn = tokenIn; this.dataIn = dataIn; @@ -199,11 +223,12 @@ public abstract class Instruction { } */ - public static class HalfLiteral extends Instruction { + public static class HalfLiteral extends PredicatedInstruction { public final long literal; public final boolean high; public boolean isRequeueing() { return true; } - public HalfLiteral(Pump pump, long literal, int count, boolean high) { + public HalfLiteral(Pump pump, long literal, int count, boolean high) { this(pump, P_ALWAYS, literal, count, high); } + public HalfLiteral(Pump pump, int predicate, long literal, int count, boolean high) { super(pump); this.literal = literal; this.high = high; @@ -211,12 +236,14 @@ public abstract class Instruction { public boolean isLooping() { return true; } } - public static class CodeBagDescriptor extends Instruction { - /** address of CBD, relative to address that this instruction was loaded from */ + + public static class CodeBagDescriptor extends PredicatedInstruction { + // address of CBD, relative to address that this instruction was loaded from public final long offset; public final long size; - public CodeBagDescriptor(Pump pump, long offset, long size) { - super(pump); + public CodeBagDescriptor(Pump pump, long offset, long size) { this(pump, P_ALWAYS, offset, size); } + public CodeBagDescriptor(Pump pump, int predicate, long offset, long size) { + super(pump, predicate); this.offset = offset; this.size = size; } diff --git a/src/edu/berkeley/fleet/assembler/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java index 05c5aaa..9a0ebaf 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -275,6 +275,11 @@ public class Parser { OUTER: for(Tree tt : t.child(1)) { int count = 1; + int predicate = Instruction.PredicatedInstruction.P_ALWAYS; + if ("[a]".equals(tt.child(0).head())) predicate = Instruction.PredicatedInstruction.P_IF_A; + if ("[b]".equals(tt.child(0).head())) predicate = Instruction.PredicatedInstruction.P_IF_B; + if ("[z]".equals(tt.child(0).head())) predicate = Instruction.PredicatedInstruction.P_IF_Z; + tt = tt.child(1); if ("unclog".equals(tt.head())) { cb.add(new Instruction.UnClog(pump)); continue; @@ -383,9 +388,9 @@ public class Parser { else if ("notify".equals(ttt.head())) { tokenOut = true; dest = portReference(ttt.child(0)); } else if ("notifyLast".equals(ttt.head())) { tokenOut = true; ignoreUntilLast = true; dest = portReference(ttt.child(0)); } } - cb.add(new Instruction.Move(pump, - dest, count, tokenIn, dataIn, - latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast)); + cb.add(new Instruction.Move(pump, Instruction.PredicatedInstruction.P_ALWAYS, + dest, count, tokenIn, dataIn, + latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast)); } } } diff --git a/src/edu/berkeley/fleet/assembler/fleet.g b/src/edu/berkeley/fleet/assembler/fleet.g index bfe6a3b..b674b3a 100644 --- a/src/edu/berkeley/fleet/assembler/fleet.g +++ b/src/edu/berkeley/fleet/assembler/fleet.g @@ -11,8 +11,11 @@ CodeBagBody:: = (Fiber | CodeBagDef) */ ws CodeBagDef:: = CodeBagName ":" "{" CodeBagBody "}" /ws Fiber:: = Pump ":" Instructions /ws +// FIXME: should not have predicates on clog/unclog/kill/massacre Instructions:: = Instruction +/ ws -Instruction = ^"unclog" ";" /ws +Instruction:: = Predicate InstructionX +Predicate = "" | ^"[a]" ws | ^"[b]" ws | ^"[z]" ws +InstructionX = ^"unclog" ";" /ws | ^"clog" ";" /ws | ^"massacre" ";" /ws | ^"kill" ";" /ws diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java index 97f11ef..cbe8c76 100644 --- a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -106,6 +106,7 @@ public abstract class InstructionEncoder { boolean standing = STAND.get(inst); boolean dataOutDest = PATH_DATA.get(inst); return new Instruction.Move(name, + Instruction.PredicatedInstruction.P_ALWAYS, /* FIXME */ dest, standing?0:1, tokenIn, diff --git a/src/edu/berkeley/fleet/interpreter/InstructionPump.java b/src/edu/berkeley/fleet/interpreter/InstructionPump.java index 498a14c..8e7fd82 100644 --- a/src/edu/berkeley/fleet/interpreter/InstructionPump.java +++ b/src/edu/berkeley/fleet/interpreter/InstructionPump.java @@ -80,55 +80,69 @@ abstract class InstructionPump extends InterpreterPump { if (executing==null && instructions.size() > 0) executing = instructions.remove(); if (executing==null) return; - int oldLoopCounter = loopCounter; - if (executing.isDL()) loopCounter = Math.max(0, loopCounter-1); - - if (executing instanceof Instruction.Counter) { - Instruction.Counter ic = (Instruction.Counter)executing; - if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) { - setDataLatch(oldLoopCounter); /* FIXME: which is correct here? */ - } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) { - loopCounter = (int)peekDataLatch(); - } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) { - repeatCounter = (int)peekDataLatch(); - } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) { - loopCounter = ic.source; - } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) { - repeatCounter = ic.source; - } - - } else if (executing instanceof Instruction.DecrLoop) { - - } 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) { + if (executing instanceof Instruction.Clog) { clogged++; executing = null; return; - } else { - if (!service(executing)) return; + } + + boolean enabled = true; + if (executing instanceof Instruction.PredicatedInstruction) { + Instruction.PredicatedInstruction ip = (Instruction.PredicatedInstruction)executing; + switch(ip.predicate) { + case Instruction.PredicatedInstruction.P_ALWAYS: enabled = true; break; + case Instruction.PredicatedInstruction.P_IF_A: enabled = flag_a; break; + case Instruction.PredicatedInstruction.P_IF_B: enabled = flag_b; break; + case Instruction.PredicatedInstruction.P_IF_Z: enabled = loopCounter==0; break; + } + } + + int oldLoopCounter = loopCounter; + if (enabled) { + if (executing.isDL()) loopCounter = Math.max(0, loopCounter-1); + + if (executing instanceof Instruction.Counter) { + Instruction.Counter ic = (Instruction.Counter)executing; + if (ic.source == Instruction.Counter.LOOP_COUNTER && ic.dest == Instruction.Counter.DATA_LATCH) { + setDataLatch(oldLoopCounter); /* FIXME: which is correct here? */ + } else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) { + loopCounter = (int)peekDataLatch(); + } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH) { + repeatCounter = (int)peekDataLatch(); + } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) { + loopCounter = ic.source; + } else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) { + repeatCounter = ic.source; + } + + } 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.DecrLoop) { + } else { + if (!service(executing)) return; + } } if (executing==null) return;