From a3813a2e62b9b335d78f65125bd8cb8bc7e52d8a Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 14 Feb 2008 04:52:15 +0100 Subject: [PATCH] support for [dl] and flags --- src/edu/berkeley/fleet/api/Instruction.java | 80 +++++++++++-------- src/edu/berkeley/fleet/assembler/Parser.java | 41 ++++++---- src/edu/berkeley/fleet/assembler/fleet.g | 3 +- src/edu/berkeley/fleet/fpga/Generator.java | 83 +++++++++++++------- .../berkeley/fleet/ies44/InstructionEncoder.java | 53 ++++++++++--- src/edu/berkeley/fleet/interpreter/Inbox.java | 5 +- src/edu/berkeley/fleet/interpreter/Outbox.java | 5 +- 7 files changed, 176 insertions(+), 94 deletions(-) diff --git a/src/edu/berkeley/fleet/api/Instruction.java b/src/edu/berkeley/fleet/api/Instruction.java index 81af0df..290fcac 100644 --- a/src/edu/berkeley/fleet/api/Instruction.java +++ b/src/edu/berkeley/fleet/api/Instruction.java @@ -39,13 +39,21 @@ public abstract class Instruction { public static final int P_IF_Z = 0x0004; public final int predicate; - public PredicatedInstruction(Pump pump, int predicate) { super(pump); this.predicate = predicate; } + public final boolean dl; + public boolean isDL() { return dl; } + + public PredicatedInstruction(Pump pump, boolean dl, int predicate) { + super(pump); + this.predicate = predicate; + this.dl = dl; + } public String toString() { + String dlx = dl ? "[dl] " : ""; 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(); + case P_ALWAYS: return dlx+ super.toString(); + case P_IF_A: return dlx+"[a] "+super.toString(); + case P_IF_B: return dlx+"[b] "+super.toString(); + case P_IF_Z: return dlx+"[z] "+super.toString(); } throw new Error(); } @@ -63,12 +71,12 @@ public abstract class Instruction { public final int flag_a; public final int flag_b; - public SetFlags(Pump pump, int predicate, int flag_a, int flag_b) { - super(pump, predicate); + public SetFlags(Pump pump, boolean dl, int predicate, int flag_a, int flag_b) { + super(pump, dl, 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 SetFlags(Pump pump, int flag_a, int flag_b) { this(pump, false, P_ALWAYS, flag_a, flag_b); } public boolean isLooping() { return true; } private String printFlag(int flag) { @@ -94,8 +102,8 @@ public abstract class Instruction { } public static class DecrLoop extends PredicatedInstruction { - public DecrLoop(Pump pump) { super(pump, P_ALWAYS); } - public DecrLoop(Pump pump, int predicate) { super(pump, predicate); } + public DecrLoop(Pump pump) { super(pump, true, P_ALWAYS); } + public DecrLoop(Pump pump, boolean dl, int predicate) { super(pump, dl, predicate); } public boolean isDL() { return true; } public boolean isLooping() { return true; } } @@ -107,9 +115,9 @@ public abstract class Instruction { public static final int STANDING = -3; public final int source; public final int dest; - 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); + public Counter(Pump pump, int source, int dest) { this(pump, false, P_ALWAYS, source, dest); } + public Counter(Pump pump, boolean dl, int predicate, int source, int dest) { + super(pump, dl, predicate); this.source = source; this.dest = dest; } @@ -150,6 +158,7 @@ public abstract class Instruction { /** count=0 denotes a standing move */ public Move(Pump pump, + boolean dl, int predicate, Destination dest, boolean tokenIn, @@ -160,7 +169,7 @@ public abstract class Instruction { boolean tokenOut, boolean requeue, boolean ignoreUntilLast) { - super(pump, predicate); + super(pump, dl, predicate); this.dest = dest; this.tokenIn = tokenIn; this.dataIn = dataIn; @@ -206,31 +215,36 @@ public abstract class Instruction { public boolean isRepeating() { return true; } } - /* - public static class FullLiteral extends Executable { + public static class HalfLiteral extends PredicatedInstruction { public final long literal; - public boolean isRequeueing() { return true; } - public HalfLiteral(Pump pump, long literal) { - super(pump, 1); + public final boolean high; + public HalfLiteral(Pump pump, boolean dl, int predicate, long literal, int count, boolean high) { + super(pump, dl, predicate); this.literal = literal; + this.high = high; } - public Instruction.Executable decrementCount() { - if (count==1) return null; - return new FullLiteral(pump, literal, count-1, high); - } + public boolean isRequeueing() { return true; } + public boolean isLooping() { return true; } } - */ - public static class HalfLiteral extends PredicatedInstruction { + public static class Literal extends PredicatedInstruction { public final long literal; - public final boolean high; - public boolean isRequeueing() { return true; } - public HalfLiteral(Pump pump, int predicate, long literal, int count, boolean high) { - super(pump, predicate); + public Literal(Pump pump, boolean dl, int predicate, long literal) { + super(pump, dl, predicate); this.literal = literal; - this.high = high; } public boolean isLooping() { return true; } + public boolean isRequeueing() { return true; } + public static boolean canRepresent(long literal) { + long il = literal; + long allones = ~(-1L << 37); + il = literal = literal & allones; + if (((il & ~(-1L << 19)) & allones) == 0) return true; + else if (((il | ~(-1L << 19)) & allones) == allones) return true; + else if (((il & (-1L << 19)) & allones) == 0) return true; + else if (((il | (-1L << 19)) & allones) == allones) return true; + return false; + } } @@ -238,9 +252,9 @@ public abstract class Instruction { // 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) { this(pump, P_ALWAYS, offset, size); } - public CodeBagDescriptor(Pump pump, int predicate, long offset, long size) { - super(pump, predicate); + public CodeBagDescriptor(Pump pump, long offset, long size) { this(pump, false, P_ALWAYS, offset, size); } + public CodeBagDescriptor(Pump pump, boolean dl, int predicate, long offset, long size) { + super(pump, dl, 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 c0635d9..2cc226e 100644 --- a/src/edu/berkeley/fleet/assembler/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -276,10 +276,12 @@ 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); + boolean dl = false; + if ("[dl]".equals(tt.child(0).head())) dl = true; + if ("[a]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_A; + if ("[b]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_B; + if ("[z]".equals(tt.child(1).head())) predicate = Instruction.PredicatedInstruction.P_IF_Z; + tt = tt.child(2); if ("unclog".equals(tt.head())) { cb.add(new Instruction.UnClog(pump)); continue; @@ -291,25 +293,25 @@ public class Parser { cb.add(new Instruction.Kill(pump, count)); continue; } else if ("setflags".equals(tt.head())) { - cb.add(new Instruction.SetFlags(pump, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1)))); + cb.add(new Instruction.SetFlags(pump, dl, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1)))); continue; } else if ("loop".equals(tt.head())) { - cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH)); + cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH)); continue; } else if ("load".equals(tt.head()) && "loop".equals(tt.child(0).head())) { - cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER)); + cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER)); continue; } else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head())) { - cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER)); + cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER)); continue; } else if ("*".equals(tt.head())) { - cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER)); + cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER)); continue; } else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head())) { - cb.add(new Instruction.Counter(pump, predicate, (int)number(tt.child(1)), Instruction.Counter.LOOP_COUNTER)); + cb.add(new Instruction.Counter(pump, dl, predicate, (int)number(tt.child(1)), Instruction.Counter.LOOP_COUNTER)); continue; } else if ("with".equals(tt.head()) && "repeat".equals(tt.child(0).head())) { - cb.add(new Instruction.Counter(pump, predicate, (int)number(tt.child(1)), Instruction.Counter.REPEAT_COUNTER)); + cb.add(new Instruction.Counter(pump, dl, predicate, (int)number(tt.child(1)), Instruction.Counter.REPEAT_COUNTER)); continue; } else if ("massacre".equals(tt.head())) { cb.add(new Instruction.Massacre(pump)); @@ -324,12 +326,12 @@ public class Parser { CodeBag cb2 = getCodeBag("anon"+(anoncount++)); for(Tree statement : tq.child(0)) fillCodeBag(statement, cb2); - cb.add(new Instruction.CodeBagDescriptor(pump, predicate, cb2.getFakeAddress(), 0)); + cb.add(new Instruction.CodeBagDescriptor(pump, dl, predicate, cb2.getFakeAddress(), 0)); continue OUTER; } else if (tt.child(0).head().equals("Name")) { String refname = name(tt.child(0)); CodeBag cb2 = getCodeBag(refname); - cb.add(new Instruction.CodeBagDescriptor(pump, predicate, cb2.getFakeAddress(), 0)); + cb.add(new Instruction.CodeBagDescriptor(pump, dl, predicate, cb2.getFakeAddress(), 0)); continue OUTER; } else if (tt.child(0).head().equals("[")) { literal = parseSSL(tt.child(0)); @@ -342,8 +344,13 @@ public class Parser { } else if ("forever".equals(tt.child(1).head())) { count = 0; } - cb.add(new Instruction.HalfLiteral(pump, predicate, getField(36, 19, literal), count, true)); - cb.add(new Instruction.HalfLiteral(pump, predicate, getField(18, 0, literal), count, false)); + + if (Instruction.Literal.canRepresent(literal)) { + cb.add(new Instruction.Literal(pump, dl, predicate, literal)); + } else { + cb.add(new Instruction.HalfLiteral(pump, dl, predicate, getField(36, 19, literal), count, true)); + cb.add(new Instruction.HalfLiteral(pump, dl, predicate, getField(18, 0, literal), count, false)); + } continue; } Tree ttx = null; @@ -358,7 +365,7 @@ public class Parser { } tt = tt.child(0); if (tt.head().equals("[*]")) { - cb.add(new Instruction.Counter(pump, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER)); + cb.add(new Instruction.Counter(pump, dl, predicate, Instruction.Counter.STANDING, Instruction.Counter.REPEAT_COUNTER)); //count = 0; requeue = false; } else if (tt.head().equals("int")) { @@ -392,7 +399,7 @@ 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, predicate, + cb.add(new Instruction.Move(pump, dl, predicate, dest, 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 de5e101..1d6a60b 100644 --- a/src/edu/berkeley/fleet/assembler/fleet.g +++ b/src/edu/berkeley/fleet/assembler/fleet.g @@ -13,7 +13,8 @@ Fiber:: = Pump ":" Instructions /ws // FIXME: should not have predicates on clog/unclog/kill/massacre Instructions:: = Instruction +/ ws -Instruction:: = Predicate InstructionX +Instruction:: = DL Predicate InstructionX +DL = "" | ^"[dl]" ws Predicate = "" | ^"[a]" ws | ^"[b]" ws | ^"[z]" ws InstructionX = ^"unclog" ";" /ws | ^"clog" ";" /ws diff --git a/src/edu/berkeley/fleet/fpga/Generator.java b/src/edu/berkeley/fleet/fpga/Generator.java index 3256689..9556247 100644 --- a/src/edu/berkeley/fleet/fpga/Generator.java +++ b/src/edu/berkeley/fleet/fpga/Generator.java @@ -583,6 +583,8 @@ public class Generator { Module.Latch repcount2 = box.new Latch("repcount2", WIDTH_COUNTER_LITERAL+1); Module.Latch repeat_counter = box.new Latch("repeat_counter", WIDTH_COUNTER_LITERAL+1); Module.Latch loop_counter = box.new Latch("loop_counter", WIDTH_COUNTER_LITERAL); + Module.Latch flag_a = box.new Latch("flag_a", 1); + Module.Latch flag_b = box.new Latch("flag_b", 1); Module.StateWire ondeckFull = box.new StateWire("ondeck_full"); Module.StateWire newMayProceed = box.new StateWire("newmayproceed", true); Module.StateWire doRepeat = box.new StateWire("dorepeat", false); @@ -737,19 +739,6 @@ public class Generator { isMassacreing.isEmpty(), ififo_in, "!`instruction_is_kill(instr)", - "`instruction_is_decr_loop(ondeck)" - }, - new Action[] { ondeckFull.doDrain(), - newMayProceed.doFill(), - new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)"), - new AssignAction(ififo_in, ondeck), - new ConditionalAction("`should_requeue(ondeck)", ififo_in) - } - ); - box.new Event(new Object[] { ondeckFull.isFull(), - isMassacreing.isEmpty(), - ififo_in, - "!`instruction_is_kill(instr)", "`instruction_is_load_data_to_repeat(ondeck)" }, new Action[] { ondeckFull.doDrain(), @@ -794,7 +783,7 @@ public class Generator { token_out, ififo_in, "!`instruction_is_kill(instr)", - "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) ||"+ + "(`instruction_is_normal(ondeck) || `instruction_is_literal_hi(ondeck) || `instruction_is_setflags(ondeck) || "+ " `instruction_is_literal_lo(ondeck) || `instruction_is_literal(ondeck))", new ConditionalTrigger("`instruction_bit_datain(ondeck)", data_in), new ConditionalTrigger("`instruction_bit_tokenin(ondeck)", token_in) @@ -804,29 +793,41 @@ public class Generator { new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", ififo_in), new ConditionalAction("`should_requeue(ondeck) && `done_executing(ondeck)", new AssignAction(ififo_in, ondeck)), new ConditionalAction("repcount2>1 || repcount2==`magic_standing_value", doRepeat.doFill()), - new ConditionalAction("repcount2!=`magic_standing_value", - new AssignAction(repcount, "repcount2-1")), - new ConditionalAction("repcount2==`magic_standing_value", - new AssignAction(repcount, "`magic_standing_value")), - new ConditionalAction("`instruction_is_literal(ondeck)", + new ConditionalAction("repcount2!=`magic_standing_value", new AssignAction(repcount, "repcount2-1")), + new ConditionalAction("repcount2==`magic_standing_value", new AssignAction(repcount, "`magic_standing_value")), + new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal(ondeck)", new AssignAction(data_latch, "`instruction_literal(ondeck)")), - new ConditionalAction("`instruction_is_literal_hi(ondeck)", + new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal_hi(ondeck)", new AssignAction(data_latch, "`instruction_literal_hi(ondeck,data_latch_output)")), - new ConditionalAction("`instruction_is_literal_lo(ondeck)", + new ConditionalAction("`predicate_met(ondeck) && `instruction_is_literal_lo(ondeck)", new AssignAction(data_latch, "`instruction_literal_lo(ondeck,data_latch_output)")), - new ConditionalAction("`instruction_bit_datain(ondeck)", data_in), - new ConditionalAction("`instruction_bit_dataout(ondeck)", data_out), - new ConditionalAction("`instruction_bit_tokenin(ondeck)", token_in), - new ConditionalAction("`instruction_bit_tokenout(ondeck)", token_out), - new ConditionalAction("`instruction_bit_latch(ondeck)", new AssignAction(data_latch, data_latch_input)), - new ConditionalAction("`instruction_path_from_data(ondeck)", + new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)", + new AssignAction(flag_a, "`new_flag_a(ondeck)")), + new ConditionalAction("`predicate_met(ondeck) && `instruction_is_setflags(ondeck)", + new AssignAction(flag_b, "`new_flag_b(ondeck)")), + new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_datain(ondeck)", data_in), + new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_dataout(ondeck)", data_out), + new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenin(ondeck)", token_in), + new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_tokenout(ondeck)", token_out), + new ConditionalAction("`predicate_met(ondeck) && `instruction_bit_latch(ondeck)", + new AssignAction(data_latch, data_latch_input)), + new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_data(ondeck)", new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), PUMP_NAME.verilogVal(data_latch_input))), - new ConditionalAction("`instruction_path_from_literal(ondeck)", + new ConditionalAction("`predicate_met(ondeck) && `instruction_path_from_literal(ondeck)", new AssignAction(new SimpleAssignable("`packet_dest("+token_out.getName()+")"), "`instruction_path_literal(ondeck)")), } ); + box.new Event(new Object[] { ondeckFull.isFull(), + isMassacreing.isEmpty(), + ififo_in, + "!`instruction_is_kill(instr)", + "`instruction_is_decr_loop(ondeck)" + }, + new Action[] { new AssignAction(loop_counter, "loop_counter==0 ? 0 : (loop_counter-1)") + } + ); PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(prefix+"/"+name+".v"))); @@ -851,6 +852,7 @@ public class Generator { pw.println("`define instruction_is_clog(i) "+CLOG.verilog("i")); pw.println("`define instruction_is_massacre(i) "+MASSACRE.verilog("i")); pw.println("`define instruction_is_normal(i) "+MOVE.verilog("i")); + pw.println("`define instruction_is_setflags(i) "+FLAGS.verilog("i")); pw.println("`define instruction_is_decr_loop(i) "+DL.verilog("i")); @@ -860,6 +862,31 @@ public class Generator { pw.println("`define instruction_bit_datain(i) (`instruction_is_normal(i) && "+DI.verilog("i")+")"); pw.println("`define instruction_bit_tokenin(i) (`instruction_is_normal(i) && "+TI.verilog("i")+")"); pw.println("`define should_requeue(i) (loop_counter > 0)"); + pw.println("`define flag_a flag_a"); + pw.println("`define flag_b flag_b"); + pw.println("`define flag_z (loop_counter==0 ? 1 : 0)"); + pw.println("`define flag_s (data_latch_output["+(WIDTH_WORD-1)+"])"); + pw.println("`define predicate_met(i) 1"); + /* + pw.println("`define predicate_met(i) ("+ + " " + P_A.verilog("i")+" ? `flag_a "+ + ":" + P_B.verilog("i")+" ? `flag_b "+ + ":" + P_Z.verilog("i")+" ? `flag_z "+ + ": 1"+ + ")"); + */ + pw.println("`define new_flag(x) ("+ + "( ((x >> 0) & 1) & !`flag_z) |" + + "( ((x >> 1) & 1) & `flag_z) |" + + "( ((x >> 2) & 1) & !`flag_s) |" + + "( ((x >> 3) & 1) & `flag_s) |" + + "( ((x >> 4) & 1) & !`flag_b) |" + + "( ((x >> 5) & 1) & `flag_b) |" + + "( ((x >> 6) & 1) & !`flag_a) |" + + "( ((x >> 7) & 1) & `flag_a) | 0" + + ")"); + pw.println("`define new_flag_a(i) `new_flag("+FLAGS_A.verilogVal("i")+")"); + pw.println("`define new_flag_b(i) `new_flag("+FLAGS_B.verilogVal("i")+")"); pw.println("`define done_executing(i) (repcount2==0 || repcount2==1)"); pw.println("`define magic_standing_value (1<<"+WIDTH_COUNTER_LITERAL+")"); diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java index a3422e1..2fc3386 100644 --- a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -49,6 +49,10 @@ public abstract class InstructionEncoder { 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.........................."); @@ -94,18 +98,28 @@ public abstract class InstructionEncoder { if (P_B.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_B; if (P_Z.get(inst)) predicate = Instruction.PredicatedInstruction.P_IF_Z; - if (LOOP_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)LOOP_FROM_LITERAL.getval(inst), LOOP_COUNTER); - if (REPEAT_FROM_LITERAL.get(inst)) return new Counter(name, predicate, (int)REPEAT_FROM_LITERAL.getval(inst), REPEAT_COUNTER); - if (LOOP_FROM_DATA.get(inst)) return new Counter(name, predicate, DATA_LATCH, LOOP_COUNTER); - if (REPEAT_FROM_DATA.get(inst)) return new Counter(name, predicate, DATA_LATCH, REPEAT_COUNTER); - if (REPEAT_FROM_STANDING.get(inst)) return new Counter(name, predicate, STANDING, REPEAT_COUNTER); - if (TAKE_LOOP.get(inst)) return new Counter(name, predicate, LOOP_COUNTER, DATA_LATCH); - - if (DL.get(inst)) return new Instruction.DecrLoop(name, predicate); - - if (LITERAL_LO.get(inst)) return new Instruction.HalfLiteral(name, predicate, LITERAL_LO.getval(inst), 0, false); - if (LITERAL_HI.get(inst)) return new Instruction.HalfLiteral(name, predicate, LITERAL_HI.getval(inst), 0, true); - if (FLAGS.get(inst)) return new Instruction.SetFlags(name, predicate, (int)FLAGS_A.getval(inst), (int)FLAGS_B.getval(inst)); + 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 = literal << 19; + else if (LITERAL_LOW_ONE.get(inst)) literal = (literal << 19) | ~(-1L << 19); + else if (LITERAL_HIGH_ZERO.get(inst)) literal = literal; + else if (LITERAL_HIGH_ONE.get(inst)) literal = literal | (-1L << 19); + 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)); @@ -117,6 +131,7 @@ public abstract class InstructionEncoder { boolean tokenOut = TO.get(inst); boolean dataOutDest = PATH_DATA.get(inst); return new Instruction.Move(name, + dl, predicate, dest, tokenIn, @@ -135,8 +150,10 @@ public abstract class InstructionEncoder { if (d.pump != null) instr = PUMP_NAME.setval(instr, getBoxInstAddr(d.pump)); + 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; @@ -148,7 +165,7 @@ public abstract class InstructionEncoder { if (d instanceof Instruction.CodeBagDescriptor) { Instruction.CodeBagDescriptor lc = (Instruction.CodeBagDescriptor)d; // MAJOR MAJOR FIXME: upper half here... - d = new Instruction.HalfLiteral(lc.pump, Instruction.PredicatedInstruction.P_ALWAYS, + d = new Instruction.HalfLiteral(lc.pump, dl, Instruction.PredicatedInstruction.P_ALWAYS, ((lc.offset << WIDTH_CODEBAG_SIZE)) | lc.size, 1, false); } @@ -172,6 +189,16 @@ public abstract class InstructionEncoder { 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; + 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) { diff --git a/src/edu/berkeley/fleet/interpreter/Inbox.java b/src/edu/berkeley/fleet/interpreter/Inbox.java index c4ec8cf..4fe5cb5 100644 --- a/src/edu/berkeley/fleet/interpreter/Inbox.java +++ b/src/edu/berkeley/fleet/interpreter/Inbox.java @@ -54,7 +54,10 @@ public class Inbox extends InstructionPump { // if no instruction waiting, do nothing if (instruction_ == null) return false; - if (instruction_ instanceof Instruction.HalfLiteral) { + if (instruction_ instanceof Instruction.Literal) { + register = new Packet(getInterpreter(), null, ((Instruction.Literal)instruction_).literal, null); + return true; + } else if (instruction_ instanceof Instruction.HalfLiteral) { Instruction.HalfLiteral ll = (Instruction.HalfLiteral)instruction_; long val = (register==null) ? 0 : register.value; val = diff --git a/src/edu/berkeley/fleet/interpreter/Outbox.java b/src/edu/berkeley/fleet/interpreter/Outbox.java index ff7e8e2..3a9d411 100644 --- a/src/edu/berkeley/fleet/interpreter/Outbox.java +++ b/src/edu/berkeley/fleet/interpreter/Outbox.java @@ -31,7 +31,10 @@ public class Outbox extends InstructionPump { protected long peekDataLatch() { return register; } protected final boolean service(Instruction instruction_) { - if (instruction_ instanceof Instruction.HalfLiteral) { + if (instruction_ instanceof Instruction.Literal) { + register = ((Instruction.Literal)instruction_).literal; + return true; + } else if (instruction_ instanceof Instruction.HalfLiteral) { Instruction.HalfLiteral ll = (Instruction.HalfLiteral)instruction_; register = ll.high -- 1.7.10.4