support for [dl] and flags
authoradam <adam@megacz.com>
Thu, 14 Feb 2008 03:52:15 +0000 (04:52 +0100)
committeradam <adam@megacz.com>
Thu, 14 Feb 2008 03:52:15 +0000 (04:52 +0100)
src/edu/berkeley/fleet/api/Instruction.java
src/edu/berkeley/fleet/assembler/Parser.java
src/edu/berkeley/fleet/assembler/fleet.g
src/edu/berkeley/fleet/fpga/Generator.java
src/edu/berkeley/fleet/ies44/InstructionEncoder.java
src/edu/berkeley/fleet/interpreter/Inbox.java
src/edu/berkeley/fleet/interpreter/Outbox.java

index 81af0df..290fcac 100644 (file)
@@ -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;
         }
index c0635d9..2cc226e 100644 (file)
@@ -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<String> 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));
             }
index de5e101..1d6a60b 100644 (file)
@@ -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
index 3256689..9556247 100644 (file)
@@ -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+")");
index a3422e1..2fc3386 100644 (file)
@@ -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) {
index c4ec8cf..4fe5cb5 100644 (file)
@@ -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 =
index ff7e8e2..3a9d411 100644 (file)
@@ -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